Source code: j3/J3Dict.java
1 package j3;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileInputStream;
6
7 import java.io.InputStreamReader;
8
9 import java.util.Enumeration;
10 import java.util.TreeMap;
11 import java.util.StringTokenizer;
12 import java.util.Vector;
13
14 import java.io.FileNotFoundException;
15 import java.io.UnsupportedEncodingException;
16 import java.io.IOException;
17
18
19 /**
20 * <code>J3Dict</code> is the internal representation of a dictionary in my j3 package.
21 * It handles lots of good stuff, although it's probably
22 * not as robust as it can be. It's linked into a J3. If this somehow
23 * becomes useful to others, then they can remove the call to j3.addDictionary(...)
24 * in the J3 cstr, and pass in null to the cstr instead.
25 *
26 * @author <a href="mailto:tree@ieeecs.ece.utexas.edu"></a>
27 * @version 1.0
28 */
29 public class J3Dict {
30
31 // --------------------------------------------------
32 // Static and otherwise, variables
33 // --------------------------------------------------
34
35 /***
36 * <code>L1CharacterMap</code> is the efficient storage of L1 ideographs
37 *
38 * Explanation time:
39 * Character maps are not the same as String Maps
40 * To lookup L1 char definitions query the L1CharacterMap
41 * To lookup L2 char definitions query the L2CharacterMap
42 * To lookup L1 STRING defs, query the L1StringMap
43 * To lookup L2 STRING defs, query the L2StringMap
44 *
45 * Example: Find the kanji for, "love" L2CharacterMapQuery('ai');
46 */
47 protected TreeMap L1CharacterMap = new TreeMap();
48 public TreeMap getL1CharacterMap() {
49 return L1CharacterMap;
50 }
51
52
53 /**
54 * <code>L1StringMap</code> is a map of
55 * language 1's phonetics to l2s->phonetics
56 */
57 protected TreeMap L1StringMap = new TreeMap();
58 public TreeMap getL1StringMap() {
59 return L1StringMap;
60 }
61
62
63
64 /**
65 * <code>L2CharacterMap</code> is the efficient
66 * storage of ideographs. May better be renamed,
67 * ideographTree
68 */
69 protected TreeMap L2CharacterMap = new TreeMap();
70 public TreeMap getL2CharacterMap() {
71 return L2CharacterMap;
72 }
73
74
75 /**
76 * Describe variable <code>L2StringMap</code> here.
77 *
78 */
79 protected TreeMap L2StringMap = new TreeMap();
80 public TreeMap getL2StringMap() {
81 return L2StringMap;
82 }
83
84
85
86
87 /**
88 * My local copy of the <code>j3</code> here.
89 *
90 */
91 protected static j3.J3 j3;
92
93
94 /**
95 * <code>fileName</code> is the complete, fileName included
96 * path to the dictionary file to parse
97 */
98 protected static String fileName;
99
100
101 /**
102 * <code>fileType</code> is the type of dictionary format. Valid
103 * types of formats are listed below in, knownDictionaryTypes.
104 */
105 protected static String fileType;
106
107
108 /**
109 * <code>fileEncoding</code> is the proper, JVM aware file encoding type
110 * represented as a string.
111 */
112 protected static String fileEncoding;
113
114
115 /**
116 * <code>f_dictionary</code> is a java.io.File representation of
117 * the dictionary.
118 */
119 protected static File f_dictionary;
120
121
122 /**
123 * <code>fis_dictionary</code> is a java.io.FileInputStream repr.
124 * of the dictionary
125 */
126 protected static FileInputStream fis_dictionary;
127
128
129 /**
130 * <code>isr_dictionary</code> is the InputStreamReader version
131 *
132 */
133 protected static InputStreamReader isr_dictionary;
134
135
136 /**
137 * InitLevel <code>NONE</code> corresponds to getting to null
138 * strings on cstr. call
139 */
140 public static int initLevel = -1;
141 public static int NONE = 0;
142 public static int PREPARED = 1;
143 public static int PARSED = 2;
144 /**
145 * Fully parsed dictionary ready to use: <code>FULL</code>.
146 *
147 */
148 public static int FULL = 3;
149
150
151 /** Known dicitonary type */
152 public static int EDICT = 0;
153 /** Known dicitonary type */
154 public static int CEDICT = 1;
155 /** Known dicitonary type */
156 public static int KANJIDIC = 2;
157 /** Known dicitonary type */
158 public static int KANJI212 = 3;
159 /** Known dicitonary type */
160 public static int XML = 4;
161
162 /** Known dicitonary type */
163 public static String sEDICT = "EDICT";
164 /** Known dicitonary type */
165 public static String sCEDICT = "CEDICT";
166 /** Known dicitonary type */
167 public static String sKANJIDIC = "KANJIDIC";
168 /** Known dicitonary type */
169 public static String sKANJI212 = "KANJI212";
170 /** Known dicitonary type */
171 public static String sXML = "XML";
172
173 // --------------------------------------------------
174 // End declaring member variables
175 // --------------------------------------------------
176
177 // --------------------------------------------------
178 // CSTRs
179 // --------------------------------------------------
180
181 /**
182 * Creates a new <code>J3Dict</code> instance.
183 *
184 * @param fileName a <code>String</code> value representing the FULL path to the dict. file
185 * @param fileType a <code>String</code> value representing the type of dict. Valid types are ffound in the static knownDictionaryTypes above
186 */
187 public J3Dict( String fileName, String fileType, j3.J3 j3 ) {
188
189 if ( fileType == null || fileName == null || j3 == null )
190 this.initLevel = NONE;
191
192 this.j3 = j3;
193 this.fileName = fileName;
194 this.fileType = fileType;
195
196 // prepare the dictionary file in question
197 // see below
198 if ( prepareFile() == true )
199 this.initLevel = PREPARED;
200
201 // parse the given file by the format type
202 // see below
203 if ( parseFile() == true )
204 this.initLevel = FULL;
205 }
206
207 // --------------------------------------------------
208 // End CSTRs
209 // --------------------------------------------------
210
211
212
213 /**
214 * <code>prepareFile</code> gets the fileEncoding type, (ex: EUC-JP, EUC-TW...),
215 * creates and loads the file to represent the dictionary, does any pre-parsing
216 * necessities.
217 *
218 * @return a <code>boolean</code> success or failure
219 */
220 protected boolean prepareFile() {
221 /** @todo :
222 * 0. get file encoding type
223 * 1. open file and assign proper input streams
224 */
225
226 // 0. get file encoding type
227 int codedType = utils.explicate( fileName );
228 fileEncoding = utils.convertToAcronym(utils.convertToKnownCode( codedType ));
229
230 // make a new file
231 try {
232 f_dictionary = new File( fileName );
233 } catch (NullPointerException npe) {
234 System.out.println("prepare("+ fileName+ ") failing due to NPE" + utils.lineSep );
235 f_dictionary = null;
236 fis_dictionary = null;
237 return false;
238 } // end of try-catch
239
240 // make a new FileInputStream
241 try {
242 fis_dictionary = new FileInputStream( fileName );
243 } catch (FileNotFoundException e) {
244 System.out.println("File not found, " + fileName + utils.lineSep);
245 f_dictionary = null;
246 fis_dictionary = null;
247 return false;
248 } // end of try-catch
249
250
251 // make a new InputStreamReader
252 try {
253 isr_dictionary = new InputStreamReader( fis_dictionary, fileEncoding );
254 } catch (UnsupportedEncodingException e) {
255 System.out.println("prepare("+ fileName+ ") failing USEE" + utils.lineSep);
256 f_dictionary = null;
257 fis_dictionary = null;
258 return false;
259 } // end of try-catch
260
261 return true;
262 }
263
264
265
266 /**
267 * <code>parseFile</code> takes the ready file and parses it into the
268 * internal data structures so that we may use it. Query, put, get
269 * etc., on the dictionary.
270 *
271 * @return a <code>boolean</code> value
272 */
273 protected boolean parseFile() {
274
275 // all these methods follow directly
276
277 if (fileType.equals(sEDICT)) {
278 return parseEDICT();
279 } // end of if (fileType.equals(sEDICT))
280 else if (fileType.equals(sCEDICT)) {
281 return parseCEDICT();
282 } // end of else if (fileType.equals(sCEDICT))
283 else if (fileType.equals(sKANJIDIC)) {
284 return parseKANJIDIC();
285 } // end of else if (fileType.equals(sKANJIDIC))
286 else if (fileType.equals(sKANJI212)) {
287 return parseKANJI212();
288 } // end of else if (fileType.equals(sKANJI212))
289 else if (fileType.equals(sXML)) {
290 return parseXML();
291 } // end of else if (fileType.equals(sXML))
292 else
293 return false;
294 }
295
296
297 // --------------------------------------------------
298 // Dictionary loaders & parsers
299 // --------------------------------------------------
300
301 /**
302 * <code>parseEDICT</code> parses the current GOOD dictionary file
303 * in EDICT style.
304 *
305 * @return a <code>boolean</code>, true on success, false otherwise
306 */
307 protected boolean parseEDICT(){
308 L1StringMap = parseEDICTStyleDictionary( isr_dictionary );
309
310 if (L1StringMap == null) {
311 return false;
312 } // end of if (L1StringMap == null)
313 else {
314 this.j3.addDictionary( this, sEDICT, sEDICT );
315 return true;
316 }
317 }
318
319
320 /**
321 * <code>parseCEDICT</code> parses the given dict. in CEDICT style
322 *
323 * @return a <code>boolean</code> success or not.
324 */
325 protected boolean parseCEDICT(){
326 return parseEDICT();
327 }
328
329
330 /**
331 * Describe <code>parseKANJIDIC</code> method here.
332 *
333 * @return a <code>boolean</code> value
334 */
335 protected boolean parseKANJIDIC(){
336 L1CharacterMap = parseKanjiDicStyleDictionary( isr_dictionary );
337
338 if (L1CharacterMap == null) {
339 System.out.println("What the hell, L1CharacterMap, the dict. is null!?" );
340 return false;
341 } // end of if (L1CharacterMap == null)
342 else {
343 return this.j3.addDictionary( this, fileName, sKANJIDIC );
344 }
345 }
346
347
348 /**
349 * <code>parseKANJI212</code> parses a Kanji212 dictionary
350 *
351 * @return a <code>boolean</code> value
352 */
353 protected boolean parseKANJI212(){
354 return parseKANJIDIC();
355 }
356
357
358
359 /**
360 * Describe <code>parseXML</code> method here.
361 *
362 * @return a <code>boolean</code> value
363 */
364 protected boolean parseXML(){
365 TreeMap rv = parseXMLStyleDictionary( isr_dictionary );
366
367 if (rv == null) {
368 return false;
369 } // end of if (rv == null)
370 else {
371 this.j3.addDictionary( this, fileName, sXML );
372 return true;
373 } // end of if (rv == null)else
374 }
375
376 // --------------------------------------------------
377 // End parsers
378 // --------------------------------------------------
379
380 // --------------------------------------------------
381 // start utils section -- mostly all static methods
382 // --------------------------------------------------
383
384 /** Allows us to try to parse a file based on the FileStream */
385 public static TreeMap parseEDICTStyleDictionary( InputStreamReader newDict ){
386
387 TreeMap parsedMap = new TreeMap();
388
389 // get a buffered input reader for using readline
390 BufferedReader bin = new BufferedReader( newDict );
391
392 long totalMeaningCount = 0;
393 long totalMeaningSubstringCount = 0;
394 long totalLineCount = 0;
395 long totalReadingCount = 0;
396 long totalKeyCount = 0;
397
398 try {
399
400 String s_in = bin.readLine();
401 int outerCount = 0;
402
403 while ( s_in != null ){
404
405 outerCount++;
406 totalLineCount++;
407
408 if ( outerCount % 1000 == 0 ){
409 j3.statusBar.setText( "Loading EDICT style dictionary ... ["
410 + outerCount
411 + "] lines parsed, please wait...");
412 }
413
414 String key = null;
415 Vector meanings = new Vector();
416 Vector readings = new Vector();
417
418 String lineCopy = new String(s_in);
419
420 StringTokenizer tokenizer = new StringTokenizer( s_in, " " );
421
422 // System.out.println("Current Line is: " + s_in + "; Now splitting it." );
423
424 int count = 0;
425
426 while ( tokenizer.hasMoreTokens() ){
427
428 String curToken = tokenizer.nextToken();
429
430 // System.out.println("--curToken is: " + curToken );
431
432
433 char starterChar = curToken.charAt(0);
434
435 // System.out.println( "starterChar: " + starterChar );
436
437 if ( starterChar == '[' ) {
438 // add readings...
439
440 String partialNested = new String();
441 String nestedToken = new String();
442
443 if (! tokenizer.hasMoreTokens()) {
444 partialNested = curToken;
445 } // end of if (! tokenizer.hasMoreTokens())
446 else { // still have tokens
447 while (tokenizer.hasMoreTokens()) {
448 if ( nestedToken.equals(""))
449 nestedToken = curToken; //tokenizer.nextToken();
450 else {
451 nestedToken = tokenizer.nextToken();
452 // System.out.println("nestedToken advanced: " + nestedToken );
453 }
454
455 if ( nestedToken.endsWith( "]" )) {
456 partialNested += nestedToken;
457 break;
458 } else {
459 partialNested += nestedToken;
460
461 if (partialNested.length() != 0) {
462 partialNested += " ";
463 } // end of if (partialNext.length() != 0)
464
465 }
466 }
467 }
468
469 // new char array chopping off the [ and ]
470 char[] dst = new char[partialNested.length()-2];
471 partialNested.getChars(
472 1,
473 partialNested.length()-1,
474 dst,
475 0 );
476
477 String curDef = new String( dst );
478
479 totalReadingCount++;
480 // System.out.println("--curReading: " + curDef );
481 readings.add( curDef );
482 //break;
483 }
484 else if ( starterChar == '/' ){
485
486 // Just nextToken('/');
487 // System.out.println("lineCopy = " + lineCopy );
488 StringTokenizer st_meanings = new StringTokenizer( lineCopy, "/" );
489
490 int tokenCount = 0;
491 while ( st_meanings.hasMoreTokens() ){
492 //throw away the Japanese readings
493 if ( tokenCount != 0 ) {
494 String tempDef = st_meanings.nextToken();
495 totalMeaningSubstringCount += tempDef.length();
496 totalMeaningCount++;
497 // System.out.println("--curDef " + tempDef );
498 meanings.add( tempDef );
499 }
500 else
501 st_meanings.nextToken();
502
503 tokenCount++;
504 }
505
506 // we got all the tokens.
507 while ( tokenizer.hasMoreTokens() )
508 tokenizer.nextToken();
509
510 }
511 else {
512 // add compound
513 totalKeyCount++;
514 // System.out.println("--key: " + curToken );
515 key = curToken;
516 }
517 }
518
519 // show some results
520 // String m = new String();
521 // String r = new String();
522 // for( Enumeration e = meanings.elements(); e.hasMoreElements(); ){
523 // m += (String) e.nextElement();
524 // }
525 // for( Enumeration f = readings.elements(); f.hasMoreElements(); ){
526 // r += (String) f.nextElement();
527 // }
528 // j3.resultsArea.append( "m(" + m + "); r(" + r + "); key(" + key + ")" + utils.lineSep );
529
530
531 // make the treeMap(s), now.
532 Vector mixedValues = new Vector();
533 if ( readings != null && readings.size() != 0)
534 mixedValues.addAll( readings );
535 if ( meanings != null && meanings.size() != 0)
536 mixedValues.addAll( meanings );
537
538 parsedMap.put( key, mixedValues );
539
540 s_in = bin.readLine();
541 }
542 } catch (IOException e){
543 System.out.println("IOException in parsing the EDICT dictionary");
544 return null;
545 }
546
547 j3.statusBar.setText( fileName + " successfully loaded. Thanks for waiting." );
548 // System.out.println("Total meanings: " + totalMeaningCount );
549 // System.out.println("Total meaningsSubstring: " + totalMeaningSubstringCount );
550 // System.out.println("Total readings: " + totalReadingCount );
551 // System.out.println("Total keys: " + totalKeyCount );
552
553 return parsedMap;
554 }
555
556
557
558 /** Allows us to try to parse a file based on the filename alone
559 * just sets up and calls the above method: parseEDICTStyleDict( instream )
560 * - takes String fileName to attempt to parse as an EDICT
561 * - returns HashMap on success, null otherwise
562 */
563 public static TreeMap parseEDICTStyleDictionary( String fileName ) {
564
565 FileInputStream fis_newDict = null;
566 InputStreamReader newDict = null;
567
568 // Which language?
569 String openType = utils.convertToAcronym(utils.convertToKnownCode(utils.explicate(fileName)));
570
571 /** NOTE: This must be changed to work with other languages. Explicate NEEDS
572 * to support proper decoding. I'll work on this. The IF-THEN below will
573 * be removed later when the encoding type detection works 100%
574 */
575 if ( openType.equals("EUC") )
576 openType = "EUC-JP";
577
578 // Need to get char encoding first!
579 try {
580 fis_newDict = new FileInputStream( fileName );
581 newDict = new InputStreamReader( fis_newDict, openType );
582 } catch (FileNotFoundException fnfe ) {
583 System.err.println("Cannot parse file named, "
584 + fileName
585 + " because it couldn't be found.");
586 return null;
587 } catch (UnsupportedEncodingException usee ) {
588 System.err.println("Cannot parse file named, "
589 + fileName
590 + " because its encoding type, "
591 + openType
592 + " is wrong or is not supported.");
593 return null;
594 }
595
596 return parseEDICTStyleDictionary( newDict );
597 }
598
599
600 /**
601 * <code>parseKanjiDicStyleDictionary</code> does what the names
602 * says, putting the info in the right (hopefully) place.
603 *
604 * @param dictionary an <code>InputStreamReader</code> value
605 * @return a <code>TreeMap</code> value
606 */
607 public static TreeMap parseKanjiDicStyleDictionary( InputStreamReader dictionary ){
608
609 TreeMap kanjiDic = new TreeMap();
610
611 // get a new buffered input reader -- readline rules!
612 BufferedReader bin = new BufferedReader( dictionary );
613
614
615 try {
616
617 String s_in = bin.readLine();
618 int outerCount = 0;
619
620 while (s_in != null) {
621
622 outerCount++;
623 if (outerCount % 1000 == 0) {
624 j3.statusBar.setText( "Loading KANJIDIC style dictionary... ["
625 + outerCount
626 + "] lines parsed, please wait..." );
627 } // end of if (outerCount % 10 == 0)
628
629 String key = null;
630 Vector values = new Vector();
631
632 StringTokenizer tokenizer = new StringTokenizer( s_in, " " );
633
634 int count = 0;
635 while (tokenizer.hasMoreTokens()) {
636
637 String curToken = tokenizer.nextToken();
638 // System.out.println("curToken=>" + curToken );
639
640 char starterChar = curToken.charAt(0);
641
642 if (count == 0 ) {
643 if ( starterChar == '#' ) {
644 while (tokenizer.hasMoreTokens()) {
645 tokenizer.nextToken();
646 } // end of while (tokenizer.hasMoreTokens())
647 break;
648 }
649 else {
650 key = curToken;
651 // break;
652 }
653 } // end of if (count == 0)
654 else {
655 switch (starterChar) {
656 case '{': // add a definition -- one def, or all?
657
658
659 String partialNested = new String();
660 String nestedToken = new String();
661
662 if (! tokenizer.hasMoreTokens()) {
663 partialNested = curToken;
664 } // end of if (! tokenizer.hasMoreTokens())
665 else { // still have tokens
666 while (tokenizer.hasMoreTokens()) {
667 if ( nestedToken.equals(""))
668 nestedToken = curToken; //tokenizer.nextToken();
669 else {
670 nestedToken = tokenizer.nextToken();
671 }
672
673 if ( nestedToken.endsWith( "}" )) {
674 partialNested += nestedToken;
675 break;
676 } else {
677 partialNested += nestedToken;
678
679 if (partialNested.length() != 0) {
680 partialNested += " ";
681 } // end of if (partialNext.length() != 0)
682
683 }
684 }
685 }
686
687 char[] dst = new char[partialNested.length()-2];
688 partialNested.getChars(
689 1,
690 partialNested.length()-1,
691 dst,
692 0 );
693
694 String curDef = new String( dst );
695
696 values.add( curDef );
697 break;
698 // readings I don't use now
699 case 'U':
700 case 'B':
701 case 'C':
702 case 'F':
703 case 'G':
704 case 'H':
705 case 'N':
706 case 'V':
707 case 'D':
708 case 'P':
709 case 'S':
710 case 'T':
711 case 'I':
712 case 'Q':
713 case 'M':
714 case 'E':
715 case 'K':
716 case 'L':
717 case 'O':
718 case 'W':
719 case 'X':
720 case 'Y':
721 case 'Z':
722 case '1':
723 case '2':
724 case '3':
725 case '4':
726 case '5':
727 case '6':
728 case '7':
729 case '8':
730 case '9':
731 case '0':
732 break;
733 default:
734 values.add( curToken );
735 break;
736 } // end of switch (startChar)
737 } // end of else
738
739 if ((key != null) && (values.size() != 0)) {
740 kanjiDic.put( (Object) key, (Object) values );
741 } // end of if ((key != null) && (values.size() != 0))
742 count++;
743 } // end of while (tokenizer.hasMoreTokens())
744
745 s_in = bin.readLine();
746 }
747 }
748 catch (IOException e) {
749 System.out.println("IOException in KanjiDic parsing!");
750 return null;
751 } // end of catch
752
753 j3.statusBar.setText( fileName + " successfully loaded. Thanks for waiting." );
754 return kanjiDic;
755 }
756
757
758
759 /**
760 * Describe <code>parseXMLStyleDictionary</code> method here.
761 *
762 * @return a <code>TreeMap</code> value
763 */
764 public static TreeMap parseXMLStyleDictionary( InputStreamReader dictionary ){
765 return null;
766 }
767
768
769
770 /**
771 * Look for a CHARACTER in language one, <code>L1CharacterQuery</code>.
772 *
773 * @param query a <code>String</code> value the char to look for.
774 * @return a <code>String[]</code> value, or null if not found
775 */
776 public String[] L1CharacterQuery( String query ) {
777 if (L1CharacterMap.containsKey( query )) {
778 return (String[]) ((Vector)L1CharacterMap.get((Object)query)).toArray(new String[0]);
779 } // end of if (L1CharacterMap.containsKey( query ))
780 else {
781 return null;
782 } // end of else
783 }
784
785
786
787 /**
788 * <code>L2CharacterQuery</code> queries for a character in the 2nd map
789 *
790 * @param query a <code>String</code> value
791 * @return a <code>String[]</code> value
792 */
793 public String[] L2CharacterQuery( String query ) {
794 if (L2CharacterMap.containsKey( query )) {
795 return (String[]) ((Vector)L2CharacterMap.get((Object)query)).toArray(new String[0]);
796 } // end of if (L2CharacterMap.containsKey( query ))
797 else {
798 return null;
799 } // end of else
800 }
801
802
803
804
805 /**
806 * Describe <code>L1StringQuery</code> method here.
807 *
808 * @param query a <code>String</code> value
809 * @return a <code>String[]</code> value
810 */
811 public String[] L1StringQuery( String query ) {
812 if (L1StringMap.containsKey( query )) {
813 return (String[]) ((Vector)L1StringMap.get((Object)query)).toArray(new String[0]);
814 } // end of if (L1.containsKey( query ))
815 else {
816 return null;
817 } // end of else
818 }
819
820
821
822 /**
823 * Describe <code>L2StringQuery</code> method here.
824 *
825 * @param query a <code>String</code> value
826 * @return a <code>String[]</code> value
827 */
828 public String[] L2StringQuery( String query ) {
829 if (L2StringMap.containsKey( query )) {
830 return (String[]) ((Vector)L2StringMap.get((Object)query)).toArray(new String[0]);
831 } // end of if (L1.containsKey( query ))
832 else {
833 return null;
834 } // end of else
835 }
836
837
838
839 /**
840 * Describe <code>queryDictionary</code> method here.
841 *
842 * @param parsedMap a <code>TreeMap</code> value
843 * @param query a <code>String</code> value
844 * @return a <code>String[]</code> value
845 */
846 public static String[] queryDictionary( j3.J3Dict dictionary, String query ) {
847
848 if ( dictionary == null ||
849 query == null )
850 return null;
851 else
852 return dictionary.queryDictionary( query );
853 }
854
855
856
857 /**
858 * Describe <code>queryDictionary</code> method here.
859 *
860 * @param query a <code>String</code> value
861 * @return a <code>String[]</code> value
862 */
863 public String[] queryDictionary( String query ) {
864 String[] res = null;
865 String[] res2 = null;
866 String[] res3 = null;
867 String[] res4 = null;
868
869 if (initLevel != FULL) {
870 System.out.println("Dictionary NOT properly initialized!");
871 return null;
872 } // end of if (initLevel != FULL)
873 else {
874 res = L1CharacterQuery( query );
875 res2 = L2CharacterQuery( query );
876 res3 = L1StringQuery( query );
877 res4 = L2StringQuery( query );
878
879 // shortcut
880 if ( res == null && res2 == null &&
881 res3 == null && res4 == null )
882 return null;
883
884 Vector combinedResults = new Vector();
885 if ( res != null )
886 for ( int i = 0; i < res.length; i++ ){
887 combinedResults.add( res[i].trim() );
888 // System.out.println("res: (" + res[i].trim() + ")");
889 }
890 // else
891 // System.out.println("res was null" );
892
893 if ( res2 != null )
894 for ( int j = 0; j < res2.length; j++ ){
895 combinedResults.add( res2[j].trim() );
896 // System.out.println("res2: (" + res2[j].trim() + ")");
897 }
898 // else
899 // System.out.println("res2 was null" );
900
901 if ( res3 != null )
902 for ( int k = 0; k < res3.length; k++ ){
903 combinedResults.add( res3[k].trim() );
904 // System.out.println("res3: (" + res3[k].trim() + ")");
905 }
906 // else
907 // System.out.println("res3 was null" );
908
909 if ( res4 != null )
910 for ( int l = 0; l < res4.length; l++ ){
911 combinedResults.add( res4[l].trim() );
912 // System.out.println("res4: (" + res4[l].trim() + ")");
913 }
914 // else
915 // System.out.println("res4 was null" );
916
917
918 res = (String[]) combinedResults.toArray( new String[0] );
919 // System.out.println("res has size" + res.size());
920 }
921 // if res is null now, we're never gona' find it!
922 return res;
923 }
924
925 // --------------------------------------------------
926 // End of utils section -- contains mostly static methods
927 // --------------------------------------------------
928
929 }