KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opencms > template > cache > A_CmsElement


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src-modules/com/opencms/template/cache/A_CmsElement.java,v $
3  * Date : $Date: 2005/06/27 23:22:30 $
4  * Version: $Revision: 1.5 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (C) 2001 The OpenCms Group
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 OpenCms, please see the
22  * OpenCms Website: http://www.opencms.org
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27  */

28
29 package com.opencms.template.cache;
30
31 import org.opencms.file.CmsObject;
32 import org.opencms.file.CmsResource;
33 import org.opencms.file.CmsUser;
34 import org.opencms.main.CmsException;
35 import org.opencms.main.CmsLog;
36 import org.opencms.main.OpenCms;
37 import org.opencms.security.CmsSecurityException;
38
39 import com.opencms.legacy.CmsLegacyException;
40 import com.opencms.legacy.CmsXmlTemplateLoader;
41 import com.opencms.template.A_CmsCacheDirectives;
42 import com.opencms.template.CmsCacheDirectives;
43 import com.opencms.template.CmsTemplateClassManager;
44 import com.opencms.template.I_CmsTemplate;
45
46 import java.io.ByteArrayOutputStream JavaDoc;
47 import java.io.IOException JavaDoc;
48 import java.util.Enumeration JavaDoc;
49 import java.util.Hashtable JavaDoc;
50 import java.util.Vector JavaDoc;
51
52 /**
53  * An instance of A_CmsElement represents an requestable Element in the OpenCms
54  * element cache area. It contains all informations to generate the content of this
55  * element. It also stores the variants of once generated content to speed up
56  * performance.
57  *
58  * It may point to other depending elements. Theses elements are called to generate
59  * their content on generation-time.
60  *
61  * @author Andreas Schouten
62  * @author Alexander Lucas
63  *
64  * @deprecated Will not be supported past the OpenCms 6 release.
65  */

66 public abstract class A_CmsElement {
67
68     /** The class-name of this element definition. */
69     protected String JavaDoc m_className;
70
71     /** The template-name of this element definition. */
72     protected String JavaDoc m_templateName;
73
74     /** Cache directives of this element. */
75     protected A_CmsCacheDirectives m_cacheDirectives;
76
77     /** Last time this element was generated.(used for CacheDirectives timeout) */
78     protected long m_timestamp = 0;
79
80     /** All definitions declared in this element. */
81     protected CmsElementDefinitionCollection m_elementDefinitions;
82
83     /** LruCache for element variant cache */
84     private CmsLruCache m_variants;
85
86     /** indicates if this element may have a variant that has dependencies
87      * if such a element is deletet from elementcache the extern dependencies
88      * hashtable must be updated.
89      */

90     protected boolean m_hasDepVariants = false;
91
92     /**
93      * Initializer for an element with the given class and template name.
94      */

95     protected void init(String JavaDoc className, String JavaDoc templateName, A_CmsCacheDirectives cd,
96         int variantCachesize) {
97
98         m_className = className;
99         m_templateName = templateName;
100         m_cacheDirectives = cd;
101         m_elementDefinitions = new CmsElementDefinitionCollection();
102         m_variants = new CmsLruCache(variantCachesize);
103     }
104
105     /**
106      * Initializer for building an element with the given element definitions.
107      * @param name the name of this element-definition.
108      * @param className the classname of this element-definition.
109      * @param cd Cache directives for this element
110      * @param defs Vector with ElementDefinitions for this element.
111      * @param variantCachesize The size of the variant cache.
112      */

113     protected void init(String JavaDoc className, String JavaDoc templateName, A_CmsCacheDirectives cd,
114         CmsElementDefinitionCollection defs, int variantCachesize) {
115
116         m_className = className;
117         m_templateName = templateName;
118         m_cacheDirectives = cd;
119         m_elementDefinitions = defs;
120         m_variants = new CmsLruCache(variantCachesize);
121     }
122
123     /**
124      * Adds a single definition to this element.
125      * @param def - the ElementDefinition to add.
126      */

127     public void addDefinition(CmsElementDefinition def) {
128
129         m_elementDefinitions.add(def);
130     }
131
132     /**
133      * Adds a single variant to this element.
134      * @param def - the ElementVariant to add.
135      * @return a CmsElementVariant of dependencies that must be deleted from extern store for this element
136      */

137     public Vector JavaDoc addVariant(Object JavaDoc key, CmsElementVariant variant) {
138
139         if (CmsLog.getLog(this).isInfoEnabled()) {
140             CmsLog.getLog(this).info("Adding variant \"" + key + "\" to xml template cache");
141         }
142         if (key != null) {
143             CmsElementVariant old = (CmsElementVariant)m_variants.get(key);
144             if ((old != null) && (old.size() == 0)) {
145                 variant.addDependencies(old.getDependencies());
146                 variant.mergeNextTimeout(old.getNextTimeout());
147             }
148             return m_variants.put(key, variant);
149         }
150         return null;
151     }
152
153     public void removeVariant(Object JavaDoc key) {
154
155         if (CmsLog.getLog(this).isInfoEnabled()) {
156             CmsLog.getLog(this).info(toString() + " removing variant \"" + key
157                 + "\" from xml template cache");
158         }
159         if (key != null) {
160             m_variants.remove(key);
161         }
162     }
163
164     /**
165      * checks the read access.
166      * @param cms The cms Object for reading groups.
167      * @throws CmsException if no read access.
168      */

169     public void checkReadAccess(CmsObject cms) throws CmsException {
170
171         return;
172     }
173
174     /**
175      * Clears all variants. Used for TimeCritical elements.
176      */

177     public void clearVariantCache() {
178
179         m_variants.clearCache();
180         m_timestamp = System.currentTimeMillis();
181     }
182
183     /**
184      *
185      */

186     public Vector JavaDoc getAllVariantKeys() {
187
188         return m_variants.getAllKeys();
189     }
190
191     /**
192      * Get a variant from the vatiant cache
193      * @param key Key of the ElementVariant.
194      * @return Cached CmsElementVariant object
195      */

196     public CmsElementVariant getVariant(Object JavaDoc key) {
197
198         if (key == null) {
199             return null;
200         }
201         CmsElementVariant result = (CmsElementVariant)m_variants.get(key);
202         if (result != null && result.size() == 0) {
203             result = null;
204         }
205         if (CmsLog.getLog(this).isInfoEnabled()) {
206             if (result != null) {
207                 CmsLog.getLog(this).info(toString() + " getting variant \"" + key
208                     + "\" from cache. ");
209             } else {
210                 CmsLog.getLog(this).info(toString() + " Variant \"" + key
211                     + "\" is not in element cache. ");
212             }
213         }
214         return result;
215     }
216
217     /**
218      * says if the extern dependenciescache has to be updated when this element
219      * is deleted.
220      */

221     public boolean hasDependenciesVariants() {
222
223         return m_hasDepVariants;
224     }
225
226     /**
227      * indicates this element critical for delete.
228      */

229     public void thisElementHasDepVariants() {
230
231         m_hasDepVariants = true;
232     }
233
234     /**
235      * Returns a Vector with all ElementDefinitions
236      * @return a Vector with all ElementDefinitions.
237      */

238     public CmsElementDefinitionCollection getAllDefinitions() {
239
240         return m_elementDefinitions;
241     }
242
243     /**
244      * Get the element definition for the sub-element with the given name
245      * @param name Name of the sub-element that should be looked up
246      * @return Element definition of <em>name</em>
247      */

248     public CmsElementDefinition getElementDefinition(String JavaDoc name) {
249
250         return m_elementDefinitions.get(name);
251     }
252
253     /** Get cache directives for this element.
254      * @return cache directives.
255      */

256     public A_CmsCacheDirectives getCacheDirectives() {
257
258         return m_cacheDirectives;
259     }
260
261     /**
262      * checks the proxy public and the proxy private cache settings
263      * of this element and all subelements.
264      * @param cms the cms object.
265      * @param proxySettings The CacheDirectives to merge the own CacheDriectives with.
266      * @param parameters A Hashtable with the parameters.
267      */

268     public void checkProxySettings(CmsObject cms, CmsCacheDirectives proxySettings,
269         Hashtable JavaDoc parameters) throws CmsException {
270
271         // first our own cachedirectives are they set or not?
272
if (!(m_cacheDirectives.userSetProxyPrivate() && m_cacheDirectives.userSetProxyPublic())) {
273             // we have to find out manually
274
boolean proxyPublic = false;
275             boolean proxyPrivate = false;
276             boolean export = false;
277             if (m_templateName == null) {
278                 // no template given set everything to true
279
proxyPublic = true;
280                 proxyPrivate = true;
281                 export = true;
282             } else {
283                 try {
284                     if (m_cacheDirectives.isInternalCacheable()
285                         && (!m_cacheDirectives.isUserPartOfKey())) {
286                         CmsResource templ = cms.readResource(m_templateName);
287                         int accessflags = templ.getFlags();
288                         if (!((accessflags & CmsResource.FLAG_INTERNAL) > 0)) {
289                             // internal flag not set
290
proxyPrivate = true;
291                             if ((!m_cacheDirectives.isParameterPartOfKey())
292                                 && (!m_cacheDirectives.isTimeCritical())) {
293                                 export = true;
294                             }
295                         }
296                     }
297
298                 } catch (Exception JavaDoc e) {
299                     // do nothing, set everything to false and log the error
300
if (CmsLog.getLog(this).isWarnEnabled()) {
301                         CmsLog.getLog(this).warn(toString()
302                             + " could not find out if the element is proxy cacheable", e);
303                     }
304                 }
305             }
306             if (!m_cacheDirectives.userSetProxyPrivate()) {
307                 ((CmsCacheDirectives)m_cacheDirectives).setProxyPrivateCacheable(proxyPrivate);
308             }
309             if (!m_cacheDirectives.userSetProxyPublic()) {
310                 ((CmsCacheDirectives)m_cacheDirectives).setProxyPublicCacheable(proxyPublic);
311             }
312             if (!m_cacheDirectives.userSetExport()) {
313                 ((CmsCacheDirectives)m_cacheDirectives).setExport(export);
314             }
315         }
316         proxySettings.merge(m_cacheDirectives);
317         // now for the subelements
318
Enumeration JavaDoc elementNames = m_elementDefinitions.getAllElementNames();
319         while (elementNames.hasMoreElements()) {
320             String JavaDoc name = (String JavaDoc)elementNames.nextElement();
321             CmsElementDefinition currentDef = m_elementDefinitions.get(name);
322             A_CmsElement currentEle = CmsXmlTemplateLoader.getElementCache().getElementLocator().get(cms, new CmsElementDescriptor(
323                 currentDef.getClassName(), currentDef.getTemplateName()), parameters);
324             currentEle.checkProxySettings(cms, proxySettings, parameters);
325         }
326     }
327
328     /**
329      * Abstract method for getting the content of this element.
330      * Element classes may have different implementations for getting
331      * the contents. Common tasks of all implementations are checking
332      * the variant cache and creating the variant if required.
333      * @param elementCache Entry point for the element cache
334      * @param cms CmsObject for accessing system resources
335      * @param elDefs Definitions of this element's subelements
336      * @param parameters All parameters of this request
337      * @param methodparameter used only for methode elements. Contains the parameter for the methode.
338      * @return Byte array with the processed content of this element.
339      * @throws CmsException
340      */

341     public abstract byte[] getContent(CmsElementCache elementCache, CmsObject cms,
342         CmsElementDefinitionCollection efDefs, String JavaDoc elementName, Hashtable JavaDoc parameters,
343         String JavaDoc methodParameter) throws CmsException;
344
345     /**
346      * Get a template class from the template class manager.
347      * @param cms CmsObject for accessing system resources.
348      * @param classname Name of the requested class.
349      * @throws CmsException if the loaded class is no OpenCms template class
350      */

351     protected I_CmsTemplate getTemplateClass(CmsObject cms, String JavaDoc classname) throws CmsException {
352
353         Object JavaDoc o = CmsTemplateClassManager.getClassInstance(classname);
354         // Check, if the loaded class really is a OpenCms template class.
355
if (o instanceof I_CmsTemplate) {
356             return (I_CmsTemplate)o;
357         } else {
358             throw new CmsLegacyException(classname + " is no OpenCms template class.",
359                 CmsLegacyException.C_XML_NO_TEMPLATE_CLASS);
360         }
361     }
362
363     /**
364      * Resolve given variant of this element and get content of all sub elements.<p>
365      *
366      * @param cms CmsObject for accessing system resources
367      * @param variant Variant that should be resolved
368      * @param elementCache Entry point for element cache
369      * @param elDefs Definitions for all subelements
370      * @param parameters All parameters of this request
371      * @return Byte array with processed element content
372      * @throws CmsException if resolving fails.
373      */

374     public byte[] resolveVariant(CmsObject cms, CmsElementVariant variant,
375         CmsElementCache elementCache, CmsElementDefinitionCollection elDefs, Hashtable JavaDoc parameters)
376     throws CmsException {
377
378         boolean resolveDebug = false;
379         if (resolveDebug)
380             System.err.println("= Start resolving variant " + variant);
381         int len = variant.size();
382         // Try to get the corresponding element using the element locator
383
try {
384             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
385             for (int i = 0; i < len; i++) {
386                 // put the name of the element into the params
387
if (resolveDebug)
388                     System.err.print("= Part " + i + " is a ");
389                 Object JavaDoc o = variant.get(i);
390                 // Decide what to do with the current part.
391
// If it's a String or byte array, just print it out.
392
// If it's a link to a sub element, get this element and call its getContent() method
393
if (o instanceof String JavaDoc) {
394                     if (resolveDebug)
395                         System.err.println("String");
396                     baos.write(((String JavaDoc)o).getBytes(cms.getRequestContext().getEncoding()));
397                 } else if (o instanceof byte[]) {
398                     if (resolveDebug)
399                         System.err.println("byte array");
400                     baos.write((byte[])o);
401                 } else if (o instanceof CmsElementLink) {
402                     if (resolveDebug)
403                         System.err.println("Element Link");
404
405                     // we have to resolve the element link right NOW!
406
// Look for the element definition
407
String JavaDoc lookupName = ((CmsElementLink)o).getElementName();
408                     if (resolveDebug)
409                         System.err.println("= Trying to resolve link \"" + lookupName + "\".");
410                     CmsElementDefinition elDef = elDefs.get(lookupName);
411                     if (elDef != null) {
412                         // We have successfully found an element definition.
413
// first add the parameter from the elementdefinition to the parameters
414
elDef.joinParameters(parameters);
415                         // put the name of the element into the params
416
parameters.put("_ELEMENT_", elDef.getName());
417                         if (elDef.getTemplateName() != null) {
418                             parameters.put(elDef.getName() + "._TEMPLATE_", elDef.getTemplateName());
419                         }
420                         parameters.put(elDef.getName() + "._CLASS_", elDef.getClassName());
421                         if (elDef.getTemplateSelector() != null) {
422                             parameters.put(elDef.getName() + "._TEMPLATESELECTOR_", elDef.getTemplateSelector());
423                         } else {
424                             parameters.put(elDef.getName() + "._TEMPLATESELECTOR_", "default");
425                         }
426                         // Try to get the corresponding element using the element locator
427
A_CmsElement subEl = elementCache.getElementLocator().get(cms, elDef.getDescriptor(), parameters);
428                         if (resolveDebug)
429                             System.err.println("= Element defintion for \"" + lookupName
430                                 + "\" says: ");
431                         if (resolveDebug)
432                             System.err.println("= -> Class : " + elDef.getClassName());
433                         if (resolveDebug)
434                             System.err.println("= -> Template : " + elDef.getTemplateName());
435                         String JavaDoc errorMessage = "";
436                         if (subEl != null) {
437                             // An element could be found. Very fine.
438
// So we can go on and call its getContent() method
439
if (resolveDebug)
440                                 System.err.println("= Element object found for \"" + lookupName
441                                     + "\". Calling getContent on this object. ");
442                             byte[] buffer = null;
443                             try {
444                                 buffer = subEl.getContent(elementCache, cms, elDefs, lookupName, parameters, null);
445                             } catch (Exception JavaDoc e) {
446                                 // An error occured while getting the element's content.
447
// Do some error handling here.
448
if (CmsUser.USER_TYPE_SYSTEMUSER == cms.getRequestContext().currentUser().getType()
449                                     && !OpenCms.getDefaultUsers().getUserGuest().equals(cms.getRequestContext().currentUser().getName())) {
450                                     // a systemuser gets the real message.(except guests)
451
errorMessage = e.toString();
452                                 }
453                                 subEl = null;
454                                 buffer = null;
455                                 if (e instanceof CmsException) {
456                                     CmsException ce = (CmsException)e;
457                                     if (ce instanceof CmsSecurityException) {
458                                         if (CmsLog.getLog(this).isErrorEnabled()) {
459                                             CmsLog.getLog(this).error("Access denied in element "
460                                                 + lookupName, ce);
461                                         }
462                                         throw ce;
463                                     } else {
464                                         // Any other CmsException. This may be critical
465
if (CmsLog.getLog(this).isErrorEnabled()) {
466                                             CmsLog.getLog(this).error("Error in element "
467                                                 + lookupName, e);
468                                         }
469                                     }
470                                 } else {
471                                     // Any other Non-CmsException.
472
if (CmsLog.getLog(this).isErrorEnabled()) {
473                                         CmsLog.getLog(this).error("Non-CmsException in element "
474                                             + lookupName, e);
475                                     }
476                                 }
477                             }
478                             // If we have some results print them out.
479
if (buffer != null) {
480                                 baos.write(buffer);
481                             }
482                         } else {
483                             // The subelement object is null, i.e. the element could not be found.
484
// Do nothing but a little bit logging here.
485
if (resolveDebug)
486                                 System.err.println("= Cannot find Element object for \""
487                                     + lookupName + "\". Ignoring this link. ");
488                             if (CmsLog.getLog(this).isWarnEnabled()) {
489                                 CmsLog.getLog(this).warn("Cannot find Element object for \""
490                                     + lookupName + "\", ignoring this link");
491                             }
492                         }
493
494                         // If the element could not be generated properly, print a little error
495
// message instead of the element's results.
496
if (subEl == null) {
497                             baos.write(("[" + lookupName + "] ??? ").getBytes());
498                             baos.write(errorMessage.getBytes());
499                         }
500                     } else {
501                         // No element definition could be found.
502
// Do some logging only and ignore this element
503
baos.write(("[" + lookupName + "] Element not defined.").getBytes());
504                         if (CmsLog.getLog(this).isWarnEnabled()) {
505                             CmsLog.getLog(this).warn("No element definition found for \""
506                                 + lookupName + "\", ignoring this link");
507                         }
508                         if (resolveDebug) {
509                             System.err.println("= No element definition found for \"" + lookupName
510                                 + "\". Ignoring this link. ");
511                             System.err.println(elDefs.toString());
512                         }
513                     }
514                 } else if (o instanceof CmsMethodLink) {
515                     if (resolveDebug)
516                         System.err.println("Method Link");
517                     // get the methodelement
518
String JavaDoc methodName = ((CmsMethodLink)o).getMethodeName();
519                     String JavaDoc methodParameter = ((CmsMethodLink)o).getMethodParameter();
520                     A_CmsElement metEle = elementCache.getElementLocator().get(cms, new CmsElementDescriptor(
521                         m_className + "." + methodName, "METHOD"), parameters);
522                     byte[] buffer = null;
523                     if (metEle != null) {
524                         try {
525                             buffer = metEle.getContent(elementCache, cms, elDefs, null, parameters, methodParameter);
526                         } catch (Exception JavaDoc e) {
527                             if (e instanceof CmsException) {
528                                 if (CmsLog.getLog(this).isErrorEnabled()) {
529                                     CmsLog.getLog(this).error("Error in method " + methodName, e);
530                                 }
531                             } else {
532                                 // Any other Non-CmsException.
533
if (CmsLog.getLog(this).isErrorEnabled()) {
534                                     CmsLog.getLog(this).error("Non-CmsException in method "
535                                         + methodName, e);
536                                 }
537                             }
538                         }
539                     } else {
540                         // The subelement object is null, i.e. the element could not be found.
541
// Do nothing but a little bit logging here.
542
if (resolveDebug)
543                             System.err.println("= Cannot find methodElemtn object for \""
544                                 + methodName + "\". Ignoring this link. ");
545                         if (CmsLog.getLog(this).isWarnEnabled()) {
546                             CmsLog.getLog(this).warn("Cannot find method Element object for \""
547                                 + methodName + "\", ignoring this link");
548                         }
549                     }
550                     // If we have some results print them out.
551
if (buffer != null) {
552                         baos.write(buffer);
553                     }
554                 }
555             }
556             return baos.toByteArray();
557         } catch (IOException JavaDoc e) {
558             // Something went wrong while writing to the OutputStream
559
if (CmsLog.getLog(this).isErrorEnabled()) {
560                 CmsLog.getLog(this).error("IOException while writing to XMl template OutputStream", e);
561             }
562             throw new CmsLegacyException(CmsLegacyException.C_UNKNOWN_EXCEPTION, e);
563         }
564     }
565
566     /**
567      * Get a string representation of this element.
568      * @return String representation.
569      */

570     public String JavaDoc toString() {
571
572         String JavaDoc part1 = getClass().getName();
573         part1 = part1.substring(part1.lastIndexOf(".") + 1);
574
575         String JavaDoc part2 = m_className.substring(m_className.lastIndexOf(".") + 1);
576         String JavaDoc part3 = "";
577         if (m_templateName != null) {
578             part3 = m_templateName.substring(m_templateName.lastIndexOf("/") + 1);
579         }
580
581         return "[" + part1 + " (" + part2 + "/" + part3 + ")]";
582     }
583 }
Popular Tags