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