KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > web > taglib > TLDEditorSupport


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 package org.netbeans.modules.web.taglib;
21
22 import javax.swing.text.BadLocationException JavaDoc;
23 import org.openide.ErrorManager;
24
25 import org.openide.text.DataEditorSupport;
26 import org.openide.text.NbDocument;
27
28 import org.openide.filesystems.FileObject;
29 import org.openide.filesystems.FileLock;
30 import org.openide.cookies.*;
31 import org.openide.nodes.Node.Cookie;
32 import org.openide.DialogDescriptor;
33 import org.openide.DialogDisplayer;
34 import org.openide.NotifyDescriptor;
35 import org.openide.util.NbBundle;
36
37 import org.netbeans.modules.xml.api.EncodingUtil;
38 /**
39  * Text editor support that handles I/O encoding
40  * @author mkuchtiak
41  */

42 public class TLDEditorSupport extends DataEditorSupport
43 implements OpenCookie, EditCookie, EditorCookie.Observable, PrintCookie, CloseCookie {
44     
45     /** SaveCookie for this support instance. The cookie is adding/removing
46      * data object's cookie set depending on if modification flag was set/unset. */

47     private final SaveCookie saveCookie = new SaveCookie() {
48         /** Implements <code>SaveCookie</code> interface. */
49         public void save() throws java.io.IOException JavaDoc {
50             saveDocument();
51         }
52     };
53     /*
54      * Save document using encoding declared in XML prolog if possible otherwise
55      * at UTF-8 (in such case it updates the prolog).
56      */

57     public void saveDocument () throws java.io.IOException JavaDoc {
58         final javax.swing.text.StyledDocument JavaDoc doc = getDocument();
59         String JavaDoc defaultEncoding = "UTF-8"; // NOI18N
60
// dependency on xml/core
61
String JavaDoc enc = EncodingUtil.detectEncoding(doc);
62         boolean changeEncodingToDefault = false;
63         if (enc == null) enc = defaultEncoding;
64         
65         //test encoding
66
if (!isSupportedEncoding(enc)){
67             NotifyDescriptor nd = new NotifyDescriptor.Confirmation(
68             NbBundle.getMessage (TLDEditorSupport.class, "MSG_BadEncodingDuringSave", //NOI18N
69
new Object JavaDoc [] { getDataObject().getPrimaryFile().getNameExt(),
70                                 enc,
71                                 defaultEncoding} ),
72                         NotifyDescriptor.YES_NO_OPTION,
73                         NotifyDescriptor.WARNING_MESSAGE);
74             nd.setValue(NotifyDescriptor.NO_OPTION);
75             DialogDisplayer.getDefault().notify(nd);
76             if(nd.getValue() != NotifyDescriptor.YES_OPTION) return;
77             changeEncodingToDefault = true;
78         }
79         
80         if (!changeEncodingToDefault){
81             // is it possible to save the document in the encoding?
82
try {
83                 java.nio.charset.CharsetEncoder JavaDoc coder = java.nio.charset.Charset.forName(enc).newEncoder();
84                 if (!coder.canEncode(doc.getText(0, doc.getLength()))){
85                     NotifyDescriptor nd = new NotifyDescriptor.Confirmation(
86                     NbBundle.getMessage (TLDEditorSupport.class, "MSG_BadCharConversion", //NOI18N
87
new Object JavaDoc [] { getDataObject().getPrimaryFile().getNameExt(),
88                                     enc}),
89                             NotifyDescriptor.YES_NO_OPTION,
90                             NotifyDescriptor.WARNING_MESSAGE);
91                     nd.setValue(NotifyDescriptor.NO_OPTION);
92                     DialogDisplayer.getDefault().notify(nd);
93                     if(nd.getValue() != NotifyDescriptor.YES_OPTION) return;
94                 }
95             }
96             catch (javax.swing.text.BadLocationException JavaDoc e){
97                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
98             }
99             super.saveDocument();
100             //moved from Env.save()
101
getDataObject().setModified (false);
102         }
103         else {
104                 // update prolog to new valid encoding
105

106             try {
107                 final int MAX_PROLOG = 1000;
108                 int maxPrologLen = Math.min(MAX_PROLOG, doc.getLength());
109                 final char prolog[] = doc.getText(0, maxPrologLen).toCharArray();
110                 int prologLen = 0; // actual prolog length
111

112                 //parse prolog and get prolog end
113
if (prolog[0] == '<' && prolog[1] == '?' && prolog[2] == 'x') {
114
115                     // look for delimitting ?>
116
for (int i = 3; i<maxPrologLen; i++) {
117                         if (prolog[i] == '?' && prolog[i+1] == '>') {
118                             prologLen = i + 1;
119                             break;
120                         }
121                     }
122                 }
123
124                 final int passPrologLen = prologLen;
125
126                 Runnable JavaDoc edit = new Runnable JavaDoc() {
127                      public void run() {
128                          try {
129
130                             doc.remove(0, passPrologLen + 1); // +1 it removes exclusive
131
doc.insertString(0, "<?xml version='1.0' encoding='UTF-8' ?> \n<!-- was: " + new String JavaDoc(prolog, 0, passPrologLen + 1) + " -->", null); // NOI18N
132

133                          } catch (BadLocationException JavaDoc e) {
134                              if (System.getProperty("netbeans.debug.exceptions") != null) // NOI18N
135
e.printStackTrace();
136                          }
137                      }
138                 };
139
140                 NbDocument.runAtomic(doc, edit);
141
142                 super.saveDocument();
143                 //moved from Env.save()
144
getDataObject().setModified (false);
145             }
146             catch (javax.swing.text.BadLocationException JavaDoc e){
147                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
148             }
149         }
150     }
151     
152     private boolean isSupportedEncoding(String JavaDoc encoding){
153         boolean supported;
154         try{
155             supported = java.nio.charset.Charset.isSupported(encoding);
156         }
157         catch (java.nio.charset.IllegalCharsetNameException JavaDoc e){
158             supported = false;
159         }
160         
161         return supported;
162     }
163     
164     /** Creates a new instance of TLDEditorSupport */
165     public TLDEditorSupport(TLDDataObject dobj) {
166         super(dobj,new XmlEnv(dobj));
167         setMIMEType("text/xml");
168     }
169     
170     /**
171      * Overrides superclass method. Adds adding of save cookie if the document has been marked modified.
172      * @return true if the environment accepted being marked as modified
173      * or false if it has refused and the document should remain unmodified
174      */

175     protected boolean notifyModified () {
176         if (!super.notifyModified())
177             return false;
178
179         addSaveCookie();
180
181         return true;
182     }
183
184     /** Overrides superclass method. Adds removing of save cookie. */
185     protected void notifyUnmodified () {
186         super.notifyUnmodified();
187
188         removeSaveCookie();
189     }
190
191     /** Helper method. Adds save cookie to the data object. */
192     private void addSaveCookie() {
193         TLDDataObject obj = (TLDDataObject)getDataObject();
194
195         // Adds save cookie to the data object.
196
if(obj.getCookie(SaveCookie.class) == null) {
197             obj.getCookieSet0().add(saveCookie);
198             obj.setModified(true);
199         }
200     }
201
202     /** Helper method. Removes save cookie from the data object. */
203     private void removeSaveCookie() {
204         TLDDataObject obj = (TLDDataObject)getDataObject();
205         
206         // Remove save cookie from the data object.
207
Cookie cookie = obj.getCookie(SaveCookie.class);
208
209         if(cookie != null && cookie.equals(saveCookie)) {
210             obj.getCookieSet0().remove(saveCookie);
211             obj.setModified(false);
212         }
213     }
214     
215
216     /** A description of the binding between the editor support and the object.
217      * Note this may be serialized as part of the window system and so
218      * should be static, and use the transient modifier where needed.
219      */

220     private static class XmlEnv extends DataEditorSupport.Env {
221
222         private static final long serialVersionUID = -800036748848958489L;
223         
224         //private static final long serialVersionUID = ...L;
225

226         /** Create a new environment based on the data object.
227          * @param obj the data object to edit
228          */

229         public XmlEnv (TLDDataObject obj) {
230             super (obj);
231         }
232
233         /** Get the file to edit.
234          * @return the primary file normally
235          */

236         protected FileObject getFile () {
237             return getDataObject ().getPrimaryFile ();
238         }
239
240         /** Lock the file to edit.
241          * Should be taken from the file entry if possible, helpful during
242          * e.g. deletion of the file.
243          * @return a lock on the primary file normally
244          * @throws IOException if the lock could not be taken
245          */

246         protected FileLock takeLock () throws java.io.IOException JavaDoc {
247             return ((TLDDataObject) getDataObject ()).getPrimaryEntry ().takeLock ();
248         }
249
250         /** Find the editor support this environment represents.
251          * Note that we have to look it up, as keeping a direct
252          * reference would not permit this environment to be serialized.
253          * @return the editor support
254          */

255         public org.openide.windows.CloneableOpenSupport findCloneableOpenSupport () {
256             return (TLDEditorSupport) getDataObject ().getCookie (TLDEditorSupport.class);
257         }
258     }
259 }
260
Popular Tags