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