KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2 * File : $Source: /usr/local/cvs/opencms/src-modules/com/opencms/template/cache/CmsElementLocator.java,v $
3 * Date : $Date: 2005/05/31 15:51:19 $
4 * Version: $Revision: 1.2 $
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.main.CmsException;
33 import org.opencms.main.CmsLog;
34
35 import com.opencms.legacy.CmsLegacyException;
36 import com.opencms.legacy.CmsXmlTemplateLoader;
37 import com.opencms.template.CmsMethodCacheDirectives;
38 import com.opencms.template.I_CmsTemplate;
39
40 import java.util.Enumeration JavaDoc;
41 import java.util.Hashtable JavaDoc;
42 import java.util.StringTokenizer JavaDoc;
43 import java.util.Vector JavaDoc;
44
45 /**
46  * The ElementLocator is used to receive CmsElement-Objects. It is the Cache for
47  * these CmsElement-Objects. The CmsElement-Objects are stored in memory or -
48  * if they are notc used a long time - written to an external database. The
49  * locator manages all the reading, writing and management of the CmsElement's.
50  *
51  * @author Andreas Schouten
52  * @author Alexander Lucas
53  *
54  * @deprecated Will not be supported past the OpenCms 6 release.
55  */

56 public class CmsElementLocator {
57
58     /**
59      * A hashtable to store the elements.
60      */

61     private CmsLruCache m_elements;
62
63     /**
64      * link to the extern dependencies vector
65      */

66     private Hashtable JavaDoc m_dependenciesExtern = null;
67
68     /**
69      * The default constructor for this locator.
70      */

71     CmsElementLocator(int cacheSize) {
72         if(cacheSize < 2){
73             cacheSize = 50000;
74         }
75         m_elements = new CmsLruCache(cacheSize);
76     }
77
78     /**
79      * Adds a new Element to this locator.
80      * This method is kept private and must not be used from outside.
81      * New elements automatically are generated and stored by the Locator,
82      * so no one really needs to use this method.
83      * @param descriptor - the descriptor for this element.
84      * @param element - the Element to put in this locator.
85      */

86     private void put(CmsElementDescriptor desc, A_CmsElement element) {
87         Vector JavaDoc removedElement = m_elements.put(desc, element);
88         if(removedElement != null && m_dependenciesExtern != null){
89             // look if the element is critical and if clear the m_dependenciesExtern table
90
removeElementFromDependencies((CmsElementDescriptor)removedElement.firstElement(),
91                                             (A_CmsElement)removedElement.lastElement());
92         }
93     }
94
95     /**
96      * Deletes all variantdependenciesEntries of an Element from the extern dependencies table.
97      *
98      * @param the descriptor of the element.
99      * @param the element itself.
100      */

101     public void removeElementFromDependencies(CmsElementDescriptor desc, A_CmsElement element){
102         if(element.hasDependenciesVariants()){
103             Vector JavaDoc variantKeys = element.getAllVariantKeys();
104             String JavaDoc cacheStart = desc.getClassName() +"|"+ desc.getTemplateName() +"|";
105             for(int i=0; i<variantKeys.size(); i++){
106                 String JavaDoc key = (String JavaDoc)variantKeys.elementAt(i);
107                 removeVariantFromDependencies(cacheStart + key, element.getVariant(key));
108             }
109         }
110     }
111
112     /**
113      * Deletes all variantdependenciesEntries of an Variant from the extern dependencies table.
114      *
115      * @param key the compleate entry in the table like "classname|template|variantcachekey"
116      * @param the variant
117      */

118     public void removeVariantFromDependencies(String JavaDoc key, CmsElementVariant variant){
119
120         if(variant != null){
121             Vector JavaDoc variantDeps = variant.getDependencies();
122             if(variantDeps != null){
123                 for(int j=0; j<variantDeps.size(); j++){
124                     Vector JavaDoc externEntrys = (Vector JavaDoc)m_dependenciesExtern.get(variantDeps.elementAt(j));
125                     if(externEntrys != null){
126                         externEntrys.removeElement(key);
127                     }
128                 }
129             }
130         }
131     }
132
133     /**
134      * Gets a Elements from this locator.
135      * @param desc - the descriptor to locate the element.
136      * @return the element that was found.
137      */

138     public A_CmsElement get(CmsObject cms, CmsElementDescriptor desc, Hashtable JavaDoc parameters) throws CmsException{
139         A_CmsElement result;
140         result = (A_CmsElement)m_elements.get(desc);
141         if(result == null) {
142             // the element was not found in the element cache
143
// we have to generate it
144
I_CmsTemplate cmsTemplate = null;
145             // look if it is an methode element
146
if("METHOD".equals(desc.getTemplateName())){
147                 String JavaDoc orgClassName = desc.getClassName();
148                 String JavaDoc className = orgClassName.substring(0,orgClassName.lastIndexOf("."));
149                 String JavaDoc methodName = orgClassName.substring(orgClassName.lastIndexOf(".")+1);
150                 try {
151                     cmsTemplate = (I_CmsTemplate)com.opencms.template.CmsTemplateClassManager.getClassInstance(className);
152                     CmsMethodCacheDirectives mcd = (CmsMethodCacheDirectives)cmsTemplate.getClass().getMethod(
153                                                     "getMethodCacheDirectives", new Class JavaDoc[] {
154                                                     CmsObject.class, String JavaDoc.class}).invoke(cmsTemplate,
155                                                     new Object JavaDoc[] {cms, methodName});
156                     result = new CmsMethodElement(className, methodName, mcd,
157                              CmsXmlTemplateLoader.getElementCache().getVariantCachesize());
158                     put(desc, result);
159                 } catch(Throwable JavaDoc e) {
160                     if(CmsLog.getLog(this).isErrorEnabled()) {
161                         CmsLog.getLog(this).error("Could not initialize method element for class \"" + className + "\"", e);
162                         return null;
163                     }
164                 }
165             }else{
166                 try {
167                     cmsTemplate = (I_CmsTemplate)com.opencms.template.CmsTemplateClassManager.getClassInstance(desc.getClassName());
168                     result = cmsTemplate.createElement(cms, desc.getTemplateName(), parameters);
169                     put(desc, result);
170                 } catch(Throwable JavaDoc e) {
171                     if(CmsLog.getLog(this).isErrorEnabled()) {
172                         CmsLog.getLog(this).error("Could not initialize (sub-)element for class \"" + desc.getClassName() + "\"", e);
173                         throw new CmsLegacyException("Could not initialize (sub-)element for class \"" +
174                                              desc.getClassName() + "\". " +e.toString() , CmsLegacyException.C_XML_WRONG_TEMPLATE_CLASS);
175                     }
176                 }
177             }
178         }
179         return result;
180     }
181
182     /**
183      * Gets the Information of max size and size for the cache.
184      *
185      * @return a Vector whith informations about the size of the cache.
186      */

187     public Vector JavaDoc getCacheInfo(){
188         return m_elements.getCacheInfo();
189     }
190
191     /**
192      * for debbuging only. Prints information about the cache system.
193      *
194      * @param selector Selects which info is printed.
195      */

196     public void printCacheInfo(int selector){
197
198         if(selector == 1){
199             // info about the dependencies stores
200
System.err.println("");
201             System.err.println("");
202             System.err.println("=======================");
203             System.err.println("The dependencies stores");
204             System.err.println("=======================");
205             System.err.println("");
206             System.err.println("=======================");
207             System.err.println("The extern Hashtable:");
208             System.err.println("=======================");
209             int countExtern = 0;
210             int countIntern = 0;
211             if(m_dependenciesExtern != null){
212                 Enumeration JavaDoc enu = m_dependenciesExtern.keys();
213                 int count = 1;
214                 System.err.println("");
215                 while(enu.hasMoreElements()){
216                     String JavaDoc key = (String JavaDoc)enu.nextElement();
217                     System.err.println("<"+count+"> "+key);
218                     Vector JavaDoc entrysVector = (Vector JavaDoc)m_dependenciesExtern.get(key);
219                     if(entrysVector == null){
220                         System.err.println(" Vector is null.");
221                     }else{
222                         if(entrysVector.size() == 0){
223                             System.err.println(" Vector is empty.");
224                         }
225                         for(int i=0; i<entrysVector.size(); i++){
226                             System.err.println(" ("+i+") "+(String JavaDoc)entrysVector.elementAt(i));
227                             countExtern++;
228                         }
229                     }
230                     System.err.println("");
231                     count++;
232                 }
233             }else{
234                 System.err.println("... is null!");
235             }
236             System.err.println("");
237             System.err.println("===================================");
238             System.err.println("The values in the element Variants:");
239             System.err.println("===================================");
240             //first we need all elements
241
Vector JavaDoc elementKeys = m_elements.getAllKeys();
242             for(int i=0; i<elementKeys.size(); i++){
243                 A_CmsElement element = (A_CmsElement)m_elements.get(elementKeys.elementAt(i));
244                 if(element.hasDependenciesVariants()){
245                     System.err.println("");
246                     System.err.println("<"+i+"> element:"+element.toString());
247                     Vector JavaDoc variants = element.getAllVariantKeys();
248                     if(variants == null || variants.size() == 0){
249                         System.err.println(" no variants.");
250                     }else{
251                         // now all variants from this elemetn
252
for(int j=0; j<variants.size(); j++){
253                             CmsElementVariant vari = element.getVariant(variants.elementAt(j));
254                             System.err.println("");
255                             System.err.println(" ("+j+")variant:"+(String JavaDoc)variants.elementAt(j));
256                             System.err.println(" timed:"+vari.isTimeCritical() + " nextTimeOut:"+vari.getNextTimeout() );
257                             Vector JavaDoc currentDeps = vari.getDependencies();
258                             if(currentDeps == null || currentDeps.size() == 0){
259                                 System.err.println(" no dependencies in this element");
260                             }else{
261                                 for(int k=0; k<currentDeps.size(); k++){
262                                     System.err.println(" ["+k+"] "+(String JavaDoc)currentDeps.elementAt(k));
263                                     countIntern++;
264                                 }
265                                 System.err.println("");
266                             }
267                         }
268                     }
269                 }
270             }
271             System.err.println("");
272             System.err.println("==================================");
273             System.err.println("==== found in Extern store: "+countExtern);
274             System.err.println("===================================");
275             System.err.println("==== found in Intern store: "+countIntern);
276             System.err.println("===================================");
277             System.err.println("");
278         }
279     }
280
281     /**
282      * deletes all elements in the cache that depend on one of the invalid Templates.
283      * @param invalidTemplates A vector with the ablolute path of the templates (String)
284      */

285     public void cleanupElementCache(Vector JavaDoc invalidTemplates){
286
287         cleanupExternDependencies(m_elements.deleteElementsAfterPublish());
288         for(int i=0; i < invalidTemplates.size(); i++){
289             cleanupExternDependencies(
290                     m_elements.deleteElementsByTemplate((String JavaDoc)invalidTemplates.elementAt(i)));
291         }
292     }
293
294     /**
295      * Clears the cache from unvalid variants. It looks for each entry in the invalidResources
296      * if there are variants that depend on it. If so this variant has to be deleted and
297      * the extern dependencies table is updated.
298      *
299      * @param invalidResources A vector of Strings with the entrys to compare to the
300      * externDependencies Hashtable. These entrys are resources in the vfs or
301      * the cos that are changed or deleted.
302      */

303     public void cleanupDependencies(Vector JavaDoc invalidResources){
304
305         if(invalidResources != null){
306             for(int i=0; i<invalidResources.size(); i++){
307                 Enumeration JavaDoc extKeys = m_dependenciesExtern.keys();
308                 String JavaDoc aktInvalid = (String JavaDoc)invalidResources.elementAt(i);
309                 while(extKeys.hasMoreElements()){
310                     String JavaDoc current = (String JavaDoc)extKeys.nextElement();
311                     if(aktInvalid.startsWith(current) || current.startsWith(aktInvalid)){
312                         Vector JavaDoc variantsToDelete = (Vector JavaDoc)m_dependenciesExtern.get(current);
313                         if(variantsToDelete != null){
314                             // delete all the variants in this vector
315
for(int j=0; j < variantsToDelete.size(); j++){
316                                 String JavaDoc variantKey = (String JavaDoc)variantsToDelete.elementAt(j);
317                                 // get the element for this variant
318
StringTokenizer JavaDoc tocy = new StringTokenizer JavaDoc(variantKey, "|", false);
319                                 String JavaDoc classname = tocy.nextToken();
320                                 String JavaDoc templatename = tocy.nextToken();
321                                 String JavaDoc cacheDirectivesKey = tocy.nextToken();
322                                 CmsElementDescriptor desc = new CmsElementDescriptor(classname, templatename);
323                                 A_CmsElement currentElement = (A_CmsElement)m_elements.get(desc);
324                                 if(currentElement != null){
325                                     removeVariantFromDependencies(variantKey, currentElement.getVariant(cacheDirectivesKey));
326                                     currentElement.removeVariant(cacheDirectivesKey);
327                                 }
328                             }
329                         }
330                     }
331                 }
332             }
333             // now remove all empty entrys in the extern table
334
Enumeration JavaDoc extKeys = m_dependenciesExtern.keys();
335             while(extKeys.hasMoreElements()){
336                 String JavaDoc currentKey = (String JavaDoc)extKeys.nextElement();
337                 Vector JavaDoc currentValue = (Vector JavaDoc)m_dependenciesExtern.get(currentKey);
338                 if(currentValue == null || currentValue.size() == 0){
339                     m_dependenciesExtern.remove(currentKey);
340                 }
341             }
342         }
343     }
344
345     /**
346      * Removes the elements from the extern Dependencies table.
347      *
348      * @param elements. A Vector with the elements to be removed. This Vector
349      * contains Vectors. Each of this vectors contains two objects.
350      * The first one is the CmsElementDescriptor of the element and
351      * the second one is the element itself(A_CmsElement).
352      */

353     private void cleanupExternDependencies(Vector JavaDoc elements){
354         if(elements != null){
355             for(int i=0; i<elements.size(); i++){
356                 Vector JavaDoc actElement = (Vector JavaDoc)elements.elementAt(i);
357                 removeElementFromDependencies((CmsElementDescriptor)actElement.firstElement(),
358                                                 (A_CmsElement)actElement.lastElement());
359             }
360         }
361     }
362
363     /**
364      * Clears the cache compleatly.
365      */

366     public void clearCache(){
367         m_elements.clearCache();
368         if(m_dependenciesExtern != null){
369             m_dependenciesExtern.clear();
370         }
371     }
372
373     /**
374      * TODO: there should be only one way to get this vector. remove the way through the
375      * cms Object?
376      */

377     public Hashtable JavaDoc getExternDependencies(){
378         return m_dependenciesExtern;
379     }
380
381     /**
382      * sets the extern dependencies vector used to keep the dep information syncron.
383      */

384     public void setExternDependencies(Hashtable JavaDoc externDeps){
385         m_dependenciesExtern = externDeps;
386     }
387
388 }
Popular Tags