View Javadoc

1   /*
2    WSMO Studio - a Semantic Web Service Editor
3    Copyright (c) 2004-2006, Ontotext Lab. / SIRMA Group
4    
5    This library is free software; you can redistribute it and/or modify it under
6    the terms of the GNU Lesser General Public License as published by the Free
7    Software Foundation; either version 2.1 of the License, or (at your option)
8    any later version.
9    This library is distributed in the hope that it will be useful, but WITHOUT
10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   details.
13   You should have received a copy of the GNU Lesser General Public License along
14   with this library; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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.grounding.sawsdl.ui.editor;
26  
27  import java.util.List;
28  
29  import org.eclipse.core.resources.IFile;
30  import org.eclipse.core.resources.ResourcesPlugin;
31  import org.eclipse.core.runtime.IPath;
32  import org.eclipse.core.runtime.IProgressMonitor;
33  import org.eclipse.jface.action.*;
34  import org.eclipse.jface.viewers.IStructuredSelection;
35  import org.eclipse.jface.viewers.TreeViewer;
36  import org.eclipse.jface.window.Window;
37  import org.eclipse.swt.SWT;
38  import org.eclipse.swt.custom.SashForm;
39  import org.eclipse.swt.dnd.DND;
40  import org.eclipse.swt.dnd.DropTarget;
41  import org.eclipse.swt.dnd.DropTargetAdapter;
42  import org.eclipse.swt.dnd.DropTargetEvent;
43  import org.eclipse.swt.dnd.Transfer;
44  import org.eclipse.swt.events.KeyAdapter;
45  import org.eclipse.swt.events.KeyEvent;
46  import org.eclipse.swt.events.SelectionAdapter;
47  import org.eclipse.swt.events.SelectionEvent;
48  import org.eclipse.swt.widgets.*;
49  import org.eclipse.ui.IEditorInput;
50  import org.eclipse.ui.IEditorSite;
51  import org.eclipse.ui.PartInitException;
52  import org.eclipse.ui.dialogs.SaveAsDialog;
53  import org.eclipse.ui.part.EditorPart;
54  import org.eclipse.ui.part.FileEditorInput;
55  import org.w3c.dom.*;
56  import org.wsmo.common.Entity;
57  import org.wsmostudio.ui.dnd.Clipboard;
58  import org.wsmostudio.ui.dnd.WSMOTransfer;
59  
60  public class WSDLSEditor extends EditorPart {
61  
62      private TreeViewer tree;
63      private WSDLAnnotationManager annotationManager;
64      
65      private Document model = null;
66      private boolean isWSDL11 = false;
67      private IPath srcLocation = null;
68      private boolean dirty = false;
69      
70      private MappingPropertiesView propsView;
71  
72      @Override
73      public void createPartControl(Composite parent) {
74          
75          if (this.model == null) {
76              return;
77          }
78          SashForm splitter = new SashForm(parent, SWT.VERTICAL);
79          this.tree = new TreeViewer(splitter);
80          this.tree.setContentProvider(new WSDLTreeContentProvider());
81          this.tree.setLabelProvider(new WSDLTreeLabelProvider(annotationManager));
82          this.tree.getTree().addSelectionListener(new SelectionAdapter() {
83              public void widgetSelected(SelectionEvent sel) {
84                  propsView.selectItem(sel.item.getData());
85              }
86          });
87          tree.getTree().addKeyListener(new KeyAdapter() {
88              public void keyReleased(KeyEvent e) {
89                  if (e.keyCode == SWT.F5) {
90                      tree.refresh();
91                      propsView.setMappingData();
92                  }
93              }
94          });
95          this.tree.setInput(this.model);
96          createContextMenu();
97          this.tree.expandAll();
98          initDND();
99          setDirty(annotationManager.getInitialDirtyState());
100         
101         propsView = new MappingPropertiesView(this.model, 
102                 this.annotationManager,
103                 splitter,
104                 this.tree);
105         splitter.setWeights(new int[] {4, 1 });
106     }
107     
108     public Document getModel() {
109         return this.model;
110     }
111 
112     public void doSave(IProgressMonitor monitor) {
113         Utils.saveContent(this, srcLocation.toFile().getAbsolutePath());
114     }
115 
116     @Override
117     public void doSaveAs() {
118         performSaveAs();
119         Utils.saveContent(this, srcLocation.toFile().getAbsolutePath());
120     }
121 
122     @Override
123     public void init(final IEditorSite site, IEditorInput input) throws PartInitException {
124         
125         srcLocation = ((FileEditorInput)input).getPath();
126         if (srcLocation == null) {
127             return;
128         }
129 
130         super.setInput(input);
131         super.setSite(site);
132         model = Utils.loadContent(this, srcLocation.toFile().getAbsolutePath());
133         if (model == null) {
134             if (!site.getShell().isDisposed() && !site.getShell().getDisplay().isDisposed()){
135                 site.getShell().getDisplay().asyncExec(new Runnable() {
136                     public void run() {
137                         site.getPage().closeEditor(WSDLSEditor.this, false);
138                     }
139                 });
140             }
141             return;
142         }
143         this.isWSDL11 = model.getDocumentElement().getTagName().endsWith("definitions");
144         annotationManager = new WSDLAnnotationManager(this, model);
145         if (annotationManager.getInitialDirtyState() == true) {
146             // We need this cloning in order to refresh attribute names
147             // because namespaces definition is changed 
148             Node copy = model.getDocumentElement().cloneNode(true);
149             model.replaceChild(copy, model.getDocumentElement());
150         }
151         setPartName(getPartName() + " - " +input.getName());
152     }
153     
154     public boolean isWSDL11Model() {
155         return this.isWSDL11;
156     }
157 
158     @Override
159     public boolean isSaveAsAllowed() {
160         return true;
161     }
162     @Override
163     public void setFocus() {
164     }
165 
166     public void dispose() {
167         if (annotationManager != null) {
168             annotationManager.dispose();
169             annotationManager = null;
170         }
171         this.tree = null;
172         this.model = null;
173         if (propsView != null) {
174             propsView.dispose();
175             propsView = null;
176         }
177         super.dispose();
178     }
179     
180     public WSDLAnnotationManager getAnnotationManager() {
181         return annotationManager;
182     }
183     public TreeViewer getUITree() {
184         return this.tree;
185     }
186     
187     public IPath getSourceLocation() {
188         return this.srcLocation;
189     }
190 
191     public boolean isDirty() {
192         return this.dirty;
193     }
194     public void setDirty(boolean dirty) {
195         this.dirty = dirty;
196         firePropertyChange(PROP_DIRTY);
197         if (propsView != null && dirty) {
198             propsView.setMappingData();
199         }
200     }
201     public MappingPropertiesView getMappingsView() {
202         return this.propsView;
203     }
204     private void initDND() {
205         DropTarget target = new DropTarget(this.tree.getTree(), 
206                 DND.DROP_LINK | DND.DROP_DEFAULT | DND.DROP_COPY); 
207           
208         final WSMOTransfer wsmoTransfer = WSMOTransfer.getInstance();
209         target.setTransfer(new Transfer[] {wsmoTransfer}); 
210           
211         target.addDropListener(new DropTargetAdapter() { 
212             public void dragEnter(DropTargetEvent event) { 
213                 if (Clipboard.getInstance().ensureContentType(Entity.class)) {
214                     event.detail = DND.DROP_LINK;
215                 }
216                 else {
217                     event.detail = DND.DROP_NONE;
218                 }
219             } 
220             public void dragOver(DropTargetEvent event) { 
221                 if (wsmoTransfer.isSupportedType(event.currentDataType)) {
222                     if (Clipboard.getInstance().ensureContentType(Entity.class) 
223                                   && Utils.checkConceptTargetSelection(event, annotationManager)) {
224                         event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL;
225                         event.detail = DND.DROP_LINK;
226                     }
227                     else {
228                         event.feedback = DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL;
229                         event.detail = DND.DROP_NONE;
230                     }
231                 }
232                 else {
233                     event.feedback = DND.FEEDBACK_NONE;
234                 }
235             } 
236             public void drop(DropTargetEvent event) { 
237                 if (event.item == null) {
238                     return;
239                 }
240                 if (wsmoTransfer.isSupportedType(event.currentDataType)) { 
241                     List<Entity> concepts = Clipboard.getInstance().getContent();
242                     for(Entity entity : concepts) {
243                         annotationManager.performMapping(entity, event.item.getData(), event);
244                     }
245                 } 
246             } 
247         }); 
248     }
249 
250     private void createContextMenu() {
251     	final MenuManager menuMgr = new MenuManager();
252     	menuMgr.setRemoveAllWhenShown(true);
253     	menuMgr.addMenuListener(new IMenuListener() {
254     		public void menuAboutToShow(IMenuManager mgr) {
255     			fillContextMenu(menuMgr);
256     		}
257     	});
258     	tree.getTree().setMenu(menuMgr.createContextMenu(tree.getTree()));
259     }
260 
261     private void fillContextMenu(MenuManager menuMgr) {
262 
263     	if (false == org.wsmostudio.ui.GUIHelper.containsCursor(tree.getTree())) {
264     		return;
265     	}
266         
267     	Object selection = 
268             ((IStructuredSelection)tree.getSelection()).getFirstElement();
269         if (selection == null) {
270             return;
271         }
272         if (selection instanceof String) { // lifting or lowering attribute?
273             final String schemaMapping = (String)selection;
274             final Element domElement = (Element)
275                 tree.getTree().getSelection()[0].getParentItem().getData(); 
276             
277             final boolean isLifting = 
278                 schemaMapping.startsWith(WSDLTreeContentProvider.LIFTING_PREFIX);
279             if (false == isLifting
280                     && false == schemaMapping.startsWith(WSDLTreeContentProvider.LOWERING_PREFIX)) {
281                 return;
282             }
283             final String schemaURI = (isLifting) ? 
284                     schemaMapping.substring(WSDLTreeContentProvider.LIFTING_PREFIX.length())
285                     : schemaMapping.substring(WSDLTreeContentProvider.LOWERING_PREFIX.length());
286 
287             menuMgr.add(new Action("Edit") {
288                 public void run() {
289                     ViewActionHandler.performEditSchemaRef(
290                             domElement, schemaURI, isLifting, WSDLSEditor.this);
291                 }
292             });
293             menuMgr.add(new Separator());
294             menuMgr.add(new Action("Remove") {
295                 public void run() {
296                     ViewActionHandler.performRemoveSchemaRef(domElement, 
297                             schemaURI,                                
298                             isLifting, 
299                             WSDLSEditor.this);
300                 }
301             });
302             return;
303         }
304         
305         if (false == selection instanceof Element) {
306             return;
307         }
308         final Element selEl = (Element)selection;
309         if (false == Utils.isSupportedElement(selEl, getAnnotationManager())) {
310         	return;
311         }
312     	
313         menuMgr.add(new Action(ViewActionHandler.ADD_REF_ACTION) {
314             public void run() {
315                 ViewActionHandler.performAddReference(selEl, WSDLSEditor.this);
316             }
317         });
318         // this is applicable for: xs:element, xs:simpleType, xs.complexType
319         if (Utils.isSupportingSchema(selEl, 
320                                      annotationManager.getXSDPrefix(), 
321                                      annotationManager.getWSDLPrefix())) {
322             menuMgr.add(new Separator());
323             menuMgr.add(new Action("Add Lowering Schema") {
324                 public void run() {
325                     ViewActionHandler.performEditSchemaRef(
326                             selEl, "", false /*isLifting*/, WSDLSEditor.this);
327                 }
328             });
329             menuMgr.add(new Action("Add Lifting Schema") {
330                 public void run() {
331                     ViewActionHandler.performEditSchemaRef(
332                             selEl, "", true /*isLifting*/, WSDLSEditor.this);
333                 }
334             });
335         }
336 
337     	menuMgr.add(new Separator());
338 
339         final List<String> iris = 
340             Utils.retrieveReferences(selEl, getAnnotationManager().getSAWSDLPrefix());
341         
342         if (iris.size() == 0) {
343             return;
344         }
345         if (iris.size() == 1) {
346             menuMgr.add(new Action(ViewActionHandler.REMOVE_REF_ACTION) {
347                 public void run() {
348                     iris.remove(0);
349                     ViewActionHandler.performUpdateReferences(selEl, iris, WSDLSEditor.this);
350                 }
351             });
352         }
353         else {
354             MenuManager subMenu = new MenuManager("Remove Reference ...");
355             for(int i = 0; i < iris.size(); i++ ) {
356                 final int index = i;
357                 subMenu.add(new Action(iris.get(i)) {
358                     public void run() {
359                         iris.remove(index);
360                         ViewActionHandler.performUpdateReferences(selEl, iris, WSDLSEditor.this);
361                     }
362                 });
363             }
364             menuMgr.add(subMenu);
365 
366         }
367     }
368     
369 
370     protected void performSaveAs() {
371         IEditorInput input= getEditorInput();
372 
373         SaveAsDialog dialog= new SaveAsDialog(getSite().getShell());
374 
375         IFile original=  ((FileEditorInput) input).getFile();
376         if (original != null)
377             dialog.setOriginalFile(original);
378 
379         dialog.create();
380         if (dialog.open() != Window.OK) {
381             return;
382         }
383 
384         IPath filePath= dialog.getResult();
385         if (filePath == null) {
386             return;
387         }
388         srcLocation = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath).getLocation();
389     }
390 }
391 
392 /*
393  * $Log$
394  * Revision 1.14  2007/07/19 12:54:08  alex_simov
395  * refactoring in WSMO UI plug-in
396  *
397  * Revision 1.13  2007/05/03 09:42:00  alex_simov
398  * WSDL 11 support improved with attrExtensions for operations
399  *
400  * Revision 1.12  2007/05/02 17:05:58  alex_simov
401  * update (muitliple lifting/lowering schema refs)
402  *
403  * Revision 1.11  2007/04/25 16:53:38  alex_simov
404  * no message
405  *
406  * Revision 1.10  2007/04/23 17:34:22  alex_simov
407  * SAWSDL namespace automatic replacement fix
408  *
409  * Revision 1.9  2007/04/21 13:50:52  alex_simov
410  * SAWSDL and WSDL namespaces are changed according to the latest
411  * SA-WSDL draft and the system automatically replaces occurences of older
412  * versions, followed by a warning message
413  *
414  * Revision 1.8  2006/11/21 09:43:58  alex_simov
415  * The restriction for using only WSMO concepts in the annotation is removed.
416  *
417  * Revision 1.7  2006/10/12 16:25:27  alex_simov
418  * 1) multiple URI references support added
419  * 2) basic lowering/lifting schema support added
420  *
421  * Revision 1.6  2006/09/04 15:23:33  alex_simov
422  * bugfix[1531709]: Context menus relied on right button mouse click instead of
423  * being registered as dedicated context menus for the corresponding UI
424  * controls
425  *
426  * Revision 1.5  2006/07/19 11:27:40  alex_simov
427  * WSDL 1.1 annotation support added (this option is controlled by preference
428  *  pages)
429  *
430  * Revision 1.4  2006/07/11 15:58:46  alex_simov
431  * keybindings removed - now defined as global actions for the workbench
432  *
433  * Revision 1.3  2006/07/07 13:00:41  alex_simov
434  * Mapping information panel added in the bottom of the main editor component
435  *
436  * Revision 1.2  2006/07/06 14:44:46  alex_simov
437  * editor is closed on failure
438  *
439  * Revision 1.1  2006/07/05 15:37:29  alex_simov
440  * no message
441  *
442  * Revision 1.5  2006/07/03 15:42:18  alex_simov
443  * 1) refactoring: controller separated from the viewer
444  * 2) namespaces view added in the bottom of the main viewer
445  *
446  * Revision 1.4  2006/06/29 15:14:26  alex_simov
447  * ModelRef value overwriting check added
448  *
449  * Revision 1.3  2006/06/22 11:49:47  alex_simov
450  * category support added
451  *
452  * Revision 1.2  2006/06/21 12:55:13  alex_simov
453  * no message
454  *
455  * Revision 1.1  2006/06/06 13:15:28  alex_simov
456  * no message
457  *
458  */