Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.citytechinc.cq.component.xml.XmlWriter Maven / Gradle / Ivy
package com.citytechinc.cq.component.xml;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.codehaus.plexus.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class XmlWriter {
private static final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
private static final TransformerFactory transformerFactory = TransformerFactory.newInstance();
private static final List DO_NOT_CALL = Arrays.asList("getNameSpace", "getContainedElements",
"getFieldName", "getClass", "getRanking");
/** Widget field types that require special prefixes for correct JCR values. */
private static final Set TYPES_WITH_PREFIXES;
static {
TYPES_WITH_PREFIXES = new HashSet();
TYPES_WITH_PREFIXES.add(Double.class);
TYPES_WITH_PREFIXES.add(Long.class);
TYPES_WITH_PREFIXES.add(Boolean.class);
}
private XmlWriter() {
}
public static void writeXml(XmlElement rootXmlElement, OutputStream outputStream)
throws ParserConfigurationException, TransformerException, IllegalArgumentException, SecurityException,
IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Document xmlDocument = makeDocument(rootXmlElement);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource domSource = new DOMSource(xmlDocument);
StreamResult resultStream = new StreamResult(outputStream);
transformer.transform(domSource, resultStream);
}
@SuppressWarnings({ "all" })
private static Element createElement(XmlElement xmlElement, Document document) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {
Class xmlClass = xmlElement.getClass();
Method namespaceMethod = xmlClass.getMethod("getNameSpace", null);
String namespace = (String) namespaceMethod.invoke(xmlElement, null);
Method fieldNameMethod = xmlClass.getMethod("getFieldName", null);
String fieldName = sanitize((String) fieldNameMethod.invoke(xmlElement, null));
Method containedElementsMethod = xmlClass.getMethod("getContainedElements", null);
List containedElementsReturn = (List) containedElementsMethod.invoke(xmlElement, null);
Element createdElement;
if (StringUtils.isEmpty(namespace)) {
createdElement = document.createElement(fieldName);
} else {
createdElement = document.createElementNS(namespace, fieldName);
}
Method[] methods = xmlElement.getClass().getMethods();
for (Method method : methods) {
String methodName = method.getName();
if (!DO_NOT_CALL.contains(methodName) && (methodName.startsWith("get") || methodName.startsWith("is"))) {
Object methodReturn = method.invoke(xmlElement, null);
if (methodReturn != null) {
if (methodReturn instanceof Map, ?>) {
Map, ?> returnMap = (Map, ?>) methodReturn;
for (Entry, ?> entry : returnMap.entrySet()) {
String key = entry.getKey().toString();
Object value = entry.getValue();
if (value instanceof NameSpacedAttribute>) {
NameSpacedAttribute> nsa = (NameSpacedAttribute>) value;
setPropertyOnElement(createdElement, nsa.getNameSpace(), nsa.getNameSpacePrefix(),
StringUtils.isNotEmpty(nsa.getName()) ? nsa.getName() : key, nsa.getValue());
} else {
setPropertyOnElement(createdElement, null, null, key, value);
}
}
} else if (methodReturn instanceof NameSpacedAttribute>) {
NameSpacedAttribute> nsa = (NameSpacedAttribute>) methodReturn;
Object nsaObject = nsa.getValue();
if (nsaObject != null) {
if (nsaObject instanceof List>) {
List> listReturn = (List>) nsaObject;
nsaObject = generateStringFromList(listReturn);
} else if (nsaObject.getClass().isArray()) {
Object[] arrayReturn = (Object[]) nsaObject;
nsaObject = generateStringFromArray(arrayReturn);
}
setPropertyOnElementForMethod(createdElement, nsa.getNameSpace(), nsa.getNameSpacePrefix(),
StringUtils.isNotEmpty(nsa.getName()) ? nsa.getName() : methodName, nsaObject);
}
} else if (methodReturn instanceof List>) {
List> listReturn = (List>) methodReturn;
setPropertyOnElementForMethod(createdElement, null, null, methodName,
generateStringFromList(listReturn));
} else if (methodReturn.getClass().isArray()) {
Object[] arrayReturn = (Object[]) methodReturn;
setPropertyOnElementForMethod(createdElement, null, null, methodName,
generateStringFromArray(arrayReturn));
} else {
setPropertyOnElementForMethod(createdElement, null, null, methodName, methodReturn);
}
}
}
}
if (containedElementsReturn != null && containedElementsReturn.size() > 0) {
for (XmlElement de : containedElementsReturn) {
createdElement.appendChild(createElement(de, document));
}
}
return createdElement;
}
private static Document makeDocument(XmlElement rootXmlElement) throws ParserConfigurationException,
IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
DocumentBuilder documentBuilder = docFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
Element jcrRootElement = createElement(rootXmlElement, document);
document.appendChild(jcrRootElement);
return document;
}
private static String sanitize(String uncleanString) {
uncleanString = uncleanString.replaceAll("[^A-Za-z0-9:_.-]", "");
if (uncleanString.matches("^(\\d(.*)|(?i)XML|:(.*)|\\.(.*))")) {
uncleanString = UUID.randomUUID().toString().replaceAll("-", "").replaceAll("[0-9]", "") + uncleanString;
}
return uncleanString;
}
private static void setPropertyOnElementForMethod(Element element, String nameSpace, String nameSpacePrefix,
String methodName, Object methodReturn) {
String propertyName = null;
if (methodName.startsWith("get")) {
propertyName = StringUtils.lowercaseFirstLetter(methodName.substring(3));
} else if (methodName.startsWith("is")) {
propertyName = StringUtils.lowercaseFirstLetter(methodName.substring(2));
} else {
propertyName = methodName;
}
setPropertyOnElement(element, nameSpace, nameSpacePrefix, propertyName, methodReturn);
}
private static void setPropertyOnElement(Element element, String nameSpace, String nameSpacePrefix, String name,
Object value) {
if (value != null) {
String propertyValue = value.toString();
Class clazz = value.getClass();
if (TYPES_WITH_PREFIXES.contains(clazz)) {
propertyValue = "{" + clazz.getSimpleName() + "}" + propertyValue;
}
if (StringUtils.isEmpty(nameSpace)) {
element.setAttribute(name, propertyValue);
} else {
if (StringUtils.isNotEmpty(nameSpacePrefix)) {
element.setAttributeNS(nameSpace, nameSpacePrefix + ":" + name, propertyValue);
} else {
element.setAttributeNS(nameSpace, name, propertyValue);
}
}
}
}
private static String generateStringFromList(List> list) {
StringBuilder sb = new StringBuilder();
sb.append("[").append(StringUtils.join(list.toArray(), ",")).append("]");
return sb.toString();
}
private static String generateStringFromArray(Object[] array) {
StringBuilder sb = new StringBuilder();
sb.append("[").append(StringUtils.join(array, ",")).append("]");
return sb.toString();
}
}