KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > text > SaveDocumentTest


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.openide.text;
22
23
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import javax.swing.text.BadLocationException JavaDoc;
27 import javax.swing.text.Position JavaDoc;
28 import javax.swing.text.StyledDocument JavaDoc;
29
30 import junit.textui.TestRunner;
31
32 import org.netbeans.junit.NbTestCase;
33 import org.netbeans.junit.NbTestSuite;
34 import org.openide.actions.*;
35 import org.openide.cookies.CloseCookie;
36 import org.openide.cookies.EditCookie;
37
38 import org.openide.cookies.EditorCookie;
39 import org.openide.cookies.OpenCookie;
40 import org.openide.cookies.PrintCookie;
41 import org.openide.cookies.SaveCookie;
42 import org.openide.filesystems.FileLock;
43 import org.openide.filesystems.FileObject;
44 import org.openide.filesystems.FileStateInvalidException;
45 import org.openide.filesystems.Repository;
46 import org.openide.loaders.DataNode;
47 import org.openide.loaders.DataObject;
48 import org.openide.loaders.DataObjectExistsException;
49 import org.openide.loaders.ExtensionList;
50 import org.openide.loaders.MultiDataObject;
51 import org.openide.loaders.MultiFileLoader;
52 import org.openide.loaders.UniFileLoader;
53 import org.openide.nodes.Children;
54 import org.openide.nodes.CookieSet;
55 import org.openide.nodes.Node;
56 import org.openide.text.CloneableEditorSupport;
57 import org.openide.util.HelpCtx;
58 import org.openide.util.NbBundle;
59 import org.openide.util.actions.SystemAction;
60 import org.openide.windows.CloneableOpenSupport;
61
62
63 /**
64  * How to run from IDE:
65  * 1. Mount jar: junit.jar
66  * 2. Mount dir: openide/src
67  * 3. Mount dir: openide/test/regr/src
68  * 4. Run class UnstableTest from dir openide/test/regr/src in internal execution
69  * (inside IDE VM - set execution type in Properties window)
70  * It will open new window in Editor. When deadlock is there IDE hangs.
71  * How to run from command line:
72  * In directory: <NetBeans>/openide/test/
73  * Command: ant -Dxtest.testtypes=regression -Dxtest.attribs=stable
74  *
75  * @author Peter Zavadsky
76  */

77 public class SaveDocumentTest extends NbTestCase {
78
79     /** Creates new TextTest */
80     public SaveDocumentTest(String JavaDoc s) {
81         super(s);
82     }
83     
84     protected void setUp() throws Exception JavaDoc {
85         TXTDataLoader loader = (TXTDataLoader)TXTDataLoader.getLoader (TXTDataLoader.class);
86         org.openide.loaders.AddLoaderManuallyHid.addRemoveLoader (loader, true);
87     }
88     
89     protected void tearDown() throws Exception JavaDoc {
90         TXTDataLoader loader = (TXTDataLoader)TXTDataLoader.getLoader (TXTDataLoader.class);
91         org.openide.loaders.AddLoaderManuallyHid.addRemoveLoader (loader, false);
92     }
93
94     
95     /** Tests the #17714. */
96     public void testSaveDocument() throws Exception JavaDoc {
97         System.err.println("Test Save Document");
98         
99         FileObject fo = Repository.getDefault().getDefaultFileSystem()
100             .getRoot().createData("test", "txt");
101
102         DataObject data = DataObject.find(fo);
103         
104         EditorCookie ec = (EditorCookie)data.getCookie(EditorCookie.class);
105         
106         if(!(ec instanceof CloneableEditorSupport)) {
107             throw new IllegalStateException JavaDoc("Bad editor cookie type");
108         }
109
110         CloneableEditorSupport ces = (CloneableEditorSupport)ec;
111         System.err.println("CloneableEditorSupport="+ces);
112
113         if(ces.isModified()) {
114             throw new IllegalStateException JavaDoc("Cloneable editor support should be marked as unmodified!");
115         }
116         System.err.println("Saving unmodified document");
117         ces.saveDocument();
118         
119         final StyledDocument JavaDoc doc = ces.openDocument();
120         
121         NbDocument.runAtomicAsUser(doc, new Runnable JavaDoc() {
122             public void run() {
123                 try {
124                     doc.insertString(0, "Inserted string", null);
125                 } catch(BadLocationException JavaDoc ble) {
126                     ble.printStackTrace();
127                 }
128             }
129         });
130
131         System.err.println("doc="+ces.getDocument());
132         
133         System.err.println("ec isModified="+ces.isModified());
134         if(!ec.isModified()) {
135             throw new IllegalStateException JavaDoc("CloneableEditorSupport should be marked as modified already!");
136         }
137         System.err.println("Saving modified document");
138         
139         ces.saveDocument();
140     }
141     
142     
143     //
144
// Code from text module
145
//
146

147
148     public static final class TXTDataLoader extends UniFileLoader {
149
150         /** Generated serial version UID. */
151         static final long serialVersionUID =-3658061894653334886L;
152
153         /** file attribute which forces a file to be considered a text file */
154         static final String JavaDoc ATTR_IS_TEXT_FILE = "org.netbeans.modules.text.IsTextFile"; // NOI18N
155

156
157         /** Creates new <code>TXTDataLoader</code>. */
158         public TXTDataLoader() {
159             super("org.netbeans.modules.text.TXTDataObject"); // NOI18N
160
}
161
162         /** Does initialization. Initializes extension list. */
163         protected void initialize () {
164             super.initialize();
165
166             ExtensionList ext = new ExtensionList();
167             ext.addExtension("txt"); // NOI18N
168
ext.addExtension("doc"); // NOI18N
169
ext.addExtension("me"); // for read.me files // NOI18N
170
ext.addExtension("policy"); // NOI18N
171
ext.addExtension("mf"); // for manifest.mf files // NOI18N
172
ext.addExtension("MF"); // -""- // NOI18N
173
ext.addExtension("log"); // log files are nice to be readable // NOI18N
174
setExtensions(ext);
175         }
176
177         /** Gets default display name. Overrides superclass method. */
178         protected String JavaDoc defaultDisplayName() {
179             return NbBundle.getBundle(TXTDataLoader.class).getString("PROP_TXTLoader_Name");
180         }
181
182         /** Gets default system actions. Overrides superclass method. */
183         protected SystemAction[] defaultActions() {
184             return new SystemAction[] {
185                 SystemAction.get(OpenAction.class),
186                 SystemAction.get (FileSystemAction.class),
187                 null,
188                 SystemAction.get(CutAction.class),
189                 SystemAction.get(CopyAction.class),
190                 SystemAction.get(PasteAction.class),
191                 null,
192                 SystemAction.get(DeleteAction.class),
193                 SystemAction.get(RenameAction.class),
194                 null,
195                 SystemAction.get(SaveAsTemplateAction.class),
196                 null,
197                 SystemAction.get(ToolsAction.class),
198                 SystemAction.get(PropertiesAction.class),
199             };
200         }
201
202         /** Check whether a file is recognized.
203          * It will be if the extension matches, or if it is marked to be a text file. */

204         protected FileObject findPrimaryFile (FileObject fo) {
205             boolean isSysFile;
206             try {
207                 isSysFile = fo.getFileSystem () == Repository.getDefault ().getDefaultFileSystem ();
208             } catch (FileStateInvalidException fsie) {
209                 // Never mind.
210
isSysFile = false;
211             }
212             if (! isSysFile && Boolean.TRUE.equals (fo.getAttribute (ATTR_IS_TEXT_FILE)))
213                 return fo;
214             return super.findPrimaryFile (fo);
215         }
216
217         /** Creates new <code>TXTDataObject</code> for specified <code>FileObject</code>.
218          * @param fo FileObject
219          * @return new TXTDataObject
220          */

221         protected MultiDataObject createMultiObject(final FileObject fo)
222         throws IOException JavaDoc {
223             return new TXTDataObject(fo, this);
224         }
225
226     } // end of TXTDataLoader
227

228     
229     public static final class TXTDataObject extends MultiDataObject implements CookieSet.Factory {
230
231         /** Generated Serialized Version UID */
232         static final long serialVersionUID = 4795737295255253334L;
233
234         /** Editor support for text data object. */
235         private transient TXTEditorSupport editorSupport;
236
237
238         /** Constructor. */
239         public TXTDataObject(final FileObject obj, final MultiFileLoader loader) throws DataObjectExistsException {
240             super(obj, loader);
241
242             getCookieSet().add(TXTEditorSupport.class, this);
243         }
244
245
246         /** Implements <code>CookieSet.Factory</code> interface. */
247         public Node.Cookie createCookie(Class JavaDoc clazz) {
248             if(clazz.isAssignableFrom(TXTEditorSupport.class))
249                 return getEditorSupport();
250             else
251                 return null;
252         }
253
254         // Accessibility from TXTEditorSupport:
255
CookieSet getCookieSet0() {
256             return getCookieSet();
257         }
258
259         /** Gets editor support for this data object. */
260         private TXTEditorSupport getEditorSupport() {
261             if(editorSupport == null) {
262                 synchronized(this) {
263                     if(editorSupport == null)
264                         editorSupport = new TXTEditorSupport(this);
265                 }
266             }
267
268             return editorSupport;
269         }
270
271         /** Provides node that should represent this data object. When a node for representation
272          * in a parent is requested by a call to getNode (parent) it is the exact copy of this node
273          * with only parent changed. This implementation creates instance <code>DataNode</code>.
274          * <p>
275          * This method is called only once.
276          *
277          * @return the node representation for this data object
278          * @see DataNode
279          */

280         protected Node createNodeDelegate () {
281             return new TXTNode(this);
282         }
283
284         /** Help context for this object.
285          * @return help context
286          */

287         public HelpCtx getHelpCtx () {
288             return new HelpCtx (TXTDataObject.class);
289         }
290
291
292         /** Text node implementation.
293          * Leaf node, default action opens editor or instantiates template.
294          * Icons redefined.
295          */

296         public static final class TXTNode extends DataNode {
297             /** Icon base for the TXTNode node */
298             private static final String JavaDoc TXT_ICON_BASE = "org/netbeans/modules/text/txtObject"; // NOI18N
299

300             /** Constructs node. */
301             public TXTNode (final DataObject dataObject) {
302                 super(dataObject, Children.LEAF);
303                 setIconBase(TXT_ICON_BASE);
304             }
305
306             /** Overrides default action from DataNode. */
307             public SystemAction getDefaultAction () {
308                 SystemAction result = super.getDefaultAction();
309                 return result == null ? SystemAction.get(OpenAction.class) : result;
310             }
311         } // End of nested class TXTNode.
312

313     } // TXTDataObject
314

315     
316     public static final class TXTEditorSupport extends DataEditorSupport
317     implements OpenCookie, EditCookie, EditorCookie.Observable, PrintCookie, CloseCookie {
318
319         /** SaveCookie for this support instance. The cookie is adding/removing
320          * data object's cookie set depending on if modification flag was set/unset. */

321         private final SaveCookie saveCookie = new SaveCookie() {
322             /** Implements <code>SaveCookie</code> interface. */
323             public void save() throws IOException JavaDoc {
324                 TXTEditorSupport.this.saveDocument();
325                 TXTEditorSupport.this.getDataObject().setModified(false);
326             }
327         };
328
329
330         /** Constructor. */
331         TXTEditorSupport(TXTDataObject obj) {
332             super(obj, new Environment(obj));
333
334             setMIMEType("text/plain"); // NOI18N
335
}
336
337         /**
338          * Overrides superclass method. Adds adding of save cookie if the document has been marked modified.
339          * @return true if the environment accepted being marked as modified
340          * or false if it has refused and the document should remain unmodified
341          */

342         protected boolean notifyModified () {
343             if (!super.notifyModified())
344                 return false;
345
346             addSaveCookie();
347
348             return true;
349         }
350
351         /** Overrides superclass method. Adds removing of save cookie. */
352         protected void notifyUnmodified () {
353             super.notifyUnmodified();
354
355             removeSaveCookie();
356         }
357
358         /** Helper method. Adds save cookie to the data object. */
359         private void addSaveCookie() {
360             TXTDataObject obj = (TXTDataObject)getDataObject();
361
362             // Adds save cookie to the data object.
363
if(obj.getCookie(SaveCookie.class) == null) {
364                 obj.getCookieSet0().add(saveCookie);
365                 obj.setModified(true);
366             }
367         }
368
369         /** Helper method. Removes save cookie from the data object. */
370         private void removeSaveCookie() {
371             TXTDataObject obj = (TXTDataObject)getDataObject();
372
373             // Remove save cookie from the data object.
374
Node.Cookie cookie = obj.getCookie(SaveCookie.class);
375
376             if(cookie != null && cookie.equals(saveCookie)) {
377                 obj.getCookieSet0().remove(saveCookie);
378                 obj.setModified(false);
379             }
380         }
381
382
383         /** Nested class. Environment for this support. Extends
384          * <code>DataEditorSupport.Env</code> abstract class.
385          */

386
387         private static class Environment extends DataEditorSupport.Env
388         {
389             private static final long serialVersionUID = 3499855082262173256L;
390
391             /** Constructor. */
392             public Environment(TXTDataObject obj) {
393                 super(obj);
394             }
395
396
397             /** Implements abstract superclass method. */
398             protected FileObject getFile() {
399                 return getDataObject().getPrimaryFile();
400             }
401
402             /** Implements abstract superclass method.*/
403             protected FileLock takeLock() throws IOException JavaDoc {
404                 return ((TXTDataObject)getDataObject()).getPrimaryEntry().takeLock();
405             }
406
407             /**
408              * Overrides superclass method.
409              * @return text editor support (instance of enclosing class)
410              */

411             public CloneableOpenSupport findCloneableOpenSupport() {
412                 return (TXTEditorSupport)getDataObject().getCookie(TXTEditorSupport.class);
413             }
414         } // End of nested Environment class.
415

416     } // TXTEditorSupport
417

418 }
419
Popular Tags