/** * Write the root Element to a writer. * * @param root * Root Element to write. * @param writer * Writer to write to. * @throws IOException * if the writer fails to write. */ @SuppressWarnings("unchecked") protected void write(Element root, Writer writer) throws IOException { XMLOutputter outputter = new XMLOutputter(); outputter.setFormat(Format.getPrettyFormat()); Document document = new Document(root); if (stylesheetURL != null) { Map<String, String> instructionMap = new HashMap<String, String>(2); instructionMap.put("type", "text/xsl"); instructionMap.put("href", stylesheetURL); ProcessingInstruction pi = new ProcessingInstruction( "xml-stylesheet", instructionMap); document.getContent().add(0, pi); } outputter.output(document, writer); }
private DataDrivenTest(Element e) { super(e.getAttributeValue("desc")); Filter prologFilter = new AbstractFilter() { @Override public Object filter(Object o) { if (o instanceof Element || o instanceof Comment || o instanceof ProcessingInstruction) { return o; } return null; } }; target.addContent(XmlHelper.clone(e.getChild("target").getContent(prologFilter))); diff.setRootElement((Element) e.getChild("diff").clone()); expectedResult.addContent(XmlHelper.clone(e.getChild("result").getContent(prologFilter))); String errorName = e.getChild("result").getAttributeValue("error"); expectedError = errorName == null ? null : ErrorCondition.valueOf(errorName); }
/** * Add link to XSL stylesheet for displaying OAI response in web browser. */ private Document addXSLStyle(Document doc) { String styleSheet = MCROAIAdapter.PREFIX + getServletName() + ".ResponseStylesheet"; String xsl = MCRConfiguration.instance().getString(styleSheet, "oai/oai2.xsl"); if (!xsl.isEmpty()) { Map<String, String> pairs = new HashMap<>(); pairs.put("type", "text/xsl"); pairs.put("href", MCRFrontendUtil.getBaseURL() + xsl); doc.addContent(0, new ProcessingInstruction("xml-stylesheet", pairs)); } return doc; }
public ProcessingInstruction getProcessingInstruction() { if (pi == null) { String data = RAW_OUTPUTTER.outputString(new Text(text)); this.pi = new ProcessingInstruction(type, data); } return pi; }
public MCRChangeData(ProcessingInstruction pi, String prefix) { this.pi = pi; this.context = pi.getParentElement(); this.pos = context.indexOf(pi); this.type = pi.getTarget().substring(prefix.length()); String xml = "<x>" + pi.getData() + "</x>"; this.text = text2element(xml).getText(); }
public MCRChangeData findLastChange(Document doc) { String typePrefix = PREFIX + counter + "-"; for (ProcessingInstruction instruction : doc.getDescendants(Filters.processinginstruction())) { String target = instruction.getTarget(); if (target.startsWith(typePrefix)) return new MCRChangeData(instruction, typePrefix); } throw new MCRException("Lost processing instruction for undo, not found: " + typePrefix); }
public static void removeChangeTracking(Element element) { for (Iterator<ProcessingInstruction> iter = element.getDescendants(Filters.processinginstruction()) .iterator(); iter.hasNext();) { if (iter.next().getTarget().startsWith(PREFIX)) iter.remove(); } }
public static boolean equivalent(ProcessingInstruction p1, ProcessingInstruction p2) { String t1 = p1.getTarget(); String t2 = p2.getTarget(); String d1 = p1.getData(); String d2 = p2.getData(); boolean equals = t1.equals(t2) && d1.equals(d2); if (!equals && LOGGER.isDebugEnabled()) { LOGGER.debug("ProcessingInstruction differs \"{}\"!=\"{}\"", p1, p2); } return equals; }
public static boolean equivalentContent(List<Content> l1, List<Content> l2) { if (l1.size() != l2.size()) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Number of content list elements differ {}!={}", l1.size(), l2.size()); } return false; } boolean result = true; Iterator<Content> i1 = l1.iterator(); Iterator<Content> i2 = l2.iterator(); while (result && i1.hasNext() && i2.hasNext()) { Object o1 = i1.next(); Object o2 = i2.next(); if (o1 instanceof Element && o2 instanceof Element) { result = equivalent((Element) o1, (Element) o2); } else if (o1 instanceof Text && o2 instanceof Text) { result = equivalent((Text) o1, (Text) o2); } else if (o1 instanceof Comment && o2 instanceof Comment) { result = equivalent((Comment) o1, (Comment) o2); } else if (o1 instanceof ProcessingInstruction && o2 instanceof ProcessingInstruction) { result = equivalent((ProcessingInstruction) o1, (ProcessingInstruction) o2); } else if (o1 instanceof DocType && o2 instanceof DocType) { result = equivalent((DocType) o1, (DocType) o2); } else { result = false; } } return result; }
protected String getStyleSheet(final Document doc) { String styleSheet = null; for (final Content c : doc.getContent(new ContentFilter(ContentFilter.PI))) { final ProcessingInstruction pi = (ProcessingInstruction) c; if ("text/xsl".equals(pi.getPseudoAttributeValue("type"))) { styleSheet = pi.getPseudoAttributeValue("href"); break; } } return styleSheet; }
public void track(MCRChangeData data) { ProcessingInstruction pi = data.getProcessingInstruction(); pi.setTarget(PREFIX + (++counter) + "-" + pi.getTarget()); data.getContext().addContent(data.getPosition(), pi); }
private static void doRemove(Element patch, Object node) throws JDOMException { if (node instanceof Element || node instanceof Comment || node instanceof ProcessingInstruction) { String ws = patch.getAttributeValue("ws"); boolean before = "both".equals(ws) || "before".equals(ws); boolean after = "both".equals(ws) || "after".equals(ws); Content c = (Content) node; Element e = c.getParentElement(); if (e == null) { throw new PatchException(ErrorCondition.INVALID_ROOT_ELEMENT_OPERATION, "can't remove root element"); } int index = e.indexOf(c); List<Content> nodesToDetach = new ArrayList<>(); nodesToDetach.add(c); if (before) { nodesToDetach.add(getWhitespace(e, index - 1)); } if (after) { nodesToDetach.add(getWhitespace(e, index + 1)); } for (Content detachMe : nodesToDetach) { detachMe.detach(); } return; } if (patch.getAttribute("ws") != null) { throw new PatchException(ErrorCondition.INVALID_PATCH_DIRECTIVE, "The 'ws' attribute is not allowed when removing " + "Attribute, Text or Namespace nodes."); } if (node instanceof Attribute) { Attribute a = (Attribute) node; a.getParent().removeAttribute(a); return; } if (node instanceof Text) { ((Content) node).detach(); return; } if (node instanceof Namespace) { throw new UnsupportedOperationException("removing namespace declarations is not yet implemented"); // return; } }
private TEIValidator.Errors extractMainCorpusHeader(Document doc) throws LaudatioException, IOException, SAXException { TEIValidator validator = corpusSchemeURL == null ? new TEICorpusValidator() : new FromURLValidator(corpusSchemeURL); Element corpusHeader = doc.getRootElement().getChild("teiHeader", null); if (corpusHeader != null) { File corpusDir = new File(outputDirectory, "CorpusHeader"); if (!corpusDir.exists() && !corpusDir.mkdir()) { throw new LaudatioException(messages.getString( "COULD NOT CREATE DIRECTORY") + corpusDir.getAbsolutePath()); } // create the subtree for the global corpus header Namespace teiNS = Namespace.getNamespace( "http://www.tei-c.org/ns/1.0"); Element newRootForCorpus = new Element("TEI", teiNS); newRootForCorpus.addContent(corpusHeader.clone()); Document corpusDoc = new Document(newRootForCorpus); if(corpusSchemeURL == null) { corpusDoc.addContent(0, new ProcessingInstruction("xml-model", "href=\"" + TEICorpusValidator.DEFAULT_SCHEME_URL + "\"")); } else { corpusDoc.addContent(0, new ProcessingInstruction("xml-model", "href=\"" + corpusSchemeURL + "\"")); } // we need to append an empty "text" element after the header Element text = new Element("text", teiNS); text.setText(""); newRootForCorpus.addContent(text); // we work with the copy from now corpusHeader = newRootForCorpus.getChild("teiHeader", null); Preconditions.checkNotNull(corpusHeader, messages.getString( "ERROR NO CORPUS TITLE GIVEN")); Preconditions.checkState("CorpusHeader".equals(corpusHeader.getAttributeValue("type"))); Preconditions.checkNotNull(corpusHeader.getChild("fileDesc", null), messages.getString( "ERROR NO CORPUS TITLE GIVEN")); Preconditions.checkNotNull(corpusHeader.getChild("fileDesc", null).getChild("titleStmt", null), messages.getString( "ERROR NO CORPUS TITLE GIVEN")); String title = corpusHeader.getChild("fileDesc", null) .getChild("titleStmt", null) .getChildTextNormalize("title", null); Preconditions.checkNotNull(title, messages.getString( "ERROR NO CORPUS TITLE GIVEN")); // save the file with the title as file name File outputFile = new File(corpusDir, title + ".xml"); XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat()); xmlOut.output(corpusDoc, new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")); log.info(messages.getString("WRITTEN CORPUS HEADER"), outputFile.getPath()); validator.validate(outputFile); } return validator.getErrors(); }
private TEIValidator.Errors extractDocumentHeaders(Document doc) throws LaudatioException, IOException, SAXException { TEIValidator validator = documentSchemeURL == null ? new TEIDocumentValidator(): new FromURLValidator(documentSchemeURL); File documentDir = new File(outputDirectory, "DocumentHeader"); if (!documentDir.exists() && !documentDir.mkdir()) { throw new LaudatioException(messages.getString( "COULD NOT CREATE DIRECTORY") + documentDir.getAbsolutePath()); } Element documentRoot = Preconditions.checkNotNull(doc.getRootElement() .getChild("teiCorpus", null)); for(Element docHeader : documentRoot.getChildren("teiHeader", null)) { Preconditions.checkState("DocumentHeader".equals(docHeader.getAttributeValue("type"))); // create the subtree for the global corpus header Namespace teiNS = Namespace.getNamespace( "http://www.tei-c.org/ns/1.0"); Element tei = new Element("TEI", teiNS); tei.addContent(docHeader.clone()); Document newDoc = new Document(tei); if(documentSchemeURL == null) { newDoc.addContent(0, new ProcessingInstruction("xml-model", "href=\"" + TEIDocumentValidator.DEFAULT_SCHEME_URL + "\"")); } else { newDoc.addContent(0, new ProcessingInstruction("xml-model", "href=\"" + documentSchemeURL + "\"")); } // we need to append an empty "text" element after the header Element text = new Element("text", teiNS); text.setText(""); tei.addContent(text); Element fileDesc = Preconditions.checkNotNull(tei.getChild("teiHeader", null).getChild("fileDesc", null)); String outName = UUID.randomUUID().toString(); String id = fileDesc.getAttributeValue("id", Namespace.XML_NAMESPACE); if(id != null) { outName = id; } else { Element titleStmt = Preconditions.checkNotNull(fileDesc.getChild("titleStmt", null)); String title = titleStmt.getChildText("title", null); if(title != null) { outName = title; } } File outputFile = new File(documentDir, outName + ".xml"); XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat()); xmlOut.output(newDoc, new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")); log.info(messages.getString("WRITTEN DOCUMENT HEADER"), outputFile.getPath()); validator.validate(outputFile); } return validator.getErrors(); }
private TEIValidator.Errors extractPreparationSteps(Document doc) throws LaudatioException, IOException, SAXException { TEIValidator validator = preparationSchemeURL == null ? new TEIPreparationValidator(): new FromURLValidator(preparationSchemeURL); Multiset<String> knownPreparationTitles = HashMultiset.create(); File documentDir = new File(outputDirectory, "PreparationHeader"); if (!documentDir.exists() && !documentDir.mkdir()) { throw new LaudatioException(messages.getString( "COULD NOT CREATE DIRECTORY") + documentDir.getAbsolutePath()); } Preconditions.checkNotNull(doc.getRootElement() .getChild("teiCorpus", null)); Element preparationRoot = Preconditions.checkNotNull(doc.getRootElement() .getChild("teiCorpus", null).getChild("teiCorpus", null)); for(Element preparationHeader : preparationRoot.getChildren("teiHeader", null)) { Preconditions.checkState("PreparationHeader".equals(preparationHeader.getAttributeValue("type"))); // create the subtree for the global corpus header Namespace teiNS = Namespace.getNamespace( "http://www.tei-c.org/ns/1.0"); Element tei = new Element("TEI", teiNS); tei.addContent(preparationHeader.clone()); Document newDoc = new Document(tei); if(preparationSchemeURL == null) { newDoc.addContent(0, new ProcessingInstruction("xml-model", "href=\"" + TEIPreparationValidator.DEFAULT_SCHEME_URL + "\"")); } else { newDoc.addContent(0, new ProcessingInstruction("xml-model", "href=\"" + preparationSchemeURL + "\"")); } // we need to append an empty "text" element after the header Element text = new Element("text", teiNS); text.setText(""); tei.addContent(text); Element fileDesc = Preconditions.checkNotNull(tei.getChild("teiHeader", null).getChild("fileDesc", null)); String outName = UUID.randomUUID().toString(); Element titleStmt = Preconditions.checkNotNull(fileDesc.getChild("titleStmt", null)); Element title = Preconditions.checkNotNull(titleStmt.getChild("title", null)); String corresp = title.getAttributeValue("corresp"); if(corresp != null) { if(knownPreparationTitles.contains(corresp)) { knownPreparationTitles.add(corresp); outName = corresp + "_" + knownPreparationTitles.count(corresp); log.warn(messages.getString("MORE THAN ONE PREPARATION HEADER"), corresp); } else { outName = corresp; knownPreparationTitles.add(corresp); } } File outputFile = new File(documentDir, outName + ".xml"); XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat()); xmlOut.output(newDoc, new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")); log.info(messages.getString("WRITTEN PREPARATION HEADER"), outputFile.getPath()); validator.validate(outputFile); } return validator.getErrors(); }