001: package com.xoetrope.service.xml;
002:
003: import java.io.BufferedReader;
004: import java.io.ByteArrayInputStream;
005: import java.io.StringReader;
006: import java.io.StringWriter;
007: import javax.xml.parsers.DocumentBuilder;
008: import javax.xml.parsers.DocumentBuilderFactory;
009: import javax.xml.transform.Transformer;
010: import javax.xml.transform.TransformerFactory;
011: import javax.xml.transform.dom.DOMResult;
012: import javax.xml.transform.dom.DOMSource;
013: import net.xoetrope.optional.service.ServiceContext;
014: import net.xoetrope.optional.service.ServiceProxy;
015: import net.xoetrope.optional.service.ServiceProxyArgs;
016: import net.xoetrope.optional.service.ServiceProxyException;
017: import net.xoetrope.optional.service.XRouteManager;
018: import net.xoetrope.xui.XProjectManager;
019: import org.apache.xml.serializer.OutputPropertiesFactory;
020: import org.apache.xml.serializer.Serializer;
021: import org.apache.xml.serializer.SerializerFactory;
022:
023: import net.xoetrope.xui.XProject;
024: import net.xoetrope.xui.XProjectManager;
025:
026: import org.w3c.dom.Document;
027:
028: /**
029: * ServiceProxy class for carrying out transformations on a
030: * resultset retrieved by the QueryService. The transformations are carried out
031: * by Xalan
032: *
033: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
034: * the GNU Public License (GPL), please see license.txt for more details. If
035: * you make commercial use of this software you must purchase a commercial
036: * license from Xoetrope.</p>
037: * <p> $Revision: 1.15 $</p>
038: */
039: public class TransformService extends ServiceProxy {
040:
041: /**
042: * Specifies the name of the xsl tranformation file which is to be used.
043: */
044: public static final String ARG_NAME_TRANSFORMNAME = "transformservice:TransformName";
045:
046: /**
047: * Specifies the name of the return parameter which is to be populated with
048: * the result of the transformation.
049: */
050: public static final String ARG_NAME_TRANSFORMPARAM = "transformservice:TransformParam";
051:
052: /**
053: * The owner project and the context in which this object operates.
054: */
055: protected XProject currentProject = XProjectManager
056: .getCurrentProject();
057:
058: /**
059: * The overloaded call for the ServiceProxy
060: * @param method the name of the service
061: * @param context the service context for the call
062: */
063: public Object call(String method, ServiceContext context)
064: throws ServiceProxyException {
065: /**
066: * Just call the next proxy and do something if its running on the server
067: */
068: ServiceProxyArgs args = context.getArgs();
069: callNextProxy(method, context, null);
070: if (side == XRouteManager.SERVER_SIDE) {
071: /**
072: * The resultset has already been retrieved so transform that resultset
073: * using xslt. Open the xsl file named by the 'QueryType' argument and
074: * transform the xml using it.
075: */
076: String queryType = (String) args
077: .getPassParam(ARG_NAME_TRANSFORMNAME);
078: String transParam = (String) args
079: .getPassParam(ARG_NAME_TRANSFORMPARAM);
080: String transformedXML = transformXml(queryType,
081: (String) args.getReturnParam(transParam));
082: transformedXML = fixXML(transformedXML);
083: args.setReturnParam(transParam, transformedXML);
084: }
085:
086: return null;
087: }
088:
089: /**
090: * Replace quotes with the escaped apostrophy
091: * @param input
092: */
093: private String fixXML(String input) {
094: return input;
095: }
096:
097: /**
098: * Using Xalan, create documents out of the resultset and the xsl file and
099: * carry out the transformation.
100: */
101: protected String transformXml(String queryType, String xml) {
102: try {
103: TransformerFactory tFactory = TransformerFactory
104: .newInstance();
105: DocumentBuilder dBuilder = getDocumentBuilder(tFactory);
106:
107: String xslInput = getXSLContent(queryType);
108: Document xslDoc = getDocument(dBuilder, xslInput);
109:
110: DOMSource xslDomSource = getDOMSource(xslDoc, queryType
111: + ".xsl");
112: Transformer transformer = tFactory
113: .newTransformer(xslDomSource);
114: Document xmlDoc = getDocument(dBuilder, xml);
115:
116: DOMSource xmlDomSource = getDOMSource(xmlDoc, queryType
117: + ".xml");
118: DOMResult domResult = new DOMResult();
119:
120: transformer.transform(xmlDomSource, domResult);
121:
122: //Instantiate an Xalan XML serializer and use it to serialize the output.
123: Serializer serializer = SerializerFactory
124: .getSerializer(OutputPropertiesFactory
125: .getDefaultMethodProperties("xml"));
126: StringWriter sw = new StringWriter();
127: serializer.setWriter(sw);
128: serializer.asDOMSerializer().serialize(domResult.getNode());
129: return sw.toString();
130: } catch (Exception e) {
131: e.printStackTrace();
132: return null;
133: }
134: }
135:
136: /**
137: * Retrieve a document builder
138: */
139: private DocumentBuilder getDocumentBuilder(
140: TransformerFactory tFactory) {
141: try {
142: //Instantiate a DocumentBuilderFactory.
143: DocumentBuilderFactory dFactory = DocumentBuilderFactory
144: .newInstance();
145:
146: // And setNamespaceAware, which is required when parsing xsl files
147: dFactory.setNamespaceAware(true);
148:
149: //Use the DocumentBuilderFactory to create a DocumentBuilder.
150: return dFactory.newDocumentBuilder();
151:
152: } catch (Exception e) {
153: e.printStackTrace();
154: return null;
155: }
156: }
157:
158: private String getXSLContent(String queryType) {
159: try {
160: BufferedReader br = currentProject.getBufferedReader(
161: queryType + ".xsl", "UTF-8");
162: String line = br.readLine();
163: String xslInput = "";
164: while (line != null) {
165: xslInput += line;
166: line = br.readLine();
167: }
168: return xslInput;
169: } catch (Exception e) {
170: e.printStackTrace();
171: return null;
172: }
173: }
174:
175: /**
176: * Construct an XML document from the passed xml string
177: */
178: private Document getDocument(DocumentBuilder dBuilder, String xml) {
179: try {
180: ByteArrayInputStream bais = new ByteArrayInputStream(xml
181: .getBytes("UTF-8"));
182: return dBuilder.parse(bais);
183: } catch (Exception e) {
184: e.printStackTrace();
185: return null;
186: }
187: }
188:
189: /*
190: * Create a new DOMSource object from the passed document and return it.
191: * @param doc The Document object from which the object will be created.
192: * @param id the ID which is to be used in the new object.
193: */
194: private DOMSource getDOMSource(Document doc, String id) {
195: // Use the DOM Document to define a DOMSource object.
196: DOMSource domSource = new DOMSource(doc);
197:
198: // Set the systemId: note this is actually a URL, not a local filename
199: domSource.setSystemId(id);
200: return domSource;
201: }
202: }
|