DetailsTableModel.java
001 /*
002  *  Copyright (c) 1995-2012, The University of Sheffield. See the file
003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004  *
005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
006  *  software, licenced under the GNU Library General Public License,
007  *  Version 2, June 1991 (in the distribution as file licence.html,
008  *  and also available at http://gate.ac.uk/gate/licence.html).
009  *
010  *  Niraj Aswani, 09/March/07
011  *
012  *  $Id: DetailsTableModel.html,v 1.0 2007/03/09 16:13:01 niraj Exp $
013  */
014 package gate.gui.ontology;
015 
016 import gate.creole.ontology.AnnotationProperty;
017 import gate.creole.ontology.DatatypeProperty;
018 import gate.creole.ontology.InvalidValueException;
019 import gate.creole.ontology.Literal;
020 import gate.creole.ontology.OClass;
021 import gate.creole.ontology.OConstants;
022 import gate.creole.ontology.OInstance;
023 import gate.creole.ontology.OResource;
024 import gate.creole.ontology.OValue;
025 import gate.creole.ontology.ObjectProperty;
026 import gate.creole.ontology.Ontology;
027 import gate.creole.ontology.RDFProperty;
028 import gate.creole.ontology.Restriction;
029 import gate.gui.MainFrame;
030 
031 import java.util.Collections;
032 import java.util.Iterator;
033 import java.util.List;
034 import java.util.Set;
035 
036 import javax.swing.JOptionPane;
037 import javax.swing.table.AbstractTableModel;
038 
039 /**
040  * A DataModel that is created when a node is selected in the ontology
041  * tree. It contains information such as direct/all sub/super classes,
042  * equivalent classes, instances, properties/ property values and so on.
043  * The information from this model is then shown in the right hand side
044  * panel of the ontology editor.
045  
046  @author niraj
047  
048  */
049 public class DetailsTableModel extends AbstractTableModel {
050   private static final long serialVersionUID = 3834870286880618035L;
051 
052   public DetailsTableModel() {
053     ontologyMode = false;
054     resourceInfo = new DetailsGroup("Resource Information",true,null);
055     directSuperClasses = new DetailsGroup("Direct Super Classes", true, null);
056     allSuperClasses = new DetailsGroup("All Super Classes", true, null);
057     directSubClasses = new DetailsGroup("Direct Sub Classes", true, null);
058     allSubClasses = new DetailsGroup("All Sub Classes", true, null);
059     equivalentClasses = new DetailsGroup("Equivalent Classes", true, null);
060     sameAsInstances = new DetailsGroup("Same Instances", true, null);
061     instances = new DetailsGroup("Instances", true, null);
062     propertyTypes = new DetailsGroup("Property Types", true, null);
063     propertyValues = new DetailsGroup("Property Values", true, null);
064     directTypes = new DetailsGroup("Direct Types", true, null);
065     allTypes = new DetailsGroup("All Types", true, null);
066     detailGroups = new DetailsGroup[0];
067     itemComparator = new OntologyItemComparator();
068   }
069 
070   @Override
071   public int getColumnCount() {
072     return COLUMN_COUNT;
073   }
074 
075   @Override
076   public int getRowCount() {
077     int count = detailGroups.length;
078     for(int j = 0; j < detailGroups.length; j++)
079       if(detailGroups[j].isExpanded()) {
080         count += detailGroups[j].getSize();
081       }
082     return count;
083   }
084 
085   @Override
086   public String getColumnName(int column) {
087     switch(column) {
088       case EXPANDED_COLUMN:
089         return "";
090       case LABEL_COLUMN:
091         return "";
092       case VALUE_COLUMN:
093         return "Value";
094       case DELETE_COLUMN:
095         return "Delete";
096     }
097     return "";
098   }
099 
100   @Override
101   public Class<?> getColumnClass(int columnIndex) {
102     switch(columnIndex) {
103       case EXPANDED_COLUMN:
104         return String.class;
105       case LABEL_COLUMN:
106         return Object.class;
107       case VALUE_COLUMN:
108         return String.class;
109       case DELETE_COLUMN:
110         return Object.class;
111       
112     }
113     return Object.class;
114   }
115 
116   @Override
117   public boolean isCellEditable(int rowIndex, int columnIndex) {
118     if (columnIndex != VALUE_COLUMN) { return false}
119     Object object = getItemForRow(rowIndex);
120     if (!(object instanceof PropertyValue)) { return false}
121     RDFProperty property = ((PropertyValueobject).getProperty();
122     return property instanceof AnnotationProperty
123         || property instanceof DatatypeProperty;
124   }
125 
126   @Override
127   public void setValueAt(Object value, int row, int col) {
128     Object object = getItemForRow(row);
129     switch (col) {
130       case EXPANDED_COLUMN:
131         if (object instanceof DetailsGroup) {
132           DetailsGroup detailsgroup = (DetailsGroupobject;
133           detailsgroup.setExpanded((Booleanvalue);
134         }
135         break;
136       case VALUE_COLUMN:
137         if (object instanceof PropertyValue) {
138           PropertyValue propertyValue = (PropertyValueobject;
139           RDFProperty property = propertyValue.getProperty();
140           if (property instanceof AnnotationProperty) {
141             // update the ontology
142             oResource.removeAnnotationPropertyValue((AnnotationProperty)
143               property, (LiteralpropertyValue.getValue());
144             oResource.addAnnotationPropertyValue((AnnotationProperty)
145               property, new Literal((Stringvalue));
146             // update the data structure for this table
147             setItemForRow(row, new PropertyValue(
148               property, new Literal((Stringvalue)));
149           else if (property instanceof DatatypeProperty) {
150             boolean isValidValue = ((DatatypeProperty)property)
151               .getDataType().isValidValue((Stringvalue);
152             if (!isValidValue) {
153               JOptionPane.showMessageDialog(MainFrame.getInstance(),
154                 "Incompatible value: " + value +
155                 "\nUse a value of type " ((DatatypeProperty)property)
156                 .getDataType().getXmlSchemaURIString()
157                   .replaceFirst("http://www.w3.org/2001/XMLSchema#"""));
158               return;
159             }
160             try {
161               ((OInstance)oResource).removeDatatypePropertyValue(
162                 (DatatypeProperty)property, (Literal)propertyValue.getValue());
163               ((OInstance)oResource).addDatatypePropertyValue(
164                 (DatatypeProperty)property, new Literal((Stringvalue,
165                   ((DatatypeProperty)property).getDataType()));
166               setItemForRow(row, new PropertyValue(
167                 property, new Literal((Stringvalue)));
168             catch(InvalidValueException e) {
169               JOptionPane.showMessageDialog(MainFrame.getInstance(),
170                       "Incompatible value");
171               e.printStackTrace();
172               return;
173             }
174           }
175         }
176         break;
177     }
178     // redraw the table
179     fireTableDataChanged();
180   }
181 
182   protected Object getItemForRow(int row) {
183     int groupRow = 0;
184     for (int groupIndex = 0; groupRow <= row; groupIndex++) {
185       if (groupRow == row) {
186         return detailGroups[groupIndex];
187       }
188       int groupSize = (detailGroups[groupIndex].isExpanded() ?
189         detailGroups[groupIndex].getSize() 0);
190       if (groupRow + groupSize > row) {
191         return detailGroups[groupIndex].getValueAt(row - groupRow - 1);
192       }
193       groupRow += groupSize;
194     }
195     return null;
196   }
197 
198   protected void setItemForRow(int row, Object value) {
199     int groupRow = 0;
200     for (int groupIndex = 0; groupRow <= row; groupIndex++) {
201       if (groupRow == row) {
202         detailGroups[groupIndex].setExpanded((Booleanvalue);
203         return;
204       }
205       int groupSize = (detailGroups[groupIndex].isExpanded() ?
206         detailGroups[groupIndex].getSize() 0);
207       if (groupRow + groupSize > row) {
208         detailGroups[groupIndex].setValueAt(row - groupRow - 1, value);
209         return;
210       }
211       groupRow += groupSize;
212     }
213   }
214 
215   @Override
216   public Object getValueAt(int row, int col) {
217     Object object = getItemForRow(row);
218     switch(col) {
219       case EXPANDED_COLUMN:
220         return (object instanceof DetailsGroup?
221                  ((DetailsGroupobject).getSize() ?
222                    ((DetailsGroupobject).isExpanded() ?
223                      "expanded" "closed" "empty" null;
224       case LABEL_COLUMN:
225         return object;
226       case VALUE_COLUMN:
227         if (object instanceof DetailsGroup) {
228           return "";
229         else if (object instanceof PropertyValue) {
230           PropertyValue property = (PropertyValueobject;
231           if(property.getValue() instanceof Literal) {
232             return ((Literal)property.getValue()).getValue();
233           else {
234             return property.getValue().toString();
235           }
236         else if (object instanceof KeyValuePair) {
237             KeyValuePair keyValuePair = (KeyValuePairobject;
238             return keyValuePair.getValue().toString();
239         else if (object instanceof RDFProperty) {
240           RDFProperty property = (RDFPropertyobject;
241           if (property instanceof DatatypeProperty) {
242             return ((DatatypeProperty)property).getDataType()
243               .getXmlSchemaURIString();
244           else if (!(property instanceof AnnotationProperty)) {
245             @SuppressWarnings("deprecation")
246             Set<OResource> set = property.getRange();
247             if (set == null || set.isEmpty()) {
248               return "[ALL CLASSES]";
249             else {
250               String s = "[";
251               boolean firstTime = true;
252               for(OResource res : set) {
253                 if (!firstTime) {
254                   s += ",";
255                 else {
256                   firstTime = false;
257                 }
258                 s += res.getName();
259               }
260               s += "]";
261               return s;
262             }
263           else {
264             return "[ALL RESOURCES]";
265           }
266         else {
267           return object.toString();
268         }
269       case DELETE_COLUMN:
270         return object;
271     }
272     return null;
273   }
274 
275   @SuppressWarnings("unchecked")
276   public void setItem(OResource oResource) {
277     this.oResource = oResource;
278     if(oResource instanceof OClass) {
279       detailGroups = new DetailsGroup[] {resourceInfo, directSuperClasses, allSuperClasses,
280           directSubClasses, allSubClasses, equivalentClasses, propertyTypes,
281           propertyValues, instances};
282       OClass tclass = (OClass)oResource;
283       resourceInfo.getValues().clear();
284       if(tclass instanceof Restriction) {
285           resourceInfo.getValues().addAll(Utils.getDetailsToAdd(tclass));
286       else {
287         resourceInfo.getValues().add(tclass);
288         resourceInfo.getValues().add(new KeyValuePair(tclass, "URI", tclass.getONodeID().toString()false));
289         resourceInfo.getValues().add(new KeyValuePair(tclass, "TYPE""Ontology Class"false));
290       }
291       
292       // direct super classes
293       Set<OClass> set = tclass.getSuperClasses(OConstants.Closure.DIRECT_CLOSURE);
294       directSuperClasses.getValues().clear();
295       directSuperClasses.getValues().addAll(set);
296       Collections.sort(directSuperClasses.getValues(), itemComparator);
297 
298       // all super classes
299       Set<OClass> set1 = tclass.getSuperClasses(OConstants.Closure.TRANSITIVE_CLOSURE);
300       allSuperClasses.getValues().clear();
301       allSuperClasses.getValues().addAll(set1);
302       Collections.sort(allSuperClasses.getValues(), itemComparator);
303       
304 
305       // direct subclasses
306       Set<OClass> set2 = tclass.getSubClasses(OConstants.Closure.DIRECT_CLOSURE);
307       directSubClasses.getValues().clear();
308       directSubClasses.getValues().addAll(set2);
309       Collections.sort(directSubClasses.getValues(), itemComparator);
310       
311       // all sub classes
312       Set<OClass> set3 = tclass.getSubClasses(OConstants.Closure.TRANSITIVE_CLOSURE);
313       allSubClasses.getValues().clear();
314       allSubClasses.getValues().addAll(set3);
315       Collections.sort(allSubClasses.getValues(), itemComparator);
316 
317       // equivalent classes
318       Set<OClass> set4 = tclass.getEquivalentClasses();
319       equivalentClasses.getValues().clear();
320       equivalentClasses.getValues().addAll(set4);
321       Collections.sort(equivalentClasses.getValues(), itemComparator);
322       
323       // properties with resource as domain
324       propertyTypes.getValues().clear();
325       Set<RDFProperty> dprops = tclass.getPropertiesWithResourceAsDomain();
326       propertyTypes.getValues().addAll(dprops);
327       Collections.sort(propertyTypes.getValues(), itemComparator);
328       
329 
330       // annotation property values
331       propertyValues.getValues().clear();
332       Set<AnnotationProperty> props = tclass.getSetAnnotationProperties();
333       if(props != null) {
334         Iterator<AnnotationProperty> apIter = props.iterator();
335         while(apIter.hasNext()) {
336           AnnotationProperty ap = apIter.next();
337           List<Literal> literals = tclass.getAnnotationPropertyValues(ap);
338           for(int i = 0; i < literals.size(); i++) {
339             PropertyValue pv = new PropertyValue(ap, literals.get(i));
340             propertyValues.getValues().add(pv);
341           }
342         }
343       }
344 
345       // instances
346       Set<OInstance> set5 = ontology.getOInstances(tclass,
347               OConstants.Closure.DIRECT_CLOSURE);
348       instances.getValues().clear();
349       if(set5 != null) {
350         instances.getValues().addAll(set5);
351         Collections.sort(instances.getValues(), itemComparator);
352       }
353     }
354     else if(oResource instanceof OInstance) {
355       OInstance oinstance = (OInstance)oResource;
356       detailGroups = (new DetailsGroup[] {resourceInfo, directTypes, allTypes,
357           sameAsInstances, propertyTypes, propertyValues});
358 
359       resourceInfo.getValues().clear();
360       resourceInfo.getValues().add(oinstance);
361       resourceInfo.getValues().add(new KeyValuePair(oinstance, "URI", oinstance.getOURI().toString()false));
362       resourceInfo.getValues().add(new KeyValuePair(oinstance, "TYPE""Ontology Instance"false));
363       
364       // direct classes
365       Set<OClass> set1 = oinstance.getOClasses(OConstants.Closure.DIRECT_CLOSURE);
366       directTypes.getValues().clear();
367       if(set1 != null) {
368         for(OClass aClass : set1) {
369           directTypes.getValues().addAll(Utils.getDetailsToAdd(aClass));
370         }
371       }
372 
373       // all classes
374       Set<OClass> set2 = oinstance.getOClasses(OConstants.Closure.TRANSITIVE_CLOSURE);
375       allTypes.getValues().clear();
376       if(set2 != null) {
377         for(OClass aClass : set2) {
378           allTypes.getValues().addAll(Utils.getDetailsToAdd(aClass));
379         }
380       }
381 
382       Set<OInstance> set3 = oinstance.getSameInstance();
383       sameAsInstances.getValues().clear();
384       if(set3 != null) {
385         sameAsInstances.getValues().addAll(set3);
386         Collections.sort(sameAsInstances.getValues(), itemComparator);
387       }
388 
389       propertyTypes.getValues().clear();
390       Set<RDFProperty> dprops = oinstance.getPropertiesWithResourceAsDomain();
391       propertyTypes.getValues().addAll(dprops);
392       
393       propertyValues.getValues().clear();
394       Set<AnnotationProperty> apProps = oinstance.getSetAnnotationProperties();
395       Set<DatatypeProperty> dtProps = oinstance.getSetDatatypeProperties();
396       Set<ObjectProperty> obProps = oinstance.getSetObjectProperties();
397       Set<RDFProperty> rdfProp = oinstance.getSetRDFProperties();
398 
399       for(AnnotationProperty ap : apProps) {
400         List<Literal> literals = oinstance.getAnnotationPropertyValues(ap);
401         for(int i = 0; i < literals.size(); i++) {
402           PropertyValue pv = new PropertyValue(ap, literals.get(i));
403           propertyValues.getValues().add(pv);
404         }
405       }
406 
407       for(DatatypeProperty dt : dtProps) {
408         List<Literal> literals = oinstance.getDatatypePropertyValues(dt);
409         for(int i = 0; i < literals.size(); i++) {
410           PropertyValue pv = new PropertyValue(dt, literals.get(i));
411           propertyValues.getValues().add(pv);
412         }
413       }
414 
415       for(ObjectProperty ob : obProps) {
416         List<OInstance> oinstances = oinstance.getObjectPropertyValues(ob);
417         for(int i = 0; i < oinstances.size(); i++) {
418           PropertyValue pv = new PropertyValue(ob, oinstances.get(i));
419           propertyValues.getValues().add(pv);
420         }
421       }
422 
423       for(RDFProperty rd : rdfProp) {
424         List<OValue> oinstances = oinstance.getRDFPropertyOValues(rd);
425         for(int i = 0; i < oinstances.size(); i++) {
426           PropertyValue pv = new PropertyValue(rd, oinstances.get(i));
427           propertyValues.getValues().add(pv);
428         }
429       }
430     }
431     fireTableDataChanged();
432   }
433 
434   public OResource getItem() {
435     return oResource;
436   }
437 
438   public Ontology getOntology() {
439     return ontology;
440   }
441 
442   public void setOntology(Ontology ontology) {
443     this.ontology = ontology;
444   }
445 
446   protected DetailsGroup resourceInfo;
447   protected DetailsGroup directSuperClasses;
448   protected DetailsGroup allSuperClasses;
449   protected DetailsGroup directSubClasses;
450   protected DetailsGroup allSubClasses;
451   protected DetailsGroup equivalentClasses;
452   protected DetailsGroup sameAsInstances;
453   protected DetailsGroup instances;
454   protected DetailsGroup propertyTypes;
455   protected DetailsGroup propertyValues;
456   protected DetailsGroup directTypes;
457   protected DetailsGroup allTypes;
458   protected DetailsGroup detailGroups[];
459   protected Ontology ontology;
460   protected OResource oResource;
461   protected boolean ontologyMode;
462   public static final int COLUMN_COUNT = 4;
463   public static final int EXPANDED_COLUMN = 0;
464   public static final int LABEL_COLUMN = 1;
465   public static final int VALUE_COLUMN = 2;
466   public static final int DELETE_COLUMN = 3;
467   protected OntologyItemComparator itemComparator;
468 }