KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opencms > legacy > CmsXmlTemplateLoader


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src-modules/com/opencms/legacy/CmsXmlTemplateLoader.java,v $
3  * Date : $Date: 2006/09/15 10:38:14 $
4  * Version: $Revision: 1.16 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (C) 2002 Alkacon Software (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package com.opencms.legacy;
33
34 import org.opencms.file.CmsFile;
35 import org.opencms.file.CmsObject;
36 import org.opencms.file.CmsPropertyDefinition;
37 import org.opencms.file.CmsRequestContext;
38 import org.opencms.file.CmsResource;
39 import org.opencms.flex.CmsFlexController;
40 import org.opencms.importexport.CmsCompatibleCheck;
41 import org.opencms.jsp.CmsJspTagInclude;
42 import org.opencms.loader.I_CmsLoaderIncludeExtension;
43 import org.opencms.loader.I_CmsResourceLoader;
44 import org.opencms.main.CmsEvent;
45 import org.opencms.main.CmsException;
46 import org.opencms.main.CmsLog;
47 import org.opencms.main.I_CmsEventListener;
48 import org.opencms.main.OpenCms;
49 import org.opencms.staticexport.CmsLinkManager;
50 import org.opencms.workplace.CmsWorkplace;
51 import org.opencms.workplace.editors.CmsDefaultPageEditor;
52
53 import com.opencms.core.*;
54 import com.opencms.template.*;
55 import com.opencms.template.cache.*;
56
57 import java.io.IOException JavaDoc;
58 import java.io.OutputStream JavaDoc;
59 import java.util.Collections JavaDoc;
60 import java.util.Enumeration JavaDoc;
61 import java.util.Hashtable JavaDoc;
62 import java.util.Locale JavaDoc;
63 import java.util.Map JavaDoc;
64 import java.util.TreeMap JavaDoc;
65
66 import javax.servlet.ServletRequest JavaDoc;
67 import javax.servlet.ServletResponse JavaDoc;
68 import javax.servlet.http.HttpServletRequest JavaDoc;
69 import javax.servlet.http.HttpServletResponse JavaDoc;
70 import javax.servlet.http.HttpSession JavaDoc;
71
72 import org.apache.commons.collections.ExtendedProperties;
73
74 /**
75  * Implementation of the {@link I_CmsResourceLoader} for XMLTemplates.<p>
76  *
77  * Parameters supported by this loader:<dl>
78  *
79  * <dt>elementcache.enabled</dt>
80  * <dd>(Optional) Controls if the legacy XMLTemplate element cache is disabled
81  * (the default) or enabled. Enable the element cache only to support old
82  * XMLTemplate based code that depend on specific element cache behaviour.</dd>
83  *
84  * <dt>elementcache.uri</dt>
85  * <dd>(Optional) Element cache URI size. The default is 10000.</dd>
86  *
87  * <dt>elementcache.elements</dt>
88  * <dd>(Optional) Element cache element size. The default is 50000.</dd>
89  *
90  * <dt>elementcache.variants</dt>
91  * <dd>(Optional) Element cache variant size. The default is 100.</dd></dl>
92  *
93  * @author Alexander Kandzior (a.kandzior@alkacon.com)
94  *
95  * @version $Revision: 1.16 $
96  *
97  * @deprecated Will not be supported past the OpenCms 6 release.
98  */

99 public class CmsXmlTemplateLoader implements I_CmsResourceLoader, I_CmsLoaderIncludeExtension, I_CmsEventListener {
100
101     /** URI of the bodyloader XML file in the OpenCms VFS. */
102     public static final String JavaDoc C_BODYLOADER_URI = CmsWorkplace.VFS_PATH_SYSTEM + "shared/bodyloader.html";
103
104     /** Magic element replace name. */
105     public static final String JavaDoc C_ELEMENT_REPLACE = "_CMS_ELEMENTREPLACE";
106
107     /** The id of this loader. */
108     public static final int C_RESOURCE_LOADER_ID = 3;
109
110     /** Flag for debugging output. Set to 9 for maximum verbosity. */
111     private static final int DEBUG = 0;
112
113     /** The element cache used for the online project. */
114     private static CmsElementCache m_elementCache;
115
116     /** The template cache that holds all cached templates. */
117     private static I_CmsTemplateCache m_templateCache;
118
119     /** The variant dependencies for the element cache. */
120     private static Hashtable JavaDoc m_variantDeps;
121
122     /** The resource loader configuration. */
123     private Map JavaDoc m_configuration;
124
125     /**
126      * The constructor of the class is empty and does nothing.
127      */

128     public CmsXmlTemplateLoader() {
129
130         OpenCms.addCmsEventListener(this);
131         m_templateCache = new CmsTemplateCache();
132         m_configuration = new TreeMap JavaDoc();
133     }
134
135     /**
136      * Returns the element cache,
137      * or null if the element cache is not initialized.<p>
138      *
139      * @return the element cache that belongs to the given cms context
140      */

141     public static final CmsElementCache getElementCache() {
142
143         return m_elementCache;
144     }
145
146     /**
147      * Returns the variant dependencies of the online element cache.<p>
148      *
149      * @return the variant dependencies of the online element cache
150      */

151     public static final CmsElementCache getOnlineElementCache() {
152
153         return m_elementCache;
154     }
155
156     /**
157      * Provides access to the current request through a CmsRequestContext,
158      * required for legacy backward compatibility.<p>
159      *
160      * @param context the current request context
161      * @return the request, of null if no request is available
162      */

163     public static I_CmsRequest getRequest(CmsRequestContext context) {
164
165         return (I_CmsRequest)context.getAttribute(I_CmsRequest.C_CMS_REQUEST);
166     }
167
168     /**
169      * Provides access to the current response through a CmsRequestContext,
170      * required for legacy backward compatibility.<p>
171      *
172      * @param context the current request context
173      * @return the response, of null if no request is available
174      */

175     public static I_CmsResponse getResponse(CmsRequestContext context) {
176
177         return (I_CmsResponse)context.getAttribute(I_CmsResponse.C_CMS_RESPONSE);
178     }
179
180     /**
181      * Provides access to the current session through a CmsRequestContext,
182      * required for legacy backward compatibility.<p>
183      *
184      * @param context the current request context
185      * @param value if true, try to create a session if none exist, if false, do not create a session
186      * @return the response, of null if no request is available
187      */

188     public static I_CmsSession getSession(CmsRequestContext context, boolean value) {
189
190         I_CmsRequest req = (I_CmsRequest)context.getAttribute(I_CmsRequest.C_CMS_REQUEST);
191         HttpSession JavaDoc session = req.getOriginalRequest().getSession(value);
192         if (session != null) {
193             return new CmsSession(session);
194         } else {
195             return null;
196         }
197     }
198
199     /**
200      * Returns the hashtable with the variant dependencies used for the elementcache.<p>
201      *
202      * @return the hashtable with the variant dependencies used for the elementcache
203      */

204     public static final Hashtable JavaDoc getVariantDependencies() {
205
206         return m_variantDeps;
207     }
208
209     /**
210      * Initializes the current request with the legacy Cms request and response wrappers.<p>
211      *
212      * @param cms the current cms context
213      * @param req the request to wrap
214      * @param res the response to wrap
215      * @throws CmsException if something goes wrong
216      */

217     public static void initLegacyRequest(CmsObject cms, HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res)
218     throws CmsException {
219
220         if (cms.getRequestContext().getAttribute(I_CmsRequest.C_CMS_REQUEST) != null) {
221             return;
222         }
223         try {
224             CmsRequestHttpServlet cmsReq = new CmsRequestHttpServlet(req, cms.getRequestContext().getFileTranslator());
225             CmsResponseHttpServlet cmsRes = new CmsResponseHttpServlet(req, res);
226             cms.getRequestContext().setAttribute(I_CmsRequest.C_CMS_REQUEST, cmsReq);
227             cms.getRequestContext().setAttribute(I_CmsResponse.C_CMS_RESPONSE, cmsRes);
228         } catch (IOException JavaDoc e) {
229             throw new CmsLegacyException("Trouble setting up legacy request / response", e);
230         }
231     }
232
233     /**
234      * Returns true if the element cache is enabled.<p>
235      *
236      * @return true if the element cache is enabled
237      */

238     public static final boolean isElementCacheEnabled() {
239
240         return m_elementCache != null;
241     }
242
243     /**
244      * Compatibility method to ensure the legacy cache command line parameters
245      * are still supported.<p>
246      *
247      * @param clearFiles if true, A_CmsXmlContent cache is cleared
248      * @param clearTemplates if true, internal template cache is cleared
249      */

250     private static void clearLoaderCache(boolean clearFiles, boolean clearTemplates) {
251
252         if (clearFiles) {
253             A_CmsXmlContent.clearFileCache();
254         }
255         if (clearTemplates) {
256             m_templateCache.clearCache();
257         }
258     }
259
260     /**
261      * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#addConfigurationParameter(java.lang.String, java.lang.String)
262      */

263     public void addConfigurationParameter(String JavaDoc paramName, String JavaDoc paramValue) {
264
265         m_configuration.put(paramName, paramValue);
266     }
267
268     /**
269      * Implements the CmsEvent interface,
270      * the static export properties uses the events to clear
271      * the list of cached keys in case a project is published.<p>
272      *
273      * @param event CmsEvent that has occurred
274      */

275     public synchronized void cmsEvent(CmsEvent event) {
276
277         switch (event.getType()) {
278
279             case I_CmsEventListener.EVENT_FLEX_CACHE_CLEAR:
280                 clearLoaderCache(true, true);
281                 break;
282             case I_CmsEventListener.EVENT_CLEAR_ONLINE_CACHES:
283                 clearLoaderCache(true, true);
284                 break;
285             case I_CmsEventListener.EVENT_CLEAR_OFFLINE_CACHES:
286                 clearLoaderCache(true, true);
287                 break;
288             case I_CmsEventListener.EVENT_CLEAR_CACHES:
289                 clearLoaderCache(true, true);
290                 break;
291             default:
292         // no operation
293
}
294     }
295
296     /**
297      * Destroy this ResourceLoder, this is a NOOP so far.
298      */

299     public void destroy() {
300
301         // NOOP
302
}
303
304     /**
305      * @see org.opencms.loader.I_CmsResourceLoader#dump(org.opencms.file.CmsObject, org.opencms.file.CmsResource, java.lang.String, java.util.Locale, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
306      */

307     public byte[] dump(
308         CmsObject cms,
309         CmsResource file,
310         String JavaDoc element,
311         Locale JavaDoc locale,
312         HttpServletRequest JavaDoc req,
313         HttpServletResponse JavaDoc res) throws CmsException {
314
315         initLegacyRequest(cms, req, res);
316         String JavaDoc absolutePath = cms.getSitePath(file);
317         // this will work for the "default" template class com.opencms.template.CmsXmlTemplate only
318
CmsXmlTemplate template = new CmsXmlTemplate();
319         // get the appropriate content and convert it to bytes
320
return template.getContent(cms, absolutePath, element, null);
321     }
322
323     /**
324      * @see org.opencms.loader.I_CmsResourceLoader#export(org.opencms.file.CmsObject, org.opencms.file.CmsResource, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
325      */

326     public byte[] export(CmsObject cms, CmsResource resource, HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res)
327     throws IOException JavaDoc, CmsException {
328
329         CmsFile file = CmsFile.upgrade(resource, cms);
330         initLegacyRequest(cms, req, res);
331         CmsRequestHttpServlet cmsReq = new CmsRequestHttpServlet(req, cms.getRequestContext().getFileTranslator());
332         return generateOutput(cms, file, cmsReq);
333     }
334
335     /**
336      * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#getConfiguration()
337      */

338     public Map JavaDoc getConfiguration() {
339
340         // return the configuration in an immutable form
341
return Collections.unmodifiableMap(m_configuration);
342     }
343
344     /**
345      * @see org.opencms.loader.I_CmsResourceLoader#getLoaderId()
346      */

347     public int getLoaderId() {
348
349         return C_RESOURCE_LOADER_ID;
350     }
351
352     /**
353      * Return a String describing the ResourceLoader,
354      * which is <code>"The OpenCms default resource loader for XMLTemplates"</code>.<p>
355      *
356      * @return a describing String for the ResourceLoader
357      */

358     public String JavaDoc getResourceLoaderInfo() {
359
360         return "The OpenCms default resource loader for XMLTemplates";
361     }
362
363     /**
364      * @see org.opencms.loader.I_CmsLoaderIncludeExtension#includeExtension(java.lang.String, java.lang.String, boolean, java.util.Map, javax.servlet.ServletRequest, javax.servlet.ServletResponse)
365      */

366     public String JavaDoc includeExtension(
367         String JavaDoc target,
368         String JavaDoc element,
369         boolean editable,
370         Map JavaDoc parameterMap,
371         ServletRequest JavaDoc req,
372         ServletResponse JavaDoc res) throws CmsException {
373
374         // the Flex controller provides access to the interal OpenCms structures
375
CmsFlexController controller = CmsFlexController.getController(req);
376         // simple sanity check, controller should never be null here
377
if (controller == null) {
378             return target;
379         }
380         // special code to handle XmlTemplate based file includes
381
if (element != null) {
382             if (!("body".equals(element) || "(default)".equals(element))) {
383                 // add template selector for multiple body XML files
384
CmsJspTagInclude.addParameter(parameterMap, CmsXmlTemplate.C_FRAME_SELECTOR, element, true);
385             }
386         }
387         boolean isPageTarget;
388         try {
389             // check if the target does exist in the OpenCms VFS
390
CmsResource targetResource = controller.getCmsObject().readResource(target);
391             isPageTarget = ((CmsResourceTypePage.getStaticTypeId() == targetResource.getTypeId()));
392         } catch (CmsException e) {
393             controller.setThrowable(e, target);
394             throw new CmsLegacyException("File not found: " + target, e);
395         }
396         String JavaDoc bodyAttribute = (String JavaDoc)controller.getCmsObject().getRequestContext().getAttribute(
397             CmsDefaultPageEditor.XML_BODY_ELEMENT);
398         if (bodyAttribute == null) {
399             // no body attribute is set: this is NOT a sub-element in a XML mastertemplate
400
if (isPageTarget) {
401                 // add body file path to target
402
if (!target.startsWith(CmsCompatibleCheck.VFS_PATH_BODIES)) {
403                     target = CmsCompatibleCheck.VFS_PATH_BODIES + target.substring(1);
404                 }
405                 // save target as "element replace" parameter for body loader
406
CmsJspTagInclude.addParameter(
407                     parameterMap,
408                     CmsXmlTemplateLoader.C_ELEMENT_REPLACE,
409                     "body:" + target,
410                     true);
411                 target = C_BODYLOADER_URI;
412             }
413         } else {
414             // body attribute is set: this is a sub-element in a XML mastertemplate
415
if (target.equals(controller.getCmsObject().getRequestContext().getUri())) {
416                 // target can be ignored, set body attribute as "element replace" parameter
417
CmsJspTagInclude.addParameter(parameterMap, CmsXmlTemplateLoader.C_ELEMENT_REPLACE, "body:"
418                     + bodyAttribute, true);
419                 // redirect target to body loader
420
target = C_BODYLOADER_URI;
421             } else {
422                 if (isPageTarget) {
423                     // add body file path to target
424
if (isPageTarget && !target.startsWith(CmsCompatibleCheck.VFS_PATH_BODIES)) {
425                         target = CmsCompatibleCheck.VFS_PATH_BODIES + target.substring(1);
426                     }
427                     // save target as "element replace" parameter
428
CmsJspTagInclude.addParameter(parameterMap, CmsXmlTemplateLoader.C_ELEMENT_REPLACE, "body:"
429                         + target, true);
430                     target = C_BODYLOADER_URI;
431                 }
432             }
433         }
434
435         return target;
436     }
437
438     /**
439      * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#initConfiguration()
440      */

441     public void initConfiguration() {
442
443         ExtendedProperties config = new ExtendedProperties();
444         config.putAll(m_configuration);
445
446         // check if the element cache is enabled
447
boolean elementCacheEnabled = config.getBoolean("elementcache.enabled", false);
448         if (CmsLog.INIT.isInfoEnabled()) {
449             CmsLog.INIT.info(". Loader init : XMLTemplate element cache "
450                 + (elementCacheEnabled ? "enabled" : "disabled"));
451         }
452         if (elementCacheEnabled) {
453             try {
454                 m_elementCache = new CmsElementCache(config.getInteger("elementcache.uri", 10000), config.getInteger(
455                     "elementcache.elements",
456                     50000), config.getInteger("elementcache.variants", 100));
457             } catch (Exception JavaDoc e) {
458                 if (CmsLog.INIT.isWarnEnabled()) {
459                     CmsLog.INIT.warn(". Loader init : XMLTemplate element cache non-critical error "
460                         + e.toString());
461                 }
462             }
463             m_variantDeps = new Hashtable JavaDoc();
464             m_elementCache.getElementLocator().setExternDependencies(m_variantDeps);
465         } else {
466             m_elementCache = null;
467         }
468
469         if (CmsLog.INIT.isInfoEnabled()) {
470             CmsLog.INIT.info(". Loader init : " + this.getClass().getName() + " initialized");
471         }
472     }
473
474     /**
475      * @see org.opencms.loader.I_CmsResourceLoader#isStaticExportEnabled()
476      */

477     public boolean isStaticExportEnabled() {
478
479         return true;
480     }
481
482     /**
483      * @see org.opencms.loader.I_CmsResourceLoader#isStaticExportProcessable()
484      */

485     public boolean isStaticExportProcessable() {
486
487         return true;
488     }
489
490     /**
491      * @see org.opencms.loader.I_CmsResourceLoader#isUsableForTemplates()
492      */

493     public boolean isUsableForTemplates() {
494
495         return true;
496     }
497
498     /**
499      * @see org.opencms.loader.I_CmsResourceLoader#isUsingUriWhenLoadingTemplate()
500      */

501     public boolean isUsingUriWhenLoadingTemplate() {
502
503         return true;
504     }
505
506     /**
507      * @see org.opencms.loader.I_CmsResourceLoader#load(org.opencms.file.CmsObject, org.opencms.file.CmsResource, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
508      */

509     public void load(CmsObject cms, CmsResource resource, HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res)
510     throws CmsException {
511
512         initLegacyRequest(cms, req, res);
513         processXmlTemplate(cms, CmsFile.upgrade(resource, cms));
514     }
515
516     /**
517      * @see org.opencms.loader.I_CmsResourceLoader#service(org.opencms.file.CmsObject, org.opencms.file.CmsResource, javax.servlet.ServletRequest, javax.servlet.ServletResponse)
518      */

519     public void service(CmsObject cms, CmsResource file, ServletRequest JavaDoc req, ServletResponse JavaDoc res)
520     throws CmsException, IOException JavaDoc {
521
522         long timer1 = 0;
523         if (DEBUG > 0) {
524             timer1 = System.currentTimeMillis();
525             System.err.println("============ CmsXmlTemplateLoader loading: " + cms.getSitePath(file));
526             System.err.println("CmsXmlTemplateLoader.service() cms uri is: " + cms.getRequestContext().getUri());
527         }
528         // save the original context settings
529
String JavaDoc rnc = cms.getRequestContext().getEncoding().trim();
530         // String oldUri = cms.getRequestContext().getUri();
531

532         initLegacyRequest(cms, (HttpServletRequest JavaDoc)req, (HttpServletResponse JavaDoc)res);
533         I_CmsRequest cms_req = CmsXmlTemplateLoader.getRequest(cms.getRequestContext());
534         HttpServletRequest JavaDoc originalreq = cms_req.getOriginalRequest();
535
536         try {
537             // get the CmsRequest
538
byte[] result = null;
539             org.opencms.file.CmsFile fx = cms.readFile(cms.getSitePath(file));
540             // care about encoding issues
541
String JavaDoc dnc = OpenCms.getSystemInfo().getDefaultEncoding().trim();
542             String JavaDoc enc = cms.readPropertyObject(
543                 cms.getSitePath(fx),
544                 CmsPropertyDefinition.PROPERTY_CONTENT_ENCODING,
545                 true).getValue(dnc).trim();
546             // fake the called URI (otherwise XMLTemplate / ElementCache would not work)
547
cms_req.setOriginalRequest((HttpServletRequest JavaDoc)req);
548             cms.getRequestContext().setEncoding(enc);
549             if (DEBUG > 1) {
550                 System.err.println("CmsXmlTemplateLoader.service(): Encodig set to "
551                     + cms.getRequestContext().getEncoding());
552                 System.err.println("CmsXmlTemplateLoader.service(): Uri set to " + cms.getRequestContext().getUri());
553             }
554             // process the included XMLTemplate
555
result = generateOutput(cms, fx, cms_req);
556             // append the result to the output stream
557
if (result != null) {
558                 if (DEBUG > 1) {
559                     System.err.println("CmsXmlTemplateLoader.service(): encoding="
560                         + enc
561                         + " requestEncoding="
562                         + rnc
563                         + " defaultEncoding="
564                         + dnc);
565                 }
566                 res.getOutputStream().write(result);
567             }
568         } finally {
569             // restore the context settings
570
cms_req.setOriginalRequest(originalreq);
571             cms.getRequestContext().setEncoding(rnc);
572             // cms.getRequestContext().setUri(oldUri);
573
if (DEBUG > 1) {
574                 System.err.println("CmsXmlTemplateLoader.service(): Encodig reset to "
575                     + cms.getRequestContext().getEncoding());
576                 System.err.println("CmsXmlTemplateLoader.service(): Uri reset to " + cms.getRequestContext().getUri());
577             }
578         }
579
580         if (DEBUG > 0) {
581             long timer2 = System.currentTimeMillis() - timer1;
582             System.err.println("============ CmsXmlTemplateLoader time delivering XmlTemplate for "
583                 + cms.getSitePath(file)
584                 + ": "
585                 + timer2
586                 + "ms");
587         }
588     }
589
590     /**
591      * Starts generating the output.
592      * Calls the canonical root with the appropriate template class.
593      *
594      * @param cms CmsObject Object for accessing system resources
595      * @param file CmsFile Object with the selected resource to be shown
596      * @param req the CmsRequest
597      * @return the generated output for the file
598      * @throws CmsException if something goes wrong
599      */

600     protected byte[] generateOutput(CmsObject cms, CmsFile file, I_CmsRequest req) throws CmsException {
601
602         byte[] output = null;
603
604         // hashtable for collecting all parameters.
605
Hashtable JavaDoc newParameters = new Hashtable JavaDoc();
606         String JavaDoc uri = cms.getRequestContext().getUri();
607
608         // collect xml template information
609
String JavaDoc absolutePath = cms.getSitePath(file);
610         if (CmsLog.getLog(this).isDebugEnabled()) {
611             CmsLog.getLog(this).debug("absolutePath=" + absolutePath);
612         }
613         String JavaDoc templateProp = cms.readPropertyObject(absolutePath, CmsPropertyDefinition.PROPERTY_TEMPLATE, false).getValue();
614         if (CmsLog.getLog(this).isDebugEnabled()) {
615             CmsLog.getLog(this).debug("templateProp=" + templateProp);
616         }
617         String JavaDoc templateClassProp = cms.readPropertyObject(
618             absolutePath,
619             org.opencms.file.CmsPropertyDefinition.PROPERTY_BODY_CLASS,
620             false).getValue(org.opencms.importexport.CmsCompatibleCheck.XML_CONTROL_DEFAULT_CLASS);
621         if (CmsLog.getLog(this).isDebugEnabled()) {
622             CmsLog.getLog(this).debug("templateClassProp=" + templateClassProp);
623         }
624
625         // ladies and gentelman: and now for something completly different
626
String JavaDoc xmlTemplateContent = null;
627         if (templateProp != null) {
628             // i got a black magic template,
629
StringBuffer JavaDoc buf = new StringBuffer JavaDoc(256);
630             buf.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
631             buf.append("<PAGE>\n<class>");
632             buf.append(org.opencms.importexport.CmsCompatibleCheck.XML_CONTROL_DEFAULT_CLASS);
633             buf.append("</class>\n<masterTemplate>");
634             // i got a black magic template,
635
buf.append(templateProp);
636             buf.append("</masterTemplate>\n<ELEMENTDEF name=\"body\">\n<CLASS>");
637             buf.append(templateClassProp);
638             buf.append("</CLASS>\n<TEMPLATE>");
639             // i got a black magic template got me so blind I can't see,
640
buf.append(uri);
641             buf.append("</TEMPLATE>\n</ELEMENTDEF>\n</PAGE>\n");
642             // i got a black magic template it's try'in to make a devil out of me...
643
xmlTemplateContent = buf.toString();
644             uri += com.opencms.core.I_CmsConstants.C_XML_CONTROL_FILE_SUFFIX;
645         }
646
647         // Parameters used for element cache
648
boolean elementCacheEnabled = CmsXmlTemplateLoader.isElementCacheEnabled();
649         CmsElementCache elementCache = null;
650         CmsUriDescriptor uriDesc = null;
651         CmsUri cmsUri = null;
652
653         String JavaDoc templateClass = null;
654         String JavaDoc templateName = null;
655         CmsXmlControlFile doc = null;
656
657         if (elementCacheEnabled) {
658             // Get the global element cache object
659
elementCache = CmsXmlTemplateLoader.getElementCache();
660
661             // Prepare URI Locator
662
uriDesc = new CmsUriDescriptor(uri);
663             cmsUri = elementCache.getUriLocator().get(uriDesc);
664             // check if cached
665
if (CmsLog.getLog(this).isDebugEnabled()) {
666                 CmsLog.getLog(this).debug("found cmsUri=" + cmsUri);
667             }
668             if ((cmsUri != null) && !cmsUri.getElementDescriptor().getTemplateName().equalsIgnoreCase(templateProp)) {
669                 if (CmsLog.getLog(this).isDebugEnabled()) {
670                     CmsLog.getLog(this).debug(
671                         "cmsUri has different template: "
672                             + cmsUri.getElementDescriptor().getTemplateName()
673                             + " than current template: "
674                             + templateProp
675                             + ", not using cmsUri from cache");
676                 }
677                 cmsUri = null;
678             }
679         }
680
681         // check if printversion is requested
682
String JavaDoc replace = req.getParameter(C_ELEMENT_REPLACE);
683         boolean elementreplace = false;
684         CmsElementDefinition replaceDef = null;
685         if (replace != null) {
686             int index = replace.indexOf(":");
687             if (index != -1) {
688                 elementreplace = true;
689                 cmsUri = null;
690                 String JavaDoc elementName = replace.substring(0, index);
691                 String JavaDoc replaceUri = replace.substring(index + 1);
692                 replaceDef = new CmsElementDefinition(
693                     elementName,
694                     org.opencms.importexport.CmsCompatibleCheck.XML_CONTROL_DEFAULT_CLASS,
695                     replaceUri,
696                     null,
697                     new Hashtable JavaDoc());
698                 newParameters.put(C_ELEMENT_REPLACE + "_VFS_" + elementName, cms.getRequestContext().addSiteRoot(
699                     replaceUri));
700             }
701         }
702
703         if ((cmsUri == null) || !elementCacheEnabled) {
704             // Entry point to page file analysis.
705
// For performance reasons this should only be done if the element
706
// cache is not activated or if it's activated but no URI object could be found.
707

708             // Parse the page file
709
try {
710                 if (xmlTemplateContent == null) {
711                     doc = new CmsXmlControlFile(cms, file);
712                 } else {
713                     doc = new CmsXmlControlFile(cms, uri, xmlTemplateContent);
714                 }
715             } catch (Exception JavaDoc e) {
716                 // there was an error while parsing the document.
717
// No chance to go on here.
718
handleException(cms, e, "There was an error while parsing XML page file " + cms.getSitePath(file));
719                 return "".getBytes();
720             }
721
722             if (!elementCacheEnabled && (replaceDef != null)) {
723                 // Required to enable element replacement if element cache is disabled
724
doc.setElementClass(replaceDef.getName(), replaceDef.getClassName());
725                 doc.setElementTemplate(replaceDef.getName(), replaceDef.getTemplateName());
726             }
727
728             // Get the names of the master template and the template class from
729
// the parsed page file. Fall back to default value, if template class
730
// is not defined
731
templateClass = doc.getTemplateClass();
732             if (templateClass == null || "".equals(templateClass)) {
733                 templateClass = this.getClass().getName();
734             }
735             if (templateClass == null || "".equals(templateClass)) {
736                 templateClass = org.opencms.importexport.CmsCompatibleCheck.XML_CONTROL_DEFAULT_CLASS;
737             }
738             templateName = doc.getMasterTemplate();
739             if (templateName != null && !"".equals(templateName)) {
740                 templateName = CmsLinkManager.getAbsoluteUri(templateName, cms.getSitePath(file));
741             }
742
743             // Previously, the template class was loaded here.
744
// We avoid doing this so early, since in element cache mode the template
745
// class is not needed here.
746

747             // Now look for parameters in the page file...
748
// ... first the params of the master template...
749
Enumeration JavaDoc masterTemplateParams = doc.getParameterNames();
750             while (masterTemplateParams.hasMoreElements()) {
751                 String JavaDoc paramName = (String JavaDoc)masterTemplateParams.nextElement();
752                 String JavaDoc paramValue = doc.getParameter(paramName);
753                 newParameters.put(com.opencms.core.I_CmsConstants.C_ROOT_TEMPLATE_NAME + "." + paramName, paramValue);
754             }
755
756             // ... and now the params of all subtemplates
757
Enumeration JavaDoc elementDefinitions = doc.getElementDefinitions();
758             while (elementDefinitions.hasMoreElements()) {
759                 String JavaDoc elementName = (String JavaDoc)elementDefinitions.nextElement();
760                 if (doc.isElementClassDefined(elementName)) {
761                     newParameters.put(elementName + "._CLASS_", doc.getElementClass(elementName));
762                 }
763                 if (doc.isElementTemplateDefined(elementName)) {
764                     // need to check for the body template here so that non-XMLTemplate templates
765
// like JSPs know where to find the body defined in the XMLTemplate
766
String JavaDoc template = doc.getElementTemplate(elementName);
767                     if (xmlTemplateContent == null) {
768                         template = doc.validateBodyPath(cms, template, file);
769                     }
770                     if (CmsDefaultPageEditor.XML_BODY_ELEMENT.equalsIgnoreCase(elementName)) {
771                         // found body element
772
if (template != null) {
773                             cms.getRequestContext().setAttribute(CmsDefaultPageEditor.XML_BODY_ELEMENT, template);
774                         }
775                     }
776                     newParameters.put(elementName + "._TEMPLATE_", template);
777                 }
778                 if (doc.isElementTemplSelectorDefined(elementName)) {
779                     newParameters.put(elementName + "._TEMPLATESELECTOR_", doc.getElementTemplSelector(elementName));
780                 }
781                 Enumeration JavaDoc parameters = doc.getElementParameterNames(elementName);
782                 while (parameters.hasMoreElements()) {
783                     String JavaDoc paramName = (String JavaDoc)parameters.nextElement();
784                     String JavaDoc paramValue = doc.getElementParameter(elementName, paramName);
785                     if (paramValue != null) {
786                         newParameters.put(elementName + "." + paramName, paramValue);
787                     } else {
788                         if (CmsLog.getLog(this).isInfoEnabled()) {
789                             CmsLog.getLog(this).info("Empty parameter \"" + paramName + "\" found.");
790                         }
791                     }
792                 }
793             }
794         }
795
796         // URL parameters ary really dynamic.
797
// We cannot store them in an element cache.
798
// Therefore these parameters must be collected in ANY case!
799

800         String JavaDoc datafor = req.getParameter("datafor");
801         if (datafor == null) {
802             datafor = "";
803         } else {
804             if (!"".equals(datafor)) {
805                 datafor = datafor + ".";
806             }
807         }
808         Enumeration JavaDoc urlParameterNames = req.getParameterNames();
809         while (urlParameterNames.hasMoreElements()) {
810             String JavaDoc pname = (String JavaDoc)urlParameterNames.nextElement();
811             String JavaDoc paramValue = req.getParameter(pname);
812             if (paramValue != null) {
813                 if ((!"datafor".equals(pname)) && (!"_clearcache".equals(pname))) {
814                     newParameters.put(datafor + pname, paramValue);
815                 }
816             } else {
817                 if (CmsLog.getLog(this).isInfoEnabled()) {
818                     CmsLog.getLog(this).info("Empty URL parameter \"" + pname + "\" found.");
819                 }
820             }
821         }
822
823         if (elementCacheEnabled && (cmsUri == null)) {
824             // ---- element cache stuff --------
825
// No URI could be found in cache.
826
// So create a new URI object with a start element and store it using the UriLocator
827
CmsElementDescriptor elemDesc = new CmsElementDescriptor(templateClass, templateName);
828             CmsElementDefinitionCollection eldefs = doc.getElementDefinitionCollection();
829             if (elementreplace) {
830                 // we cant cach this
831
eldefs.add(replaceDef);
832                 cmsUri = new CmsUri(elemDesc, eldefs);
833             } else {
834                 cmsUri = new CmsUri(elemDesc, eldefs);
835                 elementCache.getUriLocator().put(uriDesc, cmsUri);
836             }
837         }
838
839         if (elementCacheEnabled) {
840             // TODO: Make cache more efficient
841
clearLoaderCache(true, true);
842
843             // now lets get the output
844
if (elementreplace) {
845                 output = cmsUri.callCanonicalRoot(elementCache, cms, newParameters);
846             } else {
847                 output = elementCache.callCanonicalRoot(cms, newParameters, uri);
848             }
849         } else {
850             // ----- traditional stuff ------
851
// Element cache is deactivated. So let's go on as usual.
852
try {
853                 CmsFile masterTemplate = loadMasterTemplateFile(cms, templateName, doc);
854                 I_CmsTemplate tmpl = getTemplateClass(templateClass);
855                 if (!(tmpl instanceof I_CmsXmlTemplate)) {
856                     String JavaDoc errorMessage = "Error in "
857                         + cms.getSitePath(file)
858                         + ": "
859                         + templateClass
860                         + " is not a XML template class.";
861                     if (CmsLog.getLog(this).isErrorEnabled()) {
862                         CmsLog.getLog(this).error(errorMessage);
863                     }
864                     throw new CmsLegacyException(errorMessage, CmsLegacyException.C_XML_WRONG_TEMPLATE_CLASS);
865                 }
866                 // TODO: Make cache more efficient
867
clearLoaderCache(true, true);
868                 output = callCanonicalRoot(cms, tmpl, masterTemplate, newParameters);
869             } catch (CmsException e) {
870                 if (CmsLog.getLog(this).isWarnEnabled()) {
871                     CmsLog.getLog(this);
872                 }
873                 doc.removeFromFileCache();
874                 throw e;
875             }
876         }
877         return output;
878     }
879
880     /**
881      * Utility method used by the loader implementation to give control
882      * to the CanonicalRoot.<p>
883      *
884      * The CanonicalRoot will call the master template and return a byte array of the
885      * generated output.<p>
886      *
887      * @param cms the cms context object
888      * @param templateClass to generate the output of the master template
889      * @param masterTemplate masterTemplate for the output
890      * @param parameters contains all parameters for the template class
891      * @return the generated output or null if there were errors
892      * @throws CmsException if something goes wrong
893      */

894     private byte[] callCanonicalRoot(
895         CmsObject cms,
896         I_CmsTemplate templateClass,
897         CmsFile masterTemplate,
898         Hashtable JavaDoc parameters) throws CmsException {
899
900         try {
901             CmsRootTemplate root = new CmsRootTemplate();
902             return root.getMasterTemplate(cms, templateClass, masterTemplate, m_templateCache, parameters);
903         } catch (Exception JavaDoc e) {
904             // no document we could show...
905
handleException(cms, e, "Received error while calling canonical root for requested file "
906                 + masterTemplate.getName()
907                 + ". ");
908         }
909         return null;
910     }
911
912     /**
913      * Calls the CmsClassManager to get an instance of the given template class.<p>
914      *
915      * The returned object is checked to be an implementing class of the interface
916      * I_CmsTemplate.
917      * If the template cache of the template class is not yet set up,
918      * this will be done, too.<p>
919      *
920      * @param classname name of the requested template class
921      * @return instance of the template class
922      * @throws CmsException if something goes wrong
923      */

924     private I_CmsTemplate getTemplateClass(String JavaDoc classname) throws CmsException {
925
926         if (CmsLog.getLog(this).isDebugEnabled()) {
927             CmsLog.getLog(this).debug("Getting start template class: " + classname);
928         }
929         Object JavaDoc o = CmsTemplateClassManager.getClassInstance(classname);
930
931         // Check, if the loaded class really is a OpenCms template class.
932

933         // This is done be checking the implemented interface.
934
if (!(o instanceof I_CmsTemplate)) {
935             String JavaDoc errorMessage = "Class " + classname + " is not an OpenCms template class.";
936             if (CmsLog.getLog(this).isErrorEnabled()) {
937                 CmsLog.getLog(this).error(errorMessage);
938             }
939             throw new CmsLegacyException(errorMessage, CmsLegacyException.C_XML_NO_TEMPLATE_CLASS);
940         }
941         I_CmsTemplate cmsTemplate = (I_CmsTemplate)o;
942         if (!cmsTemplate.isTemplateCacheSet()) {
943             cmsTemplate.setTemplateCache(m_templateCache);
944         }
945         return cmsTemplate;
946     }
947
948     /**
949      * Utility method to handle any occurence of an execption.<p>
950      *
951      * If the Exception is NO CmsException (i.e. it was not detected previously)
952      * it will be written to the logfile.<p>
953      *
954      * If the current user is the anonymous user, no further exception will
955      * be thrown, but a server error will be sent
956      * (we want to prevent the user from seeing any exeptions).
957      * Otherwise a new Exception will be thrown.
958      * This will trigger the OpenCms error message box.<p>
959      *
960      * @param cms the cms context object
961      * @param e Exception that should be handled
962      * @param errorText error message that should be shown
963      * @throws CmsException if
964      */

965     private void handleException(CmsObject cms, Exception JavaDoc e, String JavaDoc errorText) throws CmsException {
966
967         // log the error if it is no CmsException
968
if (!(e instanceof CmsException)) {
969             if (CmsLog.getLog(this).isErrorEnabled()) {
970                 CmsLog.getLog(this).error(errorText, e);
971             }
972         }
973
974         // if the user is a guest (and it's not a login exception) we send an servlet error,
975
// otherwise we try to throw an exception.
976
CmsRequestContext reqContext = cms.getRequestContext();
977         if ((DEBUG == 0)
978             && reqContext.currentUser().isGuestUser()
979             && (!(e instanceof CmsLegacyException && ((e instanceof CmsLegacyException) && (((CmsLegacyException)e).getType() == CmsLegacyException.C_NO_USER))))) {
980             throw new CmsLegacyException(errorText, CmsLegacyException.C_SERVICE_UNAVAILABLE, e);
981         } else {
982             if (e instanceof CmsException) {
983                 throw (CmsException)e;
984             } else {
985                 throw new CmsLegacyException(errorText, CmsLegacyException.C_LOADER_GENERIC_ERROR, e);
986             }
987         }
988     }
989
990     /**
991      * Internal utility method for checking and loading a given template file.
992      * @param cms CmsObject for accessing system resources.
993      * @param templateName Name of the requestet template file.
994      * @param doc CmsXmlControlFile object containig the parsed body file.
995      * @return CmsFile object of the requested template file.
996      * @throws CmsException if something goes wrong
997      */

998     private CmsFile loadMasterTemplateFile(
999         CmsObject cms,
1000        String JavaDoc templateName,
1001        com.opencms.template.CmsXmlControlFile doc) throws CmsException {
1002
1003        CmsFile masterTemplate = null;
1004        try {
1005            masterTemplate = cms.readFile(templateName);
1006        } catch (Exception JavaDoc e) {
1007            handleException(cms, e, "Cannot load master template " + templateName + ". ");
1008            doc.removeFromFileCache();
1009        }
1010        return masterTemplate;
1011    }
1012
1013    /**
1014     * Processes the XmlTemplates and writes the result to
1015     * the apropriate output stream, which is obtained from the request
1016     * context of the cms object.<p>
1017     *
1018     * @param cms the cms context object
1019     * @param file the selected resource to be shown
1020     * @throws CmsException if something goes wrong
1021     */

1022    private void processXmlTemplate(CmsObject cms, CmsFile file) throws CmsException {
1023
1024        // first some debugging output.
1025
if ((DEBUG > 0) && CmsLog.getLog(this).isDebugEnabled()) {
1026            CmsLog.getLog(this).debug("Loader started for " + file.getName());
1027        }
1028
1029        // check all values to be valid
1030
String JavaDoc errorMessage = null;
1031        if (file == null) {
1032            errorMessage = "CmsFile missing";
1033        }
1034        if (cms == null) {
1035            errorMessage = "CmsObject missing";
1036        }
1037        if (errorMessage != null) {
1038            if (CmsLog.getLog(this).isErrorEnabled()) {
1039                CmsLog.getLog(this).error(errorMessage);
1040            }
1041            throw new CmsLegacyException(errorMessage, CmsLegacyException.C_LOADER_GENERIC_ERROR);
1042        }
1043
1044        // Check the clearcache parameter
1045
String JavaDoc clearcache = getRequest(cms.getRequestContext()).getParameter("_clearcache");
1046
1047        // Clear loader caches if this is required
1048
clearLoaderCache(
1049            ((clearcache != null) && ("all".equals(clearcache) || "file".equals(clearcache))),
1050            ((clearcache != null) && ("all".equals(clearcache) || "template".equals(clearcache))));
1051
1052        // get the CmsRequest
1053
I_CmsRequest req = getRequest(cms.getRequestContext());
1054        byte[] result = generateOutput(cms, file, req);
1055        if (result != null) {
1056            writeBytesToResponse(cms, result);
1057        }
1058    }
1059
1060    /**
1061     * Writes a given byte array to the HttpServletRespose output stream.<p>
1062     *
1063     * @param cms an initialized CmsObject
1064     * @param result byte array that should be written.
1065     * @throws CmsException if something goes wrong
1066     */

1067    private void writeBytesToResponse(CmsObject cms, byte[] result) throws CmsException {
1068
1069        try {
1070            I_CmsResponse resp = getResponse(cms.getRequestContext());
1071            if ((result != null) && !resp.isRedirected()) {
1072                // Only write any output to the response output stream if
1073
// the current request is neither redirected nor streamed.
1074
OutputStream JavaDoc out = resp.getOutputStream();
1075
1076                resp.setContentLength(result.length);
1077                resp.setHeader("Connection", "keep-alive");
1078                out.write(result);
1079                out.close();
1080            }
1081        } catch (IOException JavaDoc ioe) {
1082            if (CmsLog.getLog(this).isDebugEnabled()) {
1083                CmsLog.getLog(this).debug(
1084                    "IO error while writing to response stream for " + cms.getRequestContext().getUri(),
1085                    ioe);
1086            }
1087        } catch (Exception JavaDoc e) {
1088            String JavaDoc errorMessage = "Cannot write output to HTTP response stream";
1089            handleException(cms, e, errorMessage);
1090        }
1091    }
1092}
1093
Popular Tags