View Javadoc

1   /*
2    wsmo4j - a WSMO API and Reference Implementation
3    Copyright (c) 2005, University of Innsbruck, Austria
4    This library is free software; you can redistribute it and/or modify it under
5    the terms of the GNU Lesser General Public License as published by the Free
6    Software Foundation; either version 2.1 of the License, or (at your option)
7    any later version.
8    This library is distributed in the hope that it will be useful, but WITHOUT
9    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11   details.
12   You should have received a copy of the GNU Lesser General Public License along
13   with this library; if not, write to the Free Software Foundation, Inc.,
14   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15   */
16  package org.deri.wsmo4j.io.serializer.xml;
17  
18  
19  import java.util.*;
20  
21  import org.deri.wsmo4j.logicalexpression.*;
22  import org.w3c.dom.*;
23  
24  import org.omwg.logicalexpression.*;
25  import org.omwg.logicalexpression.terms.*;
26  
27  
28  /**
29   * Concrete Visitor class. For each visited logical expression,
30   * a document element is built.
31   * @see org.deri.wsmo4j.io.serializer.xml.LogExprSerializerXML
32   * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor
33   */
34  
35  public class VisitorSerializeXML
36          extends AbstractVisitor {
37  
38      private Vector stack;
39  
40      private VisitorSerializeXMLTerms visitor;
41  
42      private Document doc;
43  
44      /**
45       * @param doc Document that will be filled with the xml structure
46       * @see org.deri.wsmo4j.io.serializer.xml.LogExprSerializerXML#LogExprSerializerXML(TopEntity, Document)
47       */
48      public VisitorSerializeXML(Document doc) {
49          this.doc = doc;
50          visitor = new VisitorSerializeXMLTerms(doc);
51          stack = new Vector();
52      }
53  
54      /**
55       * Builds an element in the document with the Atom's identifier
56       * as attribute. The Atom's terms are added as children to the node.
57       * The element is then added to a vector.
58       * @param expr Atom to be serialized
59       * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitAtom(Atom)
60       */
61      public void visitAtom(Atom expr) {
62          int nbParams = expr.getArity();
63          visitor.setName("atom");
64          expr.getIdentifier().accept(visitor);
65          Node newExpr = (Node)visitor.getSerializedObject();
66          if (nbParams > 0) {
67              for (int i = 0; i < nbParams; i++) {
68                  visitor.setName("arg");
69                  expr.getParameter(i).accept(visitor);
70                  newExpr.appendChild((Node)visitor.getSerializedObject());
71              }
72          }
73          stack.add(newExpr);
74      }
75  
76      public void visitCompoundMolecule(CompoundMolecule expr) {
77          Element molecule = doc.createElement("molecule");
78          visitor.setName("term");
79          //id of molecule
80          ((Molecule) expr.listOperands().iterator().next()).getLeftParameter().accept(visitor);
81          molecule.appendChild((Node)visitor.getSerializedObject());
82          List isa = expr.listMemberShipMolecules();
83          int isaType = 0;
84          if (isa != null && isa.size() !=0) {
85              isaType = 1;
86          }
87          else {
88              isa = expr.listSubConceptMolecules();
89              if (isa != null && isa.size() !=0) {
90                  isaType = 2;
91              }
92          }
93          if (isaType != 0) {
94              molecule.appendChild(helpSerializeIsa(isa, isaType, doc));
95          }
96  
97          //Collect all attributeNames:
98          Set attrNames = new HashSet();
99          Iterator i = expr.listOperands().iterator();
100         while (i.hasNext()){
101             Object o = i.next();
102             if (o instanceof AttributeMolecule){
103                 attrNames.add(((AttributeMolecule)o).getAttribute());
104             }
105         }
106         
107         Iterator attrNamesIt = attrNames.iterator();
108         while (attrNamesIt.hasNext()){
109             Term t = (Term)attrNamesIt.next();
110             List l = expr.listAttributeConstraintMolecules(t);
111             if (l.size()>0){
112                 molecule.appendChild(helpSerializeAttrSpecification(l, doc));
113             }
114             l = expr.listAttributeInferenceMolecules(t);
115             if (l.size()>0){
116                 molecule.appendChild(helpSerializeAttrSpecification(l, doc));
117             }
118             l = expr.listAttributeValueMolecules(t);
119             if (l.size()>0){
120                 molecule.appendChild(helpSerializeAttrSpecification(l, doc));
121             }
122         }
123         stack.add(molecule);
124     }
125 
126     /**
127      * Builds a node in the document with the Unary's operator type as name.
128      * The Unary's logical expression is added as child to the node. The node
129      * is then added to a vector.
130      * @param expr Unary Expression to be serialized, with operator NAF
131      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitNegationAsFailure(NegationAsFailure)
132      */
133     public void visitNegationAsFailure(NegationAsFailure expr) {
134         Node newExpr = doc.createElement("naf");
135         expr.getOperand().accept(this);
136         newExpr.appendChild((Node)stack.remove(stack.size() - 1));
137         stack.add(newExpr);
138     }
139 
140     /**
141      * Builds a node in the document with the Unary's operator type as name.
142      * The Unary's logical expression is added as child to the node. The node
143      * is then added to a vector.
144      * @param expr Unary Expression to be serialized, with operator NEG
145      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitNegation(Negation)
146      */
147     public void visitNegation(Negation expr) {
148         Node newExpr = doc.createElement("neg");
149         expr.getOperand().accept(this);
150         newExpr.appendChild((Node)stack.remove(stack.size() - 1));
151         stack.add(newExpr);
152     }
153 
154     /**
155      * Builds a node in the document with the Unary's operator type as name.
156      * The Unary's logical expression is added as child to the node. The node
157      * is then added to a vector.
158      * @param expr Unary Expression to be serialized, with operator CONSTRAINT
159      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitConstraint(Constraint)
160      */
161     public void visitConstraint(Constraint expr) {
162         Node newExpr = doc.createElement("constraint");
163         expr.getOperand().accept(this);
164         newExpr.appendChild((Node)stack.remove(stack.size() - 1));
165         stack.add(newExpr);
166     }
167 
168     /**
169      * Builds a node in the document with the Binary's operator type as name.
170      * The Binary's logical expressions are added as children to the node. The node
171      * is then added to a vector.
172      * @param expr Binary Expression to be serialized, with operator AND
173      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitConjunction(Conjunction)
174      */
175     public void visitConjunction(Conjunction expr) {
176         Node newExpr = doc.createElement("and");
177         finishBinary(expr, newExpr);
178     }
179 
180     /**
181      * Builds a node in the document with the Binary's operator type as name.
182      * The Binary's logical expressions are added as children to the node. The node
183      * is then added to a vector.
184      * @param expr Binary Expression to be serialized, with operator EQUIVALENT
185      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitEquivalence(Equivalence)
186      */
187     public void visitEquivalence(Equivalence expr) {
188         Node newExpr = doc.createElement("equivalent");
189         finishBinary(expr, newExpr);
190     }
191 
192     /**
193      * Builds a node in the document with the Binary's operator type as name.
194      * The Binary's logical expressions are added as children to the node. The node
195      * is then added to a vector.
196      * @param expr Binary Expression to be serialized, with operator IMPLIEDBY
197      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitInverseImplication(InverseImplication)
198      */
199     public void visitInverseImplication(InverseImplication expr) {
200         Node newExpr = doc.createElement("impliedBy");
201         finishBinary(expr, newExpr);
202     }
203 
204     /**
205      * Builds a node in the document with the Binary's operator type as name.
206      * The Binary's logical expressions are added as children to the node. The node
207      * is then added to a vector.
208      * @param expr Binary Expression to be serialized, with operator IMPLIES
209      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitImplication(Implication)
210      */
211     public void visitImplication(Implication expr) {
212         Node newExpr = doc.createElement("implies");
213         finishBinary(expr, newExpr);
214     }
215 
216     /**
217      * Builds a node in the document with the Binary's operator type as name.
218      * The Binary's logical expressions are added as children to the node. The node
219      * is then added to a vector.
220      * @param expr Binary Expression to be serialized, with operator IMPLIEDBYLP
221      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitLogicProgrammingRule(LogicProgrammingRule)
222      */
223     public void visitLogicProgrammingRule(LogicProgrammingRule expr) {
224         Node newExpr = doc.createElement("impliedByLP");
225         finishBinary(expr, newExpr);
226     }
227 
228     /**
229      * Builds a node in the document with the Binary's operator type as name.
230      * The Binary's logical expressions are added as children to the node. The node
231      * is then added to a vector.
232      * @param expr Binary Expression to be serialized, with operator OR
233      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitDisjunction(Disjunction)
234      */
235     public void visitDisjunction(Disjunction expr) {
236         Node newExpr = doc.createElement("or");
237         finishBinary(expr, newExpr);
238     }
239 
240     /**
241      * This method takes a Node containing the Binary Expression operator and
242      * adds the Binary's logical expressions as children to this node. The node
243      * is then added to a vector.
244      * @param expr Binary Expression to be serialized
245      * @param newExpr Node containing the Binary Expression operator
246      * @see org.omwg.logicalexpression.Binary
247      */
248     private void finishBinary(Binary expr, Node newExpr) {
249         expr.getLeftOperand().accept(this);
250         expr.getRightOperand().accept(this);
251         newExpr.appendChild((Node)stack.remove(stack.size() - 2));
252         newExpr.appendChild((Node)stack.remove(stack.size() - 1));
253         stack.add(newExpr);
254     }
255 
256     /**
257      * Builds a node in the document with the Quantified's operator type as name.
258      * The Quantified's Variables and its logical expression are added as
259      * children to the node. The node is then added to a vector.
260      * @param expr Quantified Expression to be serialized, with operator FORALL
261      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitUniversalQuantification(UniversalQuantification)
262      */
263     public void visitUniversalQuantification(UniversalQuantification expr) {
264         Node newExpr = doc.createElement("forall");
265         addVariables(newExpr, expr);
266         expr.getOperand().accept(this);
267         newExpr.appendChild((Node)stack.remove(stack.size() - 1));
268         stack.add(newExpr);
269     }
270 
271     /**
272      * Builds a node in the document with the Quantified's operator type as name.
273      * The Quantified's Variables and its logical expression are added as
274      * children to the node. The node is then added to a vector.
275      * @param expr Quantified Expression to be serialized, with operator EXISTS
276      * @see org.deri.wsmo4j.logicalexpression.AbstractVisitor#visitExistentialQuantification(ExistentialQuantification)
277      */
278     public void visitExistentialQuantification(ExistentialQuantification expr) {
279         Node newExpr = doc.createElement("exists");
280         addVariables(newExpr, expr);
281         expr.getOperand().accept(this);
282         newExpr.appendChild((Node)stack.remove(stack.size() - 1));
283         stack.add(newExpr);
284     }
285 
286     /**
287      * All serialized elements are added to a vector. This method removes the
288      * first serialized element from this vector and shifts any subsequent
289      * elements to the left (subtracts one from their indices).
290      * @return the serialized document node that is the first element in this vector
291      */
292     public Object getSerializedObject() {
293         return stack.remove(0);
294     }
295 
296     /**
297      * This method serializes the memberOf or subConceptOf Set of a Molecule.
298      * An element in the document node, with the type of Set as attribute, is built.
299      * The Set's terms are added as children to the node.
300      * @param isaSet Set of MemberOf identifiers or of SubConceptOf identifiers
301      * @param isaType type of set: 1 = MemberOf; 2 = SubConceptOf
302      * @param doc Document
303      * @return Element representing serialized Set
304      */
305     private Node helpSerializeIsa(List isaSet, int isaType, Document doc) {
306         Element isa = doc.createElement("isa");
307         Iterator it = isaSet.iterator();
308         switch (isaType) {
309             case 1:
310                 isa.setAttribute("type", "memberOf");
311                 break;
312             case 2:
313                 isa.setAttribute("type", "subConceptOf");
314                 break;
315         }
316         visitor.setName("term");
317         while (it.hasNext()) {
318             ((Molecule)it.next()).getRightParameter().accept(visitor);
319             isa.appendChild((Node)visitor.getSerializedObject());
320         }
321         return isa;
322     }
323 
324 
325     //attrMolecules of one attributeName! and one Type!
326     private Node helpSerializeAttrSpecification(List attrMolecules, Document doc) {
327         Element attrSpec = null; 
328         AttributeMolecule am = (AttributeMolecule)attrMolecules.iterator().next();
329         if (am instanceof AttributeConstraintMolecule) {
330             attrSpec = doc.createElement("attributeDefinition");
331             attrSpec.setAttribute("type", "constraining");
332         }
333         else if (am instanceof AttributeInferenceMolecule) {
334             attrSpec = doc.createElement("attributeDefinition");
335             attrSpec.setAttribute("type", "inferring");
336         }
337         else if (am instanceof AttributeValueMolecule) {
338             attrSpec = doc.createElement("attributeValue");
339         }
340         visitor.setName("name");
341         am.getAttribute().accept(visitor);
342         attrSpec.appendChild((Node)visitor.getSerializedObject());
343         Iterator it = attrMolecules.iterator();
344         if (am instanceof AttributeConstraintMolecule || am instanceof AttributeInferenceMolecule) {
345             visitor.setName("type");
346             while (it.hasNext()) {
347                 ((AttributeMolecule)it.next()).getRightParameter().accept(visitor);
348                 attrSpec.appendChild((Node)visitor.getSerializedObject());
349             }
350         }
351         else if (am instanceof AttributeValueMolecule) {
352             visitor.setName("value");
353             while (it.hasNext()) {
354                 ((AttributeMolecule)it.next()).getRightParameter().accept(visitor);
355                 attrSpec.appendChild((Node)visitor.getSerializedObject());
356             }
357         }
358         return attrSpec;
359     }
360 
361     /**
362      * This method serializes the Variables of a Quantified logical expression.
363      * It takes a Node containing the Quantified Expression operator and
364      * adds the Quantified's variables as children to this node. The node
365      * is then added to a vector.An element in the given document node, with the attribute specification type
366      * as attribute to the node, is built. The name of the attribute specification
367      * is added as child to the node, as are also the arguments of the specification.
368      * @param q Node containing the Quantified Expression operator
369      * @param log Quantified Expression to be serialized
370      */
371     private void addVariables(Node q, LogicalExpression log) {
372         Set s = ((Quantified)log).listVariables();
373         Iterator i = s.iterator();
374         visitor.setName("variable");
375         while (i.hasNext()) {
376             ((Term)i.next()).accept(visitor);
377             q.appendChild((Node)visitor.getSerializedObject());
378         }
379     }
380 
381     public void visitSubConceptMolecule(SubConceptMolecule expr) {
382         visitConceptMolecule(expr,2);
383     }
384     
385     private void visitConceptMolecule(Molecule expr, int type){
386         Element molecule = doc.createElement("molecule");
387         visitor.setName("term");
388         expr.getLeftParameter().accept(visitor);
389         molecule.appendChild((Node)visitor.getSerializedObject());
390         List isa = new Vector(); 
391         isa.add(expr);
392         molecule.appendChild(helpSerializeIsa(isa, type, doc));
393         stack.add(molecule);
394     }
395 
396     /* (non-Javadoc)
397      * @see org.omwg.logicalexpression.Visitor#visitMemberShipMolecule(org.omwg.logicalexpression.MembershipMolecule)
398      */
399     public void visitMemberShipMolecule(MembershipMolecule expr) {
400         visitConceptMolecule(expr,1);
401     }
402 
403     /* (non-Javadoc)
404      * @see org.omwg.logicalexpression.Visitor#visitAttributeValueMolecule(org.omwg.logicalexpression.AttributeValueMolecule)
405      */
406     public void visitAttributeValueMolecule(AttributeValueMolecule expr) {
407         visitAttributeMolecule(expr);
408     }
409     
410     private void visitAttributeMolecule(AttributeMolecule expr){
411         Element molecule = doc.createElement("molecule");
412         visitor.setName("term");
413         expr.getLeftParameter().accept(visitor);
414         molecule.appendChild((Node)visitor.getSerializedObject());
415         
416         List l = new Vector();
417         l.add(expr);
418         molecule.appendChild(helpSerializeAttrSpecification(l, doc));
419         stack.add(molecule);
420     }
421 
422     /* (non-Javadoc)
423      * @see org.omwg.logicalexpression.Visitor#visitAttributeContraintMolecule(org.omwg.logicalexpression.AttributeConstraintMolecule)
424      */
425     public void visitAttributeContraintMolecule(AttributeConstraintMolecule expr) {
426         visitAttributeMolecule(expr);
427     }
428 
429     /* (non-Javadoc)
430      * @see org.omwg.logicalexpression.Visitor#visitAttributeInferenceMolecule(org.omwg.logicalexpression.AttributeInferenceMolecule)
431      */
432     public void visitAttributeInferenceMolecule(AttributeInferenceMolecule expr) {
433         visitAttributeMolecule(expr);
434     }
435 }