001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.cocoon.components.search.components.impl;
017:
018: import java.util.HashMap;
019: import java.util.Map;
020:
021: import org.apache.avalon.framework.configuration.Configurable;
022: import org.apache.avalon.framework.configuration.Configuration;
023: import org.apache.avalon.framework.configuration.ConfigurationException;
024: import org.apache.avalon.framework.logger.AbstractLogEnabled;
025: import org.apache.avalon.framework.logger.LogEnabled;
026: import org.apache.avalon.framework.service.ServiceException;
027: import org.apache.avalon.framework.service.ServiceManager;
028: import org.apache.avalon.framework.service.Serviceable;
029: import org.apache.avalon.framework.thread.ThreadSafe;
030: import org.apache.cocoon.components.search.analyzer.ConfigurableAnalyzer;
031: import org.apache.cocoon.components.search.components.AnalyzerManager;
032: import org.apache.excalibur.source.Source;
033: import org.apache.excalibur.source.SourceResolver;
034: import org.apache.lucene.analysis.Analyzer;
035:
036: /**
037: * Implementation of the Analyzer Component
038: *
039: * @author Maisonneuve Nicolas
040: * @version 1.0
041: */
042: public class AnalyzerManagerImpl extends AbstractLogEnabled implements
043: AnalyzerManager, Serviceable, Configurable, ThreadSafe {
044:
045: /**
046: * The analyzer element
047: */
048: public static final String ANALYZER_ELEMENT = "analyzer";
049:
050: /**
051: * the id of the analyzer
052: */
053: public static final String ID_ATT = "id";
054:
055: /**
056: * the analyzer class name
057: */
058: public static final String CLASSNAME_ATT = "class";
059:
060: /**
061: * (optional) a file to configure the analyzer
062: */
063: public static final String CONFIG_ATT = "configfile";
064:
065: /**
066: * Automatic update or not the analyzer when the config file changes
067: */
068: public static final String CONFIGCHECK_ATT = "checkupdate";
069:
070: /**
071: * Map of all the analyzer (ID, analyzer class)
072: */
073: private Map analyzers = new HashMap();
074:
075: private ServiceManager manager;
076:
077: public boolean exist(String id) {
078: return this .analyzers.containsKey(id);
079: }
080:
081: public void configure(Configuration configuration)
082: throws ConfigurationException {
083: Analyzer analyzer;
084: String key;
085: Source conffile = null;
086: boolean checkconfigfile = false;
087: SourceResolver resolver;
088:
089: Configuration[] confAnalyzer = configuration
090: .getChildren(ANALYZER_ELEMENT);
091: if (confAnalyzer.length == 0) {
092: throw new ConfigurationException("tag " + ANALYZER_ELEMENT
093: + " expected ");
094: }
095: try {
096: resolver = (SourceResolver) manager
097: .lookup(SourceResolver.ROLE);
098: } catch (ServiceException e) {
099: throw new ConfigurationException(" source resolver error",
100: e);
101: }
102:
103: for (int i = 0; i < confAnalyzer.length; i++) {
104:
105: // KEY
106: key = confAnalyzer[i].getAttribute(ID_ATT);
107: if (key == null) {
108: throw new ConfigurationException("element "
109: + ANALYZER_ELEMENT + " must have a " + ID_ATT
110: + " attribute");
111: }
112:
113: // CLASS
114: String classname = confAnalyzer[i]
115: .getAttribute(CLASSNAME_ATT);
116: if (classname == null) {
117: throw new ConfigurationException("element "
118: + ANALYZER_ELEMENT + " must have a "
119: + CLASSNAME_ATT + " attribute");
120: }
121: try {
122: analyzer = (Analyzer) Class.forName(classname)
123: .newInstance();
124: } catch (ClassNotFoundException ex) {
125: throw new ConfigurationException(
126: "analyzer class not found " + classname, ex);
127: } catch (Exception ex) {
128: throw new ConfigurationException("instanciation of "
129: + key + " error", ex);
130: }
131:
132: if (analyzer instanceof LogEnabled) {
133: this .setupLogger(analyzer);
134: }
135:
136: if (analyzer instanceof ConfigurableAnalyzer) {
137: ConfigurableAnalyzer confanalyzer = ((ConfigurableAnalyzer) analyzer);
138:
139: // CONFIGFILE
140: String conffilename = confAnalyzer[i]
141: .getAttribute(CONFIG_ATT);
142:
143: if (conffilename == null || conffilename.equals("")) {
144: throw new ConfigurationException("the analyzer "
145: + key + " must have a " + CONFIG_ATT
146: + " attribute");
147: }
148:
149: try {
150: conffile = resolver.resolveURI(conffilename);
151: } catch (Exception ex1) {
152: throw new ConfigurationException(
153: "Config file source error", ex1);
154: }
155:
156: // CHECKUPDATE
157: checkconfigfile = confAnalyzer[i]
158: .getAttributeAsBoolean(CONFIGCHECK_ATT, false);
159:
160: confanalyzer.setAnalyerManager(this );
161: confanalyzer.setConfigFile(conffile);
162: confanalyzer.setEnableCheckFile(checkconfigfile);
163: }
164: this .put(key, analyzer);
165: }
166:
167: manager.release(resolver);
168: getLogger().info("AnalyzerManager configured.");
169:
170: }
171:
172: /*
173: * (non-Javadoc)
174: *
175: * @see org.apache.cocoon.components.search.components.AnalyzerManager#put(java.lang.String,
176: * org.apache.lucene.analysis.Analyzer)
177: */
178: public void put(String id, Analyzer analyzer) {
179: this .analyzers.put(id, analyzer);
180: this .getLogger().info(
181: "add analyzer id: " + id + " with class "
182: + analyzer.getClass().getName());
183: }
184:
185: /*
186: * (non-Javadoc)
187: *
188: * @see org.apache.cocoon.components.search.components.AnalyzerManager#remove(java.lang.String)
189: */
190: public void remove(String id) {
191: this .analyzers.remove(id);
192: if (this .getLogger().isDebugEnabled()) {
193: this .getLogger().debug("remove analyzer id: " + id);
194: }
195: }
196:
197: /*
198: * (non-Javadoc)
199: *
200: * @see org.apache.cocoon.components.search.components.AnalyzerManager#getAnalyzersID()
201: */
202: public String[] getAnalyzersID() {
203: return (String[]) analyzers.keySet().toArray(
204: new String[analyzers.size()]);
205: }
206:
207: /*
208: * (non-Javadoc)
209: *
210: * @see org.apache.cocoon.components.search.components.AnalyzerManager#getAnalyzer(java.lang.String)
211: */
212: public Analyzer getAnalyzer(String id)
213: throws ConfigurationException {
214: Analyzer analyzer = (Analyzer) this .analyzers.get(id);
215: if (analyzer == null) {
216: throw new ConfigurationException("analyzer " + id
217: + " doesn't exist");
218: }
219: if (analyzer instanceof ConfigurableAnalyzer) {
220: ConfigurableAnalyzer confAnalyzer = ((ConfigurableAnalyzer) analyzer);
221: if (confAnalyzer.enableCheckFile()) {
222: confAnalyzer.reconfigure();
223: }
224: }
225: return analyzer;
226: }
227:
228: /*
229: * (non-Javadoc)
230: *
231: * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
232: */
233: public void service(ServiceManager manager) throws ServiceException {
234: this.manager = manager;
235: }
236:
237: }
|