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