001package org.maltparser.core.feature.spec;
002
003import java.net.URL;
004import java.util.ArrayList;
005import java.util.LinkedHashMap;
006
007import org.maltparser.core.exception.MaltChainedException;
008import org.maltparser.core.feature.FeatureException;
009import org.maltparser.core.feature.spec.reader.FeatureSpecReader;
010import org.maltparser.core.feature.spec.reader.ParReader;
011import org.maltparser.core.helper.HashMap;
012
013/**
014*
015*
016* @author Johan Hall
017*/
018public class SpecificationModels {
019        private final HashMap<URL, FeatureSpecReader> specReaderMap;
020        private final HashMap<String, SpecificationModel> specModelMap;
021        private final HashMap<Integer, SpecificationModel> specModelIntMap;
022        private final LinkedHashMap<URL, ArrayList<SpecificationModel>> specModelKeyMap;
023        private final ArrayList<SpecificationModel> currentSpecModelURL;
024        private int counter = 0;
025
026        
027        public SpecificationModels() throws MaltChainedException {
028                this.specReaderMap = new HashMap<URL, FeatureSpecReader>();
029                this.specModelMap = new HashMap<String, SpecificationModel>();
030                this.specModelIntMap = new HashMap<Integer, SpecificationModel>();
031                this.specModelKeyMap = new LinkedHashMap<URL, ArrayList<SpecificationModel>>();
032                this.currentSpecModelURL = new ArrayList<SpecificationModel>();
033        }
034        
035        public void add(int index, String featureSpec) throws MaltChainedException {
036                this.add(Integer.toString(index), "MAIN", featureSpec);
037        }
038        
039        public void add(String specModelName, String featureSpec) throws MaltChainedException {
040                this.add(specModelName, "MAIN", featureSpec);
041        }
042        
043        public void add(int index, String subModelName, String featureSpec) throws MaltChainedException {
044                this.add(Integer.toString(index), subModelName, featureSpec);
045        }
046        
047        public void add(String specModelName, String subModelName, String featureSpec) throws MaltChainedException {
048                if (featureSpec == null) { throw new FeatureException("Feature specification is missing."); }
049                if (specModelName == null) {throw new FeatureException("Unknown feature model name."); }
050                if (subModelName == null) {throw new FeatureException("Unknown subfeature model name."); }
051                
052                if (!specModelMap.containsKey(specModelName.toUpperCase())) {
053                        SpecificationModel specModel = new SpecificationModel(specModelName.toUpperCase());
054                        specModelMap.put(specModelName.toUpperCase(), specModel);
055                        currentSpecModelURL.add(specModel);
056                        specModelIntMap.put(counter++, specModel);
057                }
058                specModelMap.get(specModelName.toUpperCase()).add(subModelName, featureSpec);
059        }
060        
061        public int getNextIndex() {
062                return counter;
063        }
064        
065        public void loadParReader(URL specModelURL, String markingStrategy, String coveredRoot) throws MaltChainedException {
066                if (specModelURL == null) {
067                        throw new FeatureException("The URL to the feature specification model is missing or not well-formed. ");
068                }
069                FeatureSpecReader specReader = null;
070                String urlSuffix = specModelURL.toString().substring(specModelURL.toString().length()-3);
071                urlSuffix = Character.toUpperCase(urlSuffix.charAt(0)) + urlSuffix.substring(1);
072                try {
073                        Class<?> clazz = Class.forName("org.maltparser.core.feature.spec.reader."+urlSuffix+"Reader");
074                        specReader = (FeatureSpecReader)clazz.newInstance();
075                } catch (InstantiationException e) {
076                        throw new FeatureException("Could not initialize the feature specification reader to read the specification file: "+specModelURL.toString(), e);
077                } catch (IllegalAccessException e) {
078                        throw new FeatureException("Could not initialize the feature specification reader to read the specification file: "+specModelURL.toString(), e);
079                } catch (ClassNotFoundException e) {
080                        throw new FeatureException("Could not find the feature specification reader to read the specification file: "+specModelURL.toString(), e);
081                }
082                specReaderMap.put(specModelURL, specReader);
083                
084                if (specReader instanceof ParReader) {
085                        if (markingStrategy.equalsIgnoreCase("head") || markingStrategy.equalsIgnoreCase("path") || markingStrategy.equalsIgnoreCase("head+path")) {
086                                ((ParReader)specReader).setPplifted(true);
087                        }
088                        if (markingStrategy.equalsIgnoreCase("path") || markingStrategy.equalsIgnoreCase("head+path")) {
089                                ((ParReader)specReader).setPppath(true);
090                        }
091                        if (!coveredRoot.equalsIgnoreCase("none")) {
092                                ((ParReader)specReader).setPpcoveredRoot(true);
093                        }
094                }
095                
096                specModelKeyMap.put(specModelURL, currentSpecModelURL);
097                specReader.load(specModelURL, this);
098        }
099        
100        public void load(URL specModelURL) throws MaltChainedException {
101                if (specModelURL == null) {
102                        throw new FeatureException("The URL to the feature specification model is missing or not well-formed. ");
103                }
104                FeatureSpecReader specReader = null;
105                String urlSuffix = specModelURL.toString().substring(specModelURL.toString().length()-3);
106                urlSuffix = Character.toUpperCase(urlSuffix.charAt(0)) + urlSuffix.substring(1);
107                try {
108                        Class<?> clazz = Class.forName("org.maltparser.core.feature.spec.reader."+urlSuffix+"Reader");
109                        specReader = (FeatureSpecReader)clazz.newInstance();
110                } catch (InstantiationException e) {
111                        throw new FeatureException("Could not initialize the feature specification reader to read the specification file: "+specModelURL.toString(), e);
112                } catch (IllegalAccessException e) {
113                        throw new FeatureException("Could not initialize the feature specification reader to read the specification file: "+specModelURL.toString(), e);
114                } catch (ClassNotFoundException e) {
115                        throw new FeatureException("Could not find the feature specification reader to read the specification file: "+specModelURL.toString(), e);
116                }
117                specReaderMap.put(specModelURL, specReader);
118                
119                specModelKeyMap.put(specModelURL, currentSpecModelURL);
120                specReader.load(specModelURL, this);
121        }
122        
123        public SpecificationModel getSpecificationModel(URL url, int specModelUrlIndex) {
124                return specModelKeyMap.get(url).get(specModelUrlIndex);
125        }
126
127        public String toString() {
128                StringBuilder sb = new StringBuilder();
129
130                for (URL url : specModelKeyMap.keySet()) {
131                        for (int i = 0; i < specModelKeyMap.get(url).size(); i++) {
132                                sb.append(url.toString());
133                                sb.append(':');
134                                sb.append(i);
135                                sb.append('\n');
136                                sb.append(specModelKeyMap.get(url).get(i).toString());
137                        }
138                }
139                return sb.toString();
140        }
141}