001: package org.enhydra.dm.util;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.ByteArrayOutputStream;
005: import java.io.FileInputStream;
006: import java.io.IOException;
007: import java.io.InputStream;
008: import java.util.Date;
009: import java.util.HashMap;
010: import java.util.Iterator;
011: import java.util.Map;
012: import java.util.Properties;
013:
014: import javax.xml.transform.Result;
015: import javax.xml.transform.Source;
016: import javax.xml.transform.Templates;
017: import javax.xml.transform.Transformer;
018: import javax.xml.transform.TransformerException;
019: import javax.xml.transform.TransformerFactory;
020: import javax.xml.transform.sax.SAXResult;
021: import javax.xml.transform.stream.StreamResult;
022: import javax.xml.transform.stream.StreamSource;
023:
024: import org.apache.fop.apps.FOUserAgent;
025: import org.apache.fop.apps.Fop;
026: import org.apache.fop.apps.FopFactory;
027: import org.apache.fop.apps.MimeConstants;
028: import org.apache.fop.pdf.PDFEncryptionParams;
029: import org.enhydra.dm.api.exceptions.BaseException;
030: import org.w3c.tidy.Tidy;
031:
032: public class TransformUtility {
033:
034: private static final String TRANSFORUTILITY_PROP_PREFFIX = "TransformUtility.";
035:
036: private static final String TRANSFORUTILITY_PROP_TIDYCONFIG = "TidyConfig";
037:
038: private static final String TRANSFORUTILITY_PROP_FOPCONFIG = "FopConfig";
039:
040: private static final String TRANSFORUTILITY_PROP_FOPBASE = "FopBase";
041:
042: private static final String TRANSFORUTILITY_XSLT = "org/enhydra/dm/util/xhtml2fo.xsl";
043:
044: /**
045: * <code>tidy.properties</code> used by Tidy parser.
046: */
047: private static String tidyConfig = null;
048:
049: private static String fopBase = null;
050:
051: private static FopFactory fopFactory = null;
052:
053: private static TransformerFactory transformerFactory = null;
054:
055: private static Templates templates = null;
056:
057: /**
058: * Method finds fiels and folders on the file sistem and make transformers,
059: * necessary for making pdf file from editor content.
060: *
061: * @param properties
062: * @throws BaseException
063: */
064: public static void configure(Properties properties)
065: throws BaseException {
066: try {
067: tidyConfig = properties
068: .getProperty(TRANSFORUTILITY_PROP_PREFFIX
069: + TRANSFORUTILITY_PROP_TIDYCONFIG);
070:
071: transformerFactory = TransformerFactory.newInstance();
072: templates = transformerFactory
073: .newTemplates(new StreamSource(
074: TransformUtility.class.getClassLoader()
075: .getResourceAsStream(
076: TRANSFORUTILITY_XSLT)));
077:
078: fopBase = properties
079: .getProperty(TRANSFORUTILITY_PROP_PREFFIX
080: + TRANSFORUTILITY_PROP_FOPBASE);
081:
082: String fopConfig = properties
083: .getProperty(TRANSFORUTILITY_PROP_PREFFIX
084: + TRANSFORUTILITY_PROP_FOPCONFIG);
085: fopFactory = FopFactory.newInstance();
086: fopFactory.setUserConfig(fopConfig);
087:
088: } catch (Exception ex) {
089: throw new BaseException(
090: "TransformUtility Initialization Problem!", ex);
091: }
092: }
093:
094: /**
095: * Method make Tidy parser using <code>tidyConfig.properties</code>
096: *
097: * @return <code>Tidy</code> parser
098: */
099: public static Tidy getTidy() {
100: Tidy tidy = new Tidy();
101: tidy.setConfigurationFromFile(tidyConfig);
102: return tidy;
103: }
104:
105: /**
106: * Method get <code>Taransformer</code>
107: *
108: * @return <code>Transformer</code> object
109: * @throws BaseException
110: */
111: public static Transformer getTransformer() throws BaseException {
112: try {
113: return templates.newTransformer();
114: } catch (TransformerException ex) {
115: throw new BaseException(
116: "Not able to load xhtml2fo transformation!", ex);
117: }
118: }
119:
120: public static FopFactory getFopFactory() {
121: return fopFactory;
122: }
123:
124: public static String getFopBase() {
125: return fopBase;
126: }
127:
128: public static TransformerFactory getTransformerFactory() {
129: return transformerFactory;
130: }
131:
132: /**
133: * Method transforms TinyMCE submission from HTML to XHTML format using JTidy utility
134: *
135: * @param cont
136: * @return XHTML format of editor content
137: * @throws BaseException
138: */
139: public static String html2xhtml(String content)
140: throws BaseException {
141: byte[] cont;
142: ByteArrayInputStream bais = null;
143: ByteArrayOutputStream baos = null;
144:
145: try {
146: cont = content.getBytes(EnhydraDMConstants.ENCODING);
147: bais = new ByteArrayInputStream(cont);
148: baos = new ByteArrayOutputStream();
149:
150: Tidy tidy = TransformUtility.getTidy();
151: tidy.getDropFontTags();
152: tidy.parse(bais, baos);
153:
154: baos.flush();
155: cont = baos.toByteArray();
156:
157: content = new String(cont, EnhydraDMConstants.ENCODING);
158:
159: content = content.replace("<body>",
160: "<body> <font face=\"times new roman,times\">");
161: content = content.replace("</body>", "</font></body>");
162: } catch (Exception ex) {
163: content = null;
164: throw new BaseException(ex);
165: } finally {
166: if (bais != null)
167: try {
168: bais.close();
169: } catch (IOException e) {
170: e.printStackTrace();
171: }
172: if (baos != null) {
173: try {
174: baos.close();
175: } catch (IOException e) {
176: e.printStackTrace();
177: }
178: }
179: }
180: return content;
181: }
182:
183: /**
184: * Method transforms XHTML content format to FO format using xhtml2fo (XSl) template
185: *
186: * @param cont
187: * @return FO format of editor content
188: * @throws BaseException
189: */
190: public static String xhtml2fo(String content) throws BaseException {
191: byte[] cont;
192: ByteArrayInputStream bais = null;
193: ByteArrayOutputStream baos = null;
194:
195: try {
196: cont = content.getBytes(EnhydraDMConstants.ENCODING);
197: bais = new ByteArrayInputStream(cont);
198: baos = new ByteArrayOutputStream();
199:
200: Transformer foTransformer = getTransformer();
201: StreamSource ss = new StreamSource(bais);
202: StreamResult sr = new StreamResult(baos);
203: foTransformer.transform(ss, sr);
204:
205: baos.flush();
206: cont = baos.toByteArray();
207:
208: content = new String(cont, EnhydraDMConstants.ENCODING);
209:
210: int start = content
211: .indexOf("<fo:block role=\"html:body\">");
212: int end = content.lastIndexOf("</fo:block>");
213:
214: if (start > 0 && end > 0) {
215: end += 11;
216: content = content.substring(start, end);
217: }
218:
219: } catch (Exception ex) {
220: content = null;
221: throw new BaseException(ex);
222: } finally {
223: if (bais != null)
224: try {
225: bais.close();
226: } catch (IOException e) {
227: e.printStackTrace();
228: }
229: if (baos != null) {
230: try {
231: baos.close();
232: } catch (IOException e) {
233: e.printStackTrace();
234: }
235: }
236: }
237: return content;
238: }
239:
240: /**
241: * Method embeds editor content and other "Document properties" fields in the same
242: * String that represents input for final transformation.
243: *
244: * @param foParams
245: * @return XML data format
246: */
247: public static String params2xml(HashMap foParams) {
248: String key = null;
249: String value = null;
250: String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> "
251: + "<root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\"> ";
252:
253: if (foParams != null) {
254: Iterator entries = foParams.entrySet().iterator();
255: while (entries.hasNext()) {
256: Map.Entry me = (Map.Entry) entries.next();
257: key = (String) me.getKey();
258: value = (String) me.getValue();
259: content += "<item name='" + key + "'>" + value
260: + "</item>";
261:
262: }
263: }
264:
265: content += "</root>";
266:
267: return content;
268: }
269:
270: /**
271: * Method generate PDF file specialized (XSLFast) XSL-FO template and FOP utility
272: *
273: * @param cont
274: * @param userAgentProps
275: * @param templatePath
276: * @return PDF file content
277: */
278: public static byte[] xml2pdf(byte[] cont, HashMap userAgentProps,
279: String templatePath) throws BaseException {
280: ByteArrayInputStream bais = null;
281: ByteArrayOutputStream baos = null;
282: try {
283: bais = new ByteArrayInputStream(cont);
284: baos = new ByteArrayOutputStream();
285:
286: String fopRender = MimeConstants.MIME_PDF;
287:
288: FopFactory fopFactory = TransformUtility.getFopFactory();
289: String fopBase = TransformUtility.getFopBase();
290:
291: FOUserAgent userAgent = fopFactory.newFOUserAgent();
292: userAgent.setBaseURL("file:///" + fopBase + "/");
293:
294: userAgent.setRendererOverride(null);
295: userAgent.setAuthor((String) userAgentProps.get("author"));
296: userAgent
297: .setCreationDate((Date) userAgentProps.get("date"));
298: userAgent
299: .setCreator((String) userAgentProps.get("creator"));
300: userAgent.setProducer((String) userAgentProps
301: .get("producer"));
302: userAgent.setTitle((String) userAgentProps.get("title"));
303: userAgent.setKeywords((String) userAgentProps
304: .get("keywords"));
305: userAgent.setTargetResolution(((Integer) userAgentProps
306: .get("resolution")).intValue());
307:
308: userAgent
309: .getRendererOptions()
310: .put(
311: "encryption-params",
312: new PDFEncryptionParams(
313: (String) userAgentProps
314: .get(EnhydraDMConstants.PDF_PARAM_PREFIX
315: + EnhydraDMConstants.PDF_PARAM_USERPASSWORD),
316: (String) userAgentProps
317: .get(EnhydraDMConstants.PDF_PARAM_PREFIX
318: + EnhydraDMConstants.PDF_PARAM_OWNERPASSWORD),
319: ((Boolean) userAgentProps
320: .get(EnhydraDMConstants.PDF_PARAM_PREFIX
321: + EnhydraDMConstants.PDF_PARAM_ALLOWPRINT))
322: .booleanValue(),
323: ((Boolean) userAgentProps
324: .get(EnhydraDMConstants.PDF_PARAM_PREFIX
325: + EnhydraDMConstants.PDF_PARAM_ALLOWCOPYCONTENT))
326: .booleanValue(),
327: ((Boolean) userAgentProps
328: .get(EnhydraDMConstants.PDF_PARAM_PREFIX
329: + EnhydraDMConstants.PDF_PARAM_ALLOWEDITANNOTATION))
330: .booleanValue(),
331: ((Boolean) userAgentProps
332: .get(EnhydraDMConstants.PDF_PARAM_PREFIX
333: + EnhydraDMConstants.PDF_PARAM_ALLOWEDITANNOTATION))
334: .booleanValue()));
335:
336: Fop fop = fopFactory.newFop(fopRender, userAgent, baos);
337:
338: InputStream in = new FileInputStream(templatePath);
339: Transformer foTransformer = transformerFactory
340: .newTransformer(new StreamSource(in));
341:
342: Source src = new StreamSource(bais);
343: Result res = new SAXResult(fop.getDefaultHandler());
344: foTransformer.transform(src, res);
345: cont = baos.toByteArray();
346: } catch (Exception ex) {
347: throw new BaseException(ex);
348: } finally {
349: if (bais != null)
350: try {
351: bais.close();
352: } catch (IOException e) {
353: e.printStackTrace();
354: }
355: if (baos != null)
356: try {
357: baos.close();
358: } catch (IOException e) {
359: e.printStackTrace();
360: }
361: }
362: return cont;
363: }
364:
365: }
|