001package org.maltparser.core.lw.parser;
002
003import java.io.BufferedReader;
004import java.io.IOException;
005import java.io.InputStream;
006import java.io.InputStreamReader;
007import java.io.ObjectInputStream;
008import java.io.UnsupportedEncodingException;
009import java.net.MalformedURLException;
010import java.net.URL;
011import java.util.Collections;
012import java.util.Map;
013import java.util.Set;
014import java.util.jar.JarEntry;
015import java.util.jar.JarInputStream;
016
017import org.maltparser.core.helper.HashMap;
018import org.maltparser.core.helper.HashSet;
019
020/**
021 * @author Johan Hall
022 *
023 */
024public final class McoModel {
025        private final URL mcoUrl;
026        private final Map<String, URL> nameUrlMap;
027        private final Map<String, Object> preLoadedObjects;
028        private final Map<String, String> preLoadedStrings;
029        private final URL infoURL;
030        private final String internalMcoName;
031
032        
033        public McoModel(URL _mcoUrl) { 
034                this.mcoUrl = _mcoUrl;
035                this.nameUrlMap = Collections.synchronizedMap(new HashMap<String, URL>());
036                this.preLoadedObjects = Collections.synchronizedMap(new HashMap<String, Object>());
037                this.preLoadedStrings = Collections.synchronizedMap(new HashMap<String, String>());
038                URL tmpInfoURL = null;
039                String tmpInternalMcoName = null;
040                try {
041                        JarEntry je;
042                        JarInputStream jis = new JarInputStream(mcoUrl.openConnection().getInputStream());
043
044                        while ((je = jis.getNextJarEntry()) != null) {
045                                String fileName = je.getName();
046                                URL entryURL = new URL("jar:"+mcoUrl+"!/"+fileName + "\n");
047                                int index = fileName.indexOf('/');
048                                if (index == -1) {
049                                        index = fileName.indexOf('\\');
050                                }                               
051                                nameUrlMap.put(fileName.substring(index+1), entryURL);
052                                if (fileName.endsWith(".info") && tmpInfoURL == null) {
053                                        tmpInfoURL = entryURL;
054                                } else if (fileName.endsWith(".moo") || fileName.endsWith(".map")) {
055                                        preLoadedObjects.put(fileName.substring(index+1), preLoadObject(entryURL.openStream()));
056                                } else if (fileName.endsWith(".dsm")) {
057                                        preLoadedStrings.put(fileName.substring(index+1), preLoadString(entryURL.openStream()));
058                                }
059                                if (tmpInternalMcoName == null) {
060                                        tmpInternalMcoName = fileName.substring(0, index);
061                                }
062                                jis.closeEntry();
063                        }
064                        jis.close();
065                } catch (IOException e) {
066                        e.printStackTrace();
067                } catch (ClassNotFoundException e) {
068                        e.printStackTrace();
069                }
070                this.internalMcoName = tmpInternalMcoName;
071                this.infoURL = tmpInfoURL;
072        }
073        
074        private Object preLoadObject(InputStream is) throws IOException, ClassNotFoundException {
075                Object object = null;
076                
077            ObjectInputStream input = new ObjectInputStream(is);
078            try {
079                object = input.readObject();
080            } finally {
081                input.close();
082            }
083            return object;
084        }
085        
086        private String preLoadString(InputStream is) throws IOException, ClassNotFoundException {
087                final BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8"));
088                String line;
089                StringBuilder sb = new StringBuilder();
090                
091                while((line = in.readLine()) != null) {
092                         sb.append(line);
093                         sb.append('\n');
094                }
095            return sb.toString();
096        }
097        
098        public InputStream getInputStream(String fileName) throws IOException {
099                return nameUrlMap.get(fileName).openStream();
100        }
101        
102        public InputStreamReader getInputStreamReader(String fileName, String charSet) throws IOException, UnsupportedEncodingException {
103                return new InputStreamReader(getInputStream(fileName),  charSet);
104        }
105        
106        public URL getMcoEntryURL(String fileName) throws MalformedURLException {
107                return new URL(nameUrlMap.get(fileName).toString());
108        }
109        
110        public URL getMcoURL() throws MalformedURLException {
111                return new URL(mcoUrl.toString());
112        }
113        
114        public Object getMcoEntryObject(String fileName) {
115                return preLoadedObjects.get(fileName);
116        }
117        
118        public Set<String> getMcoEntryObjectKeys() {
119                return Collections.synchronizedSet(new HashSet<String>(preLoadedObjects.keySet()));
120        }
121        
122        public String getMcoEntryString(String fileName) {
123                return preLoadedStrings.get(fileName);
124        }
125        
126        public String getInternalName() {
127                return internalMcoName;
128        }
129        
130        public String getMcoURLString() {
131                return mcoUrl.toString();
132        }
133        
134        public String getMcoInfo() throws IOException {
135                StringBuilder sb = new StringBuilder();
136
137                BufferedReader reader = new BufferedReader(new InputStreamReader(infoURL.openStream(), "UTF-8"));
138                String line;
139                while ((line = reader.readLine()) != null) {
140                        sb.append(line);
141                        sb.append('\n');
142                }
143
144                return sb.toString();
145        }
146}