001: /*
002: * hgcommons 7
003: * Hammurapi Group Common Library
004: * Copyright (C) 2003 Hammurapi Group
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
021: * e-Mail: support@hammurapi.biz
022: */
023:
024: package biz.hammurapi.render.dom;
025:
026: import java.io.IOException;
027: import java.io.InputStream;
028: import java.io.OutputStream;
029: import java.io.UnsupportedEncodingException;
030: import java.util.HashMap;
031: import java.util.Iterator;
032: import java.util.Map;
033:
034: import javax.xml.parsers.DocumentBuilder;
035: import javax.xml.parsers.DocumentBuilderFactory;
036: import javax.xml.parsers.ParserConfigurationException;
037: import javax.xml.transform.Templates;
038: import javax.xml.transform.Transformer;
039: import javax.xml.transform.TransformerConfigurationException;
040: import javax.xml.transform.TransformerException;
041: import javax.xml.transform.TransformerFactory;
042: import javax.xml.transform.dom.DOMSource;
043: import javax.xml.transform.stream.StreamResult;
044: import javax.xml.transform.stream.StreamSource;
045:
046: import org.w3c.dom.Element;
047:
048: import biz.hammurapi.config.Parameterizable;
049: import biz.hammurapi.render.RenderRequest;
050: import biz.hammurapi.render.RenderingException;
051:
052: /**
053: *
054: * @author Pavel Vlasov
055: * @version $Revision: 1.5 $
056: */
057: public abstract class AbstractRenderer implements DomRenderer,
058: Parameterizable {
059: private static class StyleKey {
060: Class clazz;
061: String profile;
062:
063: public StyleKey(Class clazz, String profile) {
064: super ();
065: this .clazz = clazz;
066: this .profile = profile;
067: }
068:
069: public boolean equals(Object obj) {
070: if (obj == this ) {
071: return true;
072: } else if (obj instanceof StyleKey) {
073: StyleKey otherKey = (StyleKey) obj;
074: if (clazz.equals(otherKey.clazz)) {
075: if (profile == null) {
076: return otherKey.profile == null;
077: } else if (otherKey.profile == null) {
078: return false;
079: } else {
080: return profile.equals(otherKey.profile);
081: }
082: }
083: return false;
084: } else {
085: return super .equals(obj);
086: }
087: }
088:
089: public int hashCode() {
090: int ret = clazz.hashCode();
091: if (profile != null) {
092: ret ^= profile.hashCode();
093: }
094: return ret;
095: }
096: }
097:
098: private static Map styleMap = new HashMap();
099:
100: protected RenderRequest request;
101: protected String profile;
102: public static final String PROFILE_SEPARATOR = "!";
103:
104: protected AbstractRenderer(RenderRequest request) {
105: this .request = request;
106: }
107:
108: protected AbstractRenderer(RenderRequest request, String profile) {
109: this .request = request;
110: this .profile = profile;
111: }
112:
113: /**
114: * Searches for class name first, then for all interfaces and then for
115: * superclass.
116: * @param clazz
117: * @return
118: * @throws TransformerConfigurationException
119: */
120: public synchronized Transformer getEmbeddedStyle(Class clazz)
121: throws TransformerConfigurationException {
122: StyleKey key = new StyleKey(clazz, profile);
123: Templates templates = (Templates) styleMap.get(key);
124: if (templates == null) {
125: String transletClass = clazz.getName()
126: + StyleCompiler.POSTFIX;
127: if (profile != null) {
128: transletClass += StyleCompiler.TRANSLET_PROFILE_SEPARATOR
129: + profile;
130: }
131:
132: // try {
133: // getClass().getClassLoader().loadClass(transletClass);
134: // int idx=transletClass.lastIndexOf('.');
135: // TransformerFactory tf=new TransformerFactoryImpl();
136: // tf.setAttribute("use-classpath", Boolean.TRUE);
137: // if (idx!=-1) {
138: // tf.setAttribute("package-name", transletClass.substring(0, idx));
139: // }
140: // templates=tf.newTemplates(new StreamSource(idx==-1 ? transletClass : transletClass.substring(idx+1)));
141: // styleMap.put(key, templates);
142: // return templates.newTransformer();
143: // } catch (ClassNotFoundException e) {
144: String resourceName = clazz.getName().replace('.', '/')
145: + (profile == null ? "" : PROFILE_SEPARATOR
146: + profile) + ".xsl";
147: InputStream rets = getClass().getClassLoader()
148: .getResourceAsStream(resourceName);
149: if (rets != null) {
150: TransformerFactory tf = TransformerFactory
151: .newInstance();
152: templates = tf.newTemplates(new StreamSource(rets));
153: styleMap.put(key, templates);
154: return templates.newTransformer();
155: }
156: // }
157:
158: Class[] interfaces = clazz.getInterfaces();
159: for (int i = 0; i < interfaces.length; i++) {
160: Transformer rett = getEmbeddedStyle(interfaces[i]);
161: if (rett != null) {
162: return rett;
163: }
164: }
165:
166: if (clazz.getSuperclass() == null) {
167: styleMap.put(key, null);
168: return null;
169: }
170: return getEmbeddedStyle(clazz.getSuperclass());
171: }
172: return templates.newTransformer();
173: }
174:
175: public RenderRequest render(OutputStream out)
176: throws RenderingException {
177: return render(null, out);
178: }
179:
180: public RenderRequest render(InputStream style, OutputStream out)
181: throws RenderingException {
182: try {
183: Transformer transformer = null;
184:
185: if (style == null && useEmbeddedStyle) {
186: transformer = getEmbeddedStyle(request.getRenderee()
187: .getClass());
188: }
189:
190: if (transformer == null) {
191: TransformerFactory tFactory = TransformerFactory
192: .newInstance();
193: transformer = style == null ? tFactory.newTransformer()
194: : tFactory.newTransformer(new StreamSource(
195: style));
196: }
197:
198: Iterator pit = params.entrySet().iterator();
199: while (pit.hasNext()) {
200: Map.Entry entry = (Map.Entry) pit.next();
201: transformer.setParameter((String) entry.getKey(), entry
202: .getValue());
203: }
204:
205: DocumentBuilder builder = null;
206:
207: if (request.getDocument() == null) {
208: DocumentBuilderFactory factory = DocumentBuilderFactory
209: .newInstance();
210: builder = factory.newDocumentBuilder();
211: request.setDocument(builder.newDocument());
212: request.getDocument().appendChild(
213: render(request.getDocument()));
214: }
215:
216: DOMSource domSource = new DOMSource(request.getDocument());
217: transformer.transform(domSource, new StreamResult(out));
218: out.close();
219: return request;
220: } catch (TransformerConfigurationException e) {
221: throw new RenderingException(e.toString(), e);
222: } catch (ParserConfigurationException e) {
223: throw new RenderingException(e.toString(), e);
224: } catch (TransformerException e) {
225: throw new RenderingException(e.toString(), e);
226: } catch (UnsupportedEncodingException e) {
227: throw new RenderingException(e.toString(), e);
228: } catch (IOException e) {
229: throw new RenderingException(e.toString(), e);
230: }
231: }
232:
233: protected boolean useEmbeddedStyle = true;
234:
235: public void setEmbeddedStyle(boolean useEmbeddedStyle) {
236: this .useEmbeddedStyle = useEmbeddedStyle;
237: }
238:
239: protected Map params = new HashMap();
240:
241: public boolean setParameter(String name, Object value) {
242: params.put(name, value);
243: return true;
244: }
245:
246: /**
247: * Creates and add element with text if text!=null && name!=null
248: * @param name
249: * @param text
250: * @param owner
251: * @return
252: */
253: public static void appendTextElement(String name, String text,
254: Element owner) {
255: if (name != null && text != null) {
256: Element e = owner.getOwnerDocument().createElement(name);
257: owner.appendChild(e);
258: e
259: .appendChild(owner.getOwnerDocument()
260: .createTextNode(text));
261: }
262: }
263: }
|