001: /*
002: * IndexManager.java
003: *
004: * Created on 01 June 2003, 08:17
005: */
006:
007: package com.jofti.manager;
008:
009: import java.io.InputStream;
010: import java.lang.reflect.Constructor;
011: import java.util.Iterator;
012: import java.util.Map;
013:
014: import org.apache.commons.logging.Log;
015: import org.apache.commons.logging.LogFactory;
016:
017: import com.jofti.api.Index;
018: import com.jofti.api.IndexManager;
019: import com.jofti.api.NameSpacedIndex;
020: import com.jofti.cache.LifeCycleAdapter;
021: import com.jofti.cache.NameSpacedCacheAdapter;
022: import com.jofti.config.ConfigFileParser;
023: import com.jofti.config.IndexConfig;
024: import com.jofti.core.GenericIndexFactory;
025: import com.jofti.core.InternalIndex;
026: import com.jofti.exception.JoftiException;
027: import com.jofti.introspect.ClassIntrospector;
028: import com.jofti.util.ReflectionUtil;
029:
030: import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
031:
032: /**
033: *
034:
035: *
036: *
037: * The manager is responsible for providing access to caches. This class is not a singleton
038: * and is not intended to be used in that manner.<p>
039: *
040: * The usage for the cache manager is:<p>
041: *
042: * IndexManager manager = new IndexManagerImpl();<br>
043: * manager.setConfigFile("configFile");<br>
044: * manager.init(); <br>
045: * IndexCache index = manager.getIndex("name");<br>
046: * <p>
047: * or:
048: * <p>
049: * IndexManager manager = new IndexManagerImpl();<br>
050: * manager.init(inputStream); <br>
051: * IndexCache index = manager.getIndex("name");<br>
052: * <p>
053: * or
054: * <p>
055: * IndexManager manager = new IndexManagerImpl();<br>
056: * manager.init(configFile); <br>
057: * IndexCache index = manager.getIndex("name");<br>
058: * <p>
059: * The name of the index is one of the indexs configured in the configFile.
060: * <p>
061: * NameSpaced caches such as JBossCache are obtained using:
062: * <p>
063: * IndexManager manager = new IndexManagerImpl();<br>
064: * manager.init(configFile); <br>
065: * NameSpacedIndex index = manager.getNameSpacedIndex("name");<br>
066: * <p>
067: * @author Steve Woodcock
068: * @version 1.0
069: *
070: */
071: public class IndexManagerImpl implements IndexManager {
072:
073: private static Log log = LogFactory.getLog(IndexManagerImpl.class);
074:
075: private final Map cacheMap = new ConcurrentHashMap();
076:
077: private final Map configMap = new ConcurrentHashMap();
078:
079: private String configFile = null;
080:
081: private boolean initialised = false;
082:
083: /** Creates a new instance of IndexManagerImpl */
084: public IndexManagerImpl() {
085:
086: }
087:
088: /**
089: * Sets a config file to use in the indexManager. This file must be on the
090: * classpath.
091: */
092: public void setConfigFile(String configFile) {
093: this .configFile = configFile;
094: }
095:
096: /**
097: *
098: * Initialise method that takes a config file name. This over-rides the
099: * fileName (if any) set in the setConfigFile() method.
100: *
101: * @param configFileName
102: * @throws JoftiException
103: */
104: public synchronized void init(String configFileName)
105: throws JoftiException {
106:
107: if (!initialised) {
108:
109: Map temp = null;
110: if (log.isInfoEnabled()) {
111: log.info("Loading config from file '" + configFileName
112: + "'");
113: }
114: temp = loadConfig(configFileName);
115: if (log.isInfoEnabled()) {
116: log.info("Loaded config from file '" + configFileName
117: + "'");
118: }
119: configureIndexes(temp);
120: initialised = true;
121: } else {
122: if (log.isWarnEnabled()) {
123: log
124: .warn("IndexCache is already initialised - ignoring repeat attempt using '"
125: + configFileName + "'");
126: }
127: }
128: }
129:
130: /**
131: *
132: * Initialise method that no parameters. This configures the Indexes with the
133: * fileName set in the setConfigFile() method.
134: *
135: * @throws JoftiException
136: */
137: public synchronized void init() throws JoftiException {
138:
139: if (!initialised) {
140:
141: Map temp = null;
142: if (configFile != null) {
143: if (log.isInfoEnabled()) {
144: log.info("Loading config from file '" + configFile
145: + "'");
146: }
147:
148: temp = loadConfig(configFile);
149:
150: if (log.isInfoEnabled()) {
151: log.info("Loaded config from file '" + configFile
152: + "'");
153: }
154: configureIndexes(temp);
155: } else {
156: if (log.isInfoEnabled()) {
157: log
158: .info("No config file configured - not loading any caches");
159: }
160: }
161: initialised = true;
162: } else {
163: if (log.isWarnEnabled()) {
164: log
165: .warn("IndexCache is already initialised - ignoring repeat attempt ");
166: }
167: }
168: }
169:
170: /**
171: *
172: * Initialise method that takes an inputstream. This over-rides the fileName
173: * (if any) set in the setConfigFile() method.
174: *
175: * @param configStream
176: * @throws JoftiException
177: */
178: public synchronized void init(InputStream configStream)
179: throws JoftiException {
180:
181: if (!initialised) {
182:
183: Map temp = null;
184: if (log.isInfoEnabled()) {
185: log.info("Loading config from stream");
186: }
187: temp = loadConfig(configStream);
188: if (log.isInfoEnabled()) {
189: log.info("Loaded config from stream");
190: }
191: configureIndexes(temp);
192: initialised = true;
193: } else {
194: if (log.isWarnEnabled()) {
195: log
196: .warn("IndexCache is already initialised - ignoring repeat attempt ");
197: }
198: }
199: }
200:
201: /**
202: * This method allows cache instances to be added to the cache
203: * programatically rather than at start-up. <p>
204: * The usage is for example:<p>
205: *
206: * DefaultIndexConfig config = new DefaultIndexConfig();<br>
207: * config.setName("test");<br>
208: * IndexCache index = (IndexCache)<br>
209: * manager.addIndexedCache(config, <cacheImpl>,
210: * <xml-filename-with-classes-in-it>);<br>
211: * <p>
212: * any type of cache can be added in this manner, providing a CacheAdapter
213: * exists for it and the correct adapter has been configured in the
214: * @link IndexConfig class.
215: * <p>
216: * If you are using a nameSpaced cache like JBossCache then the usage would
217: * be:
218: * <p>
219: * DefaultIndexConfig config = new DefaultIndexConfig();<br>
220: * config.setName("test"); <br>
221: * NameSpacedIndex index = (NameSpacedIndex)
222: * manager.addIndexedCache(config, <cacheImpl>, <xml-filename-with-classes-in-it>);<br>
223: * <p>
224: * Note: The cache implementations must be started correctly before they are
225: * passed into this method. Added caches are assumed to have been started
226: * and the manager will NOT attempt to initialise the actual cache
227: * implementation.
228: * <p>
229: *
230: * @param config -
231: * the config class containing definitions of the adapter, index
232: * type and parser to use.
233: * @param cache -
234: * the cache implementation. Passing NULL will result in the adapter creating a new
235: * cache instance.
236: * @param classesFileName -
237: * the xml file containing the classes definitions for the cache.
238: * This file must be available on the classpath.
239: * @return The added cache.
240: * @throws JoftiException
241: */
242: public Index addIndex(IndexConfig config, Object cache,
243: String classesFileName) throws JoftiException {
244:
245: config = parseClassesForConfig(config, classesFileName);
246: return createIndexedCache(config, cache);
247:
248: }
249:
250: /**
251: * This method allows cache instances to be added to the cache
252: * programatically rather than at start-up. This method will result in the
253: * adapter used creating a new instance of its cache type.<p>
254: *
255: *
256: *
257: * Any type of cache can be added in this manner, providing a CacheAdapter
258: * exists for it and the correct adapter has been configured in the
259: * @link IndexConfig class.
260: * <p>
261: * Note: This method is the equivalent of an index entry in the
262: * configuration file. The manager will atttempt to construct and initialise
263: * a new indexed cache based on the attributes in the cacheConfig class and
264: * the class definition file.
265: * <p>
266: * @param config -
267: * the config class containing definitions of the adapter, index
268: * type and parser to use.
269: * @param classesFileName -
270: * the xml file containing the classes definitions for the
271: * cache.This file must be available on the classpath.
272: * @return The added cache.
273: * @throws JoftiException
274: */
275: public Index addIndexCache(IndexConfig config,
276: String classesFileName) throws JoftiException {
277:
278: config = parseClassesForConfig(config, classesFileName);
279: return createIndexedCache(config, null);
280:
281: }
282:
283: /**
284: * This method allows cache instances to be added to the cache
285: * programatically rather than at start-up.
286: * <p>
287: *
288: *
289: * Any type of cache can be added in this manner, providing a CacheAdapter
290: * exists for it and the correct adapter has been configured in the
291: * @link IndexConfig class. This method will result in the
292: * adapter used creating a new instance of its cache type.
293: * <p>
294: * Note: This method is the equivalent of an index entry in the
295: * configuration file. The manager will atttempt to construct and initialise
296: * a new indexed cache based solely on the attributes in the cacheConfig
297: * class.
298: * <p>
299: * Class definitions can be added using attribute classMappings in the
300: * IndexConfig class. See this class for details on how to configure these.
301: * <p>
302: * @param config -
303: * the config class containing definitions of the adapter, index
304: * type and parser to use.
305: * @return The added cache.
306: * @throws JoftiException
307: */
308:
309: public Index addIndexCache(IndexConfig config)
310: throws JoftiException {
311:
312: return createIndexedCache(config, null);
313:
314: }
315:
316: /**
317: * This method allows cache instances to be added to the cache
318: * programatically rather than at start-up. The usage is for example:
319: * <p>
320: * DefaultIndexConfig config = new DefaultIndexConfig();<br>
321: * config.setName("test"); <br>
322: * IndexCache index = (IndexCache)
323: * manager.addIndexedCache(config, <cacheImpl>,
324: * <xml-filename-with-classes-in-it>);<br>
325: * <p>
326: * any type of cache can be added in this manner, providing a CacheAdapter
327: * exists for it and the correct adapter has been configured in the
328: * @link IndexConfig class.
329: * <p>
330: * If you are using a nameSpaced cache like JBossCache then the usage would
331: * be:
332: * <p>
333: * DefaultIndexConfig config = new DefaultIndexConfig();<br>
334: * config.setName("test");<br>
335: * NameSpacedIndex index = (NameSpacedIndex)
336: * manager.addIndexedCache(config, <cacheImpl>);<br>
337: * <p>
338: * Note: The cache implementations must be started correctly before they are
339: * passed into this method. Added caches are assumed to have been started
340: * and the manager will NOT attempt to initialise the actual cache
341: * implementation.
342: * <p>
343: *
344: * @param config -
345: * the config class containing definitions of the adapter, index
346: * type and parser to use.
347: * @param cache -
348: * the cache implementation. Passing NULL will result in the adapter creating a new
349: * cache instance.
350: * @return The added cache.
351: * @throws JoftiException
352: */
353: public Index addIndex(IndexConfig config, Object cache)
354: throws JoftiException {
355:
356: return createIndexedCache(config, cache);
357:
358: }
359:
360: /* (non-Javadoc)
361: * @see com.jofti.api.IndexManager#addIndexedCache(com.jofti.config.IndexConfig, java.lang.Object, java.io.InputStream)
362: */
363: public Index addIndex(IndexConfig config, Object cache,
364: InputStream stream) throws JoftiException {
365: config = parseClassesForConfig(config, stream);
366: return createIndexedCache(config, cache);
367:
368: }
369:
370: private IndexConfig parseClassesForConfig(IndexConfig config,
371: InputStream stream) throws JoftiException {
372: if (log.isDebugEnabled()) {
373: log.info("parsing classes from inputStream ");
374: }
375: // load the classes to be indexed from the supplied file
376: config = loadConfig(config, stream);
377:
378: if (log.isDebugEnabled()) {
379: log.info("successfully parsed classes from inputStream ");
380: }
381: // return the config with the parsed classes in it.
382: return config;
383: }
384:
385: /**
386: * This method does the actual work of loading in the class definitions from the file.
387: *
388: *
389: * @param config -
390: * the config class containing definitions of the adapter, index
391: * type and parser to use.
392: * @param classesFileName -
393: * the xml file containing the classes definitions for the
394: * cache.This file must be available on the classpath.
395: * @return The cacheConfig object with the class definitions added.
396: * @throws JoftiException
397: */
398: private IndexConfig parseClassesForConfig(IndexConfig config,
399: String fileName) throws JoftiException {
400: if (log.isDebugEnabled()) {
401: log.info("parsing classes from file " + fileName);
402: }
403: // load the classes to be indexed from the supplied file
404: config = loadConfig(config, fileName);
405:
406: if (log.isDebugEnabled()) {
407: log.info("successfully parsed classes from file "
408: + fileName);
409: }
410: // return the config with the parsed classes in it.
411: return config;
412: }
413:
414: /**
415: * This method does the actual work of creating the cache for the addIndexCache methods.
416: *
417: *
418: * @param config -
419: * the config class containing definitions of the adapter, index
420: * type and parser to use.
421: * @param cache -
422: * the cache implementation.
423: * @return The added cache.
424: * @throws JoftiException
425: */
426: private Index createIndexedCache(IndexConfig config, Object cache)
427: throws JoftiException {
428:
429: // load up the adaptor
430: if (log.isInfoEnabled()) {
431: log.info("loading cache '" + config.getName()
432: + "' with adapter " + config.getCacheAdapter());
433: }
434: LifeCycleAdapter cacheAdaptor = null;
435:
436: // if we do not have a supplied cache then the adapter will create one
437: if (cache == null) {
438: cacheAdaptor = loadAdaptor(config);
439: } else {
440: cacheAdaptor = loadAdaptor(config, cache);
441: }
442:
443: // set the name for the adapter - used as the key in the cacheMap
444: cacheAdaptor.setName(config.getName());
445:
446: if (cacheAdaptor.getName() == null) {
447: throw new JoftiException(
448: "A cache must have a name to be inserted into the cache");
449: }
450: // we should now call init - it is up to the dapter to protect itself
451:
452: cacheAdaptor.init(config.getAdapterProperties());
453:
454: if (log.isInfoEnabled()) {
455: log.info("Configuring cache '" + cacheAdaptor.getName()
456: + "'");
457: }
458:
459: // create the wrapper for the cache
460: cacheAdaptor = configureIndexedCache(config, cacheAdaptor);
461:
462: if (log.isInfoEnabled()) {
463: log.info("Starting cache '" + cacheAdaptor.getName() + "'");
464: }
465: // start the wrapper to start the caches
466: cacheAdaptor.start();
467:
468: if (cacheMap.get(config.getName()) != null) {
469: log
470: .warn("added cache '"
471: + cacheAdaptor.getName()
472: + "' will replace an already existing cache of the same name in the loaded cache mappings");
473: }
474: cacheMap.put(config.getName(), cacheAdaptor);
475: if (log.isInfoEnabled()) {
476: log.info("Added cache '" + cacheAdaptor.getName()
477: + "' to loaded caches");
478: }
479: return (Index) cacheAdaptor;
480: }
481:
482: /**
483: * Configures each of the caches in turn from the config file used to initialise the manager.
484: *
485: * @param configuredMap
486: * @throws JoftiException
487: */
488: private void configureIndexes(Map configuredMap)
489: throws JoftiException {
490:
491: configMap.putAll(configuredMap);
492:
493: // we have loaded the map so lets now create our internal stuff
494: if (log.isInfoEnabled()) {
495: log.info("Initialising indexes and caches");
496: }
497: // loop through the map of config entries and try and inialise each one
498: for (Iterator it = configMap.entrySet().iterator(); it
499: .hasNext();) {
500: Map.Entry entry = (Map.Entry) it.next();
501: IndexConfig config = (IndexConfig) entry.getValue();
502: LifeCycleAdapter adapter = null;
503:
504: // see if cache is lazy loaded
505:
506: if (log.isInfoEnabled()) {
507: log.info("instantiating adapter '" + config.getName()
508: + "'");
509: }
510: adapter = instantiateAdapter(config);
511: if (log.isInfoEnabled()) {
512: log.info("instantiated adapter '" + config.getName()
513: + "'");
514: }
515:
516: // carry on and do the indexes even if we have no cache started
517: // configure each cache
518: if (log.isInfoEnabled()) {
519: log.info("Configuring index for cache '"
520: + config.getName() + "'");
521: }
522: // configure the wrapper
523: adapter = configureIndexedCache(config, adapter);
524:
525: //add the queries
526:
527: // start the caches
528: adapter.start();
529: if (log.isInfoEnabled()) {
530: log.info("IndexCache Configured for cache '"
531: + config.getName() + "'");
532: }
533:
534: cacheMap.put(config.getName(), adapter);
535: }
536:
537: }
538:
539: private synchronized LifeCycleAdapter instantiateAdapter(
540: IndexConfig config) throws JoftiException {
541: LifeCycleAdapter adapter = null;
542:
543: if (config == null) {
544: return adapter;
545: } else {
546:
547: // create the cache adapter
548: adapter = loadAdaptor(config);
549: adapter.setName(config.getName());
550: // now try and do the complicated stuff
551: if (log.isInfoEnabled()) {
552: log.info("initialising adapter '" + config.getName()
553: + "'");
554: }
555: try {
556: // initialise the cache - we should pass in some properties here
557: adapter.init(config.getAdapterProperties());
558: } catch (Throwable e) {
559: log.error("Unable to instantiate adapter for '"
560: + config.getName() + "':" + e);
561: try {
562: if (adapter != null) {
563: adapter.destroy();
564: }
565: } catch (Throwable t) {
566: throw new JoftiException(t);
567: }
568: throw new JoftiException(e);
569: }
570: if (log.isInfoEnabled()) {
571: log.info("initialised adapter '" + config.getName()
572: + "'");
573: }
574: }
575: return adapter;
576: }
577:
578: /**
579: * @param config
580: * @return
581: * @throws JoftiException
582: */
583:
584: private LifeCycleAdapter loadAdaptor(IndexConfig config,
585: Object cacheImpl) throws JoftiException {
586: LifeCycleAdapter cache;
587: if (log.isDebugEnabled()) {
588: log.debug("Creating adaptor " + config.getCacheAdapter()
589: + " for '" + config.getName() + "'");
590: }
591:
592: cache = (LifeCycleAdapter) createClass(
593: config.getCacheAdapter(), cacheImpl);
594: if (log.isDebugEnabled()) {
595: log.debug("Created adaptor " + config.getCacheAdapter()
596: + " for '" + config.getName() + "'");
597: }
598: return cache;
599: }
600:
601: private LifeCycleAdapter loadAdaptor(IndexConfig config)
602: throws JoftiException {
603: LifeCycleAdapter cache;
604: if (log.isDebugEnabled()) {
605: log.debug("Creating adaptor " + config.getCacheAdapter()
606: + " for '" + config.getName() + "'");
607: }
608: cache = (LifeCycleAdapter) createClass(config.getCacheAdapter());
609: if (log.isDebugEnabled()) {
610: log.debug("Created adaptor " + config.getCacheAdapter()
611: + " for '" + config.getName() + "'");
612: }
613: return cache;
614: }
615:
616: private LifeCycleAdapter configureIndexedCache(IndexConfig config,
617: LifeCycleAdapter adapter) throws JoftiException {
618:
619: if (config == null) {
620: return null;
621: } else {
622:
623: try {
624: // create the parser
625: if (log.isDebugEnabled()) {
626: log.debug("Creating parser "
627: + config.getParserType() + " for '"
628: + config.getName() + "'");
629: }
630: ClassIntrospector parser = (ClassIntrospector) createClass(config
631: .getParserType());
632:
633: if (log.isDebugEnabled()) {
634: log.debug("Created parser "
635: + config.getParserType() + " for '"
636: + config.getName() + "'");
637: }
638:
639: //create the index
640: InternalIndex index = null;
641:
642: // construct the class/method map so we can do all the
643: // reflection stuff early
644: if (log.isDebugEnabled()) {
645: log.debug("Parsing Config "
646: + config.getIndexMappings() + " for '"
647: + config.getName() + "'");
648: }
649: parser.parseConfig(config);
650:
651: if (log.isDebugEnabled()) {
652: log.debug("Parsed Config for '" + config.getName()
653: + "'");
654: }
655:
656: if (log.isDebugEnabled()) {
657: log.debug("Creating index " + config.getIndexType()
658: + " for '" + config.getName() + "'");
659: }
660:
661: index = GenericIndexFactory.getInstance().createIndex(
662: config.getIndexType(), parser,
663: config.getIndexProperties(), config.getName());
664:
665: if (log.isDebugEnabled()) {
666: log.debug("Created index " + config.getIndexType()
667: + " for '" + config.getName() + "'");
668: }
669: if (log.isDebugEnabled()) {
670: log.debug("adding preconfigured queries "
671: + config.getQueryMappings() + " for '"
672: + config.getName() + "'");
673: }
674:
675: for (Iterator it = config.getQueryMappings().entrySet()
676: .iterator(); it.hasNext();) {
677: Map.Entry entry = (Map.Entry) it.next();
678: index.getParserManager().addQuery(
679: (String) entry.getKey(),
680: (String) entry.getValue());
681: }
682: if (log.isDebugEnabled()) {
683: log.debug("added preconfigured queries " + " for '"
684: + config.getName() + "'");
685: }
686: adapter.setInternalIndex(index);
687:
688: } catch (Exception e) {
689: log.error("Unable to instantiate index for '"
690: + config.getName() + "':" + e);
691: // shut down the cache if we get an error configuring stuff
692: try {
693: if (adapter != null) {
694: adapter.destroy();
695:
696: }
697:
698: } catch (Throwable t) {
699: throw new JoftiException(t);
700: }
701: throw new JoftiException(e);
702:
703: }
704: }
705: return adapter;
706: }
707:
708: private Object createClass(String className) throws JoftiException {
709:
710: Object obj = null;
711: try {
712: obj = ReflectionUtil.classForName(className).newInstance();
713: } catch (Exception e) {
714: throw new JoftiException(e);
715: }
716: return obj;
717:
718: }
719:
720: private Object createClass(String className, Object param)
721: throws JoftiException {
722:
723: Object obj = null;
724: try {
725: Class types[] = new Class[1];
726: types[0] = Object.class;
727: Class clazz = ReflectionUtil.classForName(className);
728: Constructor cons = clazz.getConstructor(types);
729: obj = cons.newInstance(new Object[] { param });
730: } catch (Throwable e) {
731: throw new JoftiException(e);
732: }
733: return obj;
734:
735: }
736:
737: /**
738: * Retrieves a cache from the manager. If the cache does not exist in the manager the
739: * method returns NULL, rather than throw an exception.
740: *
741: * Attempting to retrieve a name spaced cache using this method will result in an
742: * exception.
743: * @param indexName - the key name to retrive the cache. This set in the config as the cacheName.
744: * @return - the cache or NULL if no cache can be found under that name.
745: *
746: * @throws JoftiException
747: */
748: public Index getIndexCache(String indexName) throws JoftiException {
749:
750: if (!initialised) {
751: throw new JoftiException(
752: "IndexCache has not been initialised");
753: }
754:
755: LifeCycleAdapter adapter = (LifeCycleAdapter) cacheMap
756: .get(indexName);
757:
758: if (adapter == null) {
759: // check if lazily loaded
760: log.warn("No cache exists under the name " + indexName);
761: }
762:
763: return (Index) adapter;
764: }
765:
766: /**
767: * Retrieves a name spaced indexed cache from the manager. If the cache does not exist in the manager the
768: * method returns NULL, rather than throw an exception.
769: *
770: * Attempting to retrieve a non-name spaced cache using this method will result in an
771: * exception.
772: * @param indexName - the key name to retrive the cache. This set in the config as the cacheName.
773: * @return - the cache or NULL if no cache can be found under that name.
774: *
775: * @throws JoftiException
776: */
777: public NameSpacedIndex getNameSpacedIndex(String indexName)
778: throws JoftiException {
779:
780: if (!initialised) {
781: throw new JoftiException(
782: "IndexCache has not been initialised");
783: }
784:
785: LifeCycleAdapter adapter = (LifeCycleAdapter) cacheMap
786: .get(indexName);
787:
788: if (adapter == null) {
789:
790: log.warn("No cache exists under name " + indexName);
791:
792: if (!(adapter instanceof NameSpacedCacheAdapter)) {
793: return null;
794: }
795:
796: }
797: return (NameSpacedIndex) adapter;
798: }
799:
800: private synchronized Map loadConfig(String configfile)
801: throws JoftiException {
802:
803: ConfigFileParser confParser = new ConfigFileParser();
804: return confParser.parseIndexConfig(configfile);
805:
806: }
807:
808: private synchronized IndexConfig loadConfig(IndexConfig config,
809: String classesFileName) throws JoftiException {
810:
811: ConfigFileParser confParser = new ConfigFileParser();
812: return confParser.parseClassMapping(config, classesFileName);
813:
814: }
815:
816: private synchronized IndexConfig loadConfig(IndexConfig config,
817: InputStream classes) throws JoftiException {
818:
819: ConfigFileParser confParser = new ConfigFileParser();
820: return confParser.parseClassMapping(config, classes);
821:
822: }
823:
824: private synchronized Map loadConfig(InputStream configStream)
825: throws JoftiException {
826:
827: ConfigFileParser confParser = new ConfigFileParser();
828: return confParser.parseIndexConfig(configStream);
829:
830: }
831:
832: /**
833: * Used to shutdown and remove a cache from the manager. You should always use this method
834: * to remove a cache from the manager - as some cache implementations explicitly require a
835: * shutdown phase to be run before they can be removed.
836: *
837: * @param cache - the cache to be destroyed.
838: */
839: public synchronized void destroyIndex(Object cache) {
840: if (cache instanceof LifeCycleAdapter) {
841: LifeCycleAdapter wrapper = (LifeCycleAdapter) cache;
842: removeCache(wrapper);
843: }
844: }
845:
846: protected synchronized void removeCache(LifeCycleAdapter wrapper) {
847:
848: if (wrapper != null) {
849: try {
850: wrapper.destroy();
851: } catch (Exception e) {
852: log.error(e);
853: } finally {
854: cacheMap.remove(wrapper.getName());
855: }
856: }
857:
858: }
859:
860: /* (non-Javadoc)
861: * @see com.jofti.api.IndexManager#destroy()
862: */
863: public synchronized void destroy() {
864: for (Iterator it = cacheMap.values().iterator(); it.hasNext();) {
865: LifeCycleAdapter adapter = (LifeCycleAdapter) it.next();
866: removeCache(adapter);
867: }
868: configMap.clear();
869: initialised = false;
870:
871: }
872:
873: /* (non-Javadoc)
874: * @see com.jofti.api.IndexManager#removeIndexedCache(java.lang.Object)
875: */
876: public synchronized Object removeIndex(Object cache) {
877: if (cache instanceof LifeCycleAdapter) {
878:
879: Object obj = cacheMap.remove(((LifeCycleAdapter) cache)
880: .getName());
881: return obj;
882: }
883: return null;
884:
885: }
886:
887: }
|