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 }