/** * SPINdle (version 2.2.2) * Copyright (C) 2009-2012 NICTA Ltd. * * This file is part of SPINdle project. * * SPINdle is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SPINdle is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with SPINdle. If not, see <http://www.gnu.org/licenses/>. * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory */ package spindle.io.outputter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import spindle.core.dom.Conclusion; import spindle.core.dom.DomConst; import spindle.core.dom.Literal; import spindle.core.dom.LiteralVariable; import spindle.core.dom.Mode; import spindle.core.dom.Rule; import spindle.core.dom.Superiority; import spindle.core.dom.Theory; import spindle.io.OutputterException; import spindle.io.outputter.XmlTag.Attribute; import spindle.io.outputter.XmlTag.Tag; /** * Defeasible theory and conclusions outputter in XML. * * @deprecated As of version 2.2.2, the XML theory outputter class {@link spindle.io.outputter.XmlTheoryOutputter} is replaced by {@link spindle.io.outputter.XmlTheoryOutputter2}. * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory * @since version 1.0.0 * @version Last modified 2013.05.30 * @see spindle.io.outputter.XmlTheoryOutputter2 */ @Deprecated public class XmlTheoryOutputter extends AbstractTheoryOutputter { public static final String OUTPUTTER_TYPE = "xml"; public static String getTheoryAsXmlString(Theory theory) throws OutputterException { ByteArrayOutputStream writer = new ByteArrayOutputStream(); XmlTheoryOutputter outputter = new XmlTheoryOutputter(); outputter.save(writer, theory); return writer.toString(); } public static String getConclusionsAsXmlString(List<Conclusion> conclusionsAsList) throws OutputterException { ByteArrayOutputStream writer = new ByteArrayOutputStream(); XmlTheoryOutputter outputter = new XmlTheoryOutputter(); outputter.save(writer, conclusionsAsList); return writer.toString(); } public XmlTheoryOutputter() { super(OUTPUTTER_TYPE); } @Override protected void saveToStream(OutputStream os, List<Conclusion> conclusionsAsList) throws OutputterException { try { if (null == writer) throw new IOException("writer is null"); Document document = generateConclusionsDocument(conclusionsAsList); Transformer xmlTransformer = getXmlTransformer(); StreamResult result = new StreamResult(os); DOMSource source = new DOMSource(document); xmlTransformer.transform(source, result); } catch (Exception e) { throw new OutputterException(e); } } private Document generateConclusionsDocument(List<Conclusion> conclusionsAsList) throws OutputterException { Document document = null; try { document = getNewXmlDocument(); document.appendChild(document.createComment(getHeaderComment())); document.appendChild(document.createComment(getGenerationTimeString())); Element docRoot = document.createElement(XmlTag.Tag.DOC_ROOT.getXmlTag()); document.appendChild(docRoot); for (Conclusion conclusion : conclusionsAsList) { Element conclusionEle = document.createElement(XmlTag.Tag.CONCLUSION.getXmlTag()); conclusionEle.setAttribute(XmlTag.Attribute.CONCLUSION_TYPE.getAttributeName(), conclusion.getConclusionType().getTextTag()); Element literalEle = generateLiteral(document, conclusion.getLiteral(), Tag.LITERAL); conclusionEle.appendChild(literalEle); docRoot.appendChild(conclusionEle); } } catch (ParserConfigurationException e) { throw new OutputterException("exception throw while creating XML document", e); } return document; } @Override protected void saveToStream(OutputStream os, Theory theory) throws OutputterException { try { if (null == writer) throw new IOException("writer is null"); Document document = generateTheoryDocument(theory); Transformer xmlTransformer = getXmlTransformer(); StreamResult result = new StreamResult(os); DOMSource source = new DOMSource(document); xmlTransformer.transform(source, result); } catch (Exception e) { throw new OutputterException(e); } } private Document generateTheoryDocument(Theory theory) throws OutputterException { Document document = null; try { document = getNewXmlDocument(); document.appendChild(document.createComment(getHeaderComment())); document.appendChild(document.createComment(getGenerationTimeString())); Element docRoot = document.createElement(Tag.DOC_ROOT.getXmlTag()); document.appendChild(docRoot); addLiteralVariables(document, theory.getLiteralVariables(), Tag.LITERAL_VARIABLE); addLiteralVariables(document, theory.getLiteralBooleanFunctions(), Tag.LITERAL_BOOLEAN_FUNCTION); for (Rule rule : theory.getFactsAndAllRules().values()) { switch (rule.getRuleType()) { case FACT: addFact(document, rule); break; case STRICT: case DEFEASIBLE: case DEFEATER: addRule(document, rule); break; default: } } for (Superiority sup : theory.getAllSuperiority()) { addSuperiority(document, sup); } Map<String, Set<String>> resolveRules_conversion = theory.getAllModeConversionRules(); if (null != resolveRules_conversion) { for (Entry<String, Set<String>> entry : resolveRules_conversion.entrySet()) { addModeConversionRule(document, entry.getKey(), entry.getValue()); } } Map<String, Set<String>> resolveRules_conflict = theory.getAllModeConflictRules(); if (null != resolveRules_conflict) { for (Entry<String, Set<String>> entry : resolveRules_conflict.entrySet()) { addModeConflictRule(document, entry.getKey(), entry.getValue()); } } } catch (ParserConfigurationException e) { throw new OutputterException("exception throw while creating XML document", e); } return document; } private void addLiteralVariables(Document document, Map<LiteralVariable, LiteralVariable> literalVariables, Tag xmlRootTag) throws OutputterException { if (null == literalVariables || literalVariables.size() == 0) return; for (Entry<LiteralVariable, LiteralVariable> entry : literalVariables.entrySet()) { Element elementRoot = document.createElement(xmlRootTag.getXmlTag()); Element eleName = document.createElement(Tag.LITERAL_VARIABLE_NAME.getXmlTag()); Element eleValue = document.createElement(Tag.LITERAL_VARIABLE_VALUE.getXmlTag()); elementRoot.appendChild(eleName); elementRoot.appendChild(eleValue); eleName.appendChild(generateLiteral(document, entry.getKey(), Tag.LITERAL)); if (xmlRootTag.equals(Tag.LITERAL_VARIABLE)) { eleValue.appendChild(generateLiteral(document, entry.getValue(), Tag.LITERAL)); } else { eleValue.appendChild(generateLiteral(document, entry.getValue(), Tag.LITERAL_BOOLEAN_FUNCTION_FORMULA)); } document.getDocumentElement().appendChild(elementRoot); } } private void addFact(Document document, Rule rule) throws OutputterException { Element ele = document.createElement(Tag.FACT.getXmlTag()); if (!rule.getLabel().startsWith(DEFAULT_RULE_LABEL_PREFIX)) { ele.setAttribute(XmlTag.Attribute.RULE_LABEL.getAttributeName(), rule.getLabel()); } Element modeEle = generateMode(document, rule.getMode()); if (null != modeEle) ele.appendChild(modeEle); Element headEle = generateLiteralList(document, rule.getHeadLiterals()); if (null == headEle) throw new OutputterException("exception throw while generating xml model for rule [" + rule.getLabel() + "], head literal is empty"); ele.appendChild(headEle); document.getDocumentElement().appendChild(ele); } private void addRule(Document document, Rule rule) throws OutputterException { Element ele = document.createElement(Tag.RULE.getXmlTag()); if (!rule.getLabel().startsWith(DEFAULT_RULE_LABEL_PREFIX)) ele.setAttribute(Attribute.RULE_LABEL.getAttributeName(), rule.getLabel()); switch (rule.getRuleType()) { case STRICT: ele.setAttribute(Attribute.RULE_TYPE_STRICT_RULE.getAttributeName(), Attribute.RULE_TYPE_STRICT_RULE.getAttributeValue()); break; case DEFEASIBLE: ele.setAttribute(Attribute.RULE_TYPE_DEFEASIBLE_RULE.getAttributeName(), Attribute.RULE_TYPE_DEFEASIBLE_RULE.getAttributeValue()); break; case DEFEATER: ele.setAttribute(Attribute.RULE_TYPE_DEFEATER.getAttributeName(), XmlTag.Attribute.RULE_TYPE_DEFEATER.getAttributeValue()); break; default: } Element modeEle = generateMode(document, rule.getMode()); if (null != modeEle) ele.appendChild(modeEle); Element headEleList = generateLiteralList(document, rule.getHeadLiterals()); if (null == headEleList) throw new OutputterException("exception throw while generating xml model for rule [" + rule.getLabel() + "], head literal is empty"); Element headEle = document.createElement(Tag.HEAD.getXmlTag()); headEle.appendChild(headEleList); ele.appendChild(headEle); Element bodyEleList = generateLiteralList(document, rule.getBodyLiterals()); if (null != bodyEleList) { Element bodyEle = document.createElement(Tag.BODY.getXmlTag()); bodyEle.appendChild(bodyEleList); ele.appendChild(bodyEle); } document.getDocumentElement().appendChild(ele); } private Element generateLiteralList(Document document, List<Literal> literals) { if (null == literals || literals.size() == 0) return null; if (literals.size() == 1) return generateLiteral(document, literals.get(0), Tag.LITERAL); Element andEle = document.createElement(Tag.AND.getXmlTag()); for (Literal literal : literals) { andEle.appendChild(generateLiteral(document, literal, Tag.LITERAL)); } return andEle; } private Element generateLiteral(Document document, Literal literal, Tag xmlRootTag) { Element literalEle = document.createElement(xmlRootTag.getXmlTag()); Element atomEle = document.createElement(Tag.ATOM.getXmlTag()); atomEle.appendChild(document.createTextNode(literal.getName())); if (literal.isNegation()) { Element negEle = document.createElement(Tag.NOT.getXmlTag()); negEle.appendChild(atomEle); atomEle = negEle; } literalEle.appendChild(atomEle); StringBuilder sb = new StringBuilder(); for (int i = 0; i < literal.getPredicatesSize(); i++) { if (i > 0) sb.append(DomConst.Literal.LITERAL_SEPARATOR); sb.append(literal.getPredicate(i)); } if (!DomConst.Literal.DEFAULT_PREDICATE_VALUE.equals(sb.toString())) { Element elePredicate = document.createElement(Tag.PREDICATE.getXmlTag()); elePredicate.appendChild(document.createTextNode(sb.toString())); literalEle.appendChild(elePredicate); } Element modeEle = generateMode(document, literal.getMode()); if (null != modeEle) literalEle.appendChild(modeEle); return literalEle; } private Element generateMode(Document document, Mode mode) { Element modeEle = null; if (!"".equals(mode.getName())) { modeEle = document.createElement(Tag.MODE.getXmlTag()); modeEle.appendChild(document.createTextNode(mode.getName())); if (mode.isNegation()) { Element negEle = document.createElement(Tag.NOT.getXmlTag()); negEle.appendChild(modeEle); modeEle = negEle; } } return modeEle; } private void addSuperiority(Document document, Superiority sup) { Element ele = document.createElement(Tag.SUPERIORITY.getXmlTag()); ele.setAttribute(Attribute.SUPERIORITY_SUPERIOR.getAttributeName(), sup.getSuperior()); ele.setAttribute(Attribute.SUPERIORITY_INFERIOR.getAttributeName(), sup.getInferior()); document.getDocumentElement().appendChild(ele); } private void addModeConversionRule(Document document, String mode, Set<String> convertModes) { Element ele = document.createElement(Tag.MODE_CONVERSION.getXmlTag()); Element fromEle = document.createElement(Tag.MODE_CONVERSION_FROM.getXmlTag()); fromEle.appendChild(document.createTextNode(mode)); ele.appendChild(fromEle); for (String m : convertModes) { Element toEle = document.createElement(Tag.MODE_CONVERSION_TO.getXmlTag()); toEle.appendChild(document.createTextNode(m)); ele.appendChild(toEle); } document.getDocumentElement().appendChild(ele); } private void addModeConflictRule(Document document, String mode, Set<String> conflictModes) { Element ele = document.createElement(Tag.MODE_CONFLICT.getXmlTag()); Element modeEle = document.createElement(Tag.MODE_CONFLICT_MODE.getXmlTag()); modeEle.appendChild(document.createTextNode(mode)); ele.appendChild(modeEle); for (String m : conflictModes) { Element conflictWithEle = document.createElement(Tag.MODE_CONFLICT_WITH.getXmlTag()); conflictWithEle.appendChild(document.createTextNode(m)); ele.appendChild(conflictWithEle); } document.getDocumentElement().appendChild(ele); } }