package org.maltparser.core.feature.system;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.maltparser.core.config.ConfigurationRegistry;
import org.maltparser.core.exception.MaltChainedException;
import org.maltparser.core.feature.FeatureException;
import org.maltparser.core.feature.function.Function;
import org.maltparser.core.helper.Util;
import org.maltparser.core.plugin.Plugin;
import org.maltparser.core.plugin.PluginLoader;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
*
*
* @author Johan Hall
* @since 1.0
**/
public class FeatureEngine extends HashMap<String, FunctionDescription> {
public final static long serialVersionUID = 3256444702936019250L;
public FeatureEngine() {
super();
}
public Function newFunction(String functionName, ConfigurationRegistry registry) throws MaltChainedException {
int i = 0;
Function func = null;
while (true) {
FunctionDescription funcDesc = get(functionName + "~~" + i);
if (funcDesc == null) {
break;
}
func = funcDesc.newFunction(registry);
if (func != null) {
break;
}
i++;
}
return func;
}
public void load(String urlstring) throws MaltChainedException {
load(Util.findURL(urlstring));
}
public void load(PluginLoader plugins) throws MaltChainedException {
for (Plugin plugin : plugins) {
URL url = null;
try {
url = new URL("jar:"+plugin.getUrl() + "!/appdata/plugin.xml");
} catch (MalformedURLException e) {
throw new FeatureException("Malformed URL: 'jar:"+plugin.getUrl() + "!plugin.xml'", e);
}
try {
InputStream is = url.openStream();
is.close();
} catch (IOException e) {
continue;
}
load(url);
}
}
public void load(URL specModelURL) throws MaltChainedException {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Element root = null;
root = db.parse(specModelURL.openStream()).getDocumentElement();
if (root == null) {
throw new FeatureException("The feature system file '"+specModelURL.getFile()+"' cannot be found. ");
}
readFeatureSystem(root);
} catch (IOException e) {
throw new FeatureException("The feature system file '"+specModelURL.getFile()+"' cannot be found. ", e);
} catch (ParserConfigurationException e) {
throw new FeatureException("Problem parsing the file "+specModelURL.getFile()+". ", e);
} catch (SAXException e) {
throw new FeatureException("Problem parsing the file "+specModelURL.getFile()+". ", e);
}
}
public void readFeatureSystem(Element system) throws MaltChainedException {
NodeList functions = system.getElementsByTagName("function");
for (int i = 0; i < functions.getLength(); i++) {
readFunction((Element)functions.item(i));
}
}
public void readFunction(Element function) throws MaltChainedException {
boolean hasSubFunctions = function.getAttribute("hasSubFunctions").equalsIgnoreCase("true");
boolean hasFactory = false;
if (function.getAttribute("hasFactory").length() > 0) {
hasFactory = function.getAttribute("hasFactory").equalsIgnoreCase("true");
}
Class<?> clazz = null;
try {
if (PluginLoader.instance() != null) {
clazz = PluginLoader.instance().getClass(function.getAttribute("class"));
}
if (clazz == null) {
clazz = Class.forName(function.getAttribute("class"));
}
} catch (ClassNotFoundException e) {
throw new FeatureException("The feature system could not find the function class"+function.getAttribute("class")+".", e);
}
if (hasSubFunctions) {
NodeList subfunctions = function.getElementsByTagName("subfunction");
for (int i = 0; i < subfunctions.getLength(); i++) {
readSubFunction((Element)subfunctions.item(i), clazz, hasFactory);
}
} else {
int i = 0;
String n = null;
while (true) {
n = function.getAttribute("name") + "~~" + i;
if (!containsKey(n)) {
break;
}
i++;
}
put(n, new FunctionDescription(function.getAttribute("name"), clazz, false, hasFactory));
}
}
public void readSubFunction(Element subfunction, Class<?> clazz, boolean hasFactory) throws MaltChainedException {
int i = 0;
String n = null;
while (true) {
n = subfunction.getAttribute("name") + "~~" + i;
if (!containsKey(n)) {
break;
}
i++;
}
put(n, new FunctionDescription(subfunction.getAttribute("name"), clazz, true, hasFactory));
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if (this.size() != ((FeatureEngine)obj).size()) {
return false;
}
for (String name : keySet()) {
if (!get(name).equals(((FeatureEngine)obj).get(name))) {
return false;
}
}
return true;
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (String name : keySet()) {
sb.append(name);
sb.append('\t');
sb.append(get(name));
sb.append('\n');
}
return sb.toString();
}
}