    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    }