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.runtime.io;
26  
27  import java.io.*;
28  import java.util.*;
29  
30  import org.eclipse.core.resources.*;
31  import org.eclipse.core.runtime.*;
32  import org.eclipse.jface.dialogs.MessageDialog;
33  import org.eclipse.ui.*;
34  import org.eclipse.ui.views.navigator.ResourceNavigator;
35  import org.omwg.ontology.*;
36  import org.wsmo.common.*;
37  import org.wsmo.common.exception.SynchronisationException;
38  import org.wsmo.mediator.*;
39  import org.wsmo.service.*;
40  import org.wsmo.validator.*;
41  import org.wsmo.wsml.ParserException;
42  import org.wsmostudio.runtime.*;
43  import org.wsmostudio.runtime.cache.WSMOTopEntity;
44  
45  
46  public class WorkspaceIOManager {
47  
48      private WSMORuntime runtime;
49      public static final String DISABLE_VALIDATOR_PROPERTY = "$useWsmlValidator&";
50      public static final String VALIDATE_IMPORTS_PROPERTY = "$validateImports&";
51      
52      public WorkspaceIOManager(WSMORuntime runtime) {
53          this.runtime = runtime;
54      }
55      
56      public TopEntity[] loadContent(IPath file) {
57          IFile iResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(file);
58          return loadContent(file.toFile(), iResource, false);
59      }
60      
61      public TopEntity[] loadContent(String path, boolean ignoreError) {
62          File file = new File(path);
63          return loadContent(file, null, ignoreError);
64      }
65  
66      public TopEntity[] loadContent(File file, IFile iResource, boolean ignoreError) {
67  
68          TopEntity[] topEntities = null;
69          FileReader fr = null;
70          try {
71              fr = new FileReader(file);
72              topEntities = runtime.getWsmlParser().parse(fr);
73              if (iResource != null) {
74                  clearParserErrorMarkers(iResource);
75              }
76          }
77          catch (Exception e) {
78              if (false == ignoreError) {
79                  MessageDialog.openError(
80                          PlatformUI.getWorkbench()
81                          .getActiveWorkbenchWindow().getShell(),
82                          "WSML Parse Error",
83                          "An error occured during parsing file '"
84                          + file.toString() + "':\n"
85                          + e.getMessage());
86              }
87              if (iResource != null) {
88                  clearMarkersForResource(iResource);
89                  IMarker marker = createMarker(iResource, 
90                          "Parser error : " + e.getMessage(), 
91                          IMarker.SEVERITY_ERROR);
92                  if (marker != null) {
93                      try {
94                          marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
95                          if (e instanceof ParserException) {
96                              marker.setAttribute(IMarker.LINE_NUMBER, 
97                                      ((ParserException)e).getErrorLine());
98                              marker.setAttribute(IMarker.LOCATION, 
99                                      ((ParserException)e).getErrorPos());
100                         }
101                     }
102                     catch(CoreException coreEx) {}
103                 }
104                 refreshResourceNavigator();
105             }
106             LogManager.logError("An error occured during parsing file '"
107                                 + file.toString() 
108                                 + "'",
109                                 e);
110         }
111         finally {
112             try {
113                 fr.close();
114             }
115             catch (IOException e) {
116                 LogManager.logError(e);
117             }
118         }
119         if (iResource != null
120                 && topEntities != null 
121                 && topEntities.length > 0) {
122             refineErrorMarkers(iResource, topEntities[0]);
123             refreshResourceNavigator();
124         }
125 
126         return topEntities;
127 
128     }
129     
130     public void saveContent(TopEntity entity, IPath filePath)
131             throws Exception {
132         
133         File file = filePath.toFile();
134 
135         StringBuffer str = new StringBuffer();
136         runtime.getWsmlSerializer().serialize( new TopEntity[] { entity }, str);
137 
138         FileOutputStream fileOut = new FileOutputStream(file, false);
139         fileOut.write(str.toString().getBytes());
140         fileOut.close();
141         
142         IFile iResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(filePath);
143         
144         if (iResource == null) {
145             return; // not a local resource
146         }
147         
148         iResource.refreshLocal(IResource.DEPTH_INFINITE, null);
149         refreshResourceNavigator();
150         if (true == refineErrorMarkers(iResource, entity)) {
151             MessageDialog.openWarning(
152                     PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
153                     "WSML Validator Error",
154                     "The saved entity contains some WSML validation problems."
155                     + "\nSee 'Problems' view for details!");
156         }
157     }
158 
159     public Ontology doLoadOntology(Identifier ontoRef) {
160         return doLoadOntology(ontoRef, false);
161     }
162 
163     public Ontology doLoadOntology(Identifier ontoRef, boolean ignoreError) {
164         if (false == ontoRef instanceof IRI) {
165             return null;
166         }
167         String fileStr = WSMORuntime.getCache()
168                              .getFileLocationForId((IRI)ontoRef, WSMOTopEntity.ONTOLOGY);
169         if (fileStr == null) {
170             return null;
171         }
172         TopEntity[] result = loadContent(fileStr, ignoreError);
173         if (result == null) {
174             return null;
175         }
176         for(int i = 0; i < result.length; i++) {
177             if (result[i] instanceof Ontology
178                     && result[i].getIdentifier().equals(ontoRef)) {
179                 return (Ontology)result[i];
180             }
181         }
182         return null;
183     }
184     
185     public Goal doLoadGoal(Identifier goalRef) {
186         if (false == goalRef instanceof IRI) {
187             return null;
188         }
189         String fileStr = WSMORuntime.getCache()
190                              .getFileLocationForId((IRI)goalRef, WSMOTopEntity.GOAL);
191         if (fileStr == null) {
192             return null;
193         }
194         TopEntity[] result = loadContent(fileStr, false);
195         if (result == null) {
196             return null;
197         }
198         for(int i = 0; i < result.length; i++) {
199             if (result[i] instanceof Goal
200                     && result[i].getIdentifier().equals(goalRef)) {
201                 return (Goal)result[i];
202             }
203         }
204         return null;
205     }
206     
207     public WebService doLoadWebService(Identifier wsRef) {
208         if (false == wsRef instanceof IRI) {
209             return null;
210         }
211         String fileStr = WSMORuntime.getCache()
212                              .getFileLocationForId((IRI)wsRef, WSMOTopEntity.WEB_SERVICE);
213         if (fileStr == null) {
214             return null;
215         }
216         TopEntity[] result = loadContent(fileStr, false);
217         if (result == null) {
218             return null;
219         }
220         for(int i = 0; i < result.length; i++) {
221             if (result[i] instanceof WebService
222                     && result[i].getIdentifier().equals(wsRef)) {
223                 return (WebService)result[i];
224             }
225         }
226         return null;
227     }
228 
229     public GGMediator doLoadGGMediator(Identifier mediRef) {
230         return (GGMediator)doLoadMediator(mediRef, WSMOTopEntity.GG_MEDIATOR);
231     }
232     public OOMediator doLoadOOMediator(Identifier mediRef) {
233         return (OOMediator)doLoadMediator(mediRef, WSMOTopEntity.OO_MEDIATOR);
234     }
235     public WGMediator doLoadWGMediator(Identifier mediRef) {
236         return (WGMediator)doLoadMediator(mediRef, WSMOTopEntity.WG_MEDIATOR);
237     }
238     public WWMediator doLoadWWMediator(Identifier mediRef) {
239         return (WWMediator)doLoadMediator(mediRef, WSMOTopEntity.WW_MEDIATOR);
240     }
241 
242     private Mediator doLoadMediator(Identifier mediRef, int mediType) {
243         if (false == mediRef instanceof IRI) {
244             return null;
245         }
246         String fileStr = WSMORuntime.getCache()
247                              .getFileLocationForId((IRI)mediRef, mediType);
248         if (fileStr == null) {
249             return null;
250         }
251         TopEntity[] result = loadContent(fileStr, false);
252         if (result == null) {
253             return null;
254         }
255         for(int i = 0; i < result.length; i++) {
256             if (result[i] instanceof Mediator
257                     && result[i].getIdentifier().equals(mediRef)) {
258                 return (Mediator)result[i];
259             }
260         }
261         return null;
262     }
263 
264     private boolean refineErrorMarkers(IFile resource, TopEntity targetEntity) {
265         if (resource == null 
266                 || targetEntity == null) {
267             return false; // no errors found
268         }
269         clearMarkersForResource(resource);
270         if (false == useValidator()) {
271             return false;
272         }
273         WsmlValidator validator = runtime.getWsmlValidator();
274         LinkedList<ValidationError> errors = new LinkedList<ValidationError>();
275         LinkedList<ValidationWarning> warnings = new LinkedList<ValidationWarning>();
276         try {
277             validator.isValid(targetEntity, errors, warnings);
278         }
279         catch(UnsupportedOperationException unOpEx) {
280             createMarker(resource, 
281                     "Unsupported validator operation : " 
282                     + normalizeSpaces(unOpEx.getMessage()), 
283                     IMarker.SEVERITY_INFO);
284         }
285         for(ValidationError error : errors) {
286             createMarker(resource, normalizeSpaces(error.toString()), IMarker.SEVERITY_WARNING);
287         }
288         for(ValidationWarning warning : warnings) {
289             createMarker(resource, normalizeSpaces(warning.toString()), IMarker.SEVERITY_INFO);
290         }
291         return errors.size() > 0;
292     }
293     
294     private String normalizeSpaces(String input) {
295         StringBuffer result = new StringBuffer(input.length());
296         char ch = 'a';
297         for (int i = 0; i < input.length(); i++) {
298             if (Character.isWhitespace(input.charAt(i))) {
299                 if (ch != ' ') {
300                     ch = ' ';
301                     result.append(ch);
302                 }
303                 continue;
304             }
305             result.append(ch = input.charAt(i));
306         }
307         return result.toString();
308     }
309     
310     private void clearMarkersForResource(IResource resource) {
311         try {
312             resource.deleteMarkers("org.wsmostudio.runtime.wsmlmarker", 
313                                true, 
314                                IResource.DEPTH_INFINITE);
315         }
316         catch(CoreException coreEx) {
317             LogManager.logError(coreEx);
318         }
319     }
320     private void clearParserErrorMarkers(IResource resource) {
321         boolean hasChange = false;
322         try {
323             IMarker[] markers = resource.findMarkers(
324                     "org.wsmostudio.runtime.wsmlmarker", 
325                     true, 
326                     IResource.DEPTH_ONE);
327             if (markers == null 
328                     || markers.length == 0) {
329                 return;
330             }
331             for(int i = 0; i < markers.length; i++) {
332                 if (markers[i].getAttribute(IMarker.SEVERITY).equals(IMarker.SEVERITY_ERROR)
333                         && ((String)markers[i].getAttribute(IMarker.MESSAGE)).startsWith("Parser error : "))
334                     markers[i].delete();
335                 hasChange = true;
336             }
337         }
338         catch(CoreException coreEx) {
339             LogManager.logError(coreEx);
340         }
341         if (hasChange) {
342             refreshResourceNavigator();
343         }
344 
345     }
346     
347     private IMarker createMarker(IFile resource, String message, int severity) {
348         try {
349             IMarker marker = resource.createMarker("org.wsmostudio.runtime.wsmlmarker");
350             marker.setAttribute(IMarker.MESSAGE, message);
351             marker.setAttribute(IMarker.SEVERITY, severity);
352             marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_NORMAL);
353             return marker;
354         }
355         catch(CoreException coreEx) {
356             LogManager.logError(coreEx);
357             return null;
358         }
359     }
360     
361     private boolean useValidator() {
362         return false == RuntimePlugin.getDefault().getPreferenceStore().getBoolean(
363                 DISABLE_VALIDATOR_PROPERTY);
364     }
365     
366     @SuppressWarnings("unchecked")
367     public Ontology locateEntityContainer(Identifier item, Class type, List<Ontology> ontos, boolean searchInImportedOntos) {
368         return locateEntityContainer(item, type, ontos, searchInImportedOntos, new HashSet<Ontology>());
369     }
370 
371     @SuppressWarnings("unchecked")
372     private Ontology locateEntityContainer(Identifier item, 
373                                           Class type, 
374                                           List<Ontology> ontologies,
375                                           boolean searchInImportedOntos,
376                                           Set<Ontology> processedOntos) {
377         List<Ontology> ontos = new LinkedList<Ontology>(ontologies);
378         Ontology onto;
379         while(ontos.size() > 0) {
380             onto = ontos.remove(0);
381             if (processedOntos.contains(onto)) {
382                 continue;
383             }
384             processedOntos.add(onto);
385             if (onto.findEntity(item).size() == 0) { // if a proxy, try to resolve?
386                 onto = doLoadOntology(onto.getIdentifier(), true);
387                 if (onto == null) {
388                     continue; 
389                 }
390             }
391             if (true == containsEntity(onto, item, type)) {
392                 return onto;
393             }
394             if (searchInImportedOntos) {
395                 ontos.addAll(onto.listOntologies());
396             }
397         }
398         return null;
399     }
400 
401     @SuppressWarnings("unchecked")
402     private boolean containsEntity(Ontology onto, Identifier id, Class type) {
403         try {
404             if (type.equals(Concept.class)) {
405                 return onto.findConcept(id) != null;
406             }
407             if (type.equals(Relation.class)) {
408                 return onto.findRelation(id) != null;
409             }
410             if (type.equals(Instance.class)) {
411                 return onto.findInstance(id) != null;
412             }
413             if (type.equals(RelationInstance.class)) {
414                 return onto.findRelationInstance(id) != null;
415             }
416             if (type.equals(Axiom.class)) {
417                 return onto.findAxiom(id) != null;
418             }
419         }
420         catch(SynchronisationException synchEx) {
421             return false;
422         }
423         return false;
424     }
425     
426     public static void refreshResourceNavigator() {
427         final IWorkbenchWindow window = 
428             PlatformUI.getWorkbench().getActiveWorkbenchWindow();
429         if (window == null) {
430             return;
431         }
432         PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
433             public void run() {
434                 for (IWorkbenchPage page : window.getPages()){
435                     IViewReference[] views = page.getViewReferences();
436                     if (views == null) {
437                         return;
438                     }
439                     for (IViewReference ivref : views){
440                         IViewPart v = ivref.getView(true);
441                         if (v != null && v instanceof ResourceNavigator){
442                             ((ResourceNavigator) v).getTreeViewer().refresh();
443                         }
444                     }
445                 }
446             }
447         });
448     }
449 
450     
451 }
452 
453 /*
454  * $Log$
455  * Revision 1.19  2007/04/17 14:34:09  alex_simov
456  * migration to the latest wsmo4j (java 5)
457  *
458  * Revision 1.18  2007/04/02 12:36:14  alex_simov
459  * bugfix: obsolete parse error markers were not cleared after a resource is
460  * fixed (called from the WSMO Text editor)
461  *
462  * Revision 1.17  2007/02/15 17:37:02  alex_simov
463  * no message
464  *
465  * Revision 1.16  2006/11/02 17:16:11  alex_simov
466  * new lines in error/warning messages removed from the Problems view
467  *
468  * Revision 1.15  2006/07/11 16:10:06  alex_simov
469  * no message
470  *
471  * Revision 1.14  2006/03/08 11:31:47  alex_simov
472  * null check not performed
473  *
474  * Revision 1.13  2006/03/06 09:19:07  alex_simov
475  * load-on-demand methods for mediators added
476  *
477  * Revision 1.12  2006/02/22 10:27:25  alex_simov
478  * bugfix: ResourceNavigator refresh is forced on error markers change
479  * bugfix [1426318]: wsml validator usage changed
480  *
481  * Revision 1.11  2006/02/03 10:29:04  alex_simov
482  * entity locator methods added
483  *
484  * Revision 1.10  2006/01/31 10:44:02  alex_simov
485  * simple entity locator method added
486  *
487  * Revision 1.9  2006/01/23 16:20:16  alex_simov
488  * bugfix: external for the workspace resources not updated correctly
489  *
490  * Revision 1.8  2006/01/19 10:08:57  alex_simov
491  * on resource save, the workspace was not refreshed
492  *
493  * Revision 1.7  2006/01/10 15:02:23  alex_simov
494  * bigfix: on save in case of failure the old file content was removed
495  *
496  * Revision 1.6  2006/01/09 12:51:13  alex_simov
497  * Copyright message in header updated
498  *
499  * Revision 1.5  2005/12/21 09:52:17  alex_simov
500  * Choreography aware parser set as wsmo implementation extension
501  *
502  * Revision 1.4  2005/12/20 16:34:01  alex_simov
503  * update
504  *
505  * Revision 1.3  2005/12/07 15:36:40  alex_simov
506  * wsml validator enabled to mark invalid resources
507  *
508  * Revision 1.2  2005/11/30 14:58:55  alex_simov
509  * no message
510  *
511  * Revision 1.1  2005/11/25 14:33:50  alex_simov
512  * runtime code refactoring
513  *
514  */