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.ui.editors;
26  
27  import java.util.Observable;
28  import java.util.Observer;
29  
30  import org.eclipse.core.runtime.IAdaptable;
31  import org.eclipse.core.runtime.IProgressMonitor;
32  import org.eclipse.jface.dialogs.MessageDialog;
33  import org.eclipse.jface.viewers.ISelection;
34  import org.eclipse.jface.viewers.ISelectionChangedListener;
35  import org.eclipse.jface.viewers.ISelectionProvider;
36  import org.eclipse.jface.viewers.StructuredSelection;
37  import org.eclipse.ui.*;
38  import org.eclipse.ui.part.EditorPart;
39  import org.eclipse.ui.part.IContributedContentsView;
40  import org.eclipse.ui.views.properties.IPropertySource;
41  import org.wsmo.common.Entity;
42  import org.wsmo.common.TopEntity;
43  import org.wsmostudio.runtime.LogManager;
44  import org.wsmostudio.runtime.WSMORuntime;
45  import org.wsmostudio.ui.Utils;
46  import org.wsmostudio.ui.editors.model.ModelPersistenceListener;
47  import org.wsmostudio.ui.editors.model.ModelUtils;
48  import org.wsmostudio.ui.editors.model.ObservableModel;
49  import org.wsmostudio.ui.views.properties.WSMOPropertiesSource;
50  
51  /***
52   * An abstract editor component intended to be subclassed by editors capable
53   * to handle with different WSMO-API objects.
54   * This implementation supports a common functionality of most WSMO object 
55   * editors. It also outlines some desired subclass functionality like
56   * validation and saving specific inputs. 
57   *
58   * @author not attributable
59   * @version $Revision: 1389 $ $Date: 2007-12-04 17:25:33 +0200 $
60   */
61  
62  public abstract class WSMOEditor extends EditorPart 
63  implements IAdaptable, ISelectionProvider, Observer, ModelPersistenceListener {
64  
65      public static final String AXIOM_EDITOR_ID = "org.wsmostudio.ui.editors.axiomEditor";
66      public static final String REL_EDITOR_ID = "org.wsmostudio.ui.editors.relationEditor";
67      public static final String CONCEPT_EDITOR_ID = "org.wsmostudio.ui.editors.conceptEditor";
68      public static final String INSTANCE_EDITOR_ID = "org.wsmostudio.ui.editors.instanceEditor";
69      public static final String REL_INSTANCE_EDITOR_ID = "org.wsmostudio.ui.editors.relInstanceEditor";
70      public static final String ONTOLOGY_EDITOR_ID = "org.wsmostudio.ui.editors.ontologyEditor";
71      public static final String CAPABILITY_EDITOR_ID = "org.wsmostudio.ui.editors.capabilityEditor";
72      public static final String WEBSERVICE_EDITOR_ID = "org.wsmostudio.ui.editors.webserviceEditor";
73      public static final String INTERFACE_EDITOR_ID = "org.wsmostudio.ui.editors.interfaceEditor";
74      public static final String MEDIATOR_EDITOR_ID = "org.wsmostudio.ui.editors.mediatorEditor";
75      public static final String GOAL_EDITOR_ID = "org.wsmostudio.ui.editors.goalEditor";
76  
77      protected WSMOPropertiesSource props = null;
78      private boolean contentUpdatePostponed = false;
79      
80      /* (non-Javadoc)
81       * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
82       */
83      public void init(IEditorSite site, IEditorInput input) throws PartInitException {
84          setSite(site);
85          setInput(input);
86          setPartName(getPartName() + " - " +input.getName());
87          getSite().setSelectionProvider(this);
88          Observable uiModel = (Observable)input.getAdapter(Observable.class);
89          if (uiModel != null) {
90              uiModel.addObserver(this);
91          }
92      }
93      
94      public void doSave(IProgressMonitor monitor) {
95          try {
96              ObservableModel uiModel = 
97                  (ObservableModel)getEditorInput().getAdapter(ObservableModel.class);
98              if (uiModel != null) {
99                  ModelUtils.notifyModelAboutToSave(uiModel);
100             }
101             doTryToSave();
102             if (uiModel != null) {
103                 while (uiModel.getMasterModel() != null) {
104                     uiModel = uiModel.getMasterModel();
105                 }
106                 uiModel.clearDirty();
107                 ModelUtils.notifyModelSaved(uiModel);
108             }
109         }
110         catch(Exception e) {
111             MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
112                     "Invalid Content",
113                     e.getMessage());
114             LogManager.logError(e.getMessage(), e);
115             monitor.setCanceled(true);
116         }
117         notifyDirty();
118     }
119 
120     public void doSaveAs() {
121     }
122 
123     public boolean isDirty() {
124         if (getEditorInput() == null) {
125             return false; // not initialised yet
126         }
127         ObservableModel uiModel = 
128             (ObservableModel)getEditorInput().getAdapter(ObservableModel.class);
129         if (uiModel != null) {
130             return uiModel.isDirty();
131         }
132         return false;
133     }
134     
135     public void update(Observable o, Object arg) {
136         
137         if (isInputEntityDead()) {
138             final IWorkbenchPartSite site = getSite();
139             if (!site.getShell().isDisposed() 
140                     && !site.getShell().getDisplay().isDisposed()){
141                 site.getShell().getDisplay().asyncExec(new Runnable() {
142                     public void run() {
143                         site.getPage().closeEditor(WSMOEditor.this, false);
144                     }
145                 });
146             }
147             return;
148         }
149         
150         contentUpdatePostponed = true;
151         if (this.equals(PlatformUI.getWorkbench()
152                 .getActiveWorkbenchWindow()
153                 .getActivePage().getActiveEditor())) {
154             ObservableModel model = 
155                 (ObservableModel)getEditorInput().getAdapter(ObservableModel.class);
156             model.disableNotification();
157             updateFromModel();
158             model.enableNotification();
159         }
160         notifyDirty();
161     }
162     
163     public void setFocus() {
164         if (true == contentUpdatePostponed) {
165             ObservableModel model = 
166                 (ObservableModel)getEditorInput().getAdapter(ObservableModel.class);
167             model.disableNotification();
168             updateFromModel();
169             model.enableNotification();
170             contentUpdatePostponed = false;
171         }
172     }
173     
174     protected abstract void updateFromModel();
175     
176     public boolean isSaveAsAllowed() {
177         return false;
178     }
179     
180     public void dispose() {
181         if (getEditorInput().getAdapter(TopEntity.class) != null) {
182             TopEntity topEntity = (TopEntity)getEditorInput().getAdapter(TopEntity.class);
183             
184             boolean unregisterEntity = true;
185             IWorkbenchPage page = PlatformUI.getWorkbench()
186                                                 .getActiveWorkbenchWindow()
187                                                 .getActivePage();
188             
189             if (page != null) {
190                 IEditorReference[] editorRefs = page.getEditorReferences();
191                 if (editorRefs != null) {
192                     for (int i = 0; i < editorRefs.length; i++) {
193                         try {
194                             if (false == this.equals(editorRefs[i].getEditor(true))
195                                     && null != editorRefs[i].getEditorInput()
196                                     .getAdapter(topEntity.getClass())
197                                     && null != editorRefs[i].getEditor(true)
198                                     .getAdapter(topEntity.getClass())) {
199                                 unregisterEntity = false;
200                                 break;
201                             }
202                         }
203                         catch(PartInitException pie) {
204                             continue;
205                         }
206                     }
207                 }
208                 if (unregisterEntity) {
209                     WSMORuntime.getRuntime().unregisterEntity(
210                             (TopEntity)getEditorInput().getAdapter(TopEntity.class));
211                 }
212             }
213         }
214         ObservableModel uiModel = (ObservableModel)
215                 getEditorInput().getAdapter(ObservableModel.class);
216         if (uiModel != null) {
217             uiModel.deleteObserver(this);
218             if (uiModel.countObservers() == 0) {
219                 uiModel.setMasterModel(null);
220             }
221         }
222         super.dispose();
223     }
224 
225     @SuppressWarnings("unchecked")
226     public Object getAdapter(Class adapter) {
227         if (adapter == IPropertySource.class) {
228             if (props == null) {
229                 Object delegate = getEditorInput().getAdapter(Entity.class);
230                 if (delegate == null) {
231                     return null;
232                 }
233                 props = new WSMOPropertiesSource((Entity)delegate);
234 			}
235 			return props;
236 		}
237         if (adapter == org.eclipse.ui.part.IContributedContentsView.class) {
238             return new IContributedContentsView() {
239                 public IWorkbenchPart getContributingPart() {
240                     return WSMOEditor.this;
241                 }
242             };
243         }
244         if (adapter == ModelPersistenceListener.class) {
245             return this;
246         }
247 
248         return super.getAdapter(adapter);
249      }
250     
251     public void addSelectionChangedListener(ISelectionChangedListener listener) {
252     }
253     
254     public ISelection getSelection() {
255         return new StructuredSelection(this);
256     }
257     
258     public void removeSelectionChangedListener(ISelectionChangedListener listener) {
259     }
260     
261     public void setSelection(ISelection selection) {
262     }
263     
264     public void notifyDirty() {
265         firePropertyChange(PROP_DIRTY);
266     }
267     
268     protected void doTryToSave() throws Exception {
269         ObservableModel uiModel = (ObservableModel)
270                 getEditorInput().getAdapter(ObservableModel.class);
271         if (uiModel == null) {
272             throw new RuntimeException("WSMOEditor: unable to retrieve ObservableModel or doTryToSave() not overridden");
273         }
274         WSMORuntime.getRuntime().doUpdateEntity(
275                 Utils.findTopContainer(uiModel));
276     }
277     
278     /***
279      * The editor is notified that the data (WSMO) model is about to be persisted.
280      * At this stage the editor should update its cached internal data to the model (if any).
281      * This method is called BEFORE the model is persisted.
282      */
283     public void modelAboutToSave() throws Exception {
284     };
285     public void modelSaved() {
286     };
287     
288     /***
289      * This method checks if the current input object is still part of another object
290      * (where applicable), for exanple: if a concept/relation/instance is still part 
291      * of ontology. This method is intended to be overriden.
292      * @return
293      */
294     public boolean isInputEntityDead() {
295         return false;
296     }
297 }
298 
299 /*
300  * $Log$
301  * Revision 1.22  2007/02/13 15:53:16  alex_simov
302  * bugfix[1312971]: The WSMO Text editor synchronizes the wsmo object
303  * model automatically with the other editors (if possible) or issues a warning
304  * message otherwise.
305  *
306  * Revision 1.21  2006/07/11 16:19:32  alex_simov
307  * keybindings removed - now defined as global actions for the workbench
308  *
309  * Revision 1.20  2006/05/15 12:02:44  alex_simov
310  * pre/post save editors content notification model improved
311  *
312  * Revision 1.19  2006/01/09 12:51:13  alex_simov
313  * Copyright message in header updated
314  *
315  * Revision 1.18  2005/11/17 16:08:26  alex_simov
316  * fix
317  *
318  * Revision 1.17  2005/11/16 09:47:50  alex_simov
319  * fix
320  *
321  * Revision 1.16  2005/11/15 15:52:20  alex_simov
322  * dispose() update
323  *
324  * Revision 1.15  2005/11/09 16:17:38  alex_simov
325  * UIModels notification improved
326  *
327  * Revision 1.14  2005/11/04 13:03:11  alex_simov
328  * bugfix (#1347014): TopEntity is removed from the runtime registry only
329  * the last editor for it is closed
330  *
331  * Revision 1.13  2005/11/02 14:50:57  alex_simov
332  * moving to MVC architecture cont'd
333  *
334  * Revision 1.12  2005/10/31 15:58:21  alex_simov
335  * common (platform) shortcuts/hotkeys enabled
336  *
337  * Revision 1.11  2005/08/04 14:59:17  alex_simov
338  * editor <-> subeditor dependency links established
339  *
340  * Revision 1.10  2005/07/29 15:08:02  alex_simov
341  * added javadoc: class description, footer
342  *
343  *
344  */