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 }