View Javadoc

1   /*
2    wsmo4j - a WSMO API and Reference Implementation
3   
4    Copyright (c) 2004-2005, OntoText Lab. / SIRMA
5                             University of Innsbruck, Austria
6   
7    This library is free software; you can redistribute it and/or modify it under
8    the terms of the GNU Lesser General Public License as published by the Free
9    Software Foundation; either version 2.1 of the License, or (at your option)
10   any later version.
11   This library is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14   details.
15   You should have received a copy of the GNU Lesser General Public License along
16   with this library; if not, write to the Free Software Foundation, Inc.,
17   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18   */
19  
20  /**
21   * <p>Title: WSMO4J</p>
22   * <p>Description: WSMO API and a Reference Implementation</p>
23   * <p>Copyright:  Copyright (c) 2004-2005</p>
24   * <p>Company: OntoText Lab. / SIRMA </p>
25   */
26  
27  package com.ontotext.wsmo4j.parser.wsml;
28  
29  import java.util.*;
30  
31  import org.deri.wsmo4j.common.*;
32  import org.deri.wsmo4j.io.parser.*;
33  import org.deri.wsmo4j.logicalexpression.*;
34  import org.omwg.logicalexpression.terms.*;
35  import org.omwg.ontology.*;
36  import org.wsmo.common.*;
37  import org.wsmo.common.exception.*;
38  import org.wsmo.factory.*;
39  import org.wsmo.wsml.*;
40  import org.wsmo.wsml.compiler.node.*;
41  
42  import com.ontotext.wsmo4j.parser.*;
43  
44  public class OntologyAnalysis extends ASTAnalysis {
45  
46      private byte paramCount=0;
47      
48      private WsmoFactory factory;
49  
50      private DataFactory dFactory;
51  
52      private ASTAnalysisContainer container;
53      
54      private boolean cleanOnParse=false;
55  
56      public OntologyAnalysis(ASTAnalysisContainer container, WsmoFactory factory,
57              DataFactory dFactory) {
58          if (factory == null || container == null) {
59              throw new IllegalArgumentException();
60          }
61          this.factory = factory;
62          this.dFactory = dFactory;
63          this.container = container;
64  
65          // register the handled nodes
66          container.registerNodeHandler(AOntology.class, this);
67          container.registerNodeHandler(AConcept.class, this);
68          container.registerNodeHandler(ASuperconcept.class, this);
69          container.registerNodeHandler(AAttribute.class, this);
70          container.registerNodeHandler(ARelation.class, this);
71          container.registerNodeHandler(ASuperrelation.class, this);
72          container.registerNodeHandler(AParamtype.class, this);
73          container.registerNodeHandler(AInstance.class, this);
74          container.registerNodeHandler(AMemberof.class, this);
75          container.registerNodeHandler(AAttributevalue.class, this);
76          container.registerNodeHandler(ARelationinstance.class, this);
77          container.registerNodeHandler(AAxiom.class, this);
78      }
79      
80      public void setCleanOnParse(boolean cleanOnParse){
81          this.cleanOnParse = cleanOnParse;
82      }
83  
84      // Ontology section
85  
86      public void inAOntology(AOntology node) {
87          TopEntityAnalysis.isValidTopEntityIdentifier(node.getId(),node.getTOntology());
88          node.getId().apply(container.getNodeHandler(PId.class));
89          IRI iri = (IRI) container.popFromStack(Identifier.class, IRI.class);
90          Ontology ontology = factory.createOntology(iri);
91          
92          //clean previous contents of this ontology:
93          if (cleanOnParse)
94          try {
95              ClearTopEntity.clearTopEntity(ontology);
96          }
97          catch (SynchronisationException e) {
98              // should never happen
99              throw new RuntimeException("Error During Cleaning TopEntity from previous defintions",e);
100         }
101         catch (InvalidModelException e) {
102             // should never happen
103             throw new RuntimeException("Error During Cleaning TopEntity from previous defintions",e);
104         }
105         
106         container.getStack(TopEntity.class).push(ontology);
107         container.getStack(Entity.class).push(ontology);
108         TopEntityAnalysis.addNamespaceAndVariant(ontology, container.getStack(Namespace.class),
109                 container.getStack(AWsmlvariant.class));
110     }
111 
112     public void outAOntology(AOntology node) {
113         container.popFromStack(Entity.class, Ontology.class);
114     }
115 
116     // end Ontology section
117 
118     // Concept section
119 
120     public void inAConcept(AConcept node) {
121         node.getId().apply(container.getNodeHandler(PId.class));
122         Identifier id = (Identifier) container.popFromStack(Identifier.class, Identifier.class);
123         Concept concept = factory.createConcept(id);
124         container.getStack(Entity.class).push(concept);
125         addToOntology(concept);
126     }
127 
128     public void outASuperconcept(ASuperconcept node) {
129         Identifier[] superConceptId = (Identifier[]) container.popFromStack(Identifier[].class,
130                 Identifier[].class);
131         Concept concept = (Concept) container.peekFromStack(Entity.class, Concept.class);
132         for (int i = 0; i < superConceptId.length; i++) {
133             try {
134                 concept.addSuperConcept(factory.getConcept(superConceptId[i]));
135             }
136             catch (InvalidModelException e) {
137                 throw new WrappedInvalidModelException(e);
138             }
139         }
140     }
141     
142     private IRI inverseAttrIRI;
143 
144     public void inAAttribute(AAttribute node) {
145         node.getId().apply(container.getNodeHandler(PId.class));
146         if (node.getId().getClass().equals(AAnonymousId.class)) {
147             Token t = ((AAnonymousId) node.getId()).getAnonymous();
148             ParserException pe = new ParserException("Anonymous Attributes not supported", null);
149             pe.setErrorLine(t.getLine());
150             pe.setErrorPos(t.getPos());
151             pe.setExpectedToken("IRI");
152             pe.setFoundToken(node.getId().toString());
153             throw new WrappedParsingException(pe);
154         }
155         IRI attrIri = (IRI) container.popFromStack(Identifier.class, IRI.class);
156         Concept concept = (Concept) container.peekFromStack(Entity.class, Concept.class);
157         Attribute attribute;
158         try {
159             attribute = concept.createAttribute(attrIri);
160         } catch (InvalidModelException e) {
161             // can never happen since anonIDs are not reused during parsing
162             throw new RuntimeException(e);
163         }
164 
165         if (node.getAttType() instanceof AOpenWorldAttType) {
166             attribute.setConstraining(true); // datatype attribute
167         }
168         else if (node.getAttType() instanceof AClosedWorldAttType) {
169             attribute.setConstraining(false); // concept or datatype attribute
170         }
171 
172         if (node.getCardinality() != null) {
173             ACardinality card = (ACardinality) node.getCardinality();
174             int minCard = Integer.parseInt(card.getPosInteger().getText().trim());
175             attribute.setMinCardinality(minCard);
176             if (null != card.getCardinalityNumber()) {
177                 String str = card.getCardinalityNumber().toString().trim();
178                 if (str.startsWith("*"))
179                     attribute.setMaxCardinality(Integer.MAX_VALUE);
180                 else
181                     attribute.setMaxCardinality(Integer.parseInt(str));
182             }
183             else { //if no max is given same then min
184                 attribute.setMaxCardinality(minCard);
185             }
186         }
187 
188         // Process the attribute features
189         Object features[] = node.getAttributefeature().toArray();
190         for (int j = 0; j < features.length; j++) {
191             if (features[j] instanceof ATransitiveAttributefeature) {
192                 ((Attribute) attribute).setTransitive(true);
193             }
194             else if (features[j] instanceof ASymmetricAttributefeature) {
195                 ((Attribute) attribute).setSymmetric(true);
196             }
197             else if (features[j] instanceof AReflexiveAttributefeature) {
198                 ((Attribute) attribute).setReflexive(true);
199             }
200             else if (features[j] instanceof AInverseAttributefeature) {
201                 AInverseAttributefeature tmp = (AInverseAttributefeature) features[j];
202                 tmp.getId().apply(container.getNodeHandler(PId.class));
203                 inverseAttrIRI = (IRI) container.popFromStack(Identifier.class, IRI.class);
204                 attribute.setInverseOf(inverseAttrIRI);
205             }
206         }
207 
208         container.getStack(Attribute.class).push(attribute);
209         container.getStack(Entity.class).push(attribute);
210     }
211 
212     public void outAAttribute(AAttribute node){
213         // Process the attribute range
214         Attribute attribute = (Attribute) container.getStack(Attribute.class).pop();
215         container.popFromStack(Entity.class, Attribute.class); // remove Entity stack
216         Identifier[] typeIds = (Identifier[]) container.getStack(Identifier[].class).pop();
217         ConstantTransformer cf = ConstantTransformer.getInstance();
218         for (int i = 0; i < typeIds.length; i++) {
219             try {
220                 if (cf.isDataType(typeIds[i].toString())) {
221                     attribute.addType(dFactory.createWsmlDataType(typeIds[i].toString()));
222                 }
223                 else {
224                     attribute.addType(factory.createConcept(typeIds[i]));
225                 }
226             }
227             catch (InvalidModelException e) {
228                 throw new WrappedInvalidModelException(e);
229             }
230         }
231     }
232 
233     public void outAConcept(AConcept node) {
234         container.popFromStack(Entity.class, Concept.class);
235     }
236 
237     // end Concept section
238 
239     // Instance section
240 
241     public void inAInstance(AInstance node) {
242         Identifier id = null;
243         if (node.getId() != null) {
244             node.getId().apply(container.getNodeHandler(PId.class));
245             id = (Identifier) container.popFromStack(Identifier.class, Identifier.class);
246         }
247         else {
248             id = factory.createAnonymousID();
249         }
250 
251         Instance instance = factory.createInstance(id);
252         container.getStack(Entity.class).push(instance);
253         addToOntology(instance);
254     }
255 
256     public void outAMemberof(AMemberof node) {
257         Instance instance = (Instance) container.peekFromStack(Entity.class, Instance.class);
258         Identifier[] conceptIds = (Identifier[]) container.popFromStack(Identifier[].class,
259                 Identifier[].class);
260         for (int i = 0; i < conceptIds.length; i++) {
261             try {
262                 instance.addConcept(factory.getConcept(conceptIds[i]));
263             }
264             catch (InvalidModelException e) {
265                 throw new WrappedInvalidModelException(e);
266             }
267         }
268     }
269 
270     public void outAAttributevalue(AAttributevalue node) {
271         if (!(node.parent() instanceof AInstance)) {
272             return; // do not handle attributevalue in NFP section see NFPAnalysis
273         }
274 
275         IRI id = (IRI) container.popFromStack(Identifier.class, Identifier.class);
276         Term[] terms = (Term[]) container.popFromStack(Term[].class, Term[].class);
277         Instance instance = (Instance) container.peekFromStack(Entity.class, Instance.class);
278 
279         for (int i = 0; i < terms.length; i++) {
280             try {
281                 if (terms[i] instanceof DataValue) // DataValue
282                     instance.addAttributeValue(id, (DataValue) terms[i]);
283                 else
284                     // Instance iri
285                     instance.addAttributeValue(id, factory
286                             .getInstance((Identifier) terms[i]));
287             }
288             catch (InvalidModelException e) {
289                 throw new WrappedInvalidModelException(e);
290             }
291         }
292     }
293 
294     public void outAInstance(AInstance node) {
295         container.popFromStack(Entity.class, Instance.class);
296     }
297 
298     // end Instance section
299 
300     // Relation section
301 
302     public void inARelation(ARelation node) {
303         // Check to now allow both arity and parameters set!
304         paramCount=0;
305         ParserException ex = null;
306         if (node.getArity() == null && node.getParamtyping() == null) {
307             ex = new ParserException("For relation " + node.getId()
308                     + " are neither cardinality nor parameter types defined", null);
309         }
310         if (node.getArity() != null && node.getParamtyping() != null) {
311             ex = new ParserException("For relation " + node.getId()
312                     + " are both cardinality and parameter types defined", null);
313         }
314         if (ex != null) {
315             Token token = ((ARelation) node.getId().parent()).getTRelation();
316             ex.setErrorLine(token.getLine());
317             ex.setErrorPos(token.getPos());
318             throw new WrappedParsingException(ex);
319         }
320 
321         node.getId().apply(container.getNodeHandler(PId.class));
322         Identifier id = (Identifier) container.popFromStack(Identifier.class, Identifier.class);
323         Relation relation = factory.createRelation(id);
324         container.getStack(Entity.class).push(relation);
325         addToOntology(relation);
326 
327         if (node.getArity() != null) {
328             int arity = Integer.parseInt(((AArity) node.getArity()).getPosInteger().toString()
329                     .trim());
330             for (byte i = 0; i < arity; i++) {
331                 try {
332                     relation.createParameter(i);
333                 }
334                 catch (InvalidModelException e) {
335                     throw new WrappedInvalidModelException(e);
336                 }
337             }
338         }
339     }
340 
341     public void outASuperrelation(ASuperrelation node) {
342         Identifier[] superRelationId = (Identifier[]) container.popFromStack(Identifier[].class,
343                 Identifier[].class);
344         Relation relation = (Relation) container.peekFromStack(Entity.class, Relation.class);
345         for (int i = 0; i < superRelationId.length; i++) {
346             try {
347                 relation.addSuperRelation(factory.getRelation(superRelationId[i]));
348             }
349             catch (InvalidModelException e) {
350                 throw new WrappedInvalidModelException(e);
351             }
352         }
353     }
354 
355     public void outAParamtype(AParamtype node) {
356         Identifier[] paramTypes = (Identifier[]) container.popFromStack(Identifier[].class,
357                 Identifier[].class);
358         Relation relation = (Relation) container.peekFromStack(Entity.class, Relation.class);
359         Parameter param = null;
360         
361         try {
362             param = relation.createParameter(paramCount++);
363         }
364         catch (InvalidModelException e) {
365             throw new WrappedInvalidModelException(e);
366         }
367 
368         if (node.getAttType() instanceof AOpenWorldAttType) {
369             param.setConstraining(true);
370         }
371         else {
372             param.setConstraining(false);
373         }
374         ConstantTransformer cf = ConstantTransformer.getInstance();
375         for (int i = 0; i < paramTypes.length; i++) {
376             // can never happen since anonIDs are not reused during parsing
377             if (cf.isDataType(paramTypes[i].toString())) {
378                 try {
379                     param.addType(dFactory.createWsmlDataType(paramTypes[i].toString()));
380                 } catch (InvalidModelException e) {
381                     throw new RuntimeException(e);
382                 }
383             }
384             else {
385                 try {
386                     param.addType(factory.getConcept(paramTypes[i]));
387                 } catch (InvalidModelException e) {
388                     throw new RuntimeException(e);
389                 }
390             }
391         }
392     }
393 
394     public void outARelation(ARelation node) {
395         container.popFromStack(Entity.class, Relation.class);
396     }
397 
398     // end Relation section
399 
400     // RelationInstance section
401 
402     private Term rootTerm;
403 
404     public void inARelationinstance(ARelationinstance node) {
405         Identifier id = null;
406         if (node.getName() != null) {
407             node.getName().apply(container.getNodeHandler(PId.class));
408             id = (Identifier) container.popFromStack(Identifier.class, Identifier.class);
409         }
410         else {
411             id = factory.createAnonymousID();
412         }
413 
414         node.getRelation().apply(container.getNodeHandler(PId.class));
415         Relation relation = factory.getRelation((Identifier) container.popFromStack(
416                 Identifier.class, Identifier.class));
417         try {
418             RelationInstance relInstance = factory.createRelationInstance(id, relation);
419             addToOntology(relInstance);
420             container.getStack(Entity.class).push(relInstance);
421         }
422         catch (InvalidModelException e) {
423             throw new WrappedInvalidModelException(e);
424         }
425 
426         if (!container.getStack(Term.class).isEmpty()){
427             rootTerm = (Term) container.peekFromStack(Term.class, Term.class);
428         }
429         else {
430             rootTerm = null;
431         }
432     }
433 
434     public void outARelationinstance(ARelationinstance node) {
435         Stack termStack = container.getStack(Term.class);
436         RelationInstance relInstance = (RelationInstance) container.peekFromStack(Entity.class,
437                 RelationInstance.class);
438         //byte argument = (byte) relInstance.getRelation().listParameters().size();
439         //might be a proxy and above thus does not work
440         Vector v = new Vector();
441         while (!termStack.isEmpty() && rootTerm != container.peekFromStack(Term.class, Term.class)) {
442             v.add(0,container.popFromStack(Term.class, Term.class));
443         }
444         Iterator i = v.iterator();
445         for (byte n=0; i.hasNext(); n++) {
446             Term term = (Term) i.next();
447             try {
448                 if (term instanceof DataValue) {// DataValue
449                     relInstance.setParameterValue(n, (DataValue) term);
450                 }
451                 else { // Instance iri
452                     relInstance.setParameterValue(n, factory
453                             .getInstance((Identifier) term));
454                 }
455             }
456             catch (InvalidModelException e) {
457                 throw new WrappedInvalidModelException(e);
458             }
459         }
460         container.popFromStack(Entity.class, RelationInstance.class);
461     }
462 
463     public void outAAxiom(AAxiom node) {
464         Axiom axiom = (Axiom) container.popFromStack(Axiom.class, Axiom.class);
465         addToOntology(axiom);
466     }
467 
468     private void addToOntology(OntologyElement element) {
469         Stack topEntities = container.getStack(TopEntity.class);
470         if (topEntities.isEmpty() || !(topEntities.peek() instanceof Ontology)) {
471             throw new RuntimeException("OntologyElement does not " + "have Ontology context!");
472         }
473         try {
474             element.setOntology((Ontology) topEntities.peek());
475         }
476         catch (InvalidModelException e) {
477             throw new WrappedInvalidModelException(e);
478         }
479     }
480 }
481 
482 /*
483  * $Log$
484  * Revision 1.8  2006/04/24 08:04:58  holgerlausen
485  * improved error handling in case of topentities without identifier
486  * moved thomas unit test to "open" package, since it does not break expected behavior, but just document some derivations from the spec
487  *
488  * Revision 1.7  2006/04/11 16:06:58  holgerlausen
489  * addressed RFE 1468651 ( http://sourceforge.net/tracker/index.php?func=detail&aid=1468651&group_id=113501&atid=665349)
490  * currently the default behaviour of the parser is still as before
491  *
492  * Revision 1.6  2006/02/16 10:02:50  vassil_momtchev
493  * setInverseOf(Attribute) changed to setInverseOf(Identifier)
494  *
495  * Revision 1.5  2006/02/13 22:49:23  nathaliest
496  * - changed concept.createAttribute() and Parameter.addType to throw InvalidModelException.
497  * - small change at check AnonIds in ConceptImpl
498  *
499  * Revision 1.4  2006/02/13 09:48:52  vassil_momtchev
500  * the code to handle the topentities identifier validity refactored
501  *
502  * Revision 1.3  2006/02/10 14:35:27  vassil_momtchev
503  * parser addapted to the new api changes
504  *
505  * Revision 1.2  2005/11/29 14:23:38  nathaliest
506  * fixed bug concerning number of relation parameters
507  *
508  * Revision 1.1  2005/11/28 13:55:26  vassil_momtchev
509  * AST analyses
510  *
511 */