View Javadoc

1   /*
2    WSMO Studio - a Semantic Web Service Editor
3    Copyright (c) 2004-2006, OntoText Lab. / SIRMA
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  package org.wsmostudio.choreography.helper;
18  
19  import java.io.*;
20  import java.util.*;
21  
22  import org.deri.wsmo4j.io.parser.WrappedParsingException;
23  import org.deri.wsmo4j.io.parser.wsml.*;
24  import org.deri.wsmo4j.orchestration.OrchestrationFactoryRI;
25  import org.wsmo.common.Namespace;
26  import org.wsmo.common.TopEntity;
27  import org.wsmo.common.exception.InvalidModelException;
28  import org.wsmo.factory.*;
29  import org.wsmo.service.Interface;
30  import org.wsmo.service.WebService;
31  import org.wsmo.service.choreography.Choreography;
32  import org.wsmo.service.choreography.rule.ChoreographyIfThen;
33  import org.wsmo.service.choreography.rule.ChoreographyRules;
34  import org.wsmo.service.rule.CompoundFact;
35  import org.wsmo.service.rule.Update;
36  import org.wsmo.service.signature.StateSignature;
37  import org.wsmo.wsml.ParserException;
38  import org.wsmo.wsml.compiler.lexer.Lexer;
39  import org.wsmo.wsml.compiler.node.Start;
40  import org.wsmo.wsml.compiler.node.Token;
41  import org.wsmostudio.choreography.ChoreographyPlugin;
42  import org.wsmostudio.runtime.WSMORuntime;
43  
44  import com.ontotext.wsmo4j.parser.wsml.*;
45  
46  /***
47   * Helper class to render objects to wsml fragments and the opposite
48  * <p>Title: WSMO Studio</p>
49  * <p>Description: Semantic Web Service Editor</p>
50  * <p>Copyright:  Copyright (c) 2004-2006</p>
51  * <p>Company: OntoText Lab. / SIRMA </p>
52   */
53  public class Render {
54      
55      /***
56       * Serialize a CompoundFact(s) to a wsml string.
57       * @param nsHolder namespace holder
58       * @param facts facts[0] is new CompoundFact; facts[1] is old CompoundFact (optional) 
59       * @return wsml string
60       */
61      public static String compoundFactToWSMLString(TopEntity nsHolder, List<CompoundFact> facts) {
62          if (facts == null || facts.size() < 1 || facts.size() > 2) {
63              throw new IllegalArgumentException("Invalid facts object!");
64          }
65          if (nsHolder == null) {
66              throw new IllegalArgumentException("nsHolder argument must not be null!");
67          }
68          
69          // create dummy TopEntity
70          WsmoFactory factory = WSMORuntime.getRuntime().getWsmoFactory();
71          ChoreographyFactory cFactory = ChoreographyPlugin.getFactory();
72          String serviceNS = "none";
73          int i = 0;
74          while (nsHolder.findNamespace(serviceNS) != null) {
75              serviceNS = "none" + (i++);
76          }
77          Namespace ns = factory.createNamespace(serviceNS, 
78                  factory.createIRI("http://not_existing9876543210987654321"));
79          WebService ws = factory.createWebService(factory.createIRI(ns, "w321"));
80          Interface iface = factory.createInterface(factory.createIRI(ns, "i321"));
81          ChoreographyRules rules = cFactory.containers.createRules(factory.createAnonymousID());
82          
83          if (nsHolder.getDefaultNamespace() != null) {
84              ws.setDefaultNamespace(nsHolder.getDefaultNamespace());
85          }
86          for(Namespace nsEntry : nsHolder.listNamespaces()) {
87              ws.addNamespace(nsEntry);
88          }
89          
90          
91          try {
92              rules.addRule(cFactory.updateRules.createUpdate(facts.get(0), 
93                      facts.size() == 1 ? null : facts.get(1)));
94          }
95          catch (InvalidModelException e) {
96              throw new RuntimeException("Could not serialize fact!", e);
97          }
98          
99          StateSignature sig = cFactory.containers.createStateSignature(factory.createAnonymousID());
100         Choreography chor = cFactory.containers.createChoreography(factory.createAnonymousID(),
101                 sig, rules);
102         iface.setChoreography(chor);
103         ws.addInterface(iface);
104         
105         // serialize
106         StringBuffer buffer = new StringBuffer();
107         WSMORuntime.getRuntime().getWsmlSerializer().serialize(new TopEntity[] {ws}, buffer);
108         
109         // scan output 
110         String output = buffer.substring(buffer.indexOf("update", buffer.indexOf("webService"))+6).trim();
111         return output.substring(1, output.length() - 1); // remove ()
112     }
113 
114     /***
115      * Parse a WSML compound fact string to CompoundFact object.
116      * @param nsHolder namespace information
117      * @param factText wsml for the compound fact
118      * @return Array of CompoundFacts the new (1), old if exists (2)
119      * @throws ParserException
120      */
121     public static List<CompoundFact> wsmlStringToCompoundFact(TopEntity nsHolder, String factText)
122             throws ParserException {
123         // write the namespace information
124         StringBuffer buffer = new StringBuffer();
125         writeNamespace(buffer, nsHolder);
126         
127         // write the rule information + the CompoundFact text
128         buffer.append("webService _\"http://not_existing9876543210987654321#w321\"\r\n");
129         buffer.append("interface _\"http://not_existing9876543210987654321#i321\"\r\n");
130         buffer.append("choreography _\"http://not_existing9876543210987654321#c321\"\r\n");
131         buffer.append("stateSignature _\"http://not_existing9876543210987654321#st321\"\r\n");
132         buffer.append("transitionRules _\"http://not_existing9876543210987654321#t321\"\r\n");
133         buffer.append("if true then ");
134         buffer.append("update (\r\n");
135         buffer.append(factText);
136         buffer.append("\r\n) endIf\r\n");
137         
138         // initialize the parser container with the required analyzer
139         ASTAnalysisContainer container = new ASTAnalysisContainer();
140         WsmoFactory factory = WSMORuntime.getRuntime().getWsmoFactory();
141         DataFactory dFactory = WSMORuntime.getRuntime().getDataFactory();
142         LogicalExpressionFactory lFactory = WSMORuntime.getRuntime().getLogExprFactory();
143         ChoreographyFactory cFactory = ChoreographyPlugin.getFactory();    
144         new IdentifierAnalysis(container, factory);
145         new ValueAnalysis(container, dFactory, lFactory, factory);
146         new VariableAnalysis(container, lFactory);
147         new AtomicExpressionAnalysis(container, factory, lFactory);
148         new CompoundExpressionAnalysis(container, lFactory);
149         new RuleAnalyzer(container, factory, new OrchestrationFactoryRI(), cFactory, lFactory);
150 
151         // parse the input
152         parseWSML(container, buffer);
153 
154         // extract the rules
155         ChoreographyRules rules = (ChoreographyRules) container.getStack(ChoreographyRules.class).peek();
156         if (rules.listRules().size() != 1) {
157             throw new RuntimeException("Could not extract rules!");
158         }
159         Update rule = (Update) ((ChoreographyIfThen) rules.listRules().iterator().next()).listNestedRules()
160                 .iterator().next();
161         List<CompoundFact> facts = new LinkedList<CompoundFact>();
162         if (rule.getNewFact() != null) {
163             facts.add(rule.getNewFact());
164         }
165         if (rule.getOldFact() != null) {
166             facts.add(rule.getOldFact());
167         }
168         return facts;
169     }
170 
171     /***
172      * Writes the namespace information as WSML in a buffer.
173      * @param buffer to be used
174      * @param nsHolder namespace holder
175      */
176     private static void writeNamespace(StringBuffer buffer, TopEntity nsHolder) {
177         if (nsHolder.getDefaultNamespace() != null || nsHolder.listNamespaces().size() > 0) {
178             buffer.append("namespace {");
179         }
180         Iterator it = nsHolder.listNamespaces().iterator();
181         if (nsHolder.getDefaultNamespace() != null) {
182             buffer.append("_\"").append(nsHolder.getDefaultNamespace().getIRI().toString()).append(
183                     "\"");
184             if (it.hasNext()) {
185                 buffer.append(", ");
186             }
187         }
188         while (it.hasNext()) {
189             Namespace ns = (Namespace) it.next();
190             buffer.append(ns.getPrefix());
191             buffer.append(" ");
192             buffer.append("_\"" + ns.getIRI().toString() + "\"");
193             if (it.hasNext()) {
194                 buffer.append(", ");
195             }
196         }
197         buffer.append("}\r\n");
198     }
199 
200     /***
201      * Parse a WSML and traverse it using a specified container.
202      * @param container to hold the result objects
203      * @param wsml input
204      * @throws ParserException
205      */
206     private static void parseWSML(ASTAnalysisContainer container, StringBuffer wsml)
207             throws ParserException {
208         Lexer lexer = new Lexer(new PushbackReader(new StringReader(wsml.toString()), 16384));
209         org.wsmo.wsml.compiler.parser.Parser parser = new org.wsmo.wsml.compiler.parser.Parser(
210                 lexer);
211 
212         try {
213             Start head = parser.parse();
214             head.apply(container);
215         }
216         catch (org.wsmo.wsml.compiler.parser.ParserException pe) {
217             ParserException e = new ParserException(ParserException.NOT_VALID_PARSETREE, pe);
218             Token t = pe.getToken();
219             e.setErrorLine(t.getLine() - 7);
220             e.setErrorPos(t.getPos());
221             e.setFoundToken(t.getText());
222             try {
223                 e.setExpectedToken(pe.getMessage().split("expecting: ")[1].trim());
224             }
225             catch (IndexOutOfBoundsException iobE) {
226                 // if error message does not follow usual pattern
227                 e.setExpectedToken(pe.getMessage());
228             }
229             throw e;
230         }
231         catch (org.wsmo.wsml.compiler.lexer.LexerException le) {
232             ParserException e = new ParserException(ParserException.NOT_VALID_PARSETREE, le);
233             try {
234                 e.setErrorLine(Integer.parseInt(le.getMessage().split(",")[0].split("//[")[1]));
235             }
236             catch (NumberFormatException nfE) {
237                 // could not find line so leave default
238             }
239             try {
240                 e.setErrorPos(Integer.parseInt(le.getMessage().split(",")[1].split("//]")[0]));
241             }
242             catch (NumberFormatException nfE) {
243                 // could not find pos so leave default
244             }
245             throw e;
246         }
247         catch (WrappedParsingException wpe) {
248             if (wpe.getWrappedException() instanceof ParserException) {
249                 throw (ParserException) wpe.getWrappedException();
250             }
251             else
252                 throw new RuntimeException(wpe);
253         }
254         catch (IOException e) {
255             // should never happens
256             throw new RuntimeException(e);
257         }
258     }
259 }
260 
261 /*
262  * $Log$
263  * Revision 1.5  2007/04/17 14:27:07  alex_simov
264  * migration to the latest wsmo4j (java 5)
265  *
266  * Revision 1.4  2006/11/22 14:11:07  alex_simov
267  * Code refactoring: the plug-in is synchronized with the latest wsmo4j changes
268  *
269  * Revision 1.3  2006/06/22 13:21:06  vassil_momtchev
270  * method WsmoFactory.createVariable(String) moved to LogicalExpressionFactory.createVariable(String)
271  *
272  * Revision 1.2  2006/03/27 09:48:20  alex_simov
273  * CompoundFact <-> String conversion corrected
274  *
275  * Revision 1.1  2006/03/24 15:49:48  vassil_momtchev
276  * helper class added to render wsml fragments to choreography objects (and the opposite)
277  *
278 */