001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019:
020: package de.schlund.pfixxml.targets;
021:
022: import java.lang.reflect.Constructor;
023: import java.lang.reflect.InvocationTargetException;
024: import java.util.Properties;
025:
026: import org.apache.log4j.Logger;
027:
028: import de.schlund.pfixxml.IncludeDocument;
029:
030: /**
031: * SPCacheFactory.java
032: *
033: *
034: * Created: Mon Jul 23 17:06:56 2001
035: *
036: * @author <a href="mailto:jtl@schlund.de">Jens Lautenbacher</a>
037: * @author <a href="mailto:haecker@schlund.de">Joerg Haecker</a>
038: *
039: * This class realises the factory and the singleton pattern and implements the {@link FactoryInit}
040: * interface. It is responsible to create and store the caches uses by the PUSTEFIX system.
041: * Currently PUSTEFIX uses one cache for the targets and one for the include-modules. The
042: * properties of the caches are passed via the init-method of the FactoryInit-interface.
043: * If the propertries can't be interpreted correctly or the init-method is not called,
044: * {@link LRUCache} initialised with default values will be returned.
045: *
046: */
047:
048: public class SPCacheFactory {
049: private final static Logger LOG = Logger
050: .getLogger(SPCacheFactory.class);
051: private static SPCacheFactory instance = new SPCacheFactory();
052:
053: private SPCache<Object, Object> targetCache = new LRUCache<Object, Object>();
054: private SPCache<String, IncludeDocument> documentCache = new LRUCache<String, IncludeDocument>();
055:
056: private static final String PROP_TARGET_CACHE_CLASS = "targetcache.cacheclass";
057: private static final String PROP_TARGET_CACHE_SIZE = "targetcache.cachecapacity";
058:
059: private static final String PROP_DOCUMENT_CACHE_CLASS = "includecache.cacheclass";
060: private static final String PROP_DOCUMENT_CACHE_SIZE = "includecache.cachecapacity";
061:
062: private SPCacheFactory() {
063: }
064:
065: /**
066: * Implemented from FactoryInit.
067: */
068: public void init(Properties props) {
069: synchronized (targetCache) {
070: targetCache.createCache(LRUCache.DEFAULT_SIZE);
071: SPCache<Object, Object> tmp = getConfiguredCache(props,
072: PROP_TARGET_CACHE_CLASS, PROP_TARGET_CACHE_SIZE);
073: if (tmp != null) {
074: targetCache = tmp;
075: }
076: }
077:
078: synchronized (documentCache) {
079: documentCache.createCache(LRUCache.DEFAULT_SIZE);
080: SPCache<String, IncludeDocument> tmp = getConfiguredCache(
081: props, PROP_DOCUMENT_CACHE_CLASS,
082: PROP_DOCUMENT_CACHE_SIZE);
083: if (tmp != null) {
084: documentCache = tmp;
085: }
086: }
087: if (LOG.isInfoEnabled()) {
088: LOG.info("SPCacheFactory initialized: ");
089: LOG.info(" TargetCache : Class="
090: + targetCache.getClass().getName() + " Capacity="
091: + targetCache.getCapacity() + " Size="
092: + targetCache.getSize());
093: LOG.info(" DocumentCache : Class="
094: + documentCache.getClass().getName() + " Capacity="
095: + documentCache.getCapacity() + " Size="
096: + documentCache.getSize());
097: }
098: }
099:
100: private <T1, T2> SPCache<T1, T2> getConfiguredCache(
101: Properties props, String propNameClass, String propNameSize) {
102: SPCache<T1, T2> tmp = null;
103: if (props != null) {
104: String classname = props.getProperty(propNameClass);
105: String csize = props.getProperty(propNameSize);
106: boolean sizeError = false;
107: int cachesize = 0;
108:
109: if (csize != null) {
110: try {
111: cachesize = Integer.parseInt(csize);
112: } catch (NumberFormatException e) {
113: sizeError = true;
114: LOG.error("The property " + propNameSize
115: + " is not an int");
116: }
117: } else {
118: sizeError = true;
119: LOG.error("The property " + propNameSize + " is null");
120: }
121:
122: if (classname != null && !sizeError) {
123:
124: //LOG.warn("*** Found SPCache classname '" + classname + "' in properties!");
125:
126: tmp = getCache(classname);
127: if (tmp != null)
128: tmp.createCache(cachesize);
129: } else
130: LOG.error("Property " + propNameClass + " is null");
131:
132: } else
133: LOG.error("Properties for caches are null");
134:
135: return tmp;
136: }
137:
138: @SuppressWarnings("unchecked")
139: private <T1, T2> SPCache<T1, T2> getCache(String classname) {
140: SPCache<T1, T2> retval = null;
141: try {
142: Constructor<? extends SPCache> constr = Class.forName(
143: classname).asSubclass(SPCache.class)
144: .getConstructor((Class[]) null);
145: retval = constr.newInstance((Object[]) null);
146: } catch (InstantiationException e) {
147: LOG.error(
148: "unable to instantiate class [" + classname + "]",
149: e);
150: } catch (IllegalAccessException e) {
151: LOG.error("unable access class [" + classname + "]", e);
152: } catch (ClassNotFoundException e) {
153: LOG.error("unable to find class [" + classname + "]", e);
154: } catch (NoSuchMethodException e) {
155: LOG.error("unable to find correct method in [" + classname
156: + "]", e);
157: } catch (InvocationTargetException e) {
158: LOG.error("unable to invoke correct method in ["
159: + classname + "]", e);
160: } catch (ClassCastException e) {
161: LOG.error("class [" + classname
162: + "] does not implement the interface SPCache", e);
163: }
164: return retval;
165: }
166:
167: /**
168: * The getInstance method of a singleton.
169: */
170: public static SPCacheFactory getInstance() {
171: return instance;
172: }
173:
174: /**
175: * Get the cache for targets.
176: */
177: public synchronized SPCache<Object, Object> getCache() {
178: synchronized (targetCache) {
179: /*LOG.debug("Cache is: "+targetCache.getClass().getName());
180: LOG.debug("Cache capacity is: "+targetCache.getCapacity());
181: LOG.debug("Cache size is: "+targetCache.getSize());*/
182: return targetCache;
183: }
184: }
185:
186: /**
187: * Get the cache for include-modules.
188: */
189: public synchronized SPCache<String, IncludeDocument> getDocumentCache() {
190: synchronized (documentCache) {
191: /*LOG.debug("DocumentCache is: "+documentCache.getClass().getName());
192: LOG.debug("DocumentCache capacity is: "+documentCache.getCapacity());
193: LOG.debug("DocumentCache size is: "+documentCache.getSize());*/
194: return documentCache;
195: }
196: }
197:
198: /**
199: * To be used with care! If you need it, take care to throw away your old instance of SPCache retrieved
200: * through getCache() and getDocumentCache()!
201: */
202: public void reset() {
203: targetCache = new LRUCache<Object, Object>();
204: documentCache = new LRUCache<String, IncludeDocument>();
205: }
206:
207: } // SPCacheFactory
|