]> gitweb.fperrin.net Git - Dictionary.git/blob - src/com/hughes/android/dictionary/Entry.java
go
[Dictionary.git] / src / com / hughes / android / dictionary / Entry.java
1 package com.hughes.android.dictionary;\r
2 \r
3 import java.io.IOException;\r
4 import java.io.RandomAccessFile;\r
5 import java.util.ArrayList;\r
6 import java.util.Arrays;\r
7 import java.util.LinkedHashMap;\r
8 import java.util.LinkedHashSet;\r
9 import java.util.List;\r
10 import java.util.Map;\r
11 import java.util.Set;\r
12 import java.util.regex.Pattern;\r
13 \r
14 import com.hughes.util.raf.RAFFactory;\r
15 import com.hughes.util.raf.RAFSerializable;\r
16 \r
17 public final class Entry implements RAFSerializable<Entry> {\r
18 \r
19   static final byte LANG1 = 0;\r
20   static final byte LANG2 = 1;\r
21 \r
22   static final Pattern lineSplitPattern = Pattern.compile("\\s::\\s");\r
23   static final Pattern sublineSplitPattern = Pattern.compile("\\s\\|\\s");\r
24 \r
25   final String[] lang1;\r
26   final String[] lang2;\r
27   \r
28 //  public Entry(final String lang1, final String lang2) {\r
29 //    this.lang1 = new String[] {lang1};\r
30 //    this.lang2 = new String[] {lang2};\r
31 //  }\r
32 \r
33   Entry(final String[] lang1, final String[] lang2) {\r
34     this.lang1 = lang1;\r
35     this.lang2 = lang2;\r
36   }\r
37 \r
38   public static final RAFFactory<Entry> RAF_FACTORY = new RAFFactory<Entry>() {\r
39     public Entry create(RandomAccessFile raf) throws IOException {\r
40       final int rows = raf.readByte();\r
41       final String[] lang1 = new String[rows];\r
42       final String[] lang2 = new String[rows];\r
43       for (int i = 0; i < lang1.length; ++i) {\r
44         lang1[i] = raf.readUTF();\r
45         lang2[i] = raf.readUTF();\r
46       }\r
47       return new Entry(lang1, lang2);\r
48     }};\r
49   public void write(RandomAccessFile raf) throws IOException {\r
50     assert lang1.length == (byte) lang1.length;\r
51     raf.writeByte(lang1.length);\r
52     for (int i = 0; i < lang1.length; ++i) {\r
53       raf.writeUTF(lang1[i]);\r
54       raf.writeUTF(lang2[i]);\r
55     }\r
56   }\r
57 \r
58   @Override\r
59   public boolean equals(Object o) {\r
60     if (!(o instanceof Entry)) {\r
61       return false;\r
62     }\r
63     final Entry that = (Entry) o;\r
64     return Arrays.deepEquals(this.lang1, that.lang1) && Arrays.deepEquals(this.lang2, that.lang2); \r
65   }\r
66 \r
67   @Override\r
68   public int hashCode() {\r
69     return Arrays.deepHashCode(lang1) + Arrays.deepHashCode(lang2);\r
70   }\r
71 \r
72   @Override\r
73   public String toString() {\r
74     return getRawText();\r
75   }\r
76 \r
77   public int getRowCount() {\r
78     assert lang1.length == lang2.length;\r
79     return lang1.length;\r
80   }\r
81 \r
82   String[] getAllText(final byte lang) {\r
83     if (lang == LANG1) {\r
84       return lang1;\r
85     }\r
86     assert lang == LANG2;\r
87     return lang2;\r
88   }\r
89   \r
90   String getRawText() {\r
91     final StringBuilder result = new StringBuilder();\r
92     for (int i = 0; i < lang1.length; ++i) {\r
93       result.append(i == 0 ? "" : " | ").append(lang1[i]);\r
94     }\r
95     result.append("\t");\r
96     for (int i = 0; i < lang2.length; ++i) {\r
97       result.append(i == 0 ? "" : " | ").append(lang2[i]);\r
98     }\r
99     return result.toString();\r
100   }\r
101   \r
102   static byte otherLang(final byte lang) {\r
103     assert lang == LANG1 || lang == LANG2;\r
104     return lang == LANG1 ? LANG2 : LANG1;\r
105   }\r
106   \r
107 \r
108   static Entry parseFromLine(String line, final boolean hasMultipleSubentries) {\r
109     line = line.replaceAll("&lt;", "<");\r
110     line = line.replaceAll("&gt;", ">");\r
111     final String[] parts = lineSplitPattern.split(line);\r
112     if (parts.length != 2) {\r
113       System.err.println("Entry:" + "Invalid line: " + line);\r
114       return null;\r
115     }\r
116     if (!hasMultipleSubentries) {\r
117       return new Entry(new String[] {parts[0].trim()}, new String[] {parts[1].trim()});\r
118     }\r
119     \r
120     final String[] lang1 = sublineSplitPattern.split(" " + parts[0].trim() + " ");\r
121     final String[] lang2 = sublineSplitPattern.split(" " + parts[1].trim() + " ");\r
122     if (lang1.length != lang2.length) {\r
123       System.err.println("Entry:" + "Invalid subline: " + line);\r
124       return null;\r
125     }\r
126     for (int i = 0; i < lang1.length; ++i) {\r
127       lang1[i] = lang1[i].trim();\r
128       lang2[i] = lang2[i].trim();\r
129     }\r
130     return new Entry(lang1, lang2);\r
131   }\r
132   \r
133   static final Map<String, String> bracketToClose = new LinkedHashMap<String, String>();\r
134   static {\r
135     bracketToClose.put("\"", "\"");\r
136     bracketToClose.put(" '", "' ");\r
137   }\r
138   \r
139   static final Pattern WHITESPACE = Pattern.compile("\\s+");\r
140   \r
141   public Set<String> getIndexableTokens(final byte lang) {\r
142     final Set<String> result = new LinkedHashSet<String>();\r
143     String text = " ";\r
144     for (final String subentry : getAllText(lang)) {\r
145       text += subentry + " ";\r
146     }\r
147 \r
148     text = text.replaceAll("fig\\.", " ");\r
149     text = text.replaceAll("\\{[^\\}]+}", " ");\r
150     text = text.replaceAll("\"-", "-");\r
151     text = text.replaceAll("-\"", "-");\r
152     text = text.replaceAll("[\"/\\()<>\\[\\],;?!.]", " ");\r
153     text = text.replaceAll("[:] ", " ");\r
154     text = text.replaceAll(" [:]", " ");\r
155     \r
156     // Now be really conservative about what we allow inside a token:\r
157     // See: http://unicode.org/Public/UNIDATA/UCD.html#General_Category_Values\r
158     text = text.replaceAll("[^-:\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nd}\\p{Nl}\\p{No}]", " ");\r
159     \r
160     result.addAll(Arrays.asList(WHITESPACE.split(text)));\r
161 \r
162     text = text.replaceAll("[-]", " ");\r
163     result.addAll(Arrays.asList(WHITESPACE.split(text)));\r
164     \r
165     final Set<String> result2 = new LinkedHashSet<String>();\r
166     for (final String token : result) {\r
167       if (isIndexable(token)) {\r
168         result2.add(token);\r
169       }\r
170     }\r
171     return result2;\r
172   }\r
173 \r
174   static boolean isIndexable(final String text) {\r
175     // Does it have an alpha-numeric anywhere?\r
176     return text.matches(".*\\w.*");\r
177   }\r
178   \r
179   static List<String> getTextInside(final String text, final String start, final String end) {\r
180     final List<String> result = new ArrayList<String>();\r
181     int startPos = 0;\r
182     while ((startPos = text.indexOf(start)) != -1) {\r
183       final int endPos = text.indexOf(end, startPos + 1);\r
184       result.add(text.substring(startPos + 1, endPos));\r
185       startPos = endPos + 1;\r
186     }\r
187     return result;\r
188   }\r
189 \r
190 }