001: package de.webman.template.jsp;
002:
003: import java.util.Enumeration;
004: import java.io.*;
005: import java.util.Properties;
006: import javax.servlet.*;
007: import javax.servlet.http.*;
008: import javax.xml.parsers.DocumentBuilder;
009: import javax.xml.parsers.DocumentBuilderFactory;
010: import com.teamkonzept.lib.*;
011: import com.teamkonzept.web.TKEvent;
012: import com.teamkonzept.lib.templates.*;
013: import org.apache.jasper.*;
014: import org.w3c.dom.Document;
015: import org.w3c.dom.Element;
016: import org.apache.log4j.Category;
017: import org.apache.log4j.Priority;
018: import javax.servlet.jsp.*;
019: import com.teamkonzept.webman.ProcessStarter;
020:
021: /**
022: * Implementierung der JSP-Templates.
023: *
024: * @author $Author: uli $
025: * @version $Revision: 1.19 $
026: */
027: public class JSPTemplate implements TemplateBasic, TemplateTypes
028:
029: {
030:
031: /** JSP Factory */
032: private static final WebManJspFactory JSP_FACTORY = new WebManJspFactory();
033:
034: /** Postfix um die erzeugten Klassen möglichst eindeutig zu machen */
035: private static final String POSTFIX = "_webmanTemplate";
036:
037: private DOMTemplateData data;
038:
039: /** Log4J Category */
040: private static Category cat = Category
041: .getInstance(JSPTemplate.class);
042:
043: /** Name des Templates */
044: private String name;
045:
046: /** letzte Modifizierung des Templates */
047: private long lastModified;
048:
049: /** gecached Template */
050: private HttpJspPage jspPage;
051:
052: /** Directory, in dem die .java und .class Dateien liegen */
053: private static final String COMPILE_DIR = "compiled";
054:
055: /** erzeugter Text */
056: private String text;
057:
058: /** Basisdirectory */
059: private String rootDir;
060:
061: /** handelt es sich um ein Template von Webman selber (Oberfläche) ? */
062: private boolean editor;
063:
064: /** der Request von Webman, um alle Umgebungsvariablen zu haben */
065: private HttpServletRequest originalRequest;
066:
067: /** aktueller Request wird gehalten */
068: private WebManRequest request;
069:
070: /**
071: * Creates a new JSP template.
072: *
073: * @param _docRoot the document root.
074: * @param _name the template source name.
075: * @param _editor the template editing mode.
076: * @throws TKTemplateSyntaxException if the specified template source is errornous.
077: */
078: public JSPTemplate(String _docRoot, String _name, boolean _editor)
079: throws TKTemplateSyntaxException {
080: try {
081: rootDir = _docRoot;
082: name = _name;
083: editor = _editor;
084: data = new DOMTemplateData();
085: } catch (Exception e) {
086: cat.error("JSPTemplate:constructor ", e);
087: }
088: init();
089: }
090:
091: public void setOriginalRequest(HttpServletRequest request) {
092: originalRequest = request;
093: }
094:
095: public String getType() {
096: return JSP_TEMPLATE;
097: }
098:
099: public HttpServletRequest getRequest() {
100: return request;
101: }
102:
103: public DOMTemplateData getDOMData() {
104: return data;
105: }
106:
107: protected void resetData() {
108: try {
109: data = new DOMTemplateData();
110: originalRequest = null;
111: } catch (Exception e) {
112: cat.error("Unable to reset Data", e);
113: }
114: }
115:
116: /**
117: kompiliert die Klasse vor
118: */
119: void init() throws TKTemplateSyntaxException {
120: try {
121: // einmal compilieren
122: String[] args = new String[8];
123: args[0] = "-uriroot";
124: if (editor)
125: args[1] = rootDir
126: + TemplateUtils.getWebmanTemplateDirectory()
127: + File.separator;
128: else
129: args[1] = rootDir
130: + TemplateUtils.getGenerationDirectory();
131:
132: /** Logging Category anhand der Log4J Prio bestimmen
133: umstellen, sobald Tomcat Log4J benutzt
134: */
135: Priority prio = cat.getPriority();
136: if (prio == null)
137: args[2] = "-v0";
138: else if (prio.equals(Priority.ERROR))
139: args[2] = "-v2";
140: else if (prio.equals(Priority.WARN))
141: args[2] = "-v4";
142: else if (prio.equals(Priority.INFO))
143: args[2] = "-v6";
144: else
145: args[2] = "-v9";
146: //args[2] = "-v2";
147: args[3] = "-d";
148: args[4] = rootDir + COMPILE_DIR; // Ausgabedirectory
149: args[5] = "-c";
150: String className = name.substring(0, name.indexOf("."))
151: + POSTFIX;
152: args[6] = className; // Klassenname
153: String fileName = "";
154: if (editor)
155: fileName = rootDir
156: + TemplateUtils.getWebmanTemplateDirectory()
157: + File.separator + name;
158: else
159: fileName = rootDir
160: + TemplateUtils.getGenerationDirectory() + name;
161: args[7] = fileName;
162: String pathToClass = rootDir + COMPILE_DIR + File.separator
163: + className + ".class";
164:
165: // Datum der Klasse vor dem Compilieren
166: long preCompiled = new File(pathToClass).lastModified();
167: File f = new File(fileName);
168: lastModified = f.lastModified();
169: /*for (int i = 0; i < 8; i++)
170: System.out.print(args[i] + " ");*/
171: // Classpath ergaenzen
172: Properties props = System.getProperties();
173: String path = props.getProperty("java.class.path");
174: if (path == null)
175: path = "";
176: String append = ProcessStarter.getWMClasspath(rootDir);
177: props.setProperty("java.class.path", path + ";" + append);
178: System.setProperties(props);
179:
180: ByteArrayOutputStream bout = new ByteArrayOutputStream();
181: PrintStream ps = new PrintStream(bout);
182:
183: JspC jspc = new JspC(args, ps);
184: jspc.parseFiles(ps);
185: ps.flush();
186: // Datum der Klasse nach dem Compilieren
187: long postCompiled = new File(pathToClass).lastModified();
188: if (!(postCompiled > preCompiled)) // ooops, hat nicht geklappt !
189: throw new TKTemplateSyntaxException(
190: "Unable to compile !" + bout.toString());
191: } catch (TKTemplateSyntaxException e) {
192: throw e;
193: } catch (Throwable t) {
194: cat.error("JSPTemplate:init ", t);
195: }
196: }
197:
198: /**
199: setzt Daten in die Root
200: */
201: public void set(TKHashtable aSubst) {
202: data.set(aSubst);
203: }
204:
205: public void set(String key, Object val) {
206: data.set(key, val);
207: }
208:
209: /**
210: initialisiert den Request
211: */
212: public void initRequest() {
213: if (jspPage == null) {
214: try {
215: initJspPage();
216: } catch (ServletException e) {
217: cat.error("initRequest: " + e.getMessage(), e);
218: }
219: }
220: request = new WebManRequest(jspPage.getServletConfig()
221: .getServletContext());
222: }
223:
224: private Class loadClass() {
225: try {
226: JSPClassLoader loader = new JSPClassLoader(rootDir
227: + File.separator + COMPILE_DIR, getClass()
228: .getClassLoader());
229: Class c = loader.loadClass(name.substring(0, name
230: .indexOf("."))
231: + POSTFIX);
232: return c;
233: } catch (ClassNotFoundException e) {
234: cat.error("JSPTemplate:loadClass", e);
235: return null;
236: }
237: }
238:
239: /**
240: checkt, ob das jsp neu compiliert werden muß und macht es auch falls noetig
241: */
242: private boolean isOutdated() throws TKTemplateSyntaxException {
243: String fileName = "";
244: if (editor)
245: fileName = rootDir
246: + TemplateUtils.getWebmanTemplateDirectory()
247: + File.separator + name;
248: else
249: fileName = rootDir + TemplateUtils.getGenerationDirectory()
250: + name;
251: File f = new File(fileName);
252: long l = f.lastModified();
253: // System.out.println("In check : " + l);
254: if (l > lastModified) {
255: cat.debug("Reload Template " + name);
256: init();
257: jspPage = null;
258: return true;
259: }
260: return false;
261: }
262:
263: public synchronized void sendData(Element node, PrintWriter out) //throws TKException
264: {
265: try {
266: if (jspPage == null || isOutdated()) {
267: initJspPage();
268: }
269: if (request == null)
270: request = new WebManRequest(jspPage.getServletConfig()
271: .getServletContext()); // ich verlasse mich auf initRequest !!!!
272: request.setData(node);
273: request.setOriginalRequest(originalRequest);
274: WebManResponse response = new WebManResponse(out);
275: jspPage._jspService(request, response);
276:
277: out.flush();
278: } catch (ServletException ee) {
279: Throwable t = ee.getRootCause();
280: cat.error("JSPTemplate.sendData: " + t.getMessage(), t);
281: } catch (Exception e) {
282: cat.error("JSPTemplate.sendData: " + e.getMessage(), e);
283: } finally {
284: resetData();
285: }
286: }
287:
288: private void initJspPage() throws ServletException {
289: try {
290: Class cl = loadClass();
291: if (cl == null) {
292: cat.error("Class not found !!!! " + name); // Exception !
293: return;
294: }
295: Object obj = cl.newInstance();
296: jspPage = (HttpJspPage) obj;
297: javax.servlet.jsp.JspFactory.setDefaultFactory(JSP_FACTORY);
298: // Page initialisieren ???
299: WebManServletConfig config = new WebManServletConfig();
300: TKEvent evt = TKEvent.getEventForThread();
301: if (evt != null) {
302: ((WebManServletContext) config.getServletContext())
303: .setDocRoot(evt.getHttpInterface()
304: .getDocumentRoot());
305: }
306: jspPage.init(config);
307: jspPage.jspInit();
308: } catch (IllegalAccessException e) {
309: cat.error("JSPTemplate.initJspPage: " + e.getMessage(), e);
310: } catch (InstantiationException ee) {
311: cat
312: .error("JSPTemplate.initJspPage: "
313: + ee.getMessage(), ee);
314: }
315: }
316:
317: /**
318: * Das substituierte Template wird als String zurueckgegeben.
319: * Hierfuer muss die Instanzvariable "text" mit dem Text eines Templates
320: * zuvor gefuellt werden. Dies geschieht, indem die Tags im Template zuerst
321: * substituiert werden.
322: * @return einen String des substituierten Templates
323: */
324: public String getText() {
325: return text;
326: }
327:
328: /**
329: * Das Template wird in den PrintStream geschrieben.
330: * Hierfuer muss die Instanzvariable "text" mit dem Text eines Templates
331: * zuvor gefuellt werden. Dies geschieht, indem die Tags im Template zuerst
332: * substituiert werden.
333: *
334: */
335: public void printTemplate(PrintStream out) {
336: sendData(data.getRoot(), new PrintWriter(out));
337: }
338:
339: /**
340: * Das Template wird in den Writer geschrieben.
341: * Hierfuer muss die Instanzvariable "text" mit dem Text eines Templates
342: * zuvor gefuellt werden. Dies geschieht, indem die Tags im Template zuerst
343: * substituiert werden.
344: *
345: */
346: public void printTemplate(Writer writer) throws IOException {
347: sendData(data.getRoot(), new PrintWriter(writer));
348: }
349:
350: /**
351: * Das Template wird auf stdout geschrieben.
352: * Hierfuer muss die Instanzvariable "text" mit dem Text eines Templates
353: * zuvor gefuellt werden. Dies geschieht, indem die Tags im Template zuerst
354: * substituiert werden.
355: *
356: */
357: public void printTemplate() {
358: throw new RuntimeException("Methode not implemented !");
359: }
360:
361: /**
362: * Das substituierte Template wird in ein File geschrieben werden.
363: * Hierfuer muss die Instanzvariable "text" mit dem Text eines Templates
364: * zuvor gefuellt werden. Dies geschieht, indem die Tags im Template zuerst
365: * substituiert werden.
366: *
367: * Bsp. Reihenfolge der Aufrufe:
368: * TKTemplateObject.doTagSubstitution();
369: * TKTemplateObject.doCleanup();
370: * TKTemplateObject.printTemplate(String file)
371: *
372: * @param String file, der Filename des zu speichernden templates
373: */
374: public void printTemplate(String file) throws IOException {
375: FileWriter w = new FileWriter(file);
376: sendData(data.getRoot(), new PrintWriter(w));
377: }
378:
379: /**
380: * Durch den Aufruf der Methode doMainSubstitution enthaelt die
381: * Instanzvariable "text" das Template mit den substituierten TKTags.
382: * Die nicht vollstaendigen Pfade werden ersetzt.
383: *
384: * Die URL-Base ist gestzt, wenn Images ausserhalb des CGI-Verzeichnisses
385: * abgelegt sind. Fuer diese Bilder muss der vollstaendige Pfad im
386: * Template gesetzt werden.
387: */
388: public void doTagSubstitution() throws TKTemplateSyntaxException {
389: doMainSubstitutions();
390: }
391:
392: /**
393: * Die Instanzvariable "text" enthaelt das Template mit den
394: * substituierten TKTags
395: * saemtliche Funktionalitaet in die print Methoden verschoben !
396: */
397: public void doMainSubstitutions() throws TKTemplateSyntaxException {
398: /*
399: StringWriter w = new StringWriter();
400: sendData(root, new PrintWriter(w));
401: text = w.toString();*/
402: }
403:
404: }
|