    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    }