/**
* Copyright 2007-2010 非也
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation。
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses. *
*/
package org.fireflow.model.io.resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.lang.StringUtils;
import org.fireflow.model.io.ModelElementNames;
import org.fireflow.model.io.SerializerException;
import org.fireflow.model.io.Util4Serializer;
import org.fireflow.model.resourcedef.ResourceDef;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
*
*
* @author 非也
* @version 2.0
*/
public class ResourceSerializer implements ModelElementNames {
private static final String DEFAULT_CHARSET = "UTF-8";
private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
private static String CDATA_SECTION_ELEMENT_LIST = "";
public static final String JDK_TRANSFORMER_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
protected static boolean useJDKTransformerFactory = false;//需要规避bug
static {
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
if (JDK_TRANSFORMER_CLASS.equals(transformerFactory.getClass().getName())){
useJDKTransformerFactory = true;
}
documentBuilderFactory.setNamespaceAware(true);
StringBuffer buf = new StringBuffer();
buf.append("{").append(ModelElementNames.SERVICE_NS_URI).append("}").append(ModelElementNames.DESCRIPTION).append(" " )
.append("{").append(ModelElementNames.SERVICE_NS_URI).append("}").append(ModelElementNames.BODY).append(" ")
.append("{").append(ModelElementNames.RESOURCE_NS_URI).append("}").append(ModelElementNames.DESCRIPTION).append(" " )
.append("{").append(ModelElementNames.RESOURCE_NS_URI).append("}").append(ModelElementNames.BODY).append(" ");
CDATA_SECTION_ELEMENT_LIST = buf.toString();
}
public static void writeResources(List<ResourceDef> resources,Element parentElement)throws SerializerException{
Document document = parentElement.getOwnerDocument();
Element resourcesElement = document.createElementNS(RESOURCE_NS_URI, RESOURCE_NS_PREFIX+":"+RESOURCES);
parentElement.appendChild(resourcesElement);
if (resources == null || resources.size() == 0) {
return;
}
for (ResourceDef r :resources){
writeResource(r, resourcesElement);
}
}
public static Document serializeToDOM(List<ResourceDef> resources)throws SerializerException{
try{
DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = docBuilder.newDocument();
Element resourcesElement = document.createElementNS(RESOURCE_NS_URI, RESOURCE_NS_PREFIX+":"+RESOURCES);
document.appendChild(resourcesElement);
// resourcesElement.addNamespace(RESOURCE_NS_PREFIX, RESOURCE_NS_URI);
// resourcesElement.addNamespace(XSD_NS_PREFIX, XSD_URI);
// resourcesElement.addNamespace(XSI_NS_PREFIX, XSI_URI);
// QName qname = df.createQName("schemaLocation", "xsi", XSI_URI);
// resourcesElement.addAttribute(qname, RESOURCE_SCHEMA_LOCATION);
if (resources == null || resources.size() == 0) {
return document;
}
for (ResourceDef r :resources){
writeResource(r, resourcesElement);
}
return document;
} catch (ParserConfigurationException e) {
throw new SerializerException(e);
}finally{
}
}
public static String serializeToXmlString(List<ResourceDef> resources)throws SerializerException{
return serializeToXmlString(resources,DEFAULT_CHARSET);
}
public static String serializeToXmlString(List<ResourceDef> resources,String charset)throws SerializerException{
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
serialize(resources, out,charset);
} catch (IOException e) {
throw new SerializerException(e);
}
return out.toString();
}
public static void serialize(List<ResourceDef> resources, OutputStream out)
throws IOException, SerializerException {
serialize(resources,out,DEFAULT_CHARSET);
}
public static void serialize(List<ResourceDef> resources, OutputStream out,String charset)
throws IOException, SerializerException {
try{
Document document = serializeToDOM(resources);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING,charset);
transformer.setOutputProperty(OutputKeys.INDENT,"yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, CDATA_SECTION_ELEMENT_LIST);
transformer.transform(new DOMSource(document), new StreamResult(out));
out.flush();
} catch (TransformerConfigurationException e) {
throw new SerializerException(e);
} catch (TransformerException e) {
throw new SerializerException(e);
}finally{
}
}
protected static void writeResource(ResourceDef r, Element resourcesElement)
throws SerializerException {
Element resourceElem = Util4Serializer.addElement(resourcesElement,
RESOURCE);
resourceElem.setAttribute(ID, r.getId());
resourceElem.setAttribute(NAME, r.getName());
if (r.getDisplayName() != null && !r.getDisplayName().trim().equals("")) {
resourceElem.setAttribute(DISPLAY_NAME, r.getDisplayName());
}
writeDescription(resourceElem,r.getDescription());
resourceElem
.setAttribute(RESOURCE_TYPE, r.getResourceType().getValue());
resourceElem.setAttribute(VALUE, r.getValue());
if (!StringUtils.isEmpty(r.getResolverBeanName())
|| !StringUtils.isEmpty(r.getResolverClassName())){
Element resolverElem = Util4Serializer.addElement(resourceElem,
RESOLVER);
if (!StringUtils.isEmpty(r.getResolverBeanName())){
resolverElem.setAttribute(BEAN_NAME, r.getResolverBeanName());
}
if (!StringUtils.isEmpty(r.getResolverClassName())){
resolverElem.setAttribute(CLASS_NAME, r.getResolverClassName());
}
}
writeExtendedAttributes(r.getExtendedAttributes(),resourceElem);
}
protected static Element writeExtendedAttributes(Map<String,String> extendedAttributes,
Element parent) {
if (extendedAttributes == null || extendedAttributes.size() == 0) {
return null;
}
Element extendedAttributesElement =
Util4Serializer.addElement(parent,
EXTENDED_ATTRIBUTES);
Iterator<String> keys = extendedAttributes.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next();
String value = extendedAttributes.get(key);
Element extendedAttributeElement = Util4Serializer.addElement(
extendedAttributesElement, EXTENDED_ATTRIBUTE);
extendedAttributeElement.setAttribute(NAME, key.toString());
if (value != null) {
extendedAttributeElement.setAttribute(VALUE, value.toString());
}
}
return extendedAttributesElement;
}
protected static void writeDescription(Element parent, String desc) {
if(desc==null || desc.trim().equals(""))return;
Document doc = parent.getOwnerDocument();
Element descElem = Util4Serializer.addElement(parent, DESCRIPTION);
CDATASection cdata = doc.createCDATASection(useJDKTransformerFactory?(" "+desc):desc);
descElem.appendChild(cdata);
}
}