]> gitweb.fperrin.net Git - DictionaryPC.git/blob - src/com/hughes/android/dictionary/engine/DictionaryBuilder.java
DictionaryBuilder prints sortable langs, JP->JA fix.
[DictionaryPC.git] / src / com / hughes / android / dictionary / engine / DictionaryBuilder.java
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package com.hughes.android.dictionary.engine;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.PrintStream;
20 import java.io.RandomAccessFile;
21 import java.nio.charset.Charset;
22 import java.util.ArrayList;
23 import java.util.LinkedHashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.regex.Pattern;
28
29 import javax.xml.parsers.ParserConfigurationException;
30
31 import org.xml.sax.SAXException;
32
33 import com.hughes.android.dictionary.parser.DictFileParser;
34 import com.hughes.android.dictionary.parser.Parser;
35 import com.hughes.android.dictionary.parser.wiktionary.EnForeignParser;
36 import com.hughes.android.dictionary.parser.wiktionary.EnToTranslationParser;
37 import com.hughes.android.dictionary.parser.wiktionary.EnTranslationToTranslationParser;
38 import com.hughes.util.Args;
39 import com.hughes.util.FileUtil;
40
41 public class DictionaryBuilder {
42   
43   public final Dictionary dictionary;
44   public final List<IndexBuilder> indexBuilders = new ArrayList<IndexBuilder>();
45   
46   public DictionaryBuilder(final String dictInfoString, final Language lang0, final Language lang1, final String normalizerRules1, final String normalizerRules2, final Set<String> lang1Stoplist, final Set<String> lang2Stoplist) {
47     dictionary = new Dictionary(dictInfoString);
48     indexBuilders.add(new IndexBuilder(this, lang0.getIsoCode(), lang0.getIsoCode() + "->" + lang1.getIsoCode(), lang0, normalizerRules1, lang1Stoplist, false));
49     indexBuilders.add(new IndexBuilder(this, lang1.getIsoCode(), lang1.getIsoCode() + "->" + lang0.getIsoCode(), lang1, normalizerRules2, lang2Stoplist, true));
50   }
51   
52   void build() {
53     for (final IndexBuilder indexBuilder : indexBuilders) {
54       indexBuilder.build();
55       dictionary.indices.add(indexBuilder.index);
56     }
57   }
58   
59   public static void main(final String[] args) throws IOException, ParserConfigurationException, SAXException {
60     System.out.println("Running with arguments:");
61     for (final String arg : args) {
62       System.out.println(arg);
63     }
64     
65     final Map<String,String> keyValueArgs = Args.keyValueArgs(args);
66     
67     if (!keyValueArgs.containsKey("lang1") || !keyValueArgs.containsKey("lang2")) {
68       fatalError("--lang1= and --lang2= must both be specified.");
69     }
70     final Language lang1 = Language.lookup(keyValueArgs.remove("lang1"));
71     final Language lang2 = Language.lookup(keyValueArgs.remove("lang2"));
72
73     final Set<String> lang1Stoplist = new LinkedHashSet<String>();
74     final Set<String> lang2Stoplist = new LinkedHashSet<String>();
75     final String lang1StoplistFile = keyValueArgs.remove("lang1Stoplist");
76     final String lang2StoplistFile = keyValueArgs.remove("lang2Stoplist");
77     if (lang1StoplistFile != null) {
78       lang1Stoplist.addAll(FileUtil.readLines(new File(lang1StoplistFile)));
79     }
80     if (lang2StoplistFile != null) {
81       lang2Stoplist.addAll(FileUtil.readLines(new File(lang2StoplistFile)));
82     }
83
84     String normalizerRules1 = keyValueArgs.remove("normalizerRules1");
85     String normalizerRules2 = keyValueArgs.remove("normalizerRules2");
86     if (normalizerRules1 == null) {
87       normalizerRules1 = lang1.getDefaultNormalizerRules();
88     }
89     if (normalizerRules2 == null) {
90       normalizerRules2 = lang2.getDefaultNormalizerRules();
91     }
92     
93     final String dictOutFilename = keyValueArgs.remove("dictOut");
94     if (dictOutFilename == null) {
95       fatalError("--dictOut= must be specified.");
96     }
97     
98     String dictInfo = keyValueArgs.remove("dictInfo");
99     if (dictInfo == null) {
100       fatalError("--dictInfo= must be specified.");
101     }
102     if (dictInfo.startsWith("@")) {
103       dictInfo = FileUtil.readToString(new File(dictInfo.substring(1)));
104     }
105     
106     final String printFile = keyValueArgs.remove("print");
107     
108     System.out.println("lang1=" + lang1);
109     System.out.println("lang2=" + lang2);
110     System.out.println("normalizerRules1=" + normalizerRules1);
111     System.out.println("normalizerRules2=" + normalizerRules2);
112     System.out.println("dictInfo=" + dictInfo);
113     System.out.println("dictOut=" + dictOutFilename);    
114     
115     final DictionaryBuilder dictionaryBuilder = new DictionaryBuilder(dictInfo, lang1, lang2, normalizerRules1, normalizerRules2, lang1Stoplist, lang2Stoplist);
116     
117     for (int i = 0; i < 100; ++i) {
118       final String prefix = "input" + i;
119       if (keyValueArgs.containsKey(prefix)) {
120         final File file = new File(keyValueArgs.remove(prefix));
121         System.out.println("Processing: " + file);
122         String charsetName = keyValueArgs.remove(prefix + "Charset");
123         if (charsetName == null) {
124           charsetName = "UTF8";
125         }
126         final Charset charset = Charset.forName(charsetName);
127         String inputName = keyValueArgs.remove(prefix + "Name");
128         if (inputName == null) {
129           fatalError("Must specify human readable name for: " + prefix + "Name");
130         }
131         String pageLimitString = keyValueArgs.remove(prefix + "PageLimit");
132         if (pageLimitString == null) {
133           pageLimitString = "-1";
134         }
135         final int pageLimit = Integer.parseInt(pageLimitString);
136
137         final EntrySource entrySource = new EntrySource(dictionaryBuilder.dictionary.sources.size(), inputName, 0);
138         System.out.println("");
139         
140         String inputFormat = keyValueArgs.remove(prefix + "Format");
141         if ("tab_separated".equals(inputFormat)) {
142           final boolean flipColumns = "true".equals(keyValueArgs.remove(prefix + "FlipColumns"));
143           new DictFileParser(charset, flipColumns, DictFileParser.TAB, null, dictionaryBuilder, dictionaryBuilder.indexBuilders.toArray(new IndexBuilder[0]), null).parse(file, entrySource, pageLimit);
144         } else if ("chemnitz".equals(inputFormat)) {
145           final boolean flipColumns = "true".equals(keyValueArgs.remove(prefix + "FlipColumns"));
146           new DictFileParser(charset, flipColumns, DictFileParser.DOUBLE_COLON, DictFileParser.PIPE, dictionaryBuilder, dictionaryBuilder.indexBuilders.toArray(new IndexBuilder[0]), null).parse(file, entrySource, pageLimit);
147         } else if ("enwiktionary".equals(inputFormat)) {
148           final String type = keyValueArgs.remove(prefix + "WiktionaryType");
149           final Pattern langPattern = Pattern.compile(keyValueArgs.remove(prefix + "LangPattern"), Pattern.CASE_INSENSITIVE);
150           final Pattern langCodePattern = Pattern.compile(keyValueArgs.remove(prefix + "LangCodePattern"));
151           final int enIndex = Integer.parseInt(keyValueArgs.remove(prefix + "EnIndex")) - 1;
152             
153           if (enIndex < 0 || enIndex >= 2) {
154             fatalError("Must be 1 or 2: " + prefix + "EnIndex");
155           }
156           final Parser parser;
157           if ("EnToTranslation".equals(type)) {
158             parser = new EnToTranslationParser(dictionaryBuilder.indexBuilders.get(enIndex), dictionaryBuilder.indexBuilders.get(1-enIndex),
159                 langPattern, langCodePattern, enIndex != 0);
160           } else if ("EnForeign".equals(type)) {
161             parser = new EnForeignParser(dictionaryBuilder.indexBuilders.get(enIndex), dictionaryBuilder.indexBuilders.get(1-enIndex),
162                 langPattern, langCodePattern, enIndex != 0);
163           } else {
164             fatalError("Invalid WiktionaryType (use EnToTranslation or EnForeign): " + type);
165             return;
166           }
167           parser.parse(file, entrySource, pageLimit);
168         } else if (EnTranslationToTranslationParser.NAME.equals(inputFormat)) {
169           final String code1 = keyValueArgs.remove(prefix + "LangPattern1");
170           final String code2 = keyValueArgs.remove(prefix + "LangPattern2");
171           if (code1 == null || code2 == null) {
172             fatalError("Must specify LangPattern1 and LangPattern2.");
173             return;
174           }
175           final Pattern codePattern1 = Pattern.compile(code1, Pattern.CASE_INSENSITIVE);
176           final Pattern codePattern2 = Pattern.compile(code2, Pattern.CASE_INSENSITIVE);
177           new EnTranslationToTranslationParser(dictionaryBuilder.indexBuilders, new Pattern[] {codePattern1, codePattern2}).parse(file, entrySource, pageLimit);
178         } else {
179           fatalError("Invalid or missing input format: " + inputFormat);
180         }
181         
182         dictionaryBuilder.dictionary.sources.add(entrySource);
183         System.out.println("Done: " + file + "\n\n");
184       }
185     }
186    
187     dictionaryBuilder.build();
188     
189     if (printFile != null) {
190       final PrintStream out = new PrintStream(new File(printFile));
191       dictionaryBuilder.dictionary.print(out);
192       out.close();
193     }
194     
195     System.out.println("Writing dictionary to: " + dictOutFilename);
196     final RandomAccessFile dictOut = new RandomAccessFile(dictOutFilename, "rw");
197     dictOut.setLength(0);
198     dictionaryBuilder.dictionary.write(dictOut);
199     dictOut.close();
200     
201     if (!keyValueArgs.isEmpty()) {
202       System.err.println("WARNING: couldn't parse arguments: " + keyValueArgs);
203       System.exit(1);
204     }
205   
206   }
207   
208   private static void fatalError(String string) {
209     System.err.println(string);
210     
211     
212     System.exit(1);
213   }
214   
215 }