001: package Language;
002:
003: import java.util.*;
004: import java.util.zip.*;
005: import java.io.*;
006: import java.net.URL;
007: import javax.swing.table.*;
008: import javax.swing.event.*;
009: import java.awt.event.*;
010:
011: import Schmortopf.Utility.Vectorizable;
012: import XMLTemplates.XMLJarLocator;
013: import Schmortopf.Utility.io.FileUtilities;
014: import Schmortopf.Utility.SortableTable.*;
015:
016: /** @contain the sentences for a given language,
017: and store the sentences that are not already translated
018:
019: */
020: public class SentenceDictionary implements Vectorizable {
021: // STORED: ... contain All Sentences, also the untranslated
022: final Vector allSentencesVector = new Vector();
023:
024: // contain sentences, key= english, value= translation in the language
025: // this is used at Schmortopf runtime for quick translation access
026: final Hashtable sentences = new Hashtable(); // quick access
027:
028: // the language
029: private String language;
030:
031: // true for dictionaries read from writable file
032: // (i.e. false for dictionaries embedded in jar files and readonly external files)
033: // is set during read from file...
034: private boolean isEditable = true;
035:
036: public SentenceDictionary(String language) {
037: this .language = language;
038: } // Constructor
039:
040: public String getLanguage() {
041: return language;
042: }
043:
044: public Vector getAllSentences() {
045: return allSentencesVector;
046: }
047:
048: public boolean getIsEditable() {
049: return isEditable;
050: }
051:
052: /** try to translate the sentence.
053: serch first for an exact mactch and then for a match
054: ignoring spaces at the beginning and at the end.
055:
056: If not found, add a request and return the original english sentence
057: */
058: public String getTranslatedSentence(String sentence) {
059: String transl = (String) sentences.get(sentence);
060: if (transl != null) {
061: return transl;
062: } else {
063: // not found... we try to find a similar string, just ignoring spaces
064: String try2 = getTranslationIgnoringSpaces(sentence);
065: if (try2 != null)
066: return try2;
067:
068: // the sentence is not translated yet, we must request his translation
069: Sentence sent = new Sentence(sentence,
070: "Occured at runtime", -1);
071: allSentencesVector.add(sent);
072:
073: // return the original sentence
074: return sentence;
075: }
076: }
077:
078: /** @return null if not found.
079: try to search for the string, ignoring spaces.
080: The same number of spaces are then added at begining and end of the answer
081: */
082: private String getTranslationIgnoringSpaces(String sentence) {
083: // not found... we try to find a similar string, just ignoring spaces
084: String trimmed = sentence.trim();
085: int spaceBegin = Common.GetNumberOfSpacesAtBegining(sentence);
086: int spaceEnd = Common.GetNumberOfSpacesAtEnd(sentence);
087:
088: Enumeration enumeration = sentences.keys();
089: while (enumeration.hasMoreElements()) {
090: String elt = (String) enumeration.nextElement();
091: if (elt.trim().equals(trimmed)) {
092: // found! add spaces at the end...
093: StringBuffer reply = new StringBuffer();
094: for (int i = 0; i < spaceBegin; i++) {
095: reply.append(" ");
096: }
097: reply.append(((String) sentences.get(elt)).trim());
098: for (int i = 0; i < spaceEnd; i++) {
099: reply.append(" ");
100: }
101: return reply.toString();
102: }
103: }
104:
105: return null;
106: }
107:
108: /** this add the new sentences parsed in source and
109: remove the old ones (no more used)
110: */
111: public void updateSentencesFromSource(
112: Vector allEnglishSentencesFoundInSource) {
113: System.out
114: .println("Update dictionary with sentences parsed from source for language "
115: + getLanguage());
116:
117: // 1. add all english sentences parsed
118: for (int p = 0; p < allEnglishSentencesFoundInSource.size(); p++) {
119: Sentence sent = (Sentence) allEnglishSentencesFoundInSource
120: .elementAt(p);
121: //if(sent.getSentence().equals("Yes")) System.out.println("* 1 *");
122: // verify (or add) and mark as present
123: verifyIfSentenceIsPresent(sent);
124: }
125:
126: // 2. remove the sentences that have not been found
127: int removed = 0;
128: Vector toRemove = new Vector();
129: for (int i = 0; i < allSentencesVector.size(); i++) {
130: Sentence s = (Sentence) allSentencesVector.elementAt(i);
131: if (s.visited == false) {
132: removed++;
133: //if(s.getSentence().equals("Yes")) System.out.println("* 3 *");
134: toRemove.addElement(s);
135: /* allSentencesVector.remove(s);
136: sentences.remove(s.getSentence()); */
137: }
138: }
139:
140: for (int i = 0; i < toRemove.size(); i++) {
141: Sentence s = (Sentence) toRemove.elementAt(i);
142: sentences.remove(s.getSentence());
143: allSentencesVector.remove(s);
144: }
145:
146: fireChangeEvent();
147:
148: System.out.println("" + removed + " removed unused sentences");
149: }
150:
151: public String getStringOfAllTranslatedSentences() {
152: StringBuffer sb = new StringBuffer();
153: for (int i = 0; i < allSentencesVector.size(); i++) {
154: Sentence s = (Sentence) allSentencesVector.elementAt(i);
155: if (s.hasTranslation()) {
156: sb.append("\n\n" + s.getTranslation());
157: }
158: }
159: return sb.toString();
160: }
161:
162: /** look if a sentence is present. if not found, add it to the translation requests
163: */
164: private void verifyIfSentenceIsPresent(Sentence sent) {
165: String sentence = sent.getSentence();
166:
167: int pos = positionInAllSentenceVector(sentence);
168: if (pos == -1) {
169: //if(sent.getSentence().equals("Yes")) System.out.println("* 2 *");
170: allSentencesVector.addElement(sent);
171: sent.visited = true;
172: } else {
173: //if(sent.getSentence().equals("Yes")) System.out.println("* 2b *");
174: Sentence s = (Sentence) allSentencesVector.elementAt(pos);
175: s.visited = true;
176: s.setLocationClass(sent.getLocationClass(), sent
177: .getLinePosition());
178: }
179:
180: /*
181: // 1. look if the translation is available
182: String transl = (String) sentences.get(sentence);
183: if(transl==null)
184: {
185: // 2. the translation is not present => look for a trimmed version
186: String reply = getTranslationIgnoringSpaces(sentence);
187: if(reply==null {
188: // 3. the sentence is really not present => add it
189: allSentencesVector.addElement(sent);
190: // mark it as visited
191: sent.visited = true;
192: fireChangeEvent();
193: }
194: }
195:
196: // 2. mark the sentence as used
197: int pos = positionInAllSentenceVector(sentence);
198: if(pos==-1)
199: {
200: System.out.println("Problem: sentence not in all vector "+sentence);
201: }
202: else
203: {
204: Sentence s = (Sentence) allSentencesVector.elementAt(pos);
205: s.visited = true;
206: } */
207: }
208:
209: /** @return the position of sent in allSentencesVector,
210: using the trimmed strings
211: */
212: private int positionInAllSentenceVector(String sent) {
213: String st = sent.trim();
214:
215: for (int i = 0; i < allSentencesVector.size(); i++) {
216: Sentence s = (Sentence) allSentencesVector.elementAt(i);
217: if (s.getSentence().trim().equals(st))
218: return i;
219: }
220: return -1;
221: }
222:
223: public int getNumberOfTranslatedSentences() {
224: return sentences.size();
225: }
226:
227: public int getNumberOfSentences() {
228: return allSentencesVector.size();
229: }
230:
231: /** add a translation
232: */
233: public void addTranslation(String english, String translation) {
234: // add /or update
235: sentences.put(english, translation);
236: int pos = this .positionInAllSentenceVector(english);
237: if (pos == -1) {
238: Sentence se = new Sentence(english, "Added during runtime",
239: 0);
240: se.setTranslation(translation);
241:
242: allSentencesVector.addElement(se);
243: System.out.println("### sentence not in dic " + english);
244: } else {
245: Sentence se = (Sentence) allSentencesVector.elementAt(pos);
246: se.setTranslation(translation);
247: }
248:
249: // inform listeners
250: fireChangeEvent();
251: }
252:
253: // Listeners
254: //
255: Vector changeListeners = new Vector();
256:
257: public void addChangeListener(ChangeListener cl) {
258: changeListeners.addElement(cl);
259: }
260:
261: public void removeChangeListener(ChangeListener cl) {
262: changeListeners.removeElement(cl);
263: }
264:
265: private void fireChangeEvent() {
266: for (int i = 0; i < changeListeners.size(); i++) {
267: ChangeListener cl = (ChangeListener) changeListeners
268: .elementAt(i);
269: cl.stateChanged(new ChangeEvent(this ));
270: }
271: }
272:
273: // Vectorizable
274: //
275: public SentenceDictionary() {
276: }
277:
278: public Vector getVectorRepresentation() throws Exception {
279: Vector v = new Vector();
280: v.addElement(new Integer(4)); // 0. version
281: v.addElement(language); // 1. language
282: Vector sentv = new Vector();
283: v.addElement(sentv); // 2. sentences
284: for (int i = 0; i < allSentencesVector.size(); i++) {
285: Sentence s = (Sentence) allSentencesVector.elementAt(i);
286: sentv.addElement(s.getVectorRepresentation());
287: }
288:
289: return v;
290: }
291:
292: public void createFromVectorRepresentation(Vector v) {
293: int version = ((Integer) v.elementAt(0)).intValue();
294: //System.out.println("dic version ="+version);
295: if (version == 2) {
296: language = (String) v.elementAt(1);
297: sentences.clear();
298: Vector sentv = (Vector) v.elementAt(2);
299: int size = sentv.size() / 2;
300: for (int i = 0; i < size; i++) {
301: String key = (String) sentv.elementAt(i * 2);
302: String val = (String) sentv.elementAt(i * 2 + 1);
303: sentences.put(key, val);
304:
305: // add to the "all" list
306: Sentence se = new Sentence(key);
307: se.setTranslation(val);
308: allSentencesVector.addElement(se);
309: }
310: Vector st = (Vector) v.elementAt(3);
311: for (int i = 0; i < st.size(); i++) {
312: Sentence se = new Sentence((String) st.elementAt(i));
313: allSentencesVector.addElement(se);
314: }
315: } else if (version == 3) {
316: language = (String) v.elementAt(1);
317: sentences.clear();
318: Vector sentv = (Vector) v.elementAt(2);
319: int size = sentv.size() / 2;
320: for (int i = 0; i < size; i++) {
321: String key = (String) sentv.elementAt(i * 2);
322: String val = (String) sentv.elementAt(i * 2 + 1);
323: sentences.put(key, val);
324:
325: // add to the "all" list
326: Sentence se = new Sentence(key);
327: se.setTranslation(val);
328: allSentencesVector.addElement(se);
329: }
330: Vector st = (Vector) v.elementAt(3);
331: for (int i = 0; i < st.size(); i++) {
332: Sentence s = new Sentence();
333: s.createFromVectorRepresentation((Vector) st
334: .elementAt(i));
335: allSentencesVector.addElement(s);
336: }
337: } else if (version == 4) {
338: language = (String) v.elementAt(1);
339: sentences.clear();
340: Vector sentv = (Vector) v.elementAt(2);
341: for (int i = 0; i < sentv.size(); i++) {
342: Sentence s = new Sentence();
343: s.createFromVectorRepresentation((Vector) sentv
344: .elementAt(i));
345: allSentencesVector.addElement(s);
346: if (!s.getTranslation().equals("")) {
347: sentences.put(s.getSentence(), s.getTranslation());
348: }
349:
350: // sentences.put(key, val);
351: }
352: }
353:
354: else {
355: throw new RuntimeException("Bad version " + version);
356: }
357: }
358:
359: public void saveToFile() throws Exception {
360: // no english
361: if (language.compareToIgnoreCase("english") == 0)
362: return;
363:
364: if (!isEditable)
365: return;
366:
367: File file = new File("Language/" + language + ".translation");
368: if (file.exists() && !file.canWrite()) {
369: throw new Exception("Language file " + language
370: + " is read-only");
371: }
372:
373: System.out.println("saving dic " + file.getAbsolutePath());
374: Common.StoreVectorToFile(file, this .getVectorRepresentation());
375: }
376:
377: /** look in the schmortopf jar file if french and german are
378: available
379: */
380: public static String[] getInternalAvailableTranslations() {
381: String[] languagesToLookFor = new String[] { "French", "German" };
382: ClassLoader cl = SentenceDictionary.class.getClassLoader();
383: if (cl == null) {
384: return new String[0];
385: }
386:
387: Vector foundLanguagesNames = new Vector();
388: for (int i = 0; i < languagesToLookFor.length; i++) {
389: InputStream is = null;
390: try {
391: is = cl.getResourceAsStream("Language/"
392: + languagesToLookFor[i] + ".translation");
393: if (is != null) {
394: foundLanguagesNames
395: .addElement(languagesToLookFor[i]);
396: //System.out.println("Found language embedded in jar: "+languagesToLookFor[i]);
397: }
398: } finally {
399: try {
400: is.close();
401: } catch (Exception e) {
402: }
403: is = null;
404: }
405: }
406: return (String[]) foundLanguagesNames
407: .toArray(new String[foundLanguagesNames.size()]);
408: }
409:
410: public static SentenceDictionary ReadFromJarFile(String language)
411: throws Exception {
412: // no english
413: if (language.compareToIgnoreCase("english") == 0)
414: return null;
415:
416: ClassLoader cl = SentenceDictionary.class.getClassLoader();
417: if (cl == null) {
418: System.out
419: .println("Class loader is null for class SentenceDictionary.");
420: // not found, maybe IDE mode ? not running from jar file
421: return null; //ReadFromFile(language);
422: }
423:
424: SentenceDictionary sd = new SentenceDictionary(language);
425:
426: InputStream is = null;
427: try {
428: is = cl.getResourceAsStream("Language/" + language
429: + ".translation");
430: if (is == null) {
431: System.out
432: .println("ResourceAsStream is null for Language/"
433: + language);
434: return null;
435: }
436: GZIPInputStream zipIn = new GZIPInputStream(is);
437: DataInputStream dis = new DataInputStream(zipIn);
438: Vector content = FileUtilities.ReceiveVector(dis, null, 0);
439:
440: sd.createFromVectorRepresentation(content);
441: // read-only
442: sd.isEditable = false;
443:
444: return sd;
445: } finally {
446: try {
447: is.close();
448: } catch (Exception e) {
449: }
450: is = null;
451: }
452:
453: }
454:
455: /** try to read the dictionary from file.
456: if not successful, try to use an internal embedded dictionary.
457: */
458: public static SentenceDictionary ReadFromFile(String language,
459: boolean useEmbeddedIfFileNotFound) throws Exception {
460: // no english
461: if (language.compareToIgnoreCase("english") == 0)
462: return null;
463:
464: File file = new File("Language/" + language + ".translation");
465:
466: System.out.println("loading dic " + file.getAbsolutePath());
467:
468: SentenceDictionary sd = new SentenceDictionary(language);
469:
470: if (file.exists()) {
471: // the read-only case
472: if (!file.canWrite())
473: sd.isEditable = false;
474:
475: Vector rep = Common.ReadVectorFromFile(file);
476: try {
477: sd.createFromVectorRepresentation(rep);
478: } catch (Exception e) {
479: throw e;
480: }
481: System.out.println(" Number of sentences = "
482: + sd.getNumberOfTranslatedSentences());
483: //System.out.println(" translation requests "+sd.getRowCount());
484: } else {
485: System.out.println("Language not found in file "
486: + file.getAbsolutePath());
487: // no file found, try to read from jar file
488: if (useEmbeddedIfFileNotFound) {
489: SentenceDictionary sdj = ReadFromJarFile(language);
490: if (sdj != null) {
491: return sdj;
492: } else {
493:
494: }
495: }
496: }
497: return sd;
498: }
499:
500: public String getFileName() {
501: File file = new File("Language/" + language + ".translation");
502: return file.getAbsolutePath();
503: }
504:
505: } // SentenceDictionary
|