001 package org.maltparser.core.feature.system; 002 003 import java.io.IOException; 004 import java.io.InputStream; 005 import java.net.MalformedURLException; 006 import java.net.URL; 007 import java.util.HashMap; 008 009 import javax.xml.parsers.DocumentBuilder; 010 import javax.xml.parsers.DocumentBuilderFactory; 011 import javax.xml.parsers.ParserConfigurationException; 012 013 import org.maltparser.core.config.Configuration; 014 import org.maltparser.core.config.ConfigurationRegistry; 015 import org.maltparser.core.exception.MaltChainedException; 016 import org.maltparser.core.feature.FeatureException; 017 import org.maltparser.core.feature.function.Function; 018 import org.maltparser.core.helper.Util; 019 import org.maltparser.core.plugin.Plugin; 020 import org.maltparser.core.plugin.PluginLoader; 021 import org.w3c.dom.Element; 022 import org.w3c.dom.NodeList; 023 import org.xml.sax.SAXException; 024 /** 025 * 026 * 027 * @author Johan Hall 028 * @since 1.0 029 **/ 030 public class FeatureEngine extends HashMap<String, FunctionDescription> { 031 public final static long serialVersionUID = 3256444702936019250L; 032 protected Configuration configuration; 033 public FeatureEngine(Configuration configuration) { 034 super(); 035 setConfiguration(configuration); 036 } 037 038 public Function newFunction(String functionName, ConfigurationRegistry registry) throws MaltChainedException { 039 FunctionDescription funcDesc = get(functionName); 040 if (funcDesc == null) { 041 return null; 042 } 043 return funcDesc.newFunction(registry); 044 } 045 046 public void load(String urlstring) throws MaltChainedException { 047 load(Util.findURL(urlstring)); 048 } 049 050 public void load(PluginLoader plugins) throws MaltChainedException { 051 for (Plugin plugin : plugins) { 052 URL url = null; 053 try { 054 url = new URL("jar:"+plugin.getUrl() + "!/appdata/plugin.xml"); 055 } catch (MalformedURLException e) { 056 throw new FeatureException("Malformed URL: 'jar:"+plugin.getUrl() + "!plugin.xml'", e); 057 } 058 try { 059 InputStream is = url.openStream(); 060 is.close(); 061 } catch (IOException e) { 062 continue; 063 } 064 065 load(url); 066 } 067 } 068 069 public void load(URL specModelURL) throws MaltChainedException { 070 try { 071 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 072 DocumentBuilder db = dbf.newDocumentBuilder(); 073 Element root = null; 074 075 root = db.parse(specModelURL.openStream()).getDocumentElement(); 076 077 if (root == null) { 078 throw new FeatureException("The feature system file '"+specModelURL.getFile()+"' cannot be found. "); 079 } 080 081 readFeatureSystem(root); 082 } catch (IOException e) { 083 throw new FeatureException("The feature system file '"+specModelURL.getFile()+"' cannot be found. ", e); 084 } catch (ParserConfigurationException e) { 085 throw new FeatureException("Problem parsing the file "+specModelURL.getFile()+". ", e); 086 } catch (SAXException e) { 087 throw new FeatureException("Problem parsing the file "+specModelURL.getFile()+". ", e); 088 } 089 } 090 091 public void readFeatureSystem(Element system) throws MaltChainedException { 092 NodeList functions = system.getElementsByTagName("function"); 093 for (int i = 0; i < functions.getLength(); i++) { 094 readFunction((Element)functions.item(i)); 095 } 096 } 097 098 public void readFunction(Element function) throws MaltChainedException { 099 boolean hasSubFunctions = function.getAttribute("hasSubFunctions").equalsIgnoreCase("true"); 100 Class<?> clazz = null; 101 try { 102 if (PluginLoader.instance() != null) { 103 clazz = PluginLoader.instance().getClass(function.getAttribute("class")); 104 } 105 if (clazz == null) { 106 clazz = Class.forName(function.getAttribute("class")); 107 } 108 } catch (ClassNotFoundException e) { 109 throw new FeatureException("The feature system could not find the function class"+function.getAttribute("class")+".", e); 110 } 111 if (hasSubFunctions) { 112 NodeList subfunctions = function.getElementsByTagName("subfunction"); 113 for (int i = 0; i < subfunctions.getLength(); i++) { 114 readSubFunction((Element)subfunctions.item(i), clazz); 115 } 116 } else { 117 if (!containsKey(function.getAttribute("name"))) { 118 put(function.getAttribute("name"), new FunctionDescription(function.getAttribute("name"), clazz, false)); 119 } 120 } 121 } 122 123 public void readSubFunction(Element subfunction, Class<?> clazz) throws MaltChainedException { 124 if (!containsKey(subfunction.getAttribute("name"))) { 125 put(subfunction.getAttribute("name"), new FunctionDescription(subfunction.getAttribute("name"), clazz, true)); 126 } 127 } 128 129 public Configuration getConfiguration() { 130 return configuration; 131 } 132 133 public void setConfiguration(Configuration configuration) { 134 this.configuration = configuration; 135 } 136 137 public boolean equals(Object obj) { 138 if (this == obj) 139 return true; 140 if (obj == null) 141 return false; 142 if (getClass() != obj.getClass()) 143 return false; 144 if (this.size() != ((FeatureEngine)obj).size()) { 145 return false; 146 } 147 for (String name : keySet()) { 148 if (!get(name).equals(((FeatureEngine)obj).get(name))) { 149 return false; 150 } 151 } 152 return true; 153 } 154 155 public String toString() { 156 StringBuilder sb = new StringBuilder(); 157 for (String name : keySet()) { 158 sb.append(get(name)); 159 sb.append('\n'); 160 } 161 return sb.toString(); 162 } 163 }