package org.jboss.seam.maven.helper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.apache.maven.plugin.logging.Log;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
/**
*
* Generates JSF taglib descriptor xml
*
* @author Rafael Benevides <https://community.jboss.org/people/rafabene>
* @author Marek Novotny <https://community.jboss.org/people/manaRH>
*
*/
public class XMLGenerator
{
private Log log;
public XMLGenerator(Log log)
{
this.log = log;
}
public Element getFaceletsTagElementFromFacesconfig(File xml, String tagName, String converterOrValidator) throws Exception
{
log.info("Generating taglib from " + xml);
DocumentBuilder dstDB = DocumentBuilderFactory.newInstance().newDocumentBuilder();
DocumentBuilder srcDB = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document destDocument = dstDB.newDocument();
Document srcDocument = srcDB.parse(xml);
XPath xpath = XPathFactory.newInstance().newXPath();
Element tagElement = destDocument.createElement("tag");
Node tagNode = destDocument.appendChild(tagElement);
Element tagNameElement = destDocument.createElement("tag-name");
tagNameElement.setTextContent(tagName);
tagNode.appendChild(tagNameElement);
Element component = destDocument.createElement(converterOrValidator);
Node componentNode = tagNode.appendChild(component);
Element description = destDocument.createElement("description");
String descriptionContent = xpath.evaluate("//" + converterOrValidator + "/description/text()", srcDocument);
description.setTextContent(descriptionContent);
componentNode.appendChild(description);
Element componentType = destDocument.createElement(converterOrValidator + "-id");
String componentTypeContent = xpath.evaluate("//" + converterOrValidator + "-id/text()", srcDocument);
componentType.setTextContent(componentTypeContent);
componentNode.appendChild(componentType);
NodeList propertyNodes = (NodeList) xpath.evaluate("//property", srcDocument, XPathConstants.NODESET);
for (int i = 0; i < propertyNodes.getLength(); i++)
{
Node nNode = propertyNodes.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE)
{
Element eElement = (Element) nNode;
String propDescription = getTagValue("description", eElement);
String propName = getTagValue("property-name", eElement);
String propClass = getTagValue("property-class", eElement);
Element attribute = destDocument.createElement("attribute");
Element atributeDescription = destDocument.createElement("description");
atributeDescription.setTextContent(propDescription);
attribute.appendChild(atributeDescription);
Element attributeName = destDocument.createElement("name");
attributeName.setTextContent(propName);
attribute.appendChild(attributeName);
Element attributeClass = destDocument.createElement("type");
attributeClass.setTextContent(propClass);
attribute.appendChild(attributeClass);
tagElement.appendChild(attribute);
}
}
return tagElement;
}
private static String getTagValue(String sTag, Element eElement)
{
NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = (Node) nlList.item(0);
return nValue.getNodeValue();
}
private void writeFileContent(File outXML, String content) throws IOException
{
log.info("Updating " + outXML);
FileOutputStream fos = new FileOutputStream(outXML);
fos.write(content.getBytes());
}
public void updateFile(File outXML, List<Element> tags) throws Exception
{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(outXML);
for (Element tag : tags)
{
Comment comment = doc.createComment("Converter added by seam-cdk-helper plugin");
Node firstchild = doc.getFirstChild();
firstchild.appendChild(comment);
firstchild.appendChild(doc.importNode(tag, true));
}
// ///////////////
// Output the XML
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute("indent-number", new Integer(4));
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
DOMImplementation domImplementation = doc.getImplementation();
if (domImplementation.hasFeature("LS", "3.0") && domImplementation.hasFeature("Core", "2.0"))
{
DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation.getFeature("LS", "3.0");
LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
DOMConfiguration domConfiguration = lsSerializer.getDomConfig();
if (domConfiguration.canSetParameter("format-pretty-print", true))
{
lsSerializer.getDomConfig().setParameter("format-pretty-print", true);
LSOutput lsOutput = domImplementationLS.createLSOutput();
lsOutput.setEncoding("UTF-8");
StringWriter stringWriter = new StringWriter();
lsOutput.setCharacterStream(stringWriter);
lsSerializer.write(doc, lsOutput);
writeFileContent(outXML, stringWriter.toString());
}
else
{
throw new RuntimeException("DOMConfiguration 'format-pretty-print' parameter isn't settable.");
}
}
else
{
throw new RuntimeException("DOM 3.0 LS and/or DOM 2.0 Core not supported.");
}
}
}