1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 /***
19 * <p>Title: WSMO Studio</p>
20 * <p>Description: Semantic Web Service Editor</p>
21 * <p>Copyright: Copyright (c) 2004-2006</p>
22 * <p>Company: OntoText Lab. / SIRMA </p>
23 */
24
25 package org.wsmostudio.ui.editors;
26
27 import java.util.*;
28 import java.util.List;
29
30 import org.eclipse.jface.dialogs.*;
31 import org.eclipse.jface.viewers.*;
32 import org.eclipse.jface.window.Window;
33 import org.eclipse.swt.SWT;
34 import org.eclipse.swt.custom.SashForm;
35 import org.eclipse.swt.dnd.*;
36 import org.eclipse.swt.events.*;
37 import org.eclipse.swt.layout.*;
38 import org.eclipse.swt.widgets.*;
39 import org.eclipse.ui.*;
40 import org.omwg.ontology.*;
41 import org.wsmo.common.*;
42 import org.wsmo.common.exception.InvalidModelException;
43 import org.wsmostudio.runtime.*;
44 import org.wsmostudio.ui.*;
45 import org.wsmostudio.ui.dnd.*;
46 import org.wsmostudio.ui.dnd.Clipboard;
47 import org.wsmostudio.ui.editors.common.*;
48 import org.wsmostudio.ui.editors.model.*;
49 import org.wsmostudio.ui.views.navigator.WSMOLabelProvider;
50
51 /***
52 * An editor component, subclass of WSMOEditor, capable to handle with WSMO-API
53 * Concept objects.
54 * This editor appears as a part of the WSMO Studio workbench. It is the default
55 * editor implementation for this kind of objects and it can be replaced by
56 * extending extension points <code>org.wsmostudio.ui.editors</code> and
57 * <code>org.eclipse.ui.editors</code>.
58 *
59 * @author not attributable
60 * @version $Revision: 1.22 $ $Date: 2006/02/20 12:45:29 $
61 */
62
63 public class ConceptEditor extends WSMOEditor
64 implements SelectionListener {
65
66 private NFPPanel nfpPanel;
67 private InstancesContainerPanel instancesPanel;
68 private ConceptModel model;
69 private Table supTable;
70
71 private TreeViewer attributesTree;
72
73 public void createPartControl(Composite parent) {
74 parent.setLayout(new GridLayout(1, false));
75
76 nfpPanel = new NFPPanel(parent,model);
77
78 SashForm mainEditor = new SashForm(parent, SWT.VERTICAL );
79 mainEditor.setLayoutData(new GridData(GridData.FILL_BOTH));
80
81 TabFolder attrTabs = new TabFolder(mainEditor, SWT.NONE);
82 TabItem attrsView = new TabItem(attrTabs, SWT.NONE);
83
84 attrsView.setText("Attributes");
85 createAttributesView(attrTabs);
86 attrsView.setControl(attributesTree.getTree());
87 initDNDTargetAttrTypes();
88
89 TabFolder supersTabs = new TabFolder(mainEditor, SWT.NONE);
90 TabItem superConceptsView = new TabItem(supersTabs, SWT.NONE);
91
92 superConceptsView.setText("Super Concepts");
93 createSuperConceptsView(supersTabs);
94 superConceptsView.setControl(supTable);
95
96 TabFolder instsTabs = new TabFolder(mainEditor, SWT.NONE);
97 instancesPanel = new InstancesContainerPanel(instsTabs, model);
98
99 initDNDTargetSuperConcepts();
100 }
101
102 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
103 super.init(site, input);
104 model = (ConceptModel)input.getAdapter(ConceptModel.class);
105 }
106
107 public void dispose() {
108 nfpPanel.dispose();
109 model = null;
110 super.dispose();
111 }
112
113 public void setFocus() {
114 super.setFocus();
115 attributesTree.getTree().setFocus();
116 }
117
118 protected void updateFromModel() {
119 doUpdateAttributeTree();
120 instancesPanel.update();
121 updateSuperConceptsTable();
122 }
123
124 @SuppressWarnings("unchecked")
125 private Table createSuperConceptsView(Composite parent) {
126 supTable = new Table(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
127 supTable.setLinesVisible(false);
128 Set<Concept> superConcepts = model.getConcept().listSuperConcepts();
129 for(Concept concept : superConcepts) {
130 Utils.createTableItem(supTable,
131 concept,
132 WsmoImageRegistry.CONCEPT_ICON);
133 }
134 supTable.addMouseListener(new MouseAdapter() {
135 public void mouseUp(MouseEvent e) {
136 if (e.button != 3) {
137 return;
138 }
139 showContextMenu(supTable, e);
140 }
141
142 });
143 return supTable;
144 }
145
146 @SuppressWarnings("unchecked")
147 private void updateSuperConceptsTable() {
148 Set<Concept> superConcepts = new HashSet<Concept>(
149 model.getConcept().listSuperConcepts());
150 TableItem[] items = supTable.getItems();
151 for(int i = 0; i < items.length; i++) {
152 if (false == superConcepts.contains(items[i].getData())) {
153 items[i].dispose();
154 }
155 else {
156 superConcepts.remove(items[i].getData());
157 }
158 }
159 for(Concept concept : superConcepts) {
160 Utils.createTableItem(supTable,
161 concept,
162 WsmoImageRegistry.CONCEPT_ICON);
163 }
164 }
165
166 private TreeViewer createAttributesView(Composite parent) {
167 attributesTree = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
168
169 attributesTree.setContentProvider(
170 new AttributeContentProvider(model.getConcept()));
171 attributesTree.setLabelProvider(new WSMOLabelProvider() {
172 public String getText(Object element) {
173 String strLabel = super.getText(element);
174 if (element instanceof Attribute) {
175 StringBuffer sbLabel = new StringBuffer();
176 Attribute attr = (Attribute)element;
177 sbLabel.append(strLabel).append(" [");
178 sbLabel.append(attr.getMinCardinality());
179 sbLabel.append("..");
180 if (attr.getMaxCardinality() == Integer.MAX_VALUE) {
181 sbLabel.append('*');
182 }
183 else {
184 sbLabel.append(attr.getMaxCardinality());
185 }
186 sbLabel.append(']');
187 strLabel = sbLabel.toString();
188 }
189 return strLabel;
190 }
191 });
192 attributesTree.setInput(model.getConcept());
193 attributesTree.getTree().addMouseListener(new MouseAdapter() {
194 public void mouseDoubleClick(MouseEvent e) {
195 TreeItem[] sel = attributesTree.getTree().getSelection();
196 Object selected = sel[0].getData();
197 if ((selected instanceof Attribute)
198 && (sel[0].getBounds().contains(e.x, e.y))) {
199 doEditAttribute((Attribute)selected);
200 doUpdateAttributeTree();
201 }
202 }
203 public void mouseUp(MouseEvent e) {
204 if (e.button != 3) {
205 return;
206 }
207 showContextMenu(attributesTree.getTree(), e);
208 }
209
210 });
211 return attributesTree;
212 }
213
214 private void doEditAttribute(Attribute target)
215 {
216 AttributeModel attrModel = (AttributeModel)Utils.createEditorModel(target, model, "");
217 new AttributeEditor(getSite().getShell(), this, attrModel).open();
218 }
219
220 public void widgetSelected(SelectionEvent e) {
221 String action = ((MenuItem)e.widget).getText();
222 if (action.equals("Add Super Concept")) {
223 WSMOChooser chooser = WSMOChooser.createConceptChooser(
224 getSite().getShell(),
225 WSMORuntime.getRuntime());
226 Concept newSuperConcept = (Concept)chooser.open();
227 if (!isValidSuperConcept(model.getConcept(), newSuperConcept)) {
228 return;
229 }
230 if (newSuperConcept != null) {
231 try {
232 model.addSuperConcept(newSuperConcept);
233 }
234 catch(InvalidModelException ime) {
235 LogManager.logError(ime);
236 }
237 }
238 return;
239 }
240 if (action.equals("Remove Super Concept")) {
241 TableItem[] sel = supTable.getSelection();
242 if (sel == null || sel.length != 1) {
243 return;
244 }
245 try {
246 model.removeSuperConcept((Concept)sel[0].getData());
247 }
248 catch(InvalidModelException ime) {
249 LogManager.logError(ime);
250 }
251 return;
252 }
253
254 if (action.equals("Remove Range")) {
255 TreeItem[] sel = attributesTree.getTree().getSelection();
256 TreeItem parentSel = sel[0].getParentItem();
257 Attribute attr = (Attribute)parentSel.getData();
258 Type rangeConcept = (Type)sel[0].getData();
259
260 try {
261 attr.removeType(rangeConcept);
262 model.setChanged();
263 }
264 catch(InvalidModelException ime) {
265 LogManager.logError(ime);
266 }
267 doUpdateAttributeTree();
268 return;
269 }
270
271 if (action.equals("Edit Attribute")) {
272 Attribute attr = (Attribute)((IStructuredSelection)attributesTree
273 .getSelection())
274 .getFirstElement();
275 doEditAttribute(attr);
276 doUpdateAttributeTree();
277 return;
278 }
279
280 if (action.equals("Remove Attribute")) {
281 TreeItem[] sel = attributesTree.getTree().getSelection();
282 try {
283 model.removeAttribute((Attribute)sel[0].getData());
284 model.setChanged();
285 }
286 catch(InvalidModelException ime) {
287 LogManager.logError(ime);
288 }
289 doUpdateAttributeTree();
290 return;
291 }
292
293 if (action.equals("Add Attribute")) {
294
295 IdentifierInputDialog iDialog = new IdentifierInputDialog(
296 getSite().getShell(),
297 "New Attribute",
298 "Please supply a valid attribute name",
299 "",
300 model.getConcept().getOntology(),
301 WSMORuntime.getRuntime().getWsmoFactory(),
302 false,
303 new IInputValidator() {
304 public String isValid(String newText) {
305 Set attrs = model.getConcept().listAttributes();
306 for (Iterator iter = attrs.iterator(); iter.hasNext();) {
307 Attribute attr = (Attribute) iter.next();
308 if (attr.getIdentifier().toString().endsWith("#"+newText.trim())) {
309 return "Attribute name already in use!";
310 }
311 }
312 return null;
313 }});
314
315
316 if (iDialog.open() != Window.OK) {
317 return;
318 }
319 IRI attrID = (IRI)iDialog.getIdentifier();
320
321 try {
322 Attribute newAttr = model.createAttribute(attrID);
323 doUpdateAttributeTree();
324 attributesTree.setSelection(new StructuredSelection(newAttr));
325 }
326 catch(InvalidModelException ime) {
327 MessageDialog.openError(getSite().getShell(),
328 "Error Creating Attribute",
329 ime.getMessage());
330 LogManager.logError(ime);
331 }
332 return;
333 }
334
335 }
336
337 public void widgetDefaultSelected(SelectionEvent e) {
338 }
339
340 private void showContextMenu(Control parentControl, MouseEvent e) {
341 Menu contextMenu = new Menu(parentControl.getShell(), SWT.POP_UP);
342 fillContextMenuContent(parentControl, contextMenu, e);
343
344 contextMenu.setLocation(parentControl.toDisplay(e.x, e.y));
345 contextMenu.setVisible(true);
346 }
347
348 private void fillContextMenuContent(Control parent,
349 Menu menu,
350 MouseEvent e) {
351 if (parent == supTable) {
352 MenuItem item = new MenuItem(menu, SWT.PUSH);
353 item.setText("Add Super Concept");
354 item.addSelectionListener(this);
355
356 TableItem[] sel = supTable.getSelection();
357 if (sel != null
358 && sel.length > 0
359 && sel[0].getBounds(0).contains(e.x, e.y)) {
360 item = new MenuItem(menu, SWT.PUSH);
361 item.setText("Remove Super Concept");
362 item.addSelectionListener(this);
363 }
364 return;
365 }
366 if (parent == attributesTree.getTree()) {
367 TreeItem[] sel = attributesTree.getTree().getSelection();
368 boolean isOnSelection = (sel != null
369 && sel.length > 0
370 && sel[0].getBounds().contains(e.x, e.y));
371
372 if (isOnSelection
373 && ((IStructuredSelection)attributesTree.getSelection())
374 .getFirstElement() instanceof Type) {
375 MenuItem item = new MenuItem(menu, SWT.PUSH);
376 item.setText("Remove Range");
377 item.addSelectionListener(this);
378 }
379 else {
380 MenuItem item = new MenuItem(menu, SWT.PUSH);
381 item.setText("Add Attribute");
382 item.addSelectionListener(this);
383
384 if (isOnSelection) {
385 item = new MenuItem(menu, SWT.SEPARATOR);
386
387 item = new MenuItem(menu, SWT.PUSH);
388 item.setText("Edit Attribute");
389 item.addSelectionListener(this);
390
391 item = new MenuItem(menu, SWT.SEPARATOR);
392
393 item = new MenuItem(menu, SWT.PUSH);
394 item.setText("Remove Attribute");
395 item.addSelectionListener(this);
396 }
397 }
398 }
399 }
400
401 private boolean isValidSuperConcept(Concept concept, Concept superConcept) {
402 if (concept == superConcept
403 || concept.listSuperConcepts().contains(superConcept)) {
404 return false;
405 }
406
407 return true;
408 }
409
410 protected void doTryToSave() throws Exception {
411 WSMORuntime.getRuntime().doUpdateEntity(model.getConcept().getOntology());
412 }
413
414 private void doUpdateAttributeTree() {
415 ((AttributeContentProvider)attributesTree.getContentProvider()).prepareToRefresh();
416 attributesTree.refresh(true);
417 }
418
419 private void initDNDTargetSuperConcepts() {
420 DropTarget target = new DropTarget(supTable,
421 DND.DROP_LINK | DND.DROP_DEFAULT);
422
423 final WSMOTransfer wsmoTransfer = WSMOTransfer.getInstance();
424 target.setTransfer(new Transfer[] {wsmoTransfer});
425
426 target.addDropListener(new DropTargetAdapter() {
427 public void dragEnter(DropTargetEvent event) {
428 if (true == Clipboard.getInstance().ensureContentType(Concept.class)) {
429 event.detail = DND.DROP_LINK;
430 }
431 else {
432 event.detail = DND.DROP_NONE;
433 }
434 }
435 public void dragOver(DropTargetEvent event) {
436 event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
437 }
438 public void drop(DropTargetEvent event) {
439 if (wsmoTransfer.isSupportedType(event.currentDataType)) {
440 List<Entity> concepts = Clipboard.getInstance().getContent();
441 for(Entity entity : concepts) {
442 if (entity instanceof Concept) {
443 try {
444 if (false == model.getConcept().listSuperConcepts().contains(entity)) {
445 model.addSuperConcept((Concept)entity);
446 }
447 }
448 catch(InvalidModelException ime) {
449 MessageDialog.openError(getSite().getShell(),
450 "Error",
451 ime.getMessage());
452 LogManager.logError(ime);
453 }
454 }
455 }
456 }
457 }
458 });
459 }
460
461 private void initDNDTargetAttrTypes() {
462 DropTarget target = new DropTarget(attributesTree.getTree(),
463 DND.DROP_LINK | DND.DROP_DEFAULT);
464
465 final WSMOTransfer wsmoTransfer = WSMOTransfer.getInstance();
466 target.setTransfer(new Transfer[] {wsmoTransfer});
467
468 target.addDropListener(new DropTargetAdapter() {
469 public void dragEnter(DropTargetEvent event) {
470 event.detail = DND.DROP_NONE;
471 }
472 public void dragOver(DropTargetEvent event) {
473 event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL | DND.FEEDBACK_EXPAND;
474 if (event.item != null) {
475 Object selected = event.item.getData();
476 if (selected instanceof Attribute
477 && Clipboard.getInstance().ensureContentType(Type.class)) {
478 event.detail = DND.DROP_LINK;
479 }
480 else {
481 event.detail = DND.DROP_NONE;
482 }
483 }
484 }
485 public void drop(DropTargetEvent event) {
486 if (wsmoTransfer.isSupportedType(event.currentDataType)) {
487 if (event.item == null) {
488 return;
489 }
490 Object selected = event.item.getData();
491 if (false == selected instanceof Attribute) {
492 return;
493 }
494
495 List<Entity> newTypes = Clipboard.getInstance().getContent();
496 Set types = ((Attribute)selected).listTypes();
497 boolean changed = false;
498 for(Entity entity : newTypes) {
499 if (entity instanceof Type) {
500 try {
501 if (false == types.contains(entity)) {
502 ((Attribute)selected).addType((Type)entity);
503 changed = true;
504 }
505 }
506 catch(InvalidModelException ime) {
507 MessageDialog.openError(getSite().getShell(),
508 "Error",
509 ime.getMessage());
510 LogManager.logError(ime);
511 }
512 }
513 }
514 if (changed) {
515 model.setChanged();
516 }
517 }
518 }
519 });
520 }
521
522 class AttributeContentProvider implements ITreeContentProvider {
523
524 private Concept root;
525 private boolean rootIsShown = false;
526
527 public AttributeContentProvider(Concept owner) {
528 root = owner;
529 }
530
531
532
533
534 public void prepareToRefresh() {
535 rootIsShown = false;
536 }
537
538 public Object[] getChildren(Object parentElement) {
539 if (parentElement instanceof Attribute) {
540 return ((Attribute)parentElement).listTypes().toArray();
541 }
542 return null;
543 }
544
545 public Object getParent(Object element) {
546 return null;
547 }
548
549 public boolean hasChildren(Object element) {
550 if (element == root) {
551 if (rootIsShown) {
552 return false;
553 }
554 return root.listAttributes().size() > 0;
555 }
556 if (element instanceof Attribute) {
557 return ((Attribute)element).listTypes().size() > 0;
558 }
559 return false;
560 }
561
562 public Object[] getElements(Object inputElement) {
563
564 if (inputElement == root) {
565 rootIsShown = true;
566 return root.listAttributes().toArray();
567 }
568 return null;
569 }
570
571 public void dispose() {
572 }
573
574 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
575 }
576 }
577 }
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627