KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > i18n > java > JavaI18nSupport


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20
21 package org.netbeans.modules.i18n.java;
22
23
24 import java.lang.reflect.Modifier JavaDoc;
25 import java.text.MessageFormat JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.regex.Pattern JavaDoc;
30 import java.util.regex.PatternSyntaxException JavaDoc;
31 import javax.swing.JPanel JavaDoc;
32 import javax.swing.text.BadLocationException JavaDoc;
33 import javax.swing.text.Element JavaDoc;
34 import javax.swing.text.Position JavaDoc;
35 import javax.swing.text.StyledDocument JavaDoc;
36 import org.netbeans.api.java.classpath.ClassPath;
37
38 import org.netbeans.modules.i18n.HardCodedString;
39 import org.netbeans.modules.i18n.InfoPanel;
40 import org.netbeans.modules.i18n.I18nString;
41 import org.netbeans.modules.i18n.I18nSupport;
42 import org.netbeans.modules.i18n.I18nUtil;
43 import org.netbeans.modules.i18n.PropertyPanel;
44 import org.netbeans.modules.i18n.ResourceHolder;
45 import org.netbeans.modules.i18n.regexp.ParseException;
46 import org.netbeans.modules.i18n.regexp.Translator;
47 import org.netbeans.modules.properties.UtilConvert; // PENDING
48

49 import org.openide.loaders.DataObject;
50 import org.openide.NotifyDescriptor;
51 import org.openide.DialogDisplayer;
52 import org.openide.filesystems.FileObject;
53 import org.openide.text.NbDocument;
54 import org.openide.util.MapFormat;
55 import org.openide.util.Lookup;
56 import org.openide.ErrorManager;
57
58
59 /**
60  * Support for internationalizing strings in java sources.
61  *
62  * @author Peter Zavadsky
63  * @see I18nSupport
64  */

65 public class JavaI18nSupport extends I18nSupport {
66
67     /** Modifiers of field which are going to be internbationalized (default is private static final). */
68     protected int modifiers = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL;
69
70     /** Identifier of field element pointing to field which defines resource bundle in the source. */
71     protected String JavaDoc identifier;
72
73     /** Generate field? */
74     protected boolean generateField;
75     
76     /** Init string format. */
77     protected String JavaDoc initFormat;
78     
79
80     /** Constructor.
81      * @see I18nSupport */

82     public JavaI18nSupport(DataObject sourceDataObject) {
83         super(sourceDataObject);
84
85         initFormat = I18nUtil.getOptions().getInitJavaCode();
86     }
87     
88     
89     /** Creates <code>I18nFinder</code>. Implements superclass abstract method. */
90     protected I18nFinder createFinder() {
91         return new JavaI18nFinder(document);
92     }
93     
94     /** Creates <code>I18nReplacer</code>. Implemens superclass abstract method. */
95     protected I18nReplacer createReplacer() {
96         return new JavaI18nReplacer();
97     }
98     
99     /** Creates <code>ResourceHolder</code>. Implemens superclass abstract method. */
100     protected ResourceHolder createResourceHolder() {
101         return new JavaResourceHolder();
102     }
103     
104     /** Implements superclass abstract method. */
105     public I18nString getDefaultI18nString(HardCodedString hcString) {
106         I18nString i18nString = new JavaI18nString(this);
107         
108         final ResourceHolder resourceHolder
109                 = i18nString.getSupport().getResourceHolder();
110         if (resourceHolder.getResource() == null) {
111             DataObject lastResource = I18nUtil.getOptions().getLastResource2();
112             if (lastResource != null) {
113                 FileObject sourceFile = sourceDataObject.getPrimaryFile();
114                 FileObject bundleFile = lastResource.getPrimaryFile();
115                 ClassPath execClassPath = ClassPath
116                                           .getClassPath(sourceFile,
117                                                         ClassPath.EXECUTE);
118                 if (execClassPath.getResourceName(bundleFile) != null) {
119                     resourceHolder.setResource(lastResource);
120                 }
121             }
122         }
123
124         if(hcString == null)
125             return i18nString;
126         
127         i18nString.setComment(""); // NOI18N
128
i18nString.setKey(hcString.getText().replace(' ', '_' ));
129         i18nString.setValue(hcString.getText());
130         
131         // If generation of field is set and replace format doesn't include identifier argument replace it with the default with identifier.
132
if(isGenerateField() && i18nString.getReplaceFormat().indexOf("{identifier}") == -1) // NOI18N
133
i18nString.setReplaceFormat((String JavaDoc)I18nUtil.getReplaceFormatItems().get(0));
134         
135         return i18nString;
136     }
137     
138     /** Implements <code>I18nSupport</code> superclass abstract method. Gets info panel about found hard string. */
139     public JPanel JavaDoc getInfo(HardCodedString hcString) {
140         return new JavaInfoPanel(hcString, document);
141     }
142
143     /** Getter for identifier. */
144     public String JavaDoc getIdentifier() {
145         if(identifier == null || identifier == "") // NOI18N
146
createIdentifier();
147         
148         return identifier;
149     }
150
151     /** Setter for identifier. */
152     public void setIdentifier(String JavaDoc identifier) {
153         this.identifier = identifier;
154     }
155
156     /** Getter for modifiers. */
157     public int getModifiers() {
158         return modifiers;
159     }
160     
161     /** Setter for modifiers. */
162     public void setModifiers(int modifiers) {
163         this.modifiers = modifiers;
164     }
165     
166     /** Getter for generate field property.*/
167     public boolean isGenerateField() {
168         return generateField;
169     }
170     
171     /** Setter for generate field property. */
172     public void setGenerateField(boolean generateField) {
173         this.generateField = generateField;
174     }
175     
176     /** Getter for init format property. */
177     public String JavaDoc getInitFormat() {
178         return initFormat;
179     }
180     
181     /** Setter for init format property. */
182     public void setInitFormat(String JavaDoc initFormat) {
183         this.initFormat = initFormat;
184     }
185
186     /** Overrides superclass method. */
187     public PropertyPanel getPropertyPanel() {
188         return new JavaPropertyPanel();
189     }
190     
191     /** Overrides superclass method.
192      * @return true */

193     public boolean hasAdditionalCustomizer() {
194         return true;
195     }
196     
197     /** Overrides superclass method.
198      * @return <code>JavaReplacePanel</code> which offers to customize additional
199      * source values (in our case for creating bundle field) */

200     public JPanel JavaDoc getAdditionalCustomizer() {
201         return new JavaReplacePanel(this);
202     }
203
204     /** Overrides superclass method.
205      * Actuallay creates bundle field specified by user */

206     public void performAdditionalChanges() {
207         // Creates field.
208
createField();
209     }
210
211     /** Utility method. Creates identifier for this support instance. */
212     public void createIdentifier() {
213         String JavaDoc name;
214         
215         try {
216             name = resourceHolder.getResource().getName();
217         } catch(NullPointerException JavaDoc npe) {
218             identifier = ""; // NOI18N
219
return;
220         }
221
222         // first letter to lowercase
223
if(name.length() > 0) {
224             name = name.substring(0,1).toLowerCase() + name.substring(1);
225         } else {
226             name = name.toLowerCase();
227         }
228         
229         identifier = name;
230     }
231     
232     /** Helper method. Creates a new field in java source hierarchy.
233      * @param javaI18nSupport which holds info about going-to-be created field element
234      * @param sourceDataObject object to which source will be new field added,
235      * the object have to have <code>SourceCookie</code>
236      * @see org.openide.cookies.SourceCookie */

237     private void createField() {
238 // // Check if we have to generate field.
239
// if(!isGenerateField())
240
// return;
241
//
242
// ClassElement sourceClass = getSourceClassElement();
243
//
244
// if(sourceClass.getField(Identifier.create(getIdentifier())) != null)
245
// // Field with such identifer exsit already, do nothing.
246
// return;
247
//
248
// try {
249
// FieldElement newField = new FieldElement();
250
// newField.setName(Identifier.create(getIdentifier()));
251
// newField.setModifiers(getModifiers());
252
// newField.setType(Type.parse("java.util.ResourceBundle")); // NOI18N
253
// newField.setInitValue(getInitString());
254
//
255
// if(sourceClass != null)
256
// // Trying to add new field.
257
// sourceClass.addField(newField);
258
// } catch(SourceException se) {
259
// ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, se);
260
// } catch(NullPointerException npe) {
261
// ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, npe);
262
// }
263
}
264
265     /**
266      * Helper method. Gets the string, the piece of code which initializes field resource bundle in the source. E.g.:
267      * <p>
268      * java.util.ResourceBundle <identifier name> = <b>java.util.ResourceBundle.getBundle("<package name></b>")
269      * @return String -> piece of initilizing code. */

270     public String JavaDoc getInitString() {
271         String JavaDoc initJavaFormat = getInitFormat();
272
273         // Create map.
274
FileObject fo = resourceHolder.getResource().getPrimaryFile();
275         ClassPath cp = ClassPath.getClassPath( fo, ClassPath.SOURCE );
276
277         
278         Map JavaDoc map = new HashMap JavaDoc(3);
279
280         map.put("bundleNameSlashes", cp.getResourceName( fo, '/', false ) ); // NOI18N
281
map.put("bundleNameDots", cp.getResourceName( fo, '.', false ) ); // NOI18N
282
map.put("sourceFileName", sourceDataObject == null ? "" : sourceDataObject.getPrimaryFile().getName()); // NOI18N
283

284         return MapFormat.format(initJavaFormat, map);
285         
286     }
287     
288     /** Helper method. Finds main top-level class element for <code>sourceDataObject</code> which should be initialized. */
289 // private ClassElement getSourceClassElement() {
290
// SourceElement sourceElem = ((SourceCookie)sourceDataObject.getCookie(SourceCookie.class)).getSource();
291
// ClassElement sourceClass = sourceElem.getClass(Identifier.create(sourceDataObject.getName()));
292
//
293
// if(sourceClass != null)
294
// return sourceClass;
295
//
296
// ClassElement[] classes = sourceElem.getClasses();
297
//
298
// // find source class
299
// for(int i=0; i<classes.length; i++) {
300
// int modifs = classes[i].getModifiers();
301
// if(classes[i].isClass() && Modifier.isPublic(modifs)) {
302
// sourceClass = classes[i];
303
// break;
304
// }
305
// }
306
//
307
// return sourceClass;
308
// }
309

310     
311     /** Finder which search hard coded strings in java sources. */
312     public static class JavaI18nFinder implements I18nFinder {
313
314         /** State when finder is in normal java code. */
315         protected static final int STATE_JAVA = 0;
316         /** State when finder is at backslash in normal java code. */
317         protected static final int STATE_JAVA_A_SLASH = 1;
318         /** State when finder is in line comment. */
319         protected static final int STATE_LINECOMMENT = 2;
320         /** State when finder is in block comment. */
321         protected static final int STATE_BLOCKCOMMENT = 3;
322         /** State when finder is at star in block commnet. */
323         protected static final int STATE_BLOCKCOMMENT_A_STAR = 4;
324         /** State when finder is in string found in nornal java code. */
325         protected static final int STATE_STRING = 5;
326         /** State when finder is at backslash in string. */
327         protected static final int STATE_STRING_A_BSLASH = 6;
328         /** State when finder is in char in noraml java code. */
329         protected static final int STATE_CHAR = 7; // to avoid misinterpreting of '"' resp. '\"' char.
330

331         /** Document on which the search is performed. */
332         protected StyledDocument JavaDoc document;
333
334         /** Keeps current state. */
335         protected int state;
336         
337         /** Flag of search type, if it is searched for i18n-ized strings or non-i18n-ized ones. */
338         protected boolean i18nSearch;
339
340         /** Keeps position from last search iteration. */
341         protected Position JavaDoc lastPosition;
342
343         /** Helper variable for keeping the java string (means pure java code, no coments etc.). */
344         protected StringBuffer JavaDoc lastJavaString;
345
346         /** Helper variable. Buffer at which perform search. */
347         protected char[] buffer;
348         
349         /** Helper variable. Actual position of search in buffer. */
350         protected int position;
351         
352         /** Helper variable. Start of actual found hard coded string or -1. */
353         protected int currentStringStart;
354         
355         /** Helper variable. End of actual found hard coded string or -1. */
356         protected int currentStringEnd;
357         
358
359         /** Constructs finder. */
360         public JavaI18nFinder(StyledDocument JavaDoc document) {
361             this.document = document;
362
363             init();
364         }
365
366         /** Initializes finder. */
367         private void init() {
368             state = STATE_JAVA;
369             initJavaStringBuffer();
370
371             lastPosition = null;
372         }
373         
374         /** Resets finder. */
375         protected void reset() {
376             init();
377         }
378
379         /**
380          * Implements <code>I18nFinder</code> interface method.
381          * Finds all non-internationalized hard coded strings in source document. */

382         public HardCodedString[] findAllHardCodedStrings() {
383             reset();
384             i18nSearch = false;
385             
386             return findAllStrings();
387         }
388         
389         /**
390          * Implements <code>I18nFinder</code> inetrface method.
391          * Finds hard coded non-internationalized string in buffer.
392          * @return next <code>HardCodedString</code> or null if there is no more one.
393          */

394         public HardCodedString findNextHardCodedString() {
395             i18nSearch = false;
396             
397             return findNextString();
398         }
399         
400         /**
401          * Implements <code>I18nFinder</code> interface method.
402          * Finds all internationalized hard coded strings in source document.
403          * It's used in test tool. */

404         public HardCodedString[] findAllI18nStrings() {
405             reset();
406             i18nSearch = true;
407             
408             return findAllStrings();
409         }
410         
411         /**
412          * Implements <code>I18nFinder</code> inetrface method.
413          * Finds hard coded internationalized string in buffer. It's used in test tool.
414          * @return next <code>HardCodedString</code> or null if there is no more one.
415          */

416         public HardCodedString findNextI18nString() {
417             i18nSearch = true;
418             
419             return findNextString();
420         }
421         
422
423         /** Finds all strings according specified regular expression. */
424         protected HardCodedString[] findAllStrings() {
425             
426             ArrayList JavaDoc list = new ArrayList JavaDoc();
427
428             HardCodedString hardString;
429
430             for(;(hardString = findNextString())!= null;) {
431                 list.add(hardString);
432             }
433
434             if(list.isEmpty())
435                 return null;
436             else {
437                 HardCodedString[] hardStrings = new HardCodedString[list.size()];
438                 list.toArray(hardStrings);
439                 return hardStrings;
440             }
441         }
442         
443         /** Finds next string according specified regular expression. */
444         protected HardCodedString findNextString() {
445             // Reset buffer.
446
try {
447                 buffer = document.getText(0, document.getLength()).toCharArray();
448             } catch(BadLocationException JavaDoc ble) {
449                 if(Boolean.getBoolean("netbeans.debug.exception")) // NOI18N
450
ble.printStackTrace();
451                 
452                 return null;
453             }
454
455             // Initialize position.
456
if(lastPosition == null)
457                 position = 0;
458             else
459                 position = lastPosition.getOffset();
460
461             // Reset hard coded string offsets.
462
currentStringStart = -1;
463             currentStringEnd = -1;
464
465             // Now serious work.
466
while(position < buffer.length) {
467
468                 char ch = buffer[position];
469
470                 // Other chars than '\n' (new line).
471
if(ch != '\n') {
472                     HardCodedString foundHardString = handleCharacter(ch);
473                     
474                     if(foundHardString != null)
475                         return foundHardString;
476                     
477                 } else
478                     handleNewLineCharacter();
479
480                 position++;
481
482             } // End of while.
483

484             // Indicate end was reached and nothing found.
485
return null;
486         }
487
488         /** Handles state changes according next charcter. */
489         protected HardCodedString handleCharacter(char character) {
490             if(state == STATE_JAVA) {
491                 return handleStateJava(character);
492             } else if(state == STATE_JAVA_A_SLASH) {
493                 return handleStateJavaASlash(character);
494             } else if(state == STATE_CHAR) {
495                 return handleStateChar(character);
496             } else if(state == STATE_STRING_A_BSLASH) {
497                 return handleStateStringABSlash(character);
498             } else if(state == STATE_LINECOMMENT) {
499                 return handleStateLineComment(character);
500             } else if(state == STATE_BLOCKCOMMENT) {
501                 return handleStateBlockComment(character);
502             } else if(state == STATE_BLOCKCOMMENT_A_STAR) {
503                 return handleStateBlockCommentAStar(character);
504             } else if(state == STATE_STRING) {
505                 return handleStateString(character);
506             }
507             
508             return null;
509         }
510
511         /** Handles state when new line '\n' char occures. */
512         protected void handleNewLineCharacter() {
513             // New line char '\n' -> reset the state.
514
if(state == STATE_JAVA
515                 || state == STATE_JAVA_A_SLASH
516                 || state == STATE_CHAR
517                 || state == STATE_LINECOMMENT
518                 || state == STATE_STRING
519                 || state == STATE_STRING_A_BSLASH) {
520                     initJavaStringBuffer();
521                     currentStringStart = -1;
522                     currentStringEnd = -1;
523                     state = STATE_JAVA;
524             } else if(state == STATE_BLOCKCOMMENT
525                 || state == STATE_BLOCKCOMMENT_A_STAR) {
526                     state = STATE_BLOCKCOMMENT;
527             }
528         }
529         
530         
531         /** Handles state <code>STATE_JAVA</code>.
532          * @param character char to proceede
533          * @return <code>HardCodedString</code> or null if not found yet */

534         protected HardCodedString handleStateJava(char character) {
535             lastJavaString.append(character);
536             if(character == '/') {
537                 state = STATE_JAVA_A_SLASH;
538             } else if(character == '"') {
539                 state = STATE_STRING;
540                 if(currentStringStart == -1)
541                     // Found start of hard coded string.
542
currentStringStart = position;
543             } else if(character == '\'') {
544                 state = STATE_CHAR;
545             }
546             
547             return null;
548         }
549
550         /** Handles state <code>STATE_JAVA_A_SLASH</code>.
551          * @param character char to proceede
552          * @return <code>HardCodedString</code> or null if not found yet */

553         protected HardCodedString handleStateJavaASlash(char character) {
554             lastJavaString.append(character);
555             if(character == '/') {
556                 state = STATE_LINECOMMENT;
557             } else if(character == '*') {
558                 state = STATE_BLOCKCOMMENT;
559             }
560             
561             return null;
562         }
563
564         /** Handles state <code>STATE_CHAR</code>.
565          * @param character char to proceede
566          * @return <code>HardCodedString</code> or null if not found yet */

567         protected HardCodedString handleStateChar(char character) {
568             lastJavaString.append(character);
569
570             if(character == '\'') {
571                 state = STATE_JAVA;
572             }
573             
574             return null;
575         }
576
577         /** Handles state <code>STATE_STRING_A_BSLASH</code>.
578          * @param character char to proceede
579          * @return <code>HardCodedString</code> or null if not found yet */

580         protected HardCodedString handleStateStringABSlash(char character) {
581             state = STATE_STRING;
582             
583             return null;
584         }
585
586         /** Handles state <code>STATE_LINECOMMENT</code>.
587          * @param character char to proceede
588          * @return null */

589         protected HardCodedString handleStateLineComment(char character) {
590             return null;
591         }
592         
593         /** Handles state <code>STATE_BLOCKCOMMENT</code>.
594          * @param character char to proceede
595          * @return <code>HardCodedString</code> or null if not found yet */

596         protected HardCodedString handleStateBlockComment(char character) {
597             if(character == '*') {
598                 state = STATE_BLOCKCOMMENT_A_STAR;
599             }
600             
601             return null;
602         }
603
604         /** Handles state <code>STATE_BLOCKCOMMENT_A_STAR</code>.
605          * @param character char to proceede
606          * @return <code>HardCodedString</code> or null if not found yet */

607         protected HardCodedString handleStateBlockCommentAStar(char character) {
608             if(character == '/') {
609                 state = STATE_JAVA;
610                 initJavaStringBuffer();
611             } else if (character != '*') {
612                 state = STATE_BLOCKCOMMENT;
613             }
614             
615             return null;
616         }
617
618         /** Handles state <code>STATE_STRING</code>.
619          * @param character char to proceede
620          * @return <code>HardCodedString</code> or null if not found yet */

621         protected HardCodedString handleStateString(char character) {
622             if(character == '\\') {
623                 state = STATE_STRING_A_BSLASH;
624             } else if(character == '"') {
625                 state = STATE_JAVA;
626
627                 if((currentStringEnd == -1) && (currentStringStart != -1)) {
628                     // Found end of hard coded string.
629
currentStringEnd = position + 1;
630
631                     int foundStringLength = currentStringEnd - currentStringStart;
632
633                     try {
634                         // Get hard coded string.
635
Position JavaDoc hardStringStart = document.createPosition(currentStringStart);
636                         Position JavaDoc hardStringEnd = document.createPosition(currentStringEnd);
637
638                         String JavaDoc hardString = document.getText(hardStringStart.getOffset(), foundStringLength);
639
640                         // Retrieve offset of the end of line where was found hard coded string.
641
String JavaDoc restBuffer = new String JavaDoc(buffer, currentStringEnd, buffer.length-currentStringEnd);
642                         int endOfLine = restBuffer.indexOf('\n');
643                         if(endOfLine == -1)
644                             endOfLine = restBuffer.length();
645
646                         lastJavaString.append(document.getText(currentStringStart+1, hardString.length()));
647
648                         // Get the rest of line.
649
String JavaDoc restOfLine = document.getText(currentStringStart+1+hardString.length(), currentStringEnd+endOfLine-currentStringStart-hardString.length());
650
651                         // Replace rest of occurences of \" to cheat out regular expression for very minor case when the same string is after our at the same line.
652
lastJavaString.append(restOfLine.replace('\"', '_'));
653
654                         // If not matches regular expression -> is not internationalized.
655
if(isSearchedString(lastJavaString.toString(), hardString) ) {
656                             lastPosition = hardStringEnd;
657
658                             // Search was successful -> return.
659
return new HardCodedString(extractString(hardString), hardStringStart, hardStringEnd);
660                         }
661                     } catch(BadLocationException JavaDoc ble) {
662                         ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ble);
663                     } finally {
664                         currentStringStart = -1;
665                         currentStringEnd = -1;
666
667                         initJavaStringBuffer();
668                     }
669                 }
670             }
671             
672             return null;
673         }
674         
675         /** Resets <code>lastJavaString</code> variable.
676          * @see #lastJavaString*/

677         private void initJavaStringBuffer() {
678             lastJavaString = new StringBuffer JavaDoc();
679         }
680
681         /** Helper utility method. */
682         private String JavaDoc extractString(String JavaDoc sourceString) {
683             if(sourceString == null)
684                 return ""; // NOI18N
685

686             if ((sourceString.length() >= 2) &&
687             (sourceString.charAt(0) == '"') &&
688             (sourceString.charAt(sourceString.length() - 1) == '"'))
689                 sourceString = sourceString.substring(1, sourceString.length() - 1);
690             return sourceString;
691         }
692
693         /**
694          * Help method for decision if found hard coded string is searched string. It means
695          * if it is i18n-zed or non-internationalized (depending on <code>i18nSearch</code> flag.
696          * <p>
697          * The part of line
698          * (starts after previous found hard coded string) with current found hard code string is compared
699          * against regular expression which can user specify via i18n options. If the compared line matches
700          * that regular expression the hard coded string is considered as internationalized.
701          *
702          * @param partHardLine line of code which includes hard coded string and starts from beginning or
703          * the end of previous hard coded string.
704          * @param hardString found hard code string
705          * @return <code>true<code> if string is internationalized and <code>i18nSearch</code> flag is <code>true</code>
706          * or if if string is non-internationalized and <code>i18nSearch</code> flag is <code>false</code> */

707         protected boolean isSearchedString(String JavaDoc partHardLine, String JavaDoc hardString) {
708             String JavaDoc lineToMatch = UtilConvert.unicodesToChars(partHardLine);
709             
710             Exception JavaDoc ex = null;
711             try {
712                 String JavaDoc regexp = createRegularExpression(hardString);
713                 return Pattern.compile(regexp).matcher(lineToMatch).find()
714                        == i18nSearch;
715             } catch (ParseException ex1) {
716                 ex = ex1;
717             } catch (PatternSyntaxException JavaDoc ex2) {
718                 ex = ex2;
719             }
720
721             /*
722              * Handle the situation that some syntax error has been detected:
723              */

724             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
725
726             // Indicate error, but allow user what to do with the found hard coded string to be able go thru
727
// this problem.
728
// Note: All this shouldn't happen. The reason is 1) bad set reg exp format (in options) or
729
// 2) it's error in this code.
730
String JavaDoc msg = MessageFormat.format(
731                 Util.getString("MSG_RegExpCompileError"),
732                 new Object JavaDoc[] {hardString}
733             );
734             
735             Object JavaDoc answer = DialogDisplayer.getDefault().notify(
736                     new NotifyDescriptor.Confirmation(
737                             msg,
738                             NotifyDescriptor.YES_NO_OPTION,
739                             NotifyDescriptor.ERROR_MESSAGE));
740             return NotifyDescriptor.YES_OPTION.equals(answer);
741         }
742
743          /**
744           * Creates a regular expression matching the pattern specified in the
745           * module options.
746           * The pattern specified in the options contains a special token
747           * <code>{hardString}</code>. This token is replaced with a regular
748           * expression matching exactly the string passed as a parameter
749           * and a result of this substitution is returned.
750           *
751           * @param hardString hard-coded string whose regexp-equivalent is
752           * to be put in place of token
753           * <code>{hardString}</code>
754           * @return regular expression matching the pattern specified
755           * in the module options
756           */

757         private String JavaDoc createRegularExpression(String JavaDoc hardString)
758                 throws ParseException {
759             String JavaDoc regexpForm;
760             if (i18nSearch) {
761                 regexpForm = I18nUtil.getOptions().getI18nRegularExpression();
762             } else {
763                 regexpForm = I18nUtil.getOptions().getRegularExpression();
764             }
765
766             /*
767              * Translate the regexp form to the JDK's java.util.regex syntax
768              * and replace tokens "{key}" and "{hardString}" with the passed
769              * hard-coded string.
770              */

771             Map JavaDoc map = new HashMap JavaDoc(3);
772             map.put("key", hardString); //older form of regexp format //NOI18N
773
map.put("hardString", hardString); //NOI18N
774
return Translator.translateRegexp(regexpForm, map);
775         }
776
777     } // End of JavaI18nFinder nested class.
778

779     
780     /** Replacer for java sources used by enclosing class. */
781     public static class JavaI18nReplacer implements I18nReplacer {
782         
783         /** Constructor.*/
784         public JavaI18nReplacer() {
785         }
786         
787
788         /** Replaces found hard coded string in source.
789          * @param hcString found hard coded string to-be replaced
790          * @param rbString holds replacing values */

791         public void replace(final HardCodedString hcString, final I18nString i18nString) {
792             if(!(i18nString instanceof JavaI18nString))
793                 throw new IllegalArgumentException JavaDoc("I18N module: i18nString have to be an instance of JavaI18nString."); // NOI18N
794

795             final String JavaDoc newCode = i18nString.getReplaceString();
796
797             final StyledDocument JavaDoc document = i18nString.getSupport().getDocument();
798             
799             // Call runAtomic method to break guarded flag if it is necessary. (For non-guarded works as well).
800
NbDocument.runAtomic(
801             document,
802             new Runnable JavaDoc() {
803                 public void run() {
804                     try {
805                         if(hcString.getLength() > 0) {
806                             document.remove(hcString.getStartPosition().getOffset(), hcString.getLength());
807                         }
808                         if(newCode != null && newCode.length() > 0) {
809                             document.insertString(hcString.getEndPosition().getOffset(), newCode, null);
810                         }
811                     } catch(BadLocationException JavaDoc ble) {
812                         NotifyDescriptor.Message message = new NotifyDescriptor.Message(
813                             Util.getString("MSG_CouldNotReplace"), NotifyDescriptor.ERROR_MESSAGE);
814                         DialogDisplayer.getDefault().notify(message);
815                     }
816                 }
817             });
818         }
819     } // End of nested class JavaI18nReplacer.
820

821     
822     /** Panel for showing info about hard coded string. */
823     private static class JavaInfoPanel extends InfoPanel {
824         
825         /** Constructor. */
826         public JavaInfoPanel(HardCodedString hcString, StyledDocument JavaDoc document) {
827             super(hcString, document);
828         }
829         
830         /** Implements superclass abstract method. */
831         protected void setHardCodedString(HardCodedString hcString, StyledDocument JavaDoc document) {
832
833             getStringText().setText(hcString == null ? "" : hcString.getText()); // NOI18N
834

835             int pos;
836
837             String JavaDoc hardLine;
838             
839             if(hcString.getStartPosition() == null)
840                 hardLine = ""; // NOI18N
841
else {
842                 pos = hcString.getStartPosition().getOffset();
843
844                 try {
845                     Element JavaDoc paragraph = document.getParagraphElement(pos);
846                     hardLine = document.getText(paragraph.getStartOffset(), paragraph.getEndOffset()-paragraph.getStartOffset()).trim();
847                 } catch (BadLocationException JavaDoc ble) {
848                     hardLine = ""; // NOI18N
849
}
850             }
851
852             getFoundInText().setText(hardLine);
853             
854             remove(getComponentLabel());
855             remove(getComponentText());
856             remove(getPropertyLabel());
857             remove(getPropertyText());
858         }
859     } // End of JavaInfoPanel inner class.
860

861     
862     /** Factory for <code>JavaI18nSupport</code>. */
863     public static class Factory extends I18nSupport.Factory {
864         
865         /** Implements interface. */
866         public I18nSupport createI18nSupport(DataObject dataObject) {
867             return new JavaI18nSupport(dataObject);
868         }
869
870         /** Gets class of supported <code>DataObject</code>.
871          * @return <code>JavaDataObject</code> class or <code>null</code>
872          * if java module is not available */

873         public Class JavaDoc getDataObjectClass() {
874             // XXX Cleaner should be this code dependend on java module
875
// -> I18n API needed.
876
try {
877                 return Class.forName(
878                     "org.netbeans.modules.java.JavaDataObject", // NOI18N
879
false,
880                     (ClassLoader JavaDoc)Lookup.getDefault().lookup(ClassLoader JavaDoc.class));
881             } catch(ClassNotFoundException JavaDoc cnfe) {
882                 return null;
883             }
884         }
885     } // End of class Factory.
886
}
887
Popular Tags