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    }