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
008 import javax.xml.parsers.DocumentBuilder;
009 import javax.xml.parsers.DocumentBuilderFactory;
010 import javax.xml.parsers.ParserConfigurationException;
011
012 import org.maltparser.core.config.ConfigurationRegistry;
013 import org.maltparser.core.exception.MaltChainedException;
014 import org.maltparser.core.feature.FeatureException;
015 import org.maltparser.core.feature.function.Function;
016 import org.maltparser.core.helper.HashMap;
017 import org.maltparser.core.helper.URLFinder;
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 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 }