View Javadoc
1   /*
2    WSMO Studio - a Semantic Web Service Editor
3    Copyright (c) 2004-2007, 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-2007</p>
22   * <p>Company: Ontotext Lab. / SIRMA </p>
23   */
24  
25  package org.wsmostudio.ui.editors.extension;
26  
27  import java.util.HashMap;
28  import java.util.Iterator;
29  import java.util.LinkedList;
30  import java.util.Map;
31  import java.util.Set;
32  
33  import org.eclipse.core.runtime.*;
34  import org.eclipse.ui.IEditorDescriptor;
35  import org.eclipse.ui.internal.Workbench;
36  import org.omwg.ontology.Axiom;
37  import org.omwg.ontology.Concept;
38  import org.omwg.ontology.Instance;
39  import org.omwg.ontology.Ontology;
40  import org.omwg.ontology.Relation;
41  import org.omwg.ontology.RelationInstance;
42  import org.wsmo.common.Entity;
43  import org.wsmo.mediator.Mediator;
44  import org.wsmo.service.Capability;
45  import org.wsmo.service.Goal;
46  import org.wsmo.service.Interface;
47  import org.wsmo.service.WebService;
48  import org.wsmostudio.runtime.LogManager;
49  import org.wsmostudio.ui.WsmoUIPlugin;
50  import org.wsmostudio.ui.editors.WSMOEditor;
51  import org.wsmostudio.ui.editors.model.*;
52  import org.wsmostudio.ui.views.navigator.ContentExtensionManager;
53  
54  /***
55   * A manager class responsible for working with studio editors extension
56   * point (<code>org.wsmostudio.ui.editors</code>) and all available extensions.
57   * The main task of the manager is to locate references to all registered
58   * editors and whenever a WSMO-API object has to be opened, to find the most
59   * suitable one.
60   *
61   * @author not attributable
62   * @version $Revision: 1032 $ $Date: 2007-01-25 11:27:55 +0200 $
63   */
64  
65  public class ExtensionManager {
66  
67      public static final String EDITOR_EXT_ID = "org.wsmostudio.ui.editors";
68  
69      public static final String BIND_CONFIG_ELEMENT = "editorBinding";
70      public static final String CONF_ATTR_EDITOR = "editorId";
71      public static final String CONF_ATTR_TYPE = "wsmoType";
72      public static final String CONF_ATTR_MODEL = "uiModel";
73      
74      private static final String PREFERRED_EDITOR_PROPERTY_PREFIX = "$prefEd$";
75      
76      // keys - wsmo-api classe names, values - lists of registered editor ids for the certain class
77      private Map<String, LinkedList<String>> wsmo2editor;
78      
79      // mapping between editor ids and their user-friendly descriptions
80      // key - editor id, value - editor name
81      private Map<String, String> editorId2Descr;
82      
83      private Map<String, ModelFactory> editor2Model = new HashMap<String, ModelFactory>();
84  
85      public String locateEditorForEntity(Object target) {
86          
87          String editorID = findEditorId(target);
88          if (editorID != null) {
89              return editorID;
90          }
91          LogManager.logWarning("Editor extension for entity" 
92                  + ((target instanceof Entity) ? 
93                          " '" + ((Entity)target).getIdentifier().toString()+ "'" 
94                          : "") 
95                  + " (of type "
96                  + target.getClass().getName()
97                  + ") not found!");
98          return null; // no editor found!
99      }
100 
101     public LinkedList<String> findEditorsForObject(Object object) {
102         if (wsmo2editor == null) {
103             initBindingsInfo();
104         }
105 
106         String key = 
107             ContentExtensionManager.getRelatedKeyForTable(object.getClass(), wsmo2editor, true);
108         if (key == null) { // no appropriate editors
109             return null;
110         }
111 
112         LinkedList<String> resultSet = new LinkedList<String>();
113         LinkedList<String> editorsFamily = wsmo2editor.get(key);
114         for(Iterator<String> innerIt = editorsFamily.iterator(); innerIt.hasNext();) {
115             String editorID = innerIt.next();
116             IEditorDescriptor editorDescr = Workbench.getInstance().getEditorRegistry().findEditor(editorID); 
117             if (null == editorDescr) {
118                 LogManager.logWarning("Editor '" + editorID + " cannot be found in the registry!");
119                 innerIt.remove(); // don't check it next time
120             }
121             else {
122                 resultSet.add(editorID);
123                 editorId2Descr.put(editorID, editorDescr.getLabel());
124             }
125         }
126         return resultSet;
127     }
128     
129     public String getEditorDescription(String editorID) {
130         if (false == editorId2Descr.containsKey(editorID)) {
131             IEditorDescriptor editorDescr = Workbench.getInstance().getEditorRegistry().findEditor(editorID); 
132             if (null != editorDescr) {
133                 editorId2Descr.put(editorID, editorDescr.getLabel());
134             }
135         }
136         return editorId2Descr.get(editorID);
137     }
138     
139     public String findPreferredEditor(Object target) {
140         String key = 
141             ContentExtensionManager.getRelatedKeyForTable(target.getClass(), wsmo2editor, true);
142         if (key != null) {
143             return findPreferredEditor(key);
144         }
145         return null;
146     }
147 
148     public String findPreferredEditor(String targetClass) {
149         return WsmoUIPlugin
150                    .getDefault()
151                        .getPreferenceStore()
152                            .getString(PREFERRED_EDITOR_PROPERTY_PREFIX 
153                                       + targetClass);
154     }
155 
156     public void setPreferredEditor(Object target, String editorID) {
157 
158         String key = 
159             ContentExtensionManager.getRelatedKeyForTable(target.getClass(), wsmo2editor, true);
160         if (key != null) {
161             setPreferredEditor(key, editorID);
162         }
163     }
164     
165     public void setPreferredEditor(String targetClass, String editorID) {
166         WsmoUIPlugin
167             .getDefault()
168                 .getPreferenceStore()
169                     .setValue(PREFERRED_EDITOR_PROPERTY_PREFIX 
170                               + targetClass, 
171                               editorID);
172     }
173     
174     public Set<String> getDefinedClasses() {
175         if (wsmo2editor == null) {
176             initBindingsInfo();
177         }
178         return wsmo2editor.keySet();
179     }
180 
181     public LinkedList<String> getRegisteredEditors(String className) {
182         return wsmo2editor.get(className);
183     }
184     
185     public ObservableModel createModelForEditor(String editorId, 
186                                                 Object wsmoObject,
187                                                 ObservableModel masterModel) {
188         if (wsmo2editor == null) {
189             initBindingsInfo();
190         }
191         ModelFactory factory = editor2Model.get(editorId);
192         if (factory == null) {
193             return null;
194         }
195         return factory.createModel(wsmoObject, masterModel);
196     }
197 
198     private void initBindingsInfo() {
199 
200         if (wsmo2editor == null) {
201             wsmo2editor = new HashMap<String, LinkedList<String>>();
202         }
203         else {
204             wsmo2editor.clear();
205         }
206         editorId2Descr = new HashMap<String,String>();
207         initSystemBindings();
208         IExtensionPoint iExtPoint = Platform
209                                         .getExtensionRegistry()
210                                             .getExtensionPoint(
211                                                 EDITOR_EXT_ID);
212         IExtension[] exts = iExtPoint.getExtensions();
213         for (int i = 0; i < exts.length; i++) {
214             IConfigurationElement[] confs = exts[i].getConfigurationElements(); 
215             for (int j = 0; j < confs.length; j++) {
216                 if (!confs[j].getName().equals(BIND_CONFIG_ELEMENT)) {
217                     continue; // not a binding element
218                 }
219                 String editorId = confs[j].getAttribute(CONF_ATTR_EDITOR);
220                 String wsmoTypeStr = confs[j].getAttribute(CONF_ATTR_TYPE);
221                 if (editorId == null 
222                         || editorId.trim().length() == 0) {
223                     LogManager.logWarning("Invalid extension config element for '"
224                             + EDITOR_EXT_ID 
225                             + "'. Editor reference expected!");
226                     continue;
227                 }
228                 if (wsmoTypeStr == null 
229                         || wsmoTypeStr.trim().length() == 0) {
230                     LogManager.logWarning("Invalid extension config element for '"
231                             + EDITOR_EXT_ID 
232                             + "'. WSMO object type expected!");
233                     continue;
234                 }
235                 LinkedList<String> editorsFamily = wsmo2editor.get(wsmoTypeStr);
236                 
237                 if (editorsFamily == null) {
238                     editorsFamily = new LinkedList<String>();
239                     wsmo2editor.put(wsmoTypeStr, editorsFamily);
240                 }
241                 if (false == editorsFamily.contains(editorId)) {
242                     editorsFamily.add(editorId);
243                 }
244                 String uiModelFactory = confs[j].getAttribute(CONF_ATTR_MODEL);
245                 if (uiModelFactory != null 
246                         && uiModelFactory.trim().length() > 0) {
247                     try {
248                         Object factory = confs[j].createExecutableExtension(CONF_ATTR_MODEL);
249                         if (false == factory instanceof ModelFactory) {
250                             LogManager.logWarning("Model factory for editor '"
251                                     + editorId
252                                     +"' does not appear as instance of a proper type.");
253                             continue;
254                         }
255                         editor2Model.put(editorId, (ModelFactory)factory);
256                     }
257                     catch(CoreException ce) {
258                         LogManager.logWarning("ModelFactory ('" 
259                                 + uiModelFactory 
260                                 + "') for editor '" 
261                                 + editorId 
262                                 +"' can not be instanciated.");
263                     }
264                 }
265             }
266         }
267     }
268     
269     private void initSystemBindings() {
270         
271         addInitialBindingEntry(Concept.class.getName(), WSMOEditor.CONCEPT_EDITOR_ID);
272         addInitialBindingEntry(Relation.class.getName(), WSMOEditor.REL_EDITOR_ID);
273         addInitialBindingEntry(Instance.class.getName(), WSMOEditor.INSTANCE_EDITOR_ID);
274         addInitialBindingEntry(RelationInstance.class.getName(), WSMOEditor.REL_INSTANCE_EDITOR_ID);
275         addInitialBindingEntry(Ontology.class.getName(), WSMOEditor.ONTOLOGY_EDITOR_ID);
276         addInitialBindingEntry(Capability.class.getName(), WSMOEditor.CAPABILITY_EDITOR_ID);
277         
278         addInitialBindingEntry(Axiom.class.getName(), WSMOEditor.AXIOM_EDITOR_ID);
279         addInitialBindingEntry(WebService.class.getName(), WSMOEditor.WEBSERVICE_EDITOR_ID);
280         addInitialBindingEntry(Goal.class.getName(), WSMOEditor.GOAL_EDITOR_ID);
281 
282         addInitialBindingEntry(Interface.class.getName(), WSMOEditor.INTERFACE_EDITOR_ID);
283         addInitialBindingEntry(Mediator.class.getName(), WSMOEditor.MEDIATOR_EDITOR_ID);
284     }
285     
286     private void addInitialBindingEntry(String wsmoClass, String editorID) {
287         LinkedList<String> buffer = new LinkedList<String>();
288         buffer.add(editorID);
289         wsmo2editor.put(wsmoClass, buffer);
290     }
291     
292     private String findEditorId(Object object) {
293         LinkedList<String> allEditors = findEditorsForObject(object);
294         if (allEditors == null 
295                 || allEditors.size() == 0) {
296             return null;
297         }
298 
299         if (allEditors.size() > 1) {
300             String preferredEditor = findPreferredEditor(object);
301             if (preferredEditor != null 
302                     && allEditors.contains(preferredEditor)) {
303                 return preferredEditor;
304             }
305         }
306         return allEditors.getFirst();
307     }
308 }
309 
310 /*
311  * $Log$
312  * Revision 1.11  2007/01/25 09:27:55  alex_simov
313  * no message
314  *
315  * Revision 1.10  2006/06/05 15:56:28  alex_simov
316  * Entity method arguments replaced by Object types - removed unnecessary restrictions
317  *
318  * Revision 1.9  2006/03/06 14:37:44  alex_simov
319  * Editors extension registry now works with string class names instead of
320  *  classes (thus coping with eclipse different classloaders)
321  *
322  * Revision 1.8  2006/01/09 12:51:14  alex_simov
323  * Copyright message in header updated
324  *
325  * Revision 1.7  2005/11/10 13:47:49  alex_simov
326  * wsmo-editors extension point update
327  *
328  * Revision 1.6  2005/11/02 08:52:28  alex_simov
329  * Entity params are replaced by Object params, allowing non-entity wsmo objects to be processed
330  *
331  * Revision 1.5  2005/09/16 14:25:11  alex_simov
332  * Identifier.asString() removed, use Object.toString() instead
333  *
334  * Revision 1.4  2005/09/08 16:46:25  alex_simov
335  * Migrating to Java 1.5
336  *
337  * Revision 1.3  2005/07/29 15:08:02  alex_simov
338  * added javadoc: class description, footer
339  *
340  *
341  */