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  package org.wsmostudio.runtime.cache;
25  
26  import java.util.*;
27  import java.util.regex.*;
28  import java.io.BufferedReader;
29  import java.io.File;
30  import java.io.FileReader;
31  
32  import org.eclipse.core.resources.*;
33  import org.eclipse.core.runtime.*;
34  import org.wsmo.common.*;
35  import org.wsmo.factory.WsmoFactory;
36  import org.wsmo.mediator.Mediator;
37  import org.wsmostudio.runtime.LogManager;
38  
39  /***
40   * A WSMO entities registry which keeps track of all known TopEntities in the workspace.
41   * The registry dynamically updates its content when a resource in the workspace is
42   * changed.
43   * The class contains a light weight WSML parser which processes files' headers to determine
44   * the types and the identifiers of the contained objects.
45   *
46   * @author not attributable
47   * @version $Revision: 1503 $ $Date: 2008-04-08 15:08:05 +0300 $
48   */
49  
50  public class WSMOCache {
51  
52      private WsmoFactory factory;
53  
54      private ArrayList<Map<IRI, String>> iri2file = new ArrayList<Map<IRI, String>>();
55  
56      private final String topEntities = "ontology|goal|webService|ooMediator|ggMediator|"
57          + "wgMediator|wwMediator|interface|capability";
58  //  private final String regexp = "^//s*(" + topEntities + ")//s+((_//\"(.+?)//\")|(//w+?)$)";
59      private final String regexp = "^//s*(" + topEntities + ")//s+((_//\"(.+?)//\")|(//S+?)//s*.*$)";
60      private Pattern pattern = Pattern.compile(regexp);
61  
62      private String nsRegExpr = "//s*namespace//s+((//{//s*(.+?)//})|(_//\"(.+?)//\"))";
63      private Pattern nsPattern = Pattern.compile(nsRegExpr);
64  
65      public WSMOCache(WsmoFactory factory) {
66          this.factory = factory;
67      }
68  
69      public Collection<Entity> getOntologies() {
70          return getWsmoObjects(WSMOTopEntity.ONTOLOGY);
71      }
72  
73      public Collection<Entity> getWebServices() {
74          return getWsmoObjects(WSMOTopEntity.WEB_SERVICE);
75      }
76  
77      public Collection<Entity> getGoals() {
78          return getWsmoObjects(WSMOTopEntity.GOAL);
79      }
80  
81      public Collection<Entity> getOOMediators() {
82          return getWsmoObjects(WSMOTopEntity.OO_MEDIATOR);
83      }
84  
85      public Collection<Entity> getWWMediators() {
86          return getWsmoObjects(WSMOTopEntity.WW_MEDIATOR);
87      }
88  
89      public Collection<Entity> getWGMediators() {
90          return getWsmoObjects(WSMOTopEntity.WG_MEDIATOR);
91      }
92  
93      public Collection<Entity> getGGMediators() {
94          return getWsmoObjects(WSMOTopEntity.GG_MEDIATOR);
95      }
96  
97      public Collection<Entity> getCapabilities() {
98          return getWsmoObjects(WSMOTopEntity.CAPABILITY);
99      }
100 
101     public Collection<Entity> getInterfaces() {
102         return getWsmoObjects(WSMOTopEntity.INTERFACE);
103     }
104 
105     public void reinit() {
106         iri2file.clear();
107         for (int i = 0; i < WSMOTopEntity.TYPE_COUNT; i++) {
108             iri2file.add(new HashMap<IRI, String>());
109         }
110 
111         IProject[] projectList = ResourcesPlugin.getWorkspace().getRoot().getProjects();
112         for (int i = 0; i < projectList.length; i++) {
113             scanPath(projectList[i]);//.getLocation().toFile());
114         }
115     }
116 
117     private void scanPath(IContainer directory) {
118         IResource[] entries = null;
119         try {
120             entries = directory.members();//listFiles();
121         }
122         catch(CoreException coreEx) {
123             return;
124         }
125         if (entries == null) {
126             return;
127         }
128         for (int i = 0; i < entries.length; i++) {
129             if (entries[i] instanceof IFile
130                     && "wsml".equalsIgnoreCase(((IFile)entries[i]).getFileExtension())) {
131                 cacheWsmoHeader((IFile)entries[i], true);
132             }
133             else if (entries[i] instanceof IContainer) {
134                 scanPath((IContainer)entries[i]);
135             }
136         }
137     }
138 
139     public IRI cacheWsmoHeader(IFile iFile, boolean registerIRI) {
140         BufferedReader br = null;
141         File file = iFile.getLocation().toFile();
142         IRI mainIRI = null; // the main (first) IRI found in the document
143         IRI iri = null;
144         try
145         {
146             br = new BufferedReader(new FileReader(file));
147             String line = null;
148             StringBuffer readData = new StringBuffer(); // necessary for namespaces detection
149             while ((line = br.readLine()) != null) {
150                 readData.append(line).append(' ');
151                 Matcher match = pattern.matcher(line);
152                 if (match.find()) {
153                     Map<String, String> nsDefs = readNamespaces(readData.toString());
154                     byte wsmoType = WSMOTopEntity.parse(match.group(1));
155                     String iriStr = match.group(2);
156                     if (iriStr.indexOf(' ') != -1) {
157                         iriStr = iriStr.substring(0, iriStr.indexOf(' '));
158                     }
159                     if (iriStr.indexOf('\t') != -1) {
160                         iriStr = iriStr.substring(0, iriStr.indexOf('\t'));
161                     }
162 
163                     if (iriStr.startsWith("_\"") 
164                             && iriStr.endsWith("\"")) {
165                         iriStr = iriStr.substring(2, iriStr.length()-1);
166                     }
167                     else {
168                         int colIndex = iriStr.indexOf('#');
169                         if (colIndex == -1) {
170                             if (nsDefs.containsKey("")) {
171                                 String defNS = nsDefs.get("");
172                                 if (false == defNS.endsWith("#") 
173                                         && false == defNS.endsWith("/")) {
174                                     defNS += '#'; 
175                                 }
176                                 iriStr = defNS + iriStr;
177                             }
178                         }
179                         else {
180                             String nsDef = nsDefs.get(iriStr.substring(0, colIndex));
181                             if (nsDef != null) {
182                                 if (false == nsDef.endsWith("#") 
183                                         && false == nsDef.endsWith("/")) {
184                                     nsDef += '#'; 
185                                 }
186                             }
187                             iriStr = nsDef + iriStr.substring(colIndex + 1);
188                         }
189                     }
190 
191                     iri = factory.createIRI(iriStr);
192                     if (registerIRI) {
193                         registerIRI(iri, wsmoType, file.getAbsolutePath(), iFile);
194                     }
195                     if (mainIRI == null) {
196                         mainIRI = iri;
197                     }
198 
199                     if (wsmoType != WSMOTopEntity.WEB_SERVICE 
200                             && wsmoType != WSMOTopEntity.GOAL
201                             && wsmoType != WSMOTopEntity.CAPABILITY
202                             && wsmoType != WSMOTopEntity.INTERFACE) {
203                         break;
204                     }
205                 }
206             }
207             br.close();
208         }
209         catch (Exception e) {
210 //          LogManager.logError("Unable to scan: " + file.getName() + " " + e.toString());
211         }
212         finally {
213             if (br != null) {
214                 try {
215                     br.close();
216                 }
217                 catch(Exception e) {
218                     LogManager.logError(e);
219                 }
220             }
221         }
222         return mainIRI;
223     }
224 
225     private Map<String, String> readNamespaces(String input) {
226 
227         Matcher nsMatch = nsPattern.matcher(input);
228         Map<String, String> result = new HashMap<String, String>();
229         if (nsMatch.find()) {
230             String resultNS = nsMatch.group(1);
231             if (resultNS.startsWith("{") 
232                     && resultNS.endsWith("}")) {
233                 resultNS = resultNS.substring(1, resultNS.length()-1);
234             }
235             StringTokenizer tokenizer = new StringTokenizer(resultNS, " \t\n\r,");
236             String defaultNS = null;
237             while (tokenizer.hasMoreElements()) {
238                 String toke = tokenizer.nextToken();
239 
240                 if (toke.startsWith(",")) {
241                     toke = toke.substring(1);
242                 }
243                 if (toke.endsWith(",")) {
244                     toke = toke.substring(0, toke.length() - 1);
245                 }
246 
247                 if (toke.startsWith("_\"") 
248                         && toke.endsWith("\"") 
249                         && defaultNS == null) {
250                     defaultNS = toke.substring(2, toke.length()-1);
251                     continue;
252                 }
253                 if (isValidName(toke) 
254                         && tokenizer.hasMoreElements()) {
255                     String nextToke = tokenizer.nextToken();
256                     if (nextToke.startsWith("_\"") 
257                             && nextToke.endsWith("\"")) {
258                         result.put(toke, nextToke.substring(2, nextToke.length()-1));
259                     }
260                 }
261             }
262             if (defaultNS != null) {
263                 result.put("", defaultNS);
264             }
265         }
266         return result;
267     }
268 
269     private boolean isValidName(String toke) {
270         if (toke.length() == 0) {
271             return false;
272         }
273         if (false == Character.isLetter(toke.charAt(0)) 
274                 && toke.charAt(0) != '_') {
275             return false;
276         }
277         for(int i = 1; i < toke.length(); i++) {
278             char ch = toke.charAt(i);
279             if (Character.isLetterOrDigit(ch) == false
280                     && ch != '.' && ch != '-' && ch != '_'
281                         && (ch == '//' && i == toke.length()-1)) {
282                 return false;
283             }
284             if (ch == '//') {
285                 i++;
286             }
287         }
288         return true;
289     }
290 
291     public IRI[] getIRIList(byte wsmoType) {
292         if (wsmoType >= 0 && wsmoType < iri2file.size()) {
293             Map<IRI, String> resultSet = iri2file.get(wsmoType);
294             return (IRI[]) resultSet.keySet().toArray(new IRI[resultSet.size()]);
295         }
296         throw new IllegalArgumentException("Unknown wsmo type");
297     }
298 
299     /***
300      * Determines the type of an entity refered by IRI.
301      * @param id
302      * @return The type of the entity identified by the IRI or -1 if no such entity is found. 
303      */
304     public byte getTypeByIRI(IRI id) {
305         for (byte i = 0; i < WSMOTopEntity.TYPE_COUNT; i++) {
306             if (iri2file.get(i) != null
307                     && iri2file.get(i).keySet().contains(id)) {
308                 return i;// a tricky way - requires ordered constants values
309             }
310         }
311         return -1;
312     }
313 
314     public Mediator findMediator(IRI mediID, byte defaultType) {
315         byte type = getTypeByIRI(mediID);
316         if (type == -1
317                 || type == WSMOTopEntity.ONTOLOGY
318                 || type == WSMOTopEntity.GOAL
319                 || type == WSMOTopEntity.WEB_SERVICE) {
320             type = defaultType;
321         }
322 
323         switch (type) {
324         case WSMOTopEntity.OO_MEDIATOR:
325             return this.factory.getOOMediator(mediID);
326         case WSMOTopEntity.GG_MEDIATOR:
327             return this.factory.getGGMediator(mediID);
328         case WSMOTopEntity.WG_MEDIATOR:
329             return this.factory.getWGMediator(mediID);
330         case WSMOTopEntity.WW_MEDIATOR:
331             return this.factory.getWWMediator(mediID);
332         default:
333             return null;
334         }
335     }
336 
337     public TopEntity findTopEntity(IRI iri) {
338 
339         byte type = getTypeByIRI(iri);
340         if (type == -1) {
341             return null;
342         }
343 
344         switch (type) {
345         case WSMOTopEntity.ONTOLOGY:
346             return this.factory.getOntology(iri);
347         case WSMOTopEntity.GOAL:
348             return this.factory.getGoal(iri);
349         case WSMOTopEntity.WEB_SERVICE:
350             return this.factory.getWebService(iri);
351         case WSMOTopEntity.OO_MEDIATOR:
352             return this.factory.getOOMediator(iri);
353         case WSMOTopEntity.GG_MEDIATOR:
354             return this.factory.getGGMediator(iri);
355         case WSMOTopEntity.WG_MEDIATOR:
356             return this.factory.getWGMediator(iri);
357         case WSMOTopEntity.WW_MEDIATOR:
358             return this.factory.getWWMediator(iri);
359         default:
360             return null;
361         }
362     }
363 
364     private void registerIRI(IRI iri, byte wsmoType, String fileLocation, IFile resource) {
365 
366         // check for metamodeling conflicts:
367             for (byte i = 0; i < WSMOTopEntity.TYPE_COUNT; i++) {
368                 if (i == wsmoType) {
369                     continue;
370                 }
371                 /*            if (getFileLocationForId(iri, i) != null) {
372                 createConflictMarker(resource, i, iri);
373                 String rootPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toString();
374                 String sPath = getFileLocationForId(iri, i).substring(rootPath.length());
375 
376                 IFile otherFile = 
377                     ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(sPath));
378 
379                 if (otherFile.exists()) {
380                     createConflictMarker(otherFile, wsmoType, iri);
381                 }
382                 return;
383             }*/
384             }
385 //          clearConflictMarker(resource);
386             iri2file.get(wsmoType).put(iri, fileLocation);
387     }
388 
389     public String getFileLocationForId(IRI iri, int wsmoType) {
390         return iri2file.get(wsmoType).get(iri);//.toString());
391     }
392 
393     private Collection<Entity> getWsmoObjects(byte type) {
394         IRI[] refs = getIRIList(type);
395         Collection<Entity> result = new LinkedHashSet<Entity>();
396         Entity entity = null;
397         for (int i = 0; i < refs.length; i++) {
398             try {
399                 switch (type) {
400                 case WSMOTopEntity.ONTOLOGY:
401                     entity = factory.getOntology(refs[i]);
402                     break;
403                 case WSMOTopEntity.GOAL:
404                     entity = factory.getGoal(refs[i]);
405                     break;
406                 case WSMOTopEntity.WEB_SERVICE:
407                     entity = factory.getWebService(refs[i]);
408                     break;
409                 case WSMOTopEntity.OO_MEDIATOR:
410                     entity = factory.getOOMediator(refs[i]);
411                     break;
412                 case WSMOTopEntity.GG_MEDIATOR:
413                     entity = factory.getGGMediator(refs[i]);
414                     break;
415                 case WSMOTopEntity.WG_MEDIATOR:
416                     entity = factory.getWGMediator(refs[i]);
417                     break;
418                 case WSMOTopEntity.WW_MEDIATOR:
419                     entity = factory.getWWMediator(refs[i]);
420                     break;
421                 case WSMOTopEntity.CAPABILITY:
422                     entity = factory.getCapability(refs[i]);
423                     break;
424                 case WSMOTopEntity.INTERFACE:
425                     entity = factory.getInterface(refs[i]);
426                     break;
427                 default:
428                     continue; // no addition to the result
429                 }
430                 result.add(entity);
431             }
432             catch(Throwable synchEx) {
433                 LogManager.logError(synchEx.getMessage());
434             }
435         }
436         return result;
437     }
438 
439     /*    private void createConflictMarker(final IFile resource, final byte type, final IRI iri) {
440         try {
441             IMarker marker = resource.createMarker("org.wsmostudio.runtime.wsmlmarker");
442             marker.setAttribute(IMarker.MESSAGE, 
443                     "Metamodeling conflict: a TopEntity with identifier '"
444                     + iri.toString()
445                     + "' is registered as a " + WSMOTopEntity.getTypeAsString(type));
446             marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
447             marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
448         }
449         catch(CoreException coreEx) {
450             LogManager.logError(coreEx);
451         }
452     }
453 
454     private void clearConflictMarker(IFile resource) {
455         try {
456             IMarker[] allMarkers = resource.findMarkers("org.wsmostudio.runtime.wsmlmarker", false, 0);
457             if (allMarkers == null) {
458                 return;
459             }
460             for(int i = 0; i < allMarkers.length; i++) {
461                 if (allMarkers[i].getAttribute(IMarker.MESSAGE).toString().startsWith("Metamodeling conflict:")) {
462                     allMarkers[i].delete();
463                 }
464             }
465         }
466         catch(CoreException coreEx) {
467             LogManager.logError(coreEx);
468         }
469     }*/
470 
471 
472 }
473 
474 /*
475  * $Log$
476  * Revision 1.16  2007/04/17 14:34:09  alex_simov
477  * migration to the latest wsmo4j (java 5)
478  *
479  * Revision 1.15  2007/02/15 17:37:02  alex_simov
480  * no message
481  *
482  * Revision 1.14  2006/05/15 11:53:01  alex_simov
483  * lightweight parse method given extra visibility
484  *
485  * Revision 1.13  2006/04/06 12:50:03  alex_simov
486  * runtime cache detects metamodeling conflicts in the workspace
487  * (ignoring the problematic ones)
488  *
489  * Revision 1.12  2006/01/31 10:44:56  alex_simov
490  * redundant memory allocation removed
491  *
492  * Revision 1.11  2006/01/09 12:51:12  alex_simov
493  * Copyright message in header updated
494  *
495  * Revision 1.10  2005/12/09 11:20:33  alex_simov
496  * workspace cache scanner is now aware of default namespaces
497  *
498  * Revision 1.9  2005/11/25 14:22:48  alex_simov
499  * runtime code refactoring
500  *
501  * Revision 1.8  2005/11/09 16:10:40  alex_simov
502  * IRI parse fix
503  *
504  * Revision 1.7  2005/11/04 09:37:07  vassil_momtchev
505  * regular expression updated to recognize also sQname's
506  *
507  * Revision 1.6  2005/09/10 09:15:52  alex_simov
508  * Migrating to Java 1.5
509  *
510  * Revision 1.5  2005/08/02 10:33:20  alex_simov
511  * minor code and/or javadoc fixes
512  *
513  * Revision 1.4  2005/07/21 14:44:40  alex_simov
514  * added javadoc: class description, footer
515  *
516  */