001: /*
002: * Copyright (C) 2004 TiongHiang Lee
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * Email: thlee@onemindsoft.org
019: */
020:
021: package org.onemind.swingweb.templaterender;
022:
023: import java.awt.Component;
024: import java.awt.Graphics2D;
025: import java.awt.image.BufferedImage;
026: import java.io.*;
027: import java.util.HashMap;
028: import java.util.Map;
029: import org.onemind.awtbridge.peer.BridgePeer;
030: import org.onemind.awtbridge.render.RenderingException;
031: import org.onemind.commons.java.util.ObjectUtils;
032: import org.onemind.commons.java.util.StringUtils;
033: import org.onemind.commons.java.xml.digest.SaxDigesterHandler;
034: import org.onemind.jxp.config.JxpConfigDigester;
035: import org.onemind.swingweb.Constants;
036: import org.onemind.swingweb.SwingWebContext;
037: import org.xml.sax.Attributes;
038: import org.xml.sax.SAXException;
039:
040: /**
041: * Jxp template engine
042: * @author TiongHiang Lee (thlee@onemindsoft.org)
043: */
044: public class JxpTemplateEngine extends JxpConfigDigester implements
045: TemplateEngine {
046:
047: /** The template resolver * */
048: private JxpTemplateResolver _templateResolver;
049:
050: /** debug template **/
051: private boolean _debugTemplate = false;
052:
053: /** resume the rendering on exception **/
054: private boolean _resumeOnException = true;
055:
056: /** whether to dump exception as comment **/
057: private boolean _dumpExceptionAsComment = true;
058:
059: /** the template ext **/
060: private String _templateExt;
061:
062: /** the image template **/
063: private String _imageTemplateLoc;
064:
065: /**
066: * Constructor
067: */
068: public JxpTemplateEngine() {
069: super ();
070: }
071:
072: /**
073: * {@inheritDoc}
074: */
075: public void renderTemplate(TemplateRenderContext context,
076: BridgePeer peer, Writer writer) throws RenderingException {
077: Object comObject = peer.getComponentObject();
078: try {
079: String templateLoc = (String) context.getContext()
080: .getComponentProperty(comObject,
081: KEY_COMPONENT_TEMPLATE);
082: if (templateLoc == null) {
083: Object renderAsImage = peer
084: .getComponentProperty(Constants.SW_RENDER_AS_IMAGE);
085: if (renderAsImage != null
086: && comObject instanceof Component
087: && !StringUtils
088: .isNullOrEmpty(_imageTemplateLoc)) {
089: templateLoc = _imageTemplateLoc;
090: } else {
091: templateLoc = (String) _templateResolver
092: .resolve(comObject.getClass());
093: }
094: }
095: if (templateLoc == null) {
096: throw new RenderingException(
097: "Cannot resolve rendering template for "
098: + comObject);
099: }
100: if (_debugTemplate) {
101: writer.write("\n<!-- start " + templateLoc + " for "
102: + comObject + "-->\n");
103: }
104: getProcessor().process(templateLoc, writer,
105: getEnvironment(context, peer));
106: if (_debugTemplate) {
107: writer.write("\n<!-- end " + templateLoc + " for "
108: + comObject + "-->\n");
109: }
110: writer.flush();
111: } catch (Exception e) {
112: if (!_resumeOnException) {
113: if (e instanceof RenderingException) {
114: throw (RenderingException) e;
115: } else if (e.getCause() instanceof RenderingException) {
116: throw (RenderingException) e.getCause();
117: } else {
118: throw new RenderingException("Error rendering "
119: + comObject, e);
120: }
121: } else {
122: try {
123: writer.write("<font color=\"#ff0000\">"
124: + e.getMessage() + "</font>");
125: if (_dumpExceptionAsComment) {
126: writer.write("\n<!-- ");
127: PrintWriter pwriter = new PrintWriter(writer);
128: e.printStackTrace(pwriter);
129: pwriter.flush();
130: }
131: } catch (IOException ioe) {
132: throw new RuntimeException(e);
133: }
134: }
135: }
136: }
137:
138: /**
139: * @param context the context
140: * @param peer the component peer
141: * @return the map as environment the jxp
142: */
143: private Map getEnvironment(TemplateRenderContext context,
144: BridgePeer peer) {
145: Map map = new HashMap();
146: map.put("context", context.getContext());
147: map.put("session", context.getContext().getSession());
148: map.put("rendercontext", context);
149: map.put("com", peer.getComponentObject());
150: map.put("_com", peer);
151: map.put("peer", peer);
152: map.put("comOpts", context.getContext().getSession().getValue(
153: "COMPONENT_OPTIONS"));
154: map.put("renderdelegate", peer.getRenderDelegate());
155: return map;
156: }
157:
158: /**
159: * {@inheritDoc}
160: */
161: public void startDigest(SaxDigesterHandler handler, Attributes attrs)
162: throws SAXException {
163: _debugTemplate = ObjectUtils.toBool(attrs
164: .getValue("debugTemplate"), false);
165: _resumeOnException = ObjectUtils.toBool(attrs
166: .getValue("resumeOnException"), true);
167: _dumpExceptionAsComment = ObjectUtils.toBool(attrs
168: .getValue("dumpExceptionAsComment"), true);
169: _templateExt = attrs.getValue("templateExt");
170: if (_templateExt == null) {
171: _templateExt = ".template";
172: }
173: _imageTemplateLoc = attrs.getValue("imageTemplate");
174: super .startDigest(handler, attrs);
175: }
176:
177: /**
178: * {@inheritDoc}
179: */
180: public void endDigest(SaxDigesterHandler handler)
181: throws SAXException {
182: super .endDigest(handler);
183: _templateResolver = new JxpTemplateResolver(getProcessor()
184: .getContext().getPageSource(), _templateExt);
185: }
186:
187: /**
188: * {@inheritDoc}
189: */
190: public void getRuntimeInfo(BridgePeer peer, Map env) {
191: env.put("jxp template", _templateResolver.resolve(peer
192: .getComponentObject().getClass()));
193: }
194: }
|