KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > i18n > form > FormI18nMnemonicEditor


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.form;
22
23
24 import java.awt.Component JavaDoc;
25 import java.beans.PropertyEditorSupport JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.text.MessageFormat JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.ResourceBundle JavaDoc;
31 import org.netbeans.api.java.classpath.ClassPath;
32
33 import org.netbeans.modules.form.FormModel;
34 import org.netbeans.modules.form.FormAwareEditor;
35 import org.netbeans.modules.form.FormDataObject;
36 import org.netbeans.modules.form.NamedPropertyEditor;
37 import org.netbeans.modules.form.FormEditorSupport;
38 import org.netbeans.modules.i18n.I18nPanel;
39 import org.netbeans.modules.i18n.I18nString;
40 import org.netbeans.modules.i18n.I18nUtil;
41 import org.netbeans.modules.i18n.java.JavaI18nSupport;
42
43 import org.openide.explorer.propertysheet.editors.EnhancedCustomPropertyEditor;
44 import org.openide.explorer.propertysheet.editors.XMLPropertyEditor;
45 import org.openide.filesystems.FileObject;
46 import org.openide.filesystems.Repository;
47 import org.openide.loaders.DataObject;
48 import org.openide.NotifyDescriptor;
49
50 import org.openide.ErrorManager;
51 import org.openide.util.HelpCtx;
52 import org.openide.util.MapFormat;
53 import org.openide.util.NbBundle;
54
55 import org.w3c.dom.Element JavaDoc;
56 import org.w3c.dom.Document JavaDoc;
57 import org.w3c.dom.DOMException JavaDoc;
58 import org.w3c.dom.NamedNodeMap JavaDoc;
59 import org.w3c.dom.Node JavaDoc;
60 import org.w3c.dom.NodeList JavaDoc;
61 import org.netbeans.api.project.Project;
62
63
64 /**
65  * Property editor for editing <code>FormI18nMnemonic</code> value in form editor.
66  * This editor is registered during installing i18n module
67  * as editor for form properties of type <code>String</code>.
68  * It provides also a capability to store such object in XML form.
69  * <B>Note: </B>This class should be named FormI18nMnemonicEditor, but due to forward compatibility
70  * remains that name.
71  *
72  * @author Petr Jiricka
73  * @see FormI18nMnemonic
74  * @see org.netbeans.modules.form.RADComponent
75  * @see org.netbeans.modules.form.RADProperty
76  */

77 public class FormI18nMnemonicEditor extends PropertyEditorSupport JavaDoc implements FormAwareEditor, NamedPropertyEditor, XMLPropertyEditor {
78
79     /** Value of <code>ResourceBundleString</code> this editor is currently editing. */
80     private FormI18nMnemonic formI18nMnemonic;
81     
82     /** <code>DataObject</code> which have <code>SourceCookie</code>, and which document contains
83      * going-to-be-internatioanlized string.
84      */

85     private FormDataObject sourceDataObject;
86
87     private final ResourceBundle JavaDoc bundle;
88     
89     /** Name of resource string XML element. */
90     public static final String JavaDoc XML_RESOURCESTRING = "ResourceString"; // NOI18N
91
/** Name of argument XML element (child element of resource string element). */
92     public static final String JavaDoc XML_ARGUMENT = "Argument"; // NOI18N
93
/** Name of attribute bundle of resource string XML element. */
94     public static final String JavaDoc ATTR_BUNDLE = "bundle"; // NOI18N
95
/** Name of attribute key of resource string XML element. */
96     public static final String JavaDoc ATTR_KEY = "key"; // NOI18N
97
/** Name of attribute identifier of resource string XML element. */
98     public static final String JavaDoc ATTR_IDENTIFIER = "identifier"; // NOI18N
99
/** Name of attribute replace format XML element. */
100     public static final String JavaDoc ATTR_REPLACE_FORMAT = "replaceFormat"; // NOI18N
101
/** Name of attribute index of argument XML element. */
102     public static final String JavaDoc ATTR_INDEX = "index"; // NOI18N
103
/** Name of attribute java code of argument XML element. */
104     public static final String JavaDoc ATTR_JAVACODE = "javacode"; // NOI18N
105

106     /** Maximal index of arguments in one argument XML element. */
107     private static final int MAX_INDEX = 1000;
108
109     /** Constructor. Creates new <code>ResourceBundleStringFormEditor</code>. */
110     public FormI18nMnemonicEditor() {
111         bundle = NbBundle.getBundle(FormI18nMnemonicEditor.class);
112     }
113
114     private Project getProject() {
115       return org.netbeans.modules.i18n.Util.getProjectFor(sourceDataObject);
116     }
117
118     /** Overrides superclass method.
119      * @return null as we don't support this feature */

120     public String JavaDoc[] getTags() {
121         return null;
122     }
123
124     /** Sets as text. Overrides superclass method to be dummy -> don't throw
125      * <code>IllegalArgumentException</code> . */

126     public void setAsText(String JavaDoc text) {}
127         
128     
129     /** Overrides superclass method.
130      * @return text for the current value */

131     public String JavaDoc getAsText() {
132         FormI18nMnemonic formI18nMnemonic = (FormI18nMnemonic)getValue();
133         DataObject dataObject = formI18nMnemonic.getSupport().getResourceHolder().getResource();
134         
135         if (dataObject == null || formI18nMnemonic.getKey() == null) {
136             return bundle.getString("TXT_InvalidValue");
137         } else {
138             String JavaDoc resourceName = org.netbeans.modules.i18n.Util.
139                 getResourceName(formI18nMnemonic.getSupport().getSourceDataObject().getPrimaryFile(),
140                                 dataObject.getPrimaryFile(),
141                                 '/', false);// NOI18N
142
return MessageFormat.format(
143                 bundle.getString("TXT_Key"),
144                 new Object JavaDoc[] {
145                     formI18nMnemonic.getKey(),
146                     resourceName ,
147                 }
148             );
149         }
150     }
151
152     /** Overrides superclass method. Gets string, piece of code which will replace the hardcoded
153      * non-internationalized string in the source. The default form is:
154      * <p>
155      * <b><identifier name>.getString("<key name>")</b>
156      * or if arguments for the ResoureBundleStrin are set the form:
157      * <p>
158      * <b>java.text.MessageFormat.format(<identifier name>getString("<key name>"), new Object[] {<code set in Parameters and Comments panel>})</b>
159      */

160     public String JavaDoc getJavaInitializationString() {
161         return ((FormI18nMnemonic)getValue()).getReplaceString();
162     }
163     
164     /** Overrides superclass method.
165      * @return <code>ResourceBundlePanel</code> fed with <code>FormI18nMnemonic</code> value. */

166     public Component JavaDoc getCustomEditor() {
167         return new CustomEditor(new FormI18nMnemonic((FormI18nMnemonic)getValue()), getProject(), sourceDataObject.getPrimaryFile());
168     }
169     
170     /** Overrides superclass method.
171      * @return true since we support this feature */

172     public boolean supportsCustomEditor() {
173         return true;
174     }
175
176     /** Overrides superclass method.
177      * @return <code>formI18nMnemonic</code> */

178     public Object JavaDoc getValue() {
179         if(formI18nMnemonic == null) {
180             formI18nMnemonic = createFormI18nMnemonic();
181
182             if(I18nUtil.getOptions().getLastResource2() != null)
183                 formI18nMnemonic.getSupport().getResourceHolder().setResource(I18nUtil.getOptions().getLastResource2());
184         }
185         
186         return formI18nMnemonic;
187     }
188
189     /** Overrides superclass method.
190      * @param value sets the new value for this editor */

191     public void setValue(Object JavaDoc object) {
192         if(object instanceof FormI18nMnemonic)
193             formI18nMnemonic = (FormI18nMnemonic)object;
194         else {
195             formI18nMnemonic = createFormI18nMnemonic();
196         
197             if(I18nUtil.getOptions().getLastResource2() != null)
198                 formI18nMnemonic.getSupport().getResourceHolder().setResource(I18nUtil.getOptions().getLastResource2());
199         }
200     }
201
202     /** Creates <code>FormI18nMnemonic</code> instance. Helper method. */
203     private FormI18nMnemonic createFormI18nMnemonic() {
204         // Note: Only here we can have support without possible document loading.
205
return new FormI18nMnemonic(new FormI18nSupport.Factory().createI18nSupport(sourceDataObject));
206     }
207     
208     /**
209      * Implements <code>FormAwareEditor</code> method.
210      * If a property editor implements the <code>FormAwareEditor</code>
211      * interface, this method is called immediately after the PropertyEditor
212      * instance is created or the custom editor is obtained from getCustomEditor().
213      * @param model the <code>FormModel</code> representing meta-data of current form */

214     public void setFormModel(FormModel model) {
215         sourceDataObject = FormEditorSupport.getFormDataObject(model);
216     }
217
218     /**
219      * Implements <code>NamePropertyEditor</code> interface method.
220      * @return Display name of the property editor
221      */

222     public String JavaDoc getDisplayName () {
223         return bundle.getString("PROP_MenmonicEditor_name");
224     }
225
226
227     /**
228      * Implements <code>XMLPropertyEditor</code> interface method.
229      * Called to load property value from specified XML subtree. If succesfully loaded,
230      * the value should be available via the getValue method.
231      * An IOException should be thrown when the value cannot be restored from the specified XML element
232      * @param element the XML DOM element representing a subtree of XML from which the value should be loaded
233      * @exception IOException thrown when the value cannot be restored from the specified XML element
234      * @see org.w3c.dom.Node
235      */

236     public void readFromXML(Node JavaDoc domNode) throws IOException JavaDoc {
237         if(!XML_RESOURCESTRING.equals (domNode.getNodeName ())) {
238             throw new IOException JavaDoc ();
239         }
240         
241         FormI18nMnemonic formI18nMnemonic = createFormI18nMnemonic();
242
243         NamedNodeMap JavaDoc namedNodes = domNode.getAttributes ();
244         
245         try {
246             Node JavaDoc node;
247             // Retrieve bundle name.
248
node = namedNodes.getNamedItem(ATTR_BUNDLE);
249             String JavaDoc bundleName = (node == null) ? null : node.getNodeValue();
250
251             // Retrieve key name.
252
node = namedNodes.getNamedItem(ATTR_KEY);
253             String JavaDoc key = (node == null) ? null : node.getNodeValue();
254
255             // Set the resource bundle property.
256
if(bundleName != null) {
257                 FileObject sourceFo = sourceDataObject.getPrimaryFile();
258                 if ( sourceFo != null ) {
259                     FileObject fileObject = org.netbeans.modules.i18n.Util.
260                         getResource(sourceFo, bundleName);
261
262                     if(fileObject != null) {
263                         try {
264                             DataObject dataObject = DataObject.find(fileObject);
265                             if(dataObject.getClass().equals(formI18nMnemonic.getSupport().getResourceHolder().getResourceClasses()[0])) // PENDING
266
formI18nMnemonic.getSupport().getResourceHolder().setResource(dataObject);
267                         }
268                         catch (IOException JavaDoc e) {
269                         }
270                     }
271                 }
272                  
273             }
274
275             // Set the key property.
276
if(key != null && key.length() > 0) {
277                 formI18nMnemonic.setKey(key);
278                 
279                 // Set value and comment.
280
formI18nMnemonic.setValue(formI18nMnemonic.getSupport().getResourceHolder().getValueForKey(key));
281                 formI18nMnemonic.setComment(formI18nMnemonic.getSupport().getResourceHolder().getCommentForKey(key));
282             }
283
284             // Try to get identifier value.
285
((JavaI18nSupport)formI18nMnemonic.getSupport()).createIdentifier();
286             
287             node = namedNodes.getNamedItem(ATTR_IDENTIFIER);
288             if(node != null) {
289                 String JavaDoc identifier = (node == null) ? null : node.getNodeValue();
290                 
291                 if(identifier != null)
292                     ((JavaI18nSupport)formI18nMnemonic.getSupport()).setIdentifier(identifier);
293             }
294             
295             // Try to get init format string value.
296
node = namedNodes.getNamedItem(ATTR_REPLACE_FORMAT);
297             if(node != null) {
298                 String JavaDoc replaceFormat = node.getNodeValue();
299                 
300                 if(replaceFormat != null && replaceFormat.length() > 0) {
301                     
302                     // Note: This part of code is only due to use in some development builds of MessageFormat
303
// instead of MapFormat. If somebidy used those builds the replace code is in MessageFormat
304
// so we will convert it to MapFormat.
305
// This could be later extracted.
306
// Note if the replace form at was in the MessageFormat convert to MapFormat
307
// Don't throw away.
308
Map JavaDoc map = new HashMap JavaDoc(6);
309                     map.put("0", "{identifier}"); // NOI18N
310
map.put("1", "{key}"); // NOI18N
311
map.put("2", "{bundleNameSlashes}"); // NOI18N
312
map.put("3", "{bundleNameDots}"); // NOI18N
313
map.put("4", "{sourceFileName}"); // NOI18N
314
map.put("fileName", "{sourceFileName}"); // NOI18N
315

316                     String JavaDoc newReplaceFormat = MapFormat.format(replaceFormat, map);
317                     
318                     formI18nMnemonic.setReplaceFormat(newReplaceFormat);
319                 }
320             } else {
321                 // Read was not succesful (old form or error) -> set old form replace format.
322
formI18nMnemonic.setReplaceFormat((String JavaDoc)I18nUtil.getDefaultReplaceFormat(false));
323             }
324         } catch(NullPointerException JavaDoc npe) {
325             throw new IOException JavaDoc ();
326         }
327
328         // Retrieve the arguments.
329
if(domNode instanceof Element JavaDoc) {
330             Element JavaDoc domElement = (Element JavaDoc)domNode;
331             NodeList JavaDoc argNodeList = domElement.getElementsByTagName(XML_ARGUMENT);
332
333             // Find out the highest index.
334
int highest = -1;
335             for(int i = 0; i < argNodeList.getLength(); i++) {
336                 NamedNodeMap JavaDoc attributes = argNodeList.item(i).getAttributes();
337                 
338                 Node JavaDoc indexNode = attributes.getNamedItem (ATTR_INDEX);
339                 String JavaDoc indexString = (indexNode == null) ? null : indexNode.getNodeValue ();
340
341                 if(indexString != null) {
342                     try {
343                         int index = Integer.parseInt(indexString);
344                         if (index > highest && index < MAX_INDEX)
345                             highest = index;
346                     } catch (Exception JavaDoc e) {}
347                 }
348             }
349
350             // Construct the array.
351
String JavaDoc[] parameters = new String JavaDoc[highest + 1];
352
353             // Fill the array.
354
for (int i = 0; i < argNodeList.getLength(); i++) {
355                 NamedNodeMap JavaDoc attr = argNodeList.item(i).getAttributes ();
356                 
357                 Node JavaDoc indexNode = attr.getNamedItem (ATTR_INDEX);
358                 String JavaDoc indexString = (indexNode == null) ? null : indexNode.getNodeValue ();
359                 if (indexString != null) {
360                     try {
361                         int index = Integer.parseInt(indexString);
362                         if (index < MAX_INDEX) {
363                             Node JavaDoc javaCodeNode = attr.getNamedItem (ATTR_JAVACODE);
364                             String JavaDoc javaCode = (javaCodeNode == null) ? null : javaCodeNode.getNodeValue ();
365                             parameters[index] = javaCode;
366                         }
367                     } catch (Exception JavaDoc e) {}
368                 }
369             }
370
371             // Fill all the values in case some are missing - make it really foolproof.
372
for (int i = 0; i < parameters.length; i++)
373                 if (parameters[i] == null)
374                     parameters[i] = ""; // NOI18N
375

376             // Set the parameters.
377
formI18nMnemonic.setArguments(parameters);
378         }
379
380         // Set the value for this editor.
381
setValue(formI18nMnemonic);
382     }
383
384     /**
385      * Implements <code>XMLPropertyEditor</code> interface method.
386      * Called to store current property value into XML subtree. The property value should be set using the
387      * setValue method prior to calling this method.
388      * @param doc The XML document to store the XML in - should be used for creating nodes only
389      * @return the XML DOM element representing a subtree of XML from which the value should be loaded
390      */

391     public Node JavaDoc storeToXML(Document JavaDoc doc) {
392         Element JavaDoc element = doc.createElement (XML_RESOURCESTRING);
393
394         String JavaDoc bundleName;
395         if (formI18nMnemonic.getSupport().getResourceHolder().getResource() == null) {
396             bundleName = "";
397         } else {
398             bundleName = org.netbeans.modules.i18n.Util.
399                 getResourceName(formI18nMnemonic.getSupport().getSourceDataObject().getPrimaryFile(),
400                                 formI18nMnemonic.getSupport().getResourceHolder().getResource().getPrimaryFile(),'/', true);
401             if (bundleName == null) bundleName = "";
402         }
403
404             
405         // Set bundle and key property.
406
element.setAttribute(ATTR_BUNDLE, bundleName);
407         element.setAttribute(ATTR_KEY, (formI18nMnemonic.getKey() == null) ? "" : formI18nMnemonic.getKey()); // NOI18N
408
// Don't save identifier, replace the identifier argument with actual value in format.
409
JavaI18nSupport support = (JavaI18nSupport)formI18nMnemonic.getSupport();
410         if(support.getIdentifier() == null)
411             support.createIdentifier();
412         Map JavaDoc map = new HashMap JavaDoc(1);
413         map.put("identifier", support.getIdentifier()); // NOI18N
414
element.setAttribute(ATTR_REPLACE_FORMAT, formI18nMnemonic.getReplaceFormat() == null ? "" : MapFormat.format(formI18nMnemonic.getReplaceFormat(), map) ); // NOI18N
415

416         // Append subelements corresponding to parameters.
417
String JavaDoc[] arguments = formI18nMnemonic.getArguments();
418         for (int i = 0; i < arguments.length; i++) {
419             Element JavaDoc childElement = doc.createElement (XML_ARGUMENT);
420             childElement.setAttribute (ATTR_INDEX, "" + i); // NOI18N
421
childElement.setAttribute (ATTR_JAVACODE, arguments[i]);
422             try {
423                 element.appendChild(childElement);
424             } catch (DOMException JavaDoc de) {}
425         }
426
427         return element;
428     }
429
430     /** Custom editor for this property editor. */
431     private static class CustomEditor extends I18nPanel implements EnhancedCustomPropertyEditor {
432
433         private final ResourceBundle JavaDoc bundle;
434         
435         /** Constructor. */
436         public CustomEditor(I18nString i18nString, Project project, FileObject file) {
437             super(i18nString.getSupport().getPropertyPanel(), false, project, file);
438             setI18nString(i18nString);
439             bundle = NbBundle.getBundle(FormI18nMnemonicEditor.class);
440             HelpCtx.setHelpIDString(this, I18nUtil.HELP_ID_FORMED);
441         }
442
443         /** Implements <code>EnhancedCustomPropertyEditor</code> interface. */
444         public Object JavaDoc getPropertyValue() throws IllegalStateException JavaDoc {
445             I18nString i18nString = getI18nString();
446
447             if(i18nString == null
448                 || !(i18nString instanceof FormI18nMnemonic)
449                 || i18nString.getSupport().getResourceHolder().getResource() == null
450                 || i18nString.getKey() == null) {
451
452                 // Notify user that invalid value set.
453
IllegalStateException JavaDoc ise = new IllegalStateException JavaDoc();
454                 String JavaDoc message = bundle.getString("MSG_InvalidValue");
455                 ErrorManager.getDefault().annotate(
456                      ise, ErrorManager.WARNING, message,
457                      message, null, null);
458                 throw ise;
459             }
460
461             // Try to add new key into resource bundle first.
462
i18nString.getSupport().getResourceHolder().addProperty(
463                 i18nString.getKey(),
464                 i18nString.getValue(),
465                 i18nString.getComment(),
466                 false //#19137 do not destroy existing locale values
467
);
468
469             return i18nString;
470         }
471
472     }
473
474     
475 }
476
Popular Tags