View Javadoc

1   /*
2    * $Id: RestrictionEditorTree.java,v 1.2 2005/07/08 18:19:13 jlerner Exp $
3    *
4    * Copyright (c) 1999-2004, BBN Technologies, LLC.
5    * All rights reserved.
6    * http://www.daml.org/legal/opensource/bbn_license.html
7    */
8   
9   package com.bbn.swede.editor.visualeditors.restriction;
10  
11  import java.net.URISyntaxException;
12  import java.util.Arrays;
13  import java.util.Collections;
14  import java.util.Iterator;
15  import java.util.List;
16  
17  import org.eclipse.jface.dialogs.MessageDialog;
18  import org.eclipse.jface.viewers.CellEditor;
19  import org.eclipse.jface.viewers.ComboBoxCellEditor;
20  import org.eclipse.jface.viewers.ICellModifier;
21  import org.eclipse.jface.viewers.ISelectionChangedListener;
22  import org.eclipse.jface.viewers.IStructuredSelection;
23  import org.eclipse.jface.viewers.ITableLabelProvider;
24  import org.eclipse.jface.viewers.LabelProvider;
25  import org.eclipse.jface.viewers.SelectionChangedEvent;
26  import org.eclipse.jface.viewers.TreeViewer;
27  import org.eclipse.jface.viewers.ViewerSorter;
28  import org.eclipse.jface.wizard.WizardDialog;
29  import org.eclipse.swt.SWT;
30  import org.eclipse.swt.events.SelectionAdapter;
31  import org.eclipse.swt.events.SelectionEvent;
32  import org.eclipse.swt.layout.GridData;
33  import org.eclipse.swt.layout.GridLayout;
34  import org.eclipse.swt.widgets.Button;
35  import org.eclipse.swt.widgets.Composite;
36  import org.eclipse.swt.widgets.Control;
37  import org.eclipse.swt.widgets.Item;
38  import org.eclipse.swt.widgets.TreeColumn;
39  import org.eclipse.ui.forms.widgets.FormToolkit;
40  import org.eclipse.ui.forms.widgets.ScrolledForm;
41  import org.eclipse.ui.forms.widgets.Section;
42  
43  import com.bbn.swede.core.OWLCore;
44  import com.bbn.swede.core.dom.DefaultOASTRunnable;
45  import com.bbn.swede.core.dom.IOWLAbstractSyntaxTree;
46  import com.bbn.swede.core.dom.OAST;
47  import com.bbn.swede.core.dom.OASTException;
48  import com.bbn.swede.core.dom.owl.Restriction;
49  import com.bbn.swede.editor.EditorPlugin;
50  import com.hp.hpl.jena.ontology.OntModel;
51  import com.hp.hpl.jena.rdf.model.Resource;
52  
53  /***
54   * The class that manages the graphical component of the Restriction Editor
55   * which contains the section heading, associated text, table tree viewer and
56   * buttons. This class also manages the configurations of the various cell
57   * editors associated with the table tree viewer.
58   * 
59   * @author aperezlo
60   */
61  public class RestrictionEditorTree implements ISelectionChangedListener
62  {
63     private TreeViewer _treeViewer;
64  
65     private ScrolledForm _form;
66  
67     private RestrictionEditorInspector _inspector;
68  
69     private IOWLAbstractSyntaxTree _oast;
70  
71     private CellEditor[] _cellEditors;
72  
73     private ComboBoxCellEditorModel _propertyModel;
74  
75     private ComboBoxCellEditorModel _restrictionValueModel;
76  
77     private ComboBoxCellEditorModel _restrictionTypeModel;
78  
79     /***
80      * Creates and initializes the table tree viewer used by the restriction
81      * editor. This is the main interface between this class and other classes.
82      * 
83      * @param form the from in which this component exists
84      * @param parent the parent in which this component should exist
85      * @param toolkit the form toolkit used by the restriction editor
86      * @param inspector the inspector used to populate this component
87      * @param oast the OAST of the document being edited
88      */
89     public void createComponent(ScrolledForm form, Composite parent,
90        FormToolkit toolkit, RestrictionEditorInspector inspector,
91        IOWLAbstractSyntaxTree oast)
92     {
93        _form = form;
94        _inspector = inspector;
95        _oast = oast;
96  
97        Section mainSection = toolkit.createSection(parent, Section.DESCRIPTION
98           | Section.TITLE_BAR | Section.EXPANDED);
99        GridData gd = new GridData(GridData.FILL_BOTH);
100       mainSection.setLayoutData(gd);
101       mainSection.setLayout(new GridLayout());
102       mainSection.setText("Restrictions:");
103       //      toolkit.createCompositeSeparator(mainSection);
104       mainSection
105          .setDescription("View, modify, add, and remove restrictions from classes in your ontology:");
106 
107       Composite client = toolkit.createComposite(mainSection, SWT.WRAP);
108       client.setLayoutData(new GridData(GridData.FILL_BOTH));
109       GridLayout clientLayout = new GridLayout();
110       clientLayout.numColumns = 2;
111       //      clientLayout.
112       client.setLayout(clientLayout);
113       toolkit.paintBordersFor(client);
114 
115       //      toolkit.createLabel(client, "View, ", SWT.WRAP);
116       //      _addRestrictionLink = toolkit.createHyperlink(client, "create",
117       // SWT.WRAP);
118       //      toolkit.createLabel(client, ", modify and ");
119       //      _removeRestrictionLink = toolkit.createHyperlink(client, "delete",
120       // SWT.WRAP);
121       //      toolkit.createLabel(client, "restrictions.", SWT.WRAP);
122 
123       _treeViewer = new TreeViewer(client, SWT.SINGLE | SWT.FULL_SELECTION);
124       toolkit.adapt(_treeViewer.getTree());
125 
126       _treeViewer.setContentProvider(RestrictionEditorProviderFactory
127          .getFactory().getContentProvider(_inspector, _oast));
128       _treeViewer
129          .setLabelProvider((ITableLabelProvider)RestrictionEditorProviderFactory
130             .getFactory().getLabelProvider(_inspector, _oast));
131       _treeViewer.setColumnProperties(RestrictionEditor.COLUMN_NAMES_ARRAY);
132       //      _treeViewer.getTableTree().getTable().setLinesVisible(true);
133       _treeViewer.getTree().setHeaderVisible(true);
134       _treeViewer.setSorter(new ViewerSorter());
135       _treeViewer.setAutoExpandLevel(2);
136 
137       gd = new GridData(GridData.FILL_BOTH);
138       gd.verticalSpan = 3;
139       _treeViewer.getTree().setLayoutData(gd);
140       _treeViewer.addSelectionChangedListener(this);
141 
142       TreeColumn tempColumn = null;
143       for(int i = 0; i < 5; i++)
144       {
145          tempColumn = new TreeColumn(_treeViewer.getTree(),
146             _treeViewer.getTree().getStyle(), i);
147          tempColumn.setWidth(100);
148          tempColumn.setText(RestrictionEditor.COLUMN_NAMES_ARRAY[i]);
149       }
150 
151       createButtons(toolkit, client);
152       createCellEditors();
153       mainSection.setClient(client);
154    }
155 
156    /***
157     * Convenience method to create the Add and Remove buttons seen in the
158     * restriction editor.
159     * 
160     * @param toolkit the toolkit to use to create the buttons
161     * @param client the parent composite of the buttons
162     */
163    protected void createButtons(FormToolkit toolkit, Composite client)
164    {
165       final Button addButton = toolkit.createButton(client, "Add", SWT.PUSH);
166       final Button removeButton = toolkit.createButton(client, "Remove",
167          SWT.PUSH);
168       addButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
169       removeButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
170       addButton.addSelectionListener(new SelectionAdapter()
171       {
172          public void widgetSelected(SelectionEvent e)
173          {
174             List classes = _inspector.getAllClasses();
175             List props = _inspector.getAllProperties();
176             IStructuredSelection iss = (IStructuredSelection)_treeViewer
177                .getSelection();
178             java.net.URI uri = null;
179             NewRestrictionWizard wiz = new NewRestrictionWizard(_inspector,
180                _oast, classes, props);
181             WizardDialog wd = new WizardDialog(_form.getShell(), wiz);
182             if(!iss.isEmpty())
183             {
184                if(iss.getFirstElement() instanceof String)
185                {
186                   try
187                   {
188                      uri = new java.net.URI((String)iss.getFirstElement());
189                   }
190                   catch (Exception urie)
191                   {
192                      //do nothing
193                   }
194                }
195                if(iss.getFirstElement() instanceof Restriction)
196                {
197                   try
198                   {
199                      Resource jenaRes = ((Restriction)iss.getFirstElement())
200                         .getAssociatedResource();
201                      if(jenaRes
202                         .canAs(com.hp.hpl.jena.ontology.Restriction.class))
203                      {
204                         com.hp.hpl.jena.ontology.Restriction jenaRest = (com.hp.hpl.jena.ontology.Restriction)jenaRes
205                            .as(com.hp.hpl.jena.ontology.Restriction.class);
206                         String temp = _inspector.getOrigin(jenaRest);
207                         uri = new java.net.URI(temp);
208                      }
209                   }
210                   catch (Exception urie)
211                   {
212                      //do nothing
213                   }
214                }
215                if(uri != null)
216                {
217                   wiz.setSelectedClass(uri);
218                }
219             }
220             wd.setBlockOnOpen(true);
221             wd.open();
222 
223             _inspector.getModel().reset();
224             _inspector.getModel().rebind();
225 
226             _treeViewer.refresh();
227             _form.reflow(true);
228          }
229       });
230       removeButton.addSelectionListener(new SelectionAdapter()
231       {
232          public void widgetSelected(SelectionEvent e)
233          {
234             boolean error = true;
235             String msg = null;
236             String title = null;
237             if(!_treeViewer.getSelection().isEmpty())
238             {
239                IStructuredSelection iss = (IStructuredSelection)_treeViewer
240                   .getSelection();
241                if(iss.getFirstElement() instanceof Restriction)
242                {
243                   // delete restriction!
244                   if(MessageDialog
245                      .openConfirm(
246                         _form.getShell(),
247                         "Remove Restriction",
248                         "You are about to remove a restriction.  "
249                         + "This operation cannot be undone - are you sure you "
250                         + "want to do this?"))
251                   {
252                      deleteRestriction((Restriction)iss.getFirstElement());
253                   }
254                   error = false;
255                }
256                else
257                {
258                   msg = "This is not a restriction, or it is a restriction "
259                         + "that is defined in a different document and therefore "
260                         + "cannot be deleted from this one.  Please select a "
261                         + "different restriction to delete.";
262                }
263             }
264 
265             if(error)
266             {
267                title = (title == null) ? "No restriction selected" : title;
268                msg = (msg == null) ? "Cannot delete restriction - please select a restriction to delete."
269                   : msg;
270                MessageDialog.openError(_form.getShell(), title, msg);
271             }
272          }
273       });
274 
275       if(_oast.isReadOnly())
276       {
277          addButton.setEnabled(false);
278          removeButton.setEnabled(false);
279       }
280    }
281 
282    /***
283     * Delegate method, passes this call through to the table tree viewer.
284     */
285    public void refresh()
286    {
287       if(_treeViewer.getContentProvider() != null)
288       {
289          _treeViewer.refresh();
290       }
291    }
292 
293    /***
294     * Creates the cell editors used by this component.
295     */
296    public void createCellEditors()
297    {
298       String[] values = {""};
299       String[] restrictionTypes = {RestrictionWrapper.ALLVALUES,
300          RestrictionWrapper.CARDINALITY, RestrictionWrapper.HASVALUE,
301          RestrictionWrapper.MAX, RestrictionWrapper.MIN,
302          RestrictionWrapper.SOMEVALUES};
303       _cellEditors = new CellEditor[5];
304       _cellEditors[RestrictionEditor.PROPERTY_NAME_COLUMN] = new ComboBoxCellEditor(
305          _treeViewer.getTree(), values, SWT.READ_ONLY);
306       _cellEditors[RestrictionEditor.RESTRICTION_TYPE_COLUMN] = new ComboBoxCellEditor(
307          _treeViewer.getTree(), values, SWT.READ_ONLY);
308       _cellEditors[RestrictionEditor.RESTRICTION_VALUE_COLUMN] = new CombinationDialogCellEditor(
309          _treeViewer.getTree(), _inspector, _oast);
310       _cellEditors[RestrictionEditor.RESTRICTION_ORIGIN_COLUMN] = new NullCellEditor();
311       _treeViewer
312          .addSelectionChangedListener(
313             (ISelectionChangedListener)_cellEditors[RestrictionEditor.RESTRICTION_VALUE_COLUMN]);
314       _treeViewer.setCellEditors(_cellEditors);
315 
316       _restrictionValueModel = new ComboBoxCellEditorModel(new LabelProvider()
317       {
318          public String getText(Object obj)
319          {
320             return obj.toString();
321          }
322       });
323       _restrictionTypeModel = new ComboBoxCellEditorModel(new LabelProvider()
324       {
325          public String getText(Object obj)
326          {
327             return obj.toString();
328          }
329       });
330 
331       _restrictionTypeModel.setElements(Arrays.asList(restrictionTypes));
332       ((ComboBoxCellEditor)_cellEditors[RestrictionEditor.RESTRICTION_TYPE_COLUMN])
333          .setItems(_restrictionTypeModel.getItems());
334       _propertyModel = new ComboBoxCellEditorModel(new LabelProvider()
335       {
336          public String getText(Object obj)
337          {
338             String toReturn = RestrictionEditorProviderFactory.NOT_DEFINED;
339             if(obj instanceof String)
340             {
341                toReturn = ((OAST)_oast).getQNameForURI((String)obj);
342             }
343             return toReturn;
344          }
345       });
346 
347       _treeViewer.setCellModifier(new InternalCellModifier());
348 
349    }
350 
351    /***
352     * Delegate method, passed on to this component's table tree viewer.
353     * 
354     * @return the input used by this component's table tree viewer
355     */
356    public Object getInput()
357    {
358       return _treeViewer.getInput();
359    }
360 
361    /***
362     * Delegate method, passed on to this component's table tree viewer.
363     * 
364     * @param oast an OWL Abstract Syntax Tree to be used to populate this
365     *        component
366     */
367    public void setInput(Object oast)
368    {
369       if(_treeViewer.getContentProvider() != null)
370       {
371          _treeViewer.setInput((IOWLAbstractSyntaxTree)oast);
372          configureCellEditors();
373       }
374    }
375 
376    /***
377     * Configures the property cell editors.
378     */
379    public void configureCellEditors()
380    {
381       List allProperties = _inspector.getAllProperties();
382       Collections.sort(allProperties);
383       _propertyModel.setElements(allProperties);
384       ((ComboBoxCellEditor)_cellEditors[RestrictionEditor.PROPERTY_NAME_COLUMN])
385          .setItems(_propertyModel.getItems());
386    }
387 
388    /***
389     * Uses an IOASTRunnable to delete the given restriction from the OAST that
390     * contains it.
391     * 
392     * @param toDelete the Restriction node to be removed
393     */
394    protected void deleteRestriction(final Restriction toDelete)
395    {
396 
397       IOWLAbstractSyntaxTree oast = toDelete.getOWLAbstractSyntaxTree();
398       try
399       {
400          oast.run(new DefaultOASTRunnable()
401          {
402             public void run() throws OASTException
403             {
404                toDelete.getParent().getParent().remove(toDelete.getParent(),
405                   true);
406             }
407          });
408       }
409       catch (OASTException e)
410       {
411          //This should never happen because the restriction editor disables the
412          //edit controls for read-only docs, but make sure it gets reported if
413          //it does.
414          OWLCore.logWarning(EditorPlugin.getID(), e.getMessage(), e);
415       }
416 
417       _inspector.getModel().reset();
418       _inspector.getModel().rebind();
419 
420       _treeViewer.refresh();
421    }
422 
423    /*
424     *  (non-Javadoc)
425     * @see org.eclipse.jface.viewers.ISelectionChangedListener
426     *    #selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
427     */
428    public void selectionChanged(SelectionChangedEvent event)
429    {
430       _form.reflow(true);
431    }
432 
433    private final class InternalCellModifier implements ICellModifier
434    {
435       private Object getByColumn(Object element, String property)
436       {
437          Object toReturn = null;
438          List children = null;
439          Restriction restriction = null;
440          Iterator i = null;
441          if(element instanceof Restriction)
442          {
443             restriction = (Restriction)element;
444          }
445          if(restriction != null)
446          {
447             if(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.PROPERTY_NAME_COLUMN]
448                .equals(property))
449             {
450                toReturn = _inspector.getObjectFromRestriction(restriction,
451                   RestrictionEditor.PROPERTY_NAME_COLUMN);
452             }
453             if(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.RESTRICTION_TYPE_COLUMN]
454                .equals(property))
455             {
456                toReturn = _inspector.getObjectFromRestriction(restriction,
457                   RestrictionEditor.RESTRICTION_TYPE_COLUMN);
458             }
459             if(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.RESTRICTION_VALUE_COLUMN]
460                .equals(property))
461             {
462                toReturn = _inspector.getObjectFromRestriction(restriction,
463                   RestrictionEditor.RESTRICTION_VALUE_COLUMN);
464             }
465          }
466          return toReturn;
467       }
468 
469       public boolean canModify(Object element, String property)
470       {
471          boolean toReturn = false;
472          if(!_oast.isReadOnly())
473          {
474             if((element instanceof Restriction)
475                && (!property
476                   .equals(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.RESTRICTION_ORIGIN_COLUMN])))
477             {
478                toReturn = true;
479             }
480          }
481          return toReturn;
482       }
483 
484       public Object getValue(Object element, String property)
485       {
486          Object toReturn = null;
487 
488          if(element instanceof Restriction)
489          {
490             Restriction restriction = (Restriction)element;
491             RestrictionWrapper wrapper = new RestrictionWrapper(restriction);
492             if(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.PROPERTY_NAME_COLUMN]
493                .equals(property))
494             {
495                String sUri = wrapper.getOnPropertyURI();
496                if(sUri != null)
497                {
498                   if(sUri.startsWith("#"))
499                   {
500                      sUri = restriction.getOWLAbstractSyntaxTree().getBaseURI()
501                         + sUri;
502                   }
503                   toReturn = _propertyModel.getIndex(sUri);
504                }
505                else
506                {
507                   toReturn = new Integer(0);
508                }
509             }
510             else if(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.RESTRICTION_TYPE_COLUMN]
511                .equals(property))
512             {
513                toReturn = _restrictionTypeModel.getIndex(wrapper
514                   .getRestrictionType());
515             }
516             //            else
517             // if(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.RESTRICTION_VALUE_COLUMN].equals(property))
518             //            {
519             //               toReturn = wrapper.getRestrictionValueText();
520             //               if(toReturn == null)
521             //               {
522             //                  toReturn = wrapper.getRestrictionValueURI();
523             //               }
524             //            }
525          }
526          return toReturn;
527       }
528 
529       public void modify(Object element, String property, Object value)
530       {
531          Restriction restriction = null;
532          OntModel model = null;
533          if(element instanceof Item)
534          {
535             element = ((Item)element).getData();
536          }
537          restriction = (Restriction)element;
538          RestrictionWrapper wrapper = new RestrictionWrapper(restriction);
539          Object currentValue = getValue(element, property);
540          if(!(((currentValue != null) && (currentValue.equals(value)) || ((currentValue == null) && (value == null)))))
541          {
542             if(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.PROPERTY_NAME_COLUMN]
543                .equals(property))
544             {
545                Integer intValue = (Integer)value;
546                String newURI = (String)_propertyModel.getElement(intValue);
547                if(newURI != null)
548                {
549                   try
550                   {
551                      wrapper.setOnPropertyURI(new java.net.URI(newURI));
552                   }
553                   catch (URISyntaxException e)
554                   {
555                      e.printStackTrace();
556                   }
557                }
558             }
559             if(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.RESTRICTION_TYPE_COLUMN]
560                .equals(property))
561             {
562                Integer intValue = (Integer)value;
563                String type = (String)_restrictionTypeModel.getElement(intValue);
564                if(type != null)
565                {
566                   wrapper.setRestictionType(type);
567                }
568             }
569             if(RestrictionEditor.COLUMN_NAMES_ARRAY[RestrictionEditor.RESTRICTION_VALUE_COLUMN]
570                .equals(property))
571             {
572                if(value instanceof String)
573                {
574                   wrapper.setRestrictionValueText((String)value);
575                }
576                else if(value instanceof java.net.URI)
577                {
578                   String sUri = ((java.net.URI)value).toString();
579                   try
580                   {
581                      //                  _inspector.oastGetRDF(klass.getOWLAbstractSyntaxTree(),
582                      // klass, "ID");
583                      //                  URI = _inspector.convertFragmentToURI(URI,
584                      // klass.getOWLAbstractSyntaxTree().getBaseURI());
585                      wrapper.setRestrictionValueURI(new java.net.URI(sUri));
586                   }
587                   catch (URISyntaxException e)
588                   {
589                      e.printStackTrace();
590                   }
591                }
592             }
593             _treeViewer.refresh();
594          } // if something's changed...
595       }
596    }
597 
598    private final class NullCellEditor extends CellEditor
599    {
600       protected Control createControl(Composite parent)
601       {
602          return null;
603       }
604 
605       protected Object doGetValue()
606       {
607          return null;
608       }
609 
610       protected void doSetFocus()
611       {
612       }
613 
614       protected void doSetValue(Object value)
615       {
616       }
617    }
618 
619 }