/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.esri.gpt.catalog.lucene; import com.esri.gpt.framework.collection.StringAttribute; import com.esri.gpt.framework.collection.StringAttributeMap; import com.esri.gpt.framework.util.Val; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.lucene.queryParser.ParseException; /** * Parser adaptor info. * <p/> * Stores all the information neccesary to create instance of the parser adaptor. * Parser adaptor is a mechanizm to delegate query parsing to another mechanizm. * <p/> * Adaptor is never accessible directly. Instead, an instance of * {@link IParserProxy} is created and used to submit query through the adaptor * to the external mechanizm. * <p/> * Adaptor class has to have one mandatory method <code>String parse(String queryTerm)</code>, * and may have optional method <code>void init(Properties attributes)</code>. * <p/> * Typically, adaptors are defined in <i>Lucene</i> configuration node, which * may look like on the example below:<br/><br/> * <div style="border-style: solid; border-width: thin; border-color: #A4A4A4; background-color: #F5F6CE"><code> * <pre><code> * <lucene * indexLocation="c:/gpt9/lucene-index/catalog1" * analyzerClassName="org.apache.lucene.analysis.standard.StandardAnalyzer"> * <adaptor name="ontology" className="com.esri.gpt.catalog.lucene.StandardParserAdaptor"> * <attribute key="baseUrl" value="http://localhost:8080/OntologyService/query?term="/> * </adaptor> * </lucene> * </pre></div> */ public class ParserAdaptorInfo { /** logger */ private static Logger log = Logger.getLogger(ParserAdaptorInfo.class.getName()); /** adaptor name */ private String name = ""; /** adaptor class name */ private String className = ""; /** attributes */ private StringAttributeMap attributes = new StringAttributeMap(); /** * Gets adaptor name. * @return adaptor name */ public String getName() { return name; } /** * Sets adaptor name. * @param name adaptor name */ public void setName(String name) { this.name = Val.chkStr(name); } /** * Gets class name. * @return class name */ public String getClassName() { return className; } /** * Sets class name. * @param className adaptor class name */ public void setClassName(String className) { this.className = Val.chkStr(className); } /** * Gets attributes. * @return attributes */ public StringAttributeMap getAttributes() { return attributes; } /** * Sets attributes. * @param attributes attributes */ public void setAttributes(StringAttributeMap attributes) { this.attributes = attributes != null ? attributes : new StringAttributeMap(); } @Override public String toString() { return "{name: \"" + getName() + "\", className=\"" + getClassName() + "\", attributes=" +getAttributes()+ "}"; } /** * Creates instance of parser proxy corresponding to the definition. * @return parser proxy or <code>null</code> if unable to create parser proxy */ public IParserProxy createParserProxy() { if (getClassName().length() > 0) { try { // create instance of the parser proxy adaptor final Object instance = Class.forName(getClassName()).newInstance(); try { // if adaptor has "init" method - call it Method method = Class.forName(getClassName()).getMethod("init", Properties.class); Properties props = new Properties(); for (StringAttribute sa : getAttributes().values()) { props.put(sa.getKey(), sa.getValue()); } method.invoke(instance, props); } catch (NoSuchMethodException ex) { log.log(Level.WARNING, "Adaptor instance has not been initialized.", ex); } // adaptor implements IParserProxy, return it if (instance instanceof IParserProxy) { return (IParserProxy) instance; // if not, wrap it withing anonymous IParserProxy calling "parse" method // from the adaptor. } else { // get "parse" method final Method method = Class.forName(getClassName()).getMethod("parse", String.class); // create parser proxy return new IParserProxy() { public String parse(String term) throws ParseException { try { return method.invoke(instance, term).toString(); } catch (IllegalAccessException ex) { Logger.getLogger(IParserProxy.class.getName()). log(Level.SEVERE, null, ex); throw new ParseException( "Unable to parse term: \"" + term + "\" due to internal error: "+ex.getMessage()); } catch (IllegalArgumentException ex) { Logger.getLogger(IParserProxy.class.getName()). log(Level.SEVERE, null, ex); throw new ParseException( "Unable to parse term: \"" + term + "\" due to internal error: "+ex.getMessage()); } catch (InvocationTargetException ex) { Logger.getLogger(IParserProxy.class.getName()). log(Level.SEVERE, null, ex); throw new ParseException( "Unable to parse term: \"" + term + "\" due to internal error: "+ex.getMessage()); } } @Override public String toString() { return "{name: \"" + getName() + "\"; className=\"" + getClassName() + "\"}"; } }; } } catch (NoSuchMethodException ex) { log.log(Level.SEVERE, "Error initializing adaptor instance.", ex); } catch (InvocationTargetException ex) { log.log(Level.SEVERE, "Error initializing adaptor instance.", ex); } catch (IllegalArgumentException ex) { log.log(Level.SEVERE, "Error initializing adaptor instance.", ex); } catch (InstantiationException ex) { log.log(Level.SEVERE, "Error creating adaptor instance.", ex); } catch (IllegalAccessException ex) { log.log(Level.SEVERE, "Error creating adaptor instance.", ex); } catch (ClassNotFoundException ex) { log.log(Level.SEVERE, "Error creating adaptor instance.", ex); } } return null; } }