/** * License Agreement for OpenSearchServer * * Copyright (C) 2010-2014 Emmanuel Keller / Jaeksoft * * http://www.open-search-server.com * * This file is part of OpenSearchServer. * * OpenSearchServer is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenSearchServer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenSearchServer. * If not, see <http://www.gnu.org/licenses/>. **/ package com.jaeksoft.searchlib.analysis; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.commons.lang3.StringEscapeUtils; import org.w3c.dom.DOMException; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.SAXException; import com.jaeksoft.searchlib.Logging; import com.jaeksoft.searchlib.SearchLibException; import com.jaeksoft.searchlib.config.Config; import com.jaeksoft.searchlib.util.DomUtils; import com.jaeksoft.searchlib.util.XmlWriter; public abstract class ClassFactory { protected Config config; protected Map<ClassPropertyEnum, ClassProperty> properties; protected List<ClassProperty> userProperties; protected String packageName; public ClassFactory() { config = null; properties = new TreeMap<ClassPropertyEnum, ClassProperty>(); userProperties = null; addProperty(ClassPropertyEnum.CLASS, null, null, 0, 0); packageName = null; } final public ClassProperty addProperty(ClassPropertyEnum classPropertyEnum, String defaultValue, Object[] valueList, int cols, int rows) { ClassProperty classProperty = properties.get(classPropertyEnum); if (classProperty != null) return classProperty; classProperty = new ClassProperty(this, classPropertyEnum, defaultValue, valueList, cols, rows); properties.put(classPropertyEnum, classProperty); if (classPropertyEnum.isUser()) { if (userProperties == null) userProperties = new ArrayList<ClassProperty>(); userProperties.add(classProperty); } return classProperty; } /** * * @param config * the current config * @param packageName * the name of the package * @param className * the name of the class * @throws IOException * inherited error * @throws SearchLibException * inherited error */ public void setParams(Config config, String packageName, String className) throws IOException, SearchLibException { this.config = config; this.packageName = packageName; getProperty(ClassPropertyEnum.CLASS).setValue(className); } protected void initProperties() throws SearchLibException { } protected void checkValue(ClassPropertyEnum prop, String value) throws SearchLibException { } public void checkProperties() throws SearchLibException { for (ClassProperty prop : properties.values()) checkValue(prop.getClassPropertyEnum(), prop.getValue()); } public ClassProperty getProperty(ClassPropertyEnum prop) { return properties.get(prop); } protected float getFloatProperty(ClassPropertyEnum prop) { ClassProperty cp = getProperty(prop); if (cp == null) return 1.0F; String value = cp.getValue(); if (value == null) return 1.0F; return Float.parseFloat(value); } protected boolean getBooleanProperty(ClassPropertyEnum prop) { ClassProperty cp = getProperty(prop); if (cp == null) return false; String value = cp.getValue(); if (value == null) return false; return Boolean.parseBoolean(value); } protected String getStringProperty(ClassPropertyEnum prop) { ClassProperty cp = getProperty(prop); if (cp == null) return null; return cp.getValue(); } final private void addProperty(final String name, final String value) throws SearchLibException { ClassPropertyEnum propEnum = ClassPropertyEnum.valueOf(name); if (propEnum != null) { ClassProperty prop = getProperty(propEnum); if (prop != null) prop.setValue(value); } else { Logging.warn("Property not found: " + name); } } final protected void addProperties(final NamedNodeMap nnm) throws SearchLibException { if (nnm == null) return; int l = nnm.getLength(); for (int i = 0; i < l; i++) { Node attr = nnm.item(i); addProperty(attr.getNodeName(), StringEscapeUtils.unescapeXml(attr.getNodeValue())); } } /** * * @return the name of the class */ public String getClassName() { return getProperty(ClassPropertyEnum.CLASS).getValue(); } /** * Return the class name and properties * * @return a string array */ public String[] getXmlAttributes() { String[] attributes = new String[properties.size() * 2]; int i = 0; for (ClassProperty prop : properties.values()) { if (!prop.isMultilinetextbox()) { attributes[i++] = prop.getClassPropertyEnum().getAttribute(); attributes[i++] = prop.getValue(); } } return attributes; } public void writeXmlNodeAttributes(XmlWriter writer, String nodeName) throws SAXException { Map<String, String> map = new HashMap<String, String>(); for (ClassProperty prop : properties.values()) { if (prop.isMultilinetextbox()) map.put(prop.getClassPropertyEnum().getAttribute(), prop.getValue()); } if (map.isEmpty()) return; writer.startElement(nodeName); for (Map.Entry<String, String> entry : map.entrySet()) { writer.startElement("attribute", "name", entry.getKey()); writer.textNode(entry.getValue()); writer.endElement(); } writer.endElement(); } /** * * @param config * the current config * @param packageName * the name of the package * @param className * the name fo the class * @return a new class factory * @throws SearchLibException * inherited error * @throws ClassNotFoundException * inherited error */ protected static ClassFactory create(Config config, String packageName, String className) throws SearchLibException, ClassNotFoundException { String cl = className; if (className.indexOf('.') == -1) cl = packageName + '.' + cl; try { ClassFactory o = (ClassFactory) Class.forName(cl).newInstance(); o.setParams(config, packageName, className); o.initProperties(); return o; } catch (InstantiationException e) { throw new SearchLibException(e); } catch (IllegalAccessException e) { throw new SearchLibException(e); } catch (IOException e) { throw new SearchLibException(e); } } /** * * @param config * the current config * @param factoryClass * the class of the factory * @param <T> * the type of the instance * @return a new instance * @throws SearchLibException * inherited error */ protected static <T extends ClassFactory> T createInstance(Config config, Class<T> factoryClass) throws SearchLibException { try { T o = factoryClass.newInstance(); o.setParams(config, factoryClass.getPackage().getName(), factoryClass.getSimpleName()); o.initProperties(); return o; } catch (InstantiationException e) { throw new SearchLibException(e); } catch (IllegalAccessException e) { throw new SearchLibException(e); } catch (IOException e) { throw new SearchLibException(e); } } /** * * @param config * the current config * @param packageName * the name of the package * @param node * the node with the parameters * @param attributeNodeName * the name of the attribute * @return a new class factory * @throws SearchLibException * inherited error * @throws DOMException * inherited error * @throws ClassNotFoundException * inherited error */ protected static ClassFactory create(Config config, String packageName, Node node, String attributeNodeName) throws SearchLibException, DOMException, ClassNotFoundException { if (node == null) return null; NamedNodeMap nnm = node.getAttributes(); if (nnm == null) return null; Node classNode = nnm.getNamedItem(ClassPropertyEnum.CLASS.getAttribute()); if (classNode == null) return null; ClassFactory newClassFactory = create(config, packageName, classNode.getNodeValue()); newClassFactory.addProperties(nnm); List<Node> attrNodes = DomUtils.getNodes(node, attributeNodeName, "attribute"); if (attrNodes != null) for (Node attrNode : attrNodes) newClassFactory.addProperty(DomUtils.getAttributeText(attrNode, "name"), attrNode.getTextContent()); return newClassFactory; } /** * * @param classFactory * a class factory * @return a new class factory instance * @throws SearchLibException * inherited error * @throws ClassNotFoundException * inherited error */ protected static ClassFactory create(ClassFactory classFactory) throws SearchLibException, ClassNotFoundException { ClassFactory newClassFactory = create(classFactory.config, classFactory.packageName, classFactory.getClassName()); for (ClassProperty prop : classFactory.properties.values()) newClassFactory.getProperty(prop.getClassPropertyEnum()).setValue(prop.getValue()); return newClassFactory; } public boolean isProperty() { if (userProperties == null) return false; return userProperties.size() > 0; } public List<ClassProperty> getUserProperties() { return userProperties; } public void setUserProperty(String name, String value) throws SearchLibException { if (userProperties == null || name == null) throw new SearchLibException("No properties"); for (ClassProperty prop : userProperties) { if (name.equals(prop.getClassPropertyEnum().getName())) { prop.setValue(value); return; } } throw new SearchLibException("Property " + name + " not found."); } }