001    /*
002     * The contents of this file are subject to the Mozilla Public
003     * License Version 1.1 (the "License"); you may not use this file
004     * except in compliance with the License. You may obtain a copy of
005     * the License at http://www.mozilla.org/MPL/
006     *
007     * Software distributed under the License is distributed on an "AS
008     * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
009     * implied. See the License for the specific language governing
010     * rights and limitations under the License.
011     *
012     * The Original Code is Knowtator.
013     *
014     * The Initial Developer of the Original Code is University of Colorado.  
015     * Copyright (C) 2005 - 2008.  All Rights Reserved.
016     *
017     * Knowtator was developed by the Center for Computational Pharmacology
018     * (http://compbio.uchcs.edu) at the University of Colorado Health 
019     *  Sciences Center School of Medicine with support from the National 
020     *  Library of Medicine.  
021     *
022     * Current information about Knowtator can be obtained at 
023     * http://knowtator.sourceforge.net/
024     *
025     * Contributor(s):
026     *   Philip V. Ogren <philip@ogren.info> (Original Author)
027     */
028    
029    /**
030     * Changes:
031     *  8/18/2005   pvo   added license
032     *  8/18/2005   pvo   added method getMentionAnnotationText to remove some duplicate code and 
033     *                    to support next change item
034     *  8/18/2005   pvo   if a browser pattern element contains a special token for the annotation text, then
035     *                    this is added to the browserText of the annotation.  When editing the
036     *                    the multi-slot browser pattern in Protege, one can add the string "[text]" in 
037     *                    one of the text fields to have the annotated text of the annotation inserted.
038     *                    This makes the integration of the annotation text and browser patterns possible.  
039     *  8/18/2005   pvo   addded method comparator for sorting annotations by their browsertext
040     */
041    package edu.uchsc.ccp.knowtator;
042    
043    import java.util.Collection;
044    import java.util.Comparator;
045    import java.util.HashSet;
046    import java.util.Iterator;
047    import java.util.List;
048    import java.util.Set;
049    
050    import edu.stanford.smi.protege.model.BrowserSlotPattern;
051    import edu.stanford.smi.protege.model.Cls;
052    import edu.stanford.smi.protege.model.Frame;
053    import edu.stanford.smi.protege.model.Instance;
054    import edu.stanford.smi.protege.model.SimpleInstance;
055    import edu.stanford.smi.protege.model.Slot;
056    import edu.stanford.smi.protege.util.CollectionUtilities;
057    
058    /**
059     * 
060     * @author Philip V. Ogren
061     */
062    public class BrowserTextUtil {
063    
064            public static final String ANNOTATION_TEXT = "[text]";
065    
066            AnnotationUtil annotationUtil;
067    
068            MentionUtil mentionUtil;
069    
070            KnowtatorProjectUtil kpu;
071    
072            /** Creates a new instance of BrowserText */
073            public BrowserTextUtil(AnnotationUtil annotationUtil, MentionUtil mentionUtil, KnowtatorProjectUtil kpu) {
074                    this.annotationUtil = annotationUtil;
075                    this.mentionUtil = mentionUtil;
076                    this.kpu = kpu;
077            }
078    
079            public String getBrowserText(SimpleInstance instance, int maxLength) {
080                    String browserText = getBrowserText(instance);
081                    if (browserText == null)
082                            return "";
083                    if (browserText.length() > maxLength) {
084                            browserText = browserText.substring(0, maxLength) + "...";
085                    }
086                    return browserText.trim();
087            }
088    
089            /**
090             * The BrowserSlotPattern in the Protege code does not work very well with
091             * annotations and their mentions. This code generates browser text that
092             * tries to capture the BrowserSlotPatterns of the Instances and Clses that
093             * are being mentioned/annotated.
094             * 
095             * If an annotation is passed in, then the instance.getBrowserText() will be
096             * returned if there is any. This will typically be the text found in
097             * knowtator_annotation_text. If there is no text returned, then text
098             * corresponding to the annotated mention will be returned via a recursive
099             * call (see next paragraph).
100             * 
101             * If a mention is passed in, then a browser text corresponding to the
102             * BrowserSlotPattern of the mentioned cls will be constructed.
103             * 
104             * Much of this code was copied and modified from
105             * edu.stanford.smi.protege.model.BrowserSlotPattern.java
106             */
107            public String getBrowserText(SimpleInstance instance) {
108                    Set<SimpleInstance> visitedInstances = new HashSet<SimpleInstance>();
109                    return _getBrowserText(instance, visitedInstances).trim();
110            }
111    
112            private String _getBrowserText(SimpleInstance instance, Set<SimpleInstance> visitedInstances) {
113                    if (instance == null)
114                            return "";
115    
116                    if (visitedInstances.contains(instance))
117                            return "";
118    
119                    visitedInstances.add(instance);
120    
121                    // if the instance is an annotation then we will simply return the
122                    // instance.getBrowserText()
123                    // unless there isn't any in which case we will recursively call
124                    // getBrowserText on the mention
125                    // of the annotation (if possible).
126                    if (annotationUtil.isAnnotation(instance)) {
127                            // String instanceBrowserText = instance.getBrowserText();
128                            // if(!instanceBrowserText.equals(instance.getName()))
129                            // return instanceBrowserText;
130    
131                            String instanceName = instance.getName();
132    
133                            SimpleInstance mention = annotationUtil.getMention(instance);
134                            if (mention == null) {
135                                    return instanceName;
136                            } else {
137                                    String browserText = _getBrowserText(mention, visitedInstances);
138                                    if (browserText == null || browserText.trim().length() == 0) {
139                                            return instanceName;
140                                    } else if (browserText.equals(mention.getName())) {
141                                            return instanceName;
142                                    } else
143                                            return browserText;
144                            }
145                    } else if (mentionUtil.isMention(instance)) {
146                            Cls mentionCls = mentionUtil.getMentionCls(instance);
147                            if (mentionCls != null) {
148                                    BrowserSlotPattern slotPattern = mentionCls.getBrowserSlotPattern();
149                                    if (slotPattern != null) {
150                                            StringBuffer browserTextBuffer = new StringBuffer();
151                                            List patternElements = slotPattern.getElements();
152                                            for (int i = 0; i < patternElements.size(); i++) {
153                                                    Object patternElement = patternElements.get(i);
154                                                    if (patternElement instanceof Slot) {
155                                                            browserTextBuffer.append(getText((Slot) patternElement, instance, visitedInstances));
156                                                    } else {
157                                                            String patternString = patternElement.toString();
158                                                            if (patternString.contains(ANNOTATION_TEXT)) {
159                                                                    String annotationText = getMentionAnnotationText(instance);
160                                                                    if (annotationText != null) {
161                                                                            patternString = patternString.replace(ANNOTATION_TEXT, annotationText);
162                                                                            patternElement = patternString;
163                                                                    }
164                                                            }
165    
166                                                            browserTextBuffer.append(patternElement);
167                                                    }
168                                            }
169                                            if (browserTextBuffer.length() > 0) {
170                                                    return browserTextBuffer.toString();
171                                            }
172                                    } else if (mentionUtil.isClassMention(instance) || mentionUtil.isInstanceMention(instance)) {
173                                            String annotationText = getMentionAnnotationText(instance);
174    
175                                            if (annotationText != null)
176                                                    return annotationText;
177                                    } else {
178                                            try {
179                                                    if (mentionUtil.isClassMention(instance)) {
180                                                            return mentionCls.getBrowserText();
181                                                    } else if (mentionUtil.isInstanceMention(instance)) {
182                                                            SimpleInstance mentionInstance = mentionUtil.getMentionInstance(instance);
183                                                            if (mentionInstance != null)
184                                                                    return mentionInstance.getBrowserText();
185                                                    } else if (mentionUtil.isSlotMention(instance)) {
186                                                            Slot mentionSlot = mentionUtil.getSlotMentionSlot(instance);
187                                                            if (mentionSlot != null)
188                                                                    return mentionSlot.getBrowserText();
189                                                    }
190                                            } catch (NullPointerException npe) {
191                                            }
192                                    }
193                            }
194                            return instance.getBrowserText();
195                    }
196                    return instance.getBrowserText();
197            }
198    
199            /**
200             * Much of this code was copied and modified from
201             * edu.stanford.smi.protege.model.BrowserSlotPattern.java
202             */
203            private String getText(Slot slot, SimpleInstance mention, Set<SimpleInstance> visitedInstances) {
204                    String text;
205    
206                    SimpleInstance slotMention = mentionUtil.getSlotMention(mention, slot);
207                    if (slotMention == null)
208                            return "";
209    
210                    Collection slotMentionValues = slotMention.getOwnSlotValues(kpu.mentionSlotValueSlot);
211                    if (slotMentionValues == null)
212                            return "";
213                    if (slotMentionValues.size() > 1) {
214                            StringBuffer buffer = new StringBuffer();
215                            buffer.append("{");
216                            boolean isFirst = true;
217                            Iterator i = slotMentionValues.iterator();
218                            while (i.hasNext()) {
219                                    if (isFirst) {
220                                            isFirst = false;
221                                    } else {
222                                            buffer.append(", ");
223                                    }
224                                    Object o = i.next();
225                                    buffer.append(getText(o, mention, visitedInstances));
226                            }
227                            buffer.append("}");
228                            text = buffer.toString();
229                    } else {
230                            Object o = CollectionUtilities.getFirstItem(slotMentionValues);
231                            text = getText(o, mention, visitedInstances);
232                    }
233                    return text;
234            }
235    
236            /**
237             * Much of this code was copied and modified from
238             * edu.stanford.smi.protege.model.BrowserSlotPattern.java
239             */
240            private String getText(Object slotValue, Instance instance, Set<SimpleInstance> visitedInstances) {
241                    if (slotValue == null) {
242                            return "";
243                    }
244                    if (slotValue instanceof Frame) {
245                            if (slotValue.equals(instance)) {
246                                    return "<recursive call>";
247                            } else if (slotValue instanceof SimpleInstance) {
248                                    SimpleInstance simpleInstance = (SimpleInstance) slotValue;
249                                    return _getBrowserText(simpleInstance, visitedInstances);
250                            } else {
251                                    return ((Frame) slotValue).getBrowserText();
252                            }
253                    } else {
254                            return slotValue.toString();
255                    }
256            }
257    
258            private String getMentionAnnotationText(SimpleInstance instance) {
259                    if (mentionUtil.isMention(instance)) {
260                            SimpleInstance mentionAnnotation = mentionUtil.getMentionAnnotation(instance);
261                            if (mentionAnnotation != null) {
262                                    String annotationText = mentionAnnotation.getBrowserText();
263                                    if (annotationText.equals(mentionAnnotation.getName()))
264                                            return "";
265                                    else {
266                                            return annotationText;
267                                    }
268    
269                            }
270                    }
271                    return null;
272            }
273    
274            public Comparator<SimpleInstance> comparator() {
275                    return new Comparator<SimpleInstance>() {
276                            public int compare(SimpleInstance annotation1, SimpleInstance annotation2) {
277                                    String browserText1 = getBrowserText(annotation1).toLowerCase();
278                                    String browserText2 = getBrowserText(annotation2).toLowerCase();
279                                    return browserText1.compareTo(browserText2);
280                            }
281                    };
282            }
283    }