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