001package org.maltparser.core.flow;
002
003import java.io.IOException;
004import java.io.InputStream;
005import java.net.MalformedURLException;
006import java.net.URL;
007import java.util.HashMap;
008
009import javax.xml.parsers.DocumentBuilder;
010import javax.xml.parsers.DocumentBuilderFactory;
011import javax.xml.parsers.ParserConfigurationException;
012
013import org.maltparser.core.exception.MaltChainedException;
014import org.maltparser.core.feature.FeatureException;
015import org.maltparser.core.flow.spec.ChartSpecification;
016import org.maltparser.core.flow.system.FlowChartSystem;
017import org.maltparser.core.helper.URLFinder;
018import org.maltparser.core.plugin.Plugin;
019import org.maltparser.core.plugin.PluginLoader;
020import org.w3c.dom.Element;
021import org.w3c.dom.NodeList;
022import org.xml.sax.SAXException;
023/**
024*
025*
026* @author Johan Hall
027*/
028public class FlowChartManager {
029        private static FlowChartManager uniqueInstance = new FlowChartManager();
030        private final FlowChartSystem flowChartSystem; 
031        private final HashMap<String,ChartSpecification> chartSpecifications;
032        
033        public FlowChartManager() {
034                flowChartSystem = new FlowChartSystem();
035                chartSpecifications = new HashMap<String,ChartSpecification>();
036        }
037        
038        /**
039        * Returns a reference to the single instance.
040        */
041        public static FlowChartManager instance() {
042                return uniqueInstance;
043        }
044        
045        public void load(String urlstring) throws MaltChainedException {
046                final URLFinder f = new URLFinder();
047                load(f.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 url) throws MaltChainedException {
070        try {
071            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
072            DocumentBuilder db = dbf.newDocumentBuilder();
073            Element root = null;
074
075            root = db.parse(url.openStream()).getDocumentElement();
076            if (root == null) {
077                throw new FlowException("The flow chart specification file '"+url.getFile()+"' cannot be found. ");
078            }
079            readFlowCharts(root);
080        } catch (IOException e) {
081                throw new FlowException("The flow chart specification file '"+url.getFile()+"' cannot be found. ", e);
082        } catch (ParserConfigurationException e) {
083                throw new FlowException("Problem parsing the flow chart file "+url.getFile()+". ", e);
084        } catch (SAXException e) {
085                throw new FlowException("Problem parsing the flow chart file "+url.getFile()+". ", e);
086        }
087        }
088        
089        private void readFlowCharts(Element flowcharts) throws MaltChainedException {
090                NodeList flowChartList = flowcharts.getElementsByTagName("flowchart");
091                for (int i = 0; i < flowChartList.getLength(); i++) {
092                        String flowChartName = ((Element)flowChartList.item(i)).getAttribute("name");
093                        if (!chartSpecifications.containsKey(flowChartName)) {
094                                ChartSpecification chart = new ChartSpecification();
095                                chartSpecifications.put(flowChartName, chart);
096                                chart.read((Element)flowChartList.item(i), this);
097                        } else {
098                                throw new FlowException("Problem parsing the flow chart file. The flow chart with the name "+flowChartName+" already exists. ");
099                        }
100                }
101        }
102
103        public FlowChartInstance initialize(int optionContainerIndex, String flowChartName) throws MaltChainedException {
104                return new FlowChartInstance(optionContainerIndex, chartSpecifications.get(flowChartName), this);
105        }
106        
107        public FlowChartSystem getFlowChartSystem() {
108                return flowChartSystem;
109        }
110        
111        public String toString() {
112                final StringBuilder sb = new StringBuilder();
113                sb.append("FLOW CHART SYSTEM\n");
114                sb.append(flowChartSystem);
115                sb.append('\n');
116                sb.append("FLOW CHARTS:\n");
117                for (String key : chartSpecifications.keySet()) {
118                        sb.append(chartSpecifications.get(key));
119                        sb.append('\n');
120                }
121                return sb.toString();
122        }
123        
124}