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
28
29 import java.util.*;
30
31 import org.eclipse.jface.action.*;
32 import org.eclipse.jface.resource.JFaceResources;
33 import org.eclipse.swt.SWT;
34 import org.eclipse.swt.events.*;
35 import org.eclipse.swt.graphics.Image;
36 import org.eclipse.swt.graphics.Point;
37 import org.eclipse.swt.layout.*;
38 import org.eclipse.swt.widgets.*;
39 import org.omwg.ontology.*;
40 import org.wsmo.common.*;
41 import org.wsmo.common.exception.InvalidModelException;
42 import org.wsmostudio.runtime.*;
43 import org.wsmostudio.ui.GUIHelper;
44 import org.wsmostudio.ui.Utils;
45 import org.wsmostudio.ui.editors.common.*;
46 import org.wsmostudio.ui.editors.model.AttributeModel;
47
48 /***
49 * An editor component capable to handle with WSMO-API Attribute objects.
50 * As attributes are highly dependent on their containing Concepts this editor
51 * is dependent on the Concept Editor (i.e. Attribute Editor is a supporting part
52 * of the Concep Editor). In contrast to the most of the other editors, this
53 * editor appears in a standalone modal window on top of the main studio workbench.
54 *
55 * @author not attributable
56 * @version $Revision: 1382 $ $Date: 2007-11-27 14:49:20 +0200 $
57 */
58
59 public class AttributeEditor {
60
61 private AttributeModel model;
62 private Identifier inverseAttrRef = null;
63
64 private NFPPanel nfpPanel;
65 private Table rangesTable;
66 private Shell shell;
67
68 private boolean dirty = false;
69
70 private Button minCheck;
71 private Button maxCheck;
72 private Text minText;
73 private Text maxText;
74
75 private Button inverseOfCheck;
76 private Text inverseAttrText;
77 private Button inverseSelect;
78
79 private Button constrCheck;
80 private Button reflexiveCheck;
81 private Button symmetricCheck;
82 private Button transCheck;
83
84
85 public AttributeEditor(Shell parentShell,
86 AttributeModel model) {
87 shell = new Shell(parentShell, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.SYSTEM_MODAL);
88 Image icon = JFaceResources.getImageRegistry().get(WsmoImageRegistry.DEFAULT_WINDOW_ICON);
89 shell.setImage(icon);
90 shell.setText("Attribute Editor");
91 shell.setLayout(new GridLayout(1, false));
92
93 nfpPanel = new NFPPanel(shell, model);
94
95 this.model = model;
96
97 createDomainView(shell);
98 createPropertiesView(shell);
99 createRangesView(shell);
100 createControlArea(shell);
101 createContextMenu();
102
103 shell.pack();
104 shell.setSize(Math.min(shell.getSize().x, 600),
105 shell.getSize().y + 40);
106
107 Point pLocation = parentShell.getLocation();
108 Point pSize = parentShell.getSize();
109 shell.setLocation(pLocation.x + pSize.x / 2 - shell.getSize().x / 2,
110 pLocation.y + pSize.y / 2 - shell.getSize().y / 2);
111 }
112
113 private void createDomainView(Composite parent) {
114 Group group = new Group(parent, SWT.NONE);
115 group.setText("Domain Concept");
116 group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
117 group.setLayout(new GridLayout(3, false));
118
119 new Label(group, SWT.NONE).setText("Concept : ");
120 final Text domainText = new Text(group, SWT.READ_ONLY | SWT.BORDER);
121 domainText.setText(model.getAttribute().getConcept().getIdentifier().toString());
122 domainText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
123
124 Button changeDomain = new Button(group, SWT.NONE);
125 changeDomain.setText("Change");
126 changeDomain.addSelectionListener(new SelectionAdapter() {
127 public void widgetSelected(SelectionEvent e) {
128 WSMOChooser chooser = WSMOChooser.createConceptChooser(shell,
129 model.getAttribute().getConcept().getOntology());
130 Concept newDomain = (Concept)chooser.open();
131 if (newDomain == null ||
132 newDomain.equals(model.getAttribute().getConcept())) {
133 return;
134 }
135 try {
136 model.setConcept(newDomain);
137 }
138 catch(Exception ime) {
139 LogManager.logError(ime);
140 }
141 model.setChanged();
142 domainText.setText(
143 model.getAttribute().getConcept().getIdentifier().toString());
144 }
145 });
146
147 }
148
149 private void createPropertiesView(Composite parent) {
150 Group group = new Group(parent, SWT.NONE);
151 group.setText("Attribute Properties");
152 group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
153 group.setLayout(new GridLayout(1, true));
154
155 Composite comp1 = new Composite(group, SWT.NONE);
156 comp1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
157 GridLayout layout = new GridLayout(7, false);
158 layout.marginHeight = 2;
159 comp1.setLayout(layout);
160
161 SelectionAdapter dirtyListener = new SelectionAdapter() {
162 public void widgetSelected(SelectionEvent e) {
163 dirty = true;
164 }
165 };
166
167 Label cardLab = new Label(comp1, SWT.NONE);
168 cardLab.setText("Cardinality: ");
169
170 minCheck = new Button(comp1, SWT.CHECK);
171 minCheck.setText("set MIN :");
172 minCheck.setSelection(model.getAttribute().getMinCardinality() != 0);
173 minCheck.addSelectionListener(dirtyListener);
174
175 minText = new Text(comp1, SWT.BORDER);
176 minText.setTextLimit(3);
177 minText.setText(String.valueOf(model.getAttribute().getMinCardinality()));
178 minText.setLayoutData(new GridData(30, SWT.DEFAULT));
179 minText.addModifyListener(new ModifyListener() {
180 public void modifyText(ModifyEvent event) {
181 dirty = true;
182 }
183 });
184 minText.setEnabled(minCheck.getSelection());
185
186 minCheck.addSelectionListener(new SelectionAdapter() {
187 public void widgetSelected(SelectionEvent e) {
188 minText.setEnabled(minCheck.getSelection());
189 }
190 });
191
192 new Label(comp1, SWT.NONE).setLayoutData(new GridData(40, 13));
193
194
195 maxCheck = new Button(comp1, SWT.CHECK);
196 maxCheck.setText("set MAX :");
197 maxCheck.setSelection(model.getAttribute().getMaxCardinality() != Integer.MAX_VALUE);
198 maxCheck.addSelectionListener(dirtyListener);
199
200 maxText = new Text(comp1, SWT.BORDER);
201 maxText.setTextLimit(3);
202 maxText.setLayoutData(new GridData(30, SWT.DEFAULT));
203 if (model.getAttribute().getMaxCardinality() != Integer.MAX_VALUE) {
204 maxText.setText(String.valueOf(model.getAttribute().getMaxCardinality()));
205 }
206 maxText.addModifyListener(new ModifyListener() {
207 public void modifyText(ModifyEvent event) {
208 dirty = true;
209 }
210 });
211 maxText.setEnabled(maxCheck.getSelection());
212
213 maxCheck.addSelectionListener(new SelectionAdapter() {
214 public void widgetSelected(SelectionEvent e) {
215 maxText.setEnabled(maxCheck.getSelection());
216 }
217 });
218
219 Composite comp2 = new Composite(group, SWT.NONE);
220 comp2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
221 layout = new GridLayout(9, false);
222 layout.marginHeight = 2;
223 comp2.setLayout(layout);
224
225 Point leadingOffset = cardLab.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
226 new Label(comp2, SWT.NONE).setLayoutData(
227 new GridData(leadingOffset.x, leadingOffset.y));
228
229 constrCheck = new Button(comp2, SWT.CHECK);
230 constrCheck.setText("Constraining");
231 constrCheck.setSelection(model.getAttribute().isConstraining());
232 constrCheck.addSelectionListener(dirtyListener);
233
234 new Label(comp2, SWT.NONE).setText(" ");
235
236 reflexiveCheck = new Button(comp2, SWT.CHECK);
237 reflexiveCheck.setText("Reflexive");
238 reflexiveCheck.setSelection(model.getAttribute().isReflexive());
239 reflexiveCheck.addSelectionListener(dirtyListener);
240
241 new Label(comp2, SWT.NONE).setText(" ");
242
243 symmetricCheck = new Button(comp2, SWT.CHECK);
244 symmetricCheck.setText("Symmetric");
245 symmetricCheck.setSelection(model.getAttribute().isSymmetric());
246 symmetricCheck.addSelectionListener(dirtyListener);
247
248
249 new Label(comp2, SWT.NONE).setText(" ");
250
251 transCheck = new Button(comp2, SWT.CHECK);
252 transCheck.setText("Transitive");
253 transCheck.setSelection(model.getAttribute().isTransitive());
254 transCheck.addSelectionListener(dirtyListener);
255
256 Composite comp3 = new Composite(group, SWT.NONE);
257 comp3.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
258 layout = new GridLayout(4, false);
259 layout.marginHeight = 2;
260 comp3.setLayout(layout);
261
262 new Label(comp3, SWT.NONE).setLayoutData(
263 new GridData(leadingOffset.x, leadingOffset.y));
264
265 Identifier invAttrRef = model.getAttribute().getInverseOf();
266 inverseAttrRef = invAttrRef;
267
268 inverseOfCheck = new Button(comp3, SWT.CHECK);
269 inverseOfCheck.setText("Inverse of");
270 inverseOfCheck.setSelection(invAttrRef != null);
271 inverseOfCheck.addSelectionListener(dirtyListener);
272
273 inverseAttrText = new Text(comp3, SWT.BORDER | SWT.READ_ONLY);
274 inverseAttrText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
275 inverseAttrText.setEnabled(inverseOfCheck.getSelection());
276 if (invAttrRef != null) {
277 inverseAttrText.setText(invAttrRef.toString());
278 }
279
280 inverseSelect = new Button(comp3, SWT.PUSH);
281 inverseSelect.setText("Select");
282 inverseSelect.setEnabled(inverseOfCheck.getSelection());
283 inverseSelect.addSelectionListener(new SelectionAdapter() {
284 public void widgetSelected(SelectionEvent event) {
285 WSMOChooser chooser = WSMOChooser.createAttributesChooser(
286 shell,
287 WSMORuntime.getRuntime());
288 Attribute inverseAttr = (Attribute)chooser.open();
289 if (inverseAttr == null) {
290 return;
291 }
292 inverseAttrRef = (IRI)inverseAttr.getIdentifier();
293 inverseAttrText.setText(inverseAttr.getIdentifier().toString());
294 dirty = true;
295 }
296 });
297
298 inverseOfCheck.addSelectionListener(new SelectionAdapter() {
299 public void widgetSelected(SelectionEvent e) {
300 inverseAttrText.setEnabled(inverseOfCheck.getSelection());
301 inverseSelect.setEnabled(inverseOfCheck.getSelection());
302 }
303 });
304 comp1.pack();
305 comp2.pack();
306 comp3.pack();
307 }
308
309 private void createRangesView(Composite parent) {
310 Group group = new Group(parent, SWT.NONE);
311 group.setLayoutData(new GridData(GridData.FILL_BOTH));
312 group.setText("Range Concepts");
313 group.setLayout(new GridLayout());
314
315 rangesTable = new Table(group, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
316 rangesTable.setLayoutData(new GridData(GridData.FILL_BOTH));
317 rangesTable.setLinesVisible(false);
318 for(Type type : model.getAttribute().listTypes()) {
319 GUIHelper.createTableItem(rangesTable, type, Utils.findTopContainer(model));
320 }
321 }
322
323
324 private void createControlArea(Composite mainContainer) {
325 Composite buttons = new Composite(mainContainer, SWT.NONE);
326 buttons.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
327 FillLayout layout = new FillLayout(SWT.HORIZONTAL);
328 layout.spacing = 3;
329 buttons.setLayout(layout);
330
331 Button okButton = new Button(buttons, SWT.PUSH);
332 okButton.setText("OK");
333 okButton.addSelectionListener(new SelectionAdapter() {
334 public void widgetSelected(SelectionEvent e) {
335 doUpdate();
336 shell.dispose();
337 }
338 });
339 shell.setDefaultButton(okButton);
340
341 Button noButton = new Button(buttons, SWT.PUSH);
342 noButton.setText("Cancel");
343 noButton.addSelectionListener(new SelectionAdapter() {
344 public void widgetSelected(SelectionEvent e) {
345 shell.dispose();
346 }
347 });
348
349 }
350
351 private void createContextMenu() {
352 final MenuManager menuMgr = new MenuManager();
353 menuMgr.setRemoveAllWhenShown(true);
354 menuMgr.addMenuListener(new IMenuListener() {
355 public void menuAboutToShow(IMenuManager mgr) {
356 fillContextMenu(menuMgr);
357 }
358 });
359 rangesTable.setMenu(menuMgr.createContextMenu(rangesTable));
360 }
361
362 private void fillContextMenu(MenuManager menuMgr) {
363
364 if (false == GUIHelper.containsCursor(rangesTable)) {
365 return;
366 }
367 menuMgr.add(new Action("Add Concept") {
368 public void run() {
369 handleAddConcept();
370 }
371 });
372 menuMgr.add(new Action("Add Data Type") {
373 public void run() {
374 handleAddDataType();
375 }
376 });
377 TableItem[] sel = rangesTable.getSelection();
378 if (sel != null
379 && sel.length > 0
380 && GUIHelper.containsCursor(sel[0].getBounds(0), rangesTable)) {
381 menuMgr.add(new Action("Remove") {
382 public void run() {
383 handleRemoveType();
384 }
385 });
386 }
387 }
388
389 public void open() {
390 shell.open();
391 Display display = shell.getDisplay();
392 while (!shell.isDisposed()) {
393 if (!display.readAndDispatch()) {
394 display.sleep();
395 }
396 }
397 }
398
399 public void dispose() {
400 rangesTable.dispose();
401 nfpPanel.dispose();
402 inverseAttrRef = null;
403 model.getMasterModel().removeSubModel(model);
404 model = null;
405 }
406
407 private void handleAddConcept() {
408 WSMOChooser chooser = WSMOChooser.createConceptChooser(shell, WSMORuntime.getRuntime());
409 Object selected = chooser.open();
410 if (selected == null || false == selected instanceof Concept) {
411 return;
412 }
413 GUIHelper.createTableItem(rangesTable, selected, Utils.findTopContainer(model));
414 dirty = true;
415 rangesTable.redraw();
416 }
417 private void handleAddDataType() {
418 WsmlDataType datatype = DataValueEditor.createTypeSelector(shell);
419 if (datatype == null) {
420 return;
421 }
422 GUIHelper.createTableItem(rangesTable, datatype, (TopEntity)null);
423 dirty = true;
424 rangesTable.redraw();
425 }
426 private void handleRemoveType() {
427 TableItem[] sel = rangesTable.getSelection();
428 sel[0].dispose();
429 dirty = true;
430 rangesTable.redraw();
431 }
432
433 private void doUpdate() {
434 if (false == dirty) {
435 return;
436 }
437
438 int minValue = 0;
439 if (minCheck.getSelection()) {
440 try {
441 minValue = Integer.parseInt(minText.getText());
442 }
443 catch (Exception e) {}
444 }
445 int maxValue = Integer.MAX_VALUE;
446 if (maxCheck.getSelection()) {
447 try {
448 maxValue = Integer.parseInt(maxText.getText());
449 }
450 catch (Exception e) {}
451 }
452 model.setMinCardinality(Math.max(minValue, 0));
453 model.setMaxCardinality(maxValue);
454
455 if (false == inverseOfCheck.getSelection()) {
456 model.setInverseOf(null);
457 }
458 else {
459 model.setInverseOf(inverseAttrRef);
460 }
461 model.setConstraining(constrCheck.getSelection());
462 model.setReflexive(reflexiveCheck.getSelection());
463 model.setSymmetric(symmetricCheck.getSelection());
464 model.setTransitive(transCheck.getSelection());
465
466
467 TableItem[] allItems = rangesTable.getItems();
468 Set<Type> typesBuffer = new HashSet<Type>();
469 Set<Type> oldTypes = new HashSet<Type>(model.getAttribute().listTypes());
470
471 for(int i = 0; i < allItems.length; i++) {
472 Type type = (Type)allItems[i].getData();
473 typesBuffer.add(type);
474 if (false == oldTypes.contains(type)) {
475 try {
476 model.addType(type);
477 }
478 catch(InvalidModelException ime) {
479 LogManager.logError(ime);
480 }
481 }
482 }
483
484 for(Type oldType : oldTypes) {
485 if (false == typesBuffer.contains(oldType)) {
486 try {
487 model.removeType(oldType);
488 }
489 catch(InvalidModelException ime) {
490 LogManager.logError(ime);
491 }
492 }
493 }
494 }
495 }
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559