KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > schema > core > SchemaEditorSupport


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.schema.core;
21
22 import java.awt.EventQueue JavaDoc;
23 import java.io.ByteArrayOutputStream JavaDoc;
24 import java.io.CharConversionException JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.io.OutputStreamWriter JavaDoc;
30 import java.io.Reader JavaDoc;
31 import java.io.Serializable JavaDoc;
32 import java.io.UnsupportedEncodingException JavaDoc;
33 import java.io.Writer JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Set JavaDoc;
37 import javax.swing.text.AbstractDocument JavaDoc;
38 import javax.swing.text.BadLocationException JavaDoc;
39 import javax.swing.text.Document JavaDoc;
40 import javax.swing.text.EditorKit JavaDoc;
41 import javax.swing.text.StyledDocument JavaDoc;
42 import org.netbeans.core.api.multiview.MultiViewHandler;
43 import org.netbeans.core.api.multiview.MultiViews;
44 import org.netbeans.core.spi.multiview.CloseOperationHandler;
45 import org.netbeans.core.spi.multiview.CloseOperationState;
46 import org.netbeans.modules.xml.axi.AXIModel;
47 import org.netbeans.modules.xml.axi.AXIModelFactory;
48 import org.netbeans.modules.xml.retriever.catalog.Utilities;
49 import org.netbeans.modules.xml.xam.ModelSource;
50 import org.netbeans.modules.xml.schema.core.multiview.SchemaMultiViewSupport;
51 import org.netbeans.modules.xml.schema.model.SchemaModel;
52 import org.netbeans.modules.xml.schema.model.SchemaModelFactory;
53 import org.netbeans.modules.xml.schema.ui.basic.SchemaModelCookie;
54 import org.netbeans.modules.xml.xam.ui.undo.QuietUndoManager;
55 import org.openide.DialogDisplayer;
56 import org.openide.ErrorManager;
57 import org.openide.NotifyDescriptor;
58 import org.openide.awt.UndoRedo;
59 import org.openide.cookies.CloseCookie;
60 import org.openide.cookies.EditCookie;
61 import org.openide.cookies.EditorCookie;
62 import org.openide.cookies.LineCookie;
63 import org.openide.cookies.OpenCookie;
64 import org.openide.cookies.PrintCookie;
65 import org.openide.filesystems.FileLock;
66 import org.openide.filesystems.FileObject;
67 import org.openide.loaders.DataObject;
68 import org.openide.text.CloneableEditor;
69 import org.openide.text.CloneableEditorSupport;
70 import org.openide.text.CloneableEditorSupport.Pane;
71 import org.openide.text.DataEditorSupport;
72 import org.openide.text.NbDocument;
73 import org.openide.util.NbBundle;
74 import org.openide.util.Task;
75 import org.openide.util.TaskListener;
76 import org.openide.windows.Mode;
77 import org.openide.windows.TopComponent;
78 import org.openide.windows.WindowManager;
79
80 /**
81  * Editor support for the schema data object.
82  *
83  * @author Jeri Lockhart
84  * @author Todd Fast, todd.fast@sun.com
85  * @author Nathan Fiedler
86  */

87 public class SchemaEditorSupport extends DataEditorSupport
88         implements SchemaModelCookie, OpenCookie, EditCookie,
89         EditorCookie.Observable, LineCookie, CloseCookie, PrintCookie {
90     /** Used for managing the prepareTask listener. */
91     private transient Task prepareTask2;
92     /** Ignore the upcoming call to updateTitles() due to changes being
93      * made to the document which cannot otherwise be ignored. */

94     private transient boolean ignoreUpdateTitles;
95     
96     /**
97      * Creates a new instance of SchemaEditorSupport.
98      *
99      * @param dobj schema data object to edit.
100      */

101     public SchemaEditorSupport(SchemaDataObject dobj) {
102         super(dobj, new SchemaEditorEnv(dobj));
103         setMIMEType(SchemaDataLoader.MIME_TYPE);
104     }
105     
106     /**
107      *
108      *
109      */

110     public SchemaEditorEnv getEnv() {
111         return (SchemaEditorEnv)env;
112     }
113     
114     protected Pane createPane() {
115         TopComponent tc = SchemaMultiViewSupport.createMultiView(
116                 (SchemaDataObject) getDataObject());
117         // Note that initialization of the editor happens separately,
118
// and we only need to handle that during the initial creation
119
// of the text editor.
120

121         Mode editorMode = WindowManager.getDefault().findMode(
122                 SchemaEditorSupport.EDITOR_MODE);
123         if (editorMode != null) {
124             editorMode.dockInto(tc);
125         }
126         
127         return (Pane) tc;
128     }
129     
130     // Change method access to public
131
public void initializeCloneableEditor(CloneableEditor editor) {
132         super.initializeCloneableEditor(editor);
133         // Force the title to update so the * left over from when the
134
// modified data object was discarded is removed from the title.
135
EventQueue.invokeLater(new Runnable JavaDoc() {
136             public void run() {
137                 // Have to do this later to avoid infinite loop.
138
updateTitles();
139             }
140         });
141     }
142
143     /**
144      * Request that the editor support ignore the subsequent call to
145      * updateTitles(), which results from a change being made to the
146      * document which should have otherwise been ignored, but could not.
147      *
148      * @param ignore true to ignore event, false to reset.
149      */

150     public void ignoreUpdateTitles(boolean ignore) {
151         ignoreUpdateTitles = ignore;
152         // Without doing this, the change made to the document causes
153
// the notifyModified() to be called, which is fine and we do
154
// not want to stop that, but it calls updateTitles() which
155
// causes the MultiViewPeer to try to construct the MVE, which
156
// is already in progress, so we want to avoid that if possible.
157
}
158
159     protected void updateTitles() {
160         // This method is invoked by DataEditorSupport.DataNodeListener
161
// whenever the DataNode displayName property is changed. It is
162
// also called when the CloneableEditorSupport is (un)modified.
163
if (ignoreUpdateTitles) {
164             return;
165         }
166         
167         // Let the superclass handle the CloneableEditor instances.
168
super.updateTitles();
169         
170         // We need to get the title updated on the MultiViewTopComponent.
171
EventQueue.invokeLater(new Runnable JavaDoc() {
172             public void run() {
173                 // Create a list of TopComponents associated with the
174
// editor's data object, starting with the active
175
// TopComponent. Add all open TopComponents in any
176
// mode that are associated with the DataObject.
177
// [Note that EDITOR_MODE does not contain editors in
178
// split mode.]
179
List JavaDoc<TopComponent> associatedTCs = new ArrayList JavaDoc<TopComponent>();
180                 DataObject targetDO = getDataObject();
181                 TopComponent activeTC = TopComponent.getRegistry().getActivated();
182                 if (activeTC != null && targetDO == (DataObject) activeTC.getLookup().lookup(
183                         DataObject.class)) {
184                     associatedTCs.add(activeTC);
185                 }
186                 Set JavaDoc openTCs = TopComponent.getRegistry().getOpened();
187                 for (Object JavaDoc tc : openTCs) {
188                     TopComponent tcc = (TopComponent) tc;
189                     if (targetDO == (DataObject) tcc.getLookup().lookup(
190                             DataObject.class)) {
191                         associatedTCs.add(tcc);
192                     }
193                 }
194                 for (TopComponent tc : associatedTCs) {
195                     // Make sure this is a multiview window, and not just some
196
// window that has our DataObject (e.g. Projects, Files).
197
MultiViewHandler mvh = MultiViews.findMultiViewHandler(tc);
198                     if (mvh != null) {
199                         tc.setHtmlDisplayName(messageHtmlName());
200                         String JavaDoc name = messageName();
201                         tc.setDisplayName(name);
202                         tc.setName(name);
203                         tc.setToolTipText(messageToolTip());
204                     }
205                 }
206             }
207         });
208     }
209     
210     @Override JavaDoc
211             protected UndoRedo.Manager createUndoRedoManager() {
212         // Override so the superclass will use our proxy undo manager
213
// instead of the default, then we can intercept edits.
214
return new QuietUndoManager(super.createUndoRedoManager());
215         // Note we cannot set the document on the undo manager right
216
// now, as CES is probably trying to open the document.
217
}
218     
219     /**
220      * Returns the UndoRedo.Manager instance managed by this editor support.
221      *
222      * @return specialized UndoRedo.Manager instance.
223      */

224     public QuietUndoManager getUndoManager() {
225         return (QuietUndoManager) getUndoRedo();
226     }
227     
228     public SchemaModel getModel() throws IOException JavaDoc {
229         SchemaDataObject dobj = getEnv().getSchemaDataObject();
230         FileObject fobj = dobj.getPrimaryFile();
231         ModelSource modelSource = Utilities.getModelSource(fobj, true);
232         boolean validModelSource = modelSource != null &&
233                 modelSource.getLookup().lookup(Document JavaDoc.class) != null;
234         if (!validModelSource) {
235             throw new IOException JavaDoc(
236                     NbBundle.getMessage(SchemaEditorSupport.class,
237                     "MSG_UnableToCreateModel"));
238         }
239         return validModelSource ? SchemaModelFactory.getDefault().getModel(modelSource) : null;
240     }
241     
242     /**
243      * Adds the undo/redo manager to the document as an undoable edit
244      * listener, so it receives the edits onto the queue. The manager
245      * will be removed from the model as an undoable edit listener.
246      *
247      * <p>This method may be called repeatedly.</p>
248      */

249     public void addUndoManagerToDocument() {
250         // This method may be called repeatedly.
251
// Stop the undo manager from listening to the model, as it will
252
// be listening to the document now.
253
QuietUndoManager undo = getUndoManager();
254         StyledDocument JavaDoc doc = getDocument();
255         synchronized (undo) {
256             try {
257                 SchemaModel model = getModel();
258                 if (model != null) {
259                     model.removeUndoableEditListener(undo);
260                 }
261                 // Must unset the model when no longer listening to it.
262
undo.setModel(null);
263                 AXIModel aModel = AXIModelFactory.getDefault().getModel(model);
264                 undo.removeWrapperModel(aModel);
265             } catch (IOException JavaDoc ioe) {
266                 // Model is gone, but just removing the listener is not
267
// going to matter anyway.
268
}
269             // Document may be null if the cloned views are not behaving correctly.
270
if (doc != null) {
271                 // Ensure the listener is not added twice.
272
doc.removeUndoableEditListener(undo);
273                 doc.addUndoableEditListener(undo);
274                 // Start the compound mode of the undo manager, such that when
275
// we are hidden, we will treat all of the edits as a single
276
// compound edit. This avoids having the user invoke undo
277
// numerous times when in the model view.
278
undo.beginCompound();
279             }
280         }
281     }
282     
283     /**
284      * Removes the undo/redo manager undoable edit listener from the
285      * document, to stop receiving undoable edits. The manager will
286      * be added to the model as an undoable edit listener.
287      *
288      * <p>This method may be called repeatedly.</p>
289      */

290     public void removeUndoManagerFromDocument() {
291         // This method may be called repeatedly.
292
QuietUndoManager undo = getUndoManager();
293         StyledDocument JavaDoc doc = getDocument();
294         synchronized (undo) {
295             // May be null when closing the editor.
296
if (doc != null) {
297                 doc.removeUndoableEditListener(undo);
298                 undo.endCompound();
299             }
300             // Have the undo manager listen to the model when it is not
301
// listening to the document.
302
addUndoManagerToModel(undo);
303         }
304     }
305     
306     /**
307      * Add the undo/redo manager undoable edit listener to the model.
308      *
309      * <p>Caller should synchronize on the undo manager prior to calling
310      * this method, to avoid thread concurrency issues.</p>
311      *
312      * @param undo the undo manager.
313      */

314     private void addUndoManagerToModel(QuietUndoManager undo) {
315         // This method may be called repeatedly.
316
try {
317             SchemaModel model = getModel();
318             if (model != null) {
319                 // Ensure the listener is not added twice.
320
model.removeUndoableEditListener(undo);
321                 model.addUndoableEditListener(undo);
322                 // Ensure the model is sync'd when undo/redo is invoked,
323
// otherwise the edits are added to the queue and eventually
324
// cause exceptions.
325
undo.setModel(model);
326             }
327         } catch (IOException JavaDoc ioe) {
328             // Model is gone, nothing will work, return immediately.
329
}
330     }
331
332     /**
333      * Remove the undo/redo manager undoable edit listener from the model.
334      *
335      * <p>Caller should synchronize on the undo manager prior to calling
336      * this method, to avoid thread concurrency issues.</p>
337      *
338      * @param undo the undo manager.
339      */

340     private void removeUndoManagerFromModel(QuietUndoManager undo) {
341         // This method may be called repeatedly.
342
try {
343             SchemaModel model = getModel();
344             if (model != null) {
345                 model.removeUndoableEditListener(undo);
346                 undo.setModel(null);
347             }
348         } catch (IOException JavaDoc ioe) {
349             // Model is gone, nothing will work, return immediately.
350
}
351     }
352
353     /**
354      * Remove the undo manager from both the model and document, such that
355      * any changes made to either will not be added to the undo queue. The
356      * caller should invoke <code>resumeUndoRedo()</code> once the changes
357      * are completed.
358      *
359      * @return a value that must be passed to <code>resumeUndoRedo()</code>.
360      */

361     public boolean suspendUndoRedo() {
362         QuietUndoManager undo = getUndoManager();
363         boolean compound;
364         synchronized (undo) {
365             compound = undo.isCompound();
366             if (compound) {
367                 removeUndoManagerFromDocument();
368             }
369             removeUndoManagerFromModel(undo);
370         }
371         return compound;
372     }
373
374     /**
375      * Add the undo manager as an undoable edit listener to either the
376      * Swing document or the XAM model, and set up the compound mode if
377      * that was in place previously.
378      *
379      * @param value value returned from <code>suspendUndoRedo()</code>
380      */

381     public void resumeUndoRedo(boolean value) {
382         if (value) {
383             addUndoManagerToDocument();
384         } else {
385             QuietUndoManager undo = getUndoManager();
386             synchronized (undo) {
387                 addUndoManagerToModel(undo);
388             }
389         }
390     }
391
392     protected void loadFromStreamToKit(StyledDocument JavaDoc doc, InputStream JavaDoc in,
393             EditorKit JavaDoc kit) throws IOException JavaDoc, BadLocationException JavaDoc {
394         // Detect the encoding to get optimized reader if UTF-8.
395
String JavaDoc enc = EncodingHelper.detectEncoding(in);
396         if (enc == null) {
397             enc = "UTF8"; // NOI18N
398
}
399         try {
400             Reader JavaDoc reader = new InputStreamReader JavaDoc(in, enc);
401             kit.read(reader, doc, 0);
402         } catch (CharConversionException JavaDoc cce) {
403         } catch (UnsupportedEncodingException JavaDoc uee) {
404         }
405     }
406     
407     protected void saveFromKitToStream(StyledDocument JavaDoc doc, EditorKit JavaDoc kit,
408             OutputStream JavaDoc out) throws IOException JavaDoc, BadLocationException JavaDoc {
409         // Detect the encoding, using UTF8 if the encoding is not set.
410
String JavaDoc enc = EncodingHelper.detectEncoding(doc);
411         if (enc == null) {
412             enc = "UTF8"; // NOI18N
413
}
414         try {
415             // Test the encoding on a dummy stream.
416
new OutputStreamWriter JavaDoc(new ByteArrayOutputStream JavaDoc(1), enc);
417             // If that worked, we can go ahead with the encoding.
418
Writer JavaDoc writer = new OutputStreamWriter JavaDoc(out, enc);
419             kit.write(writer, doc, 0, doc.getLength());
420         } catch (UnsupportedEncodingException JavaDoc uee) {
421             // Safest option is to write nothing, preserving the original file.
422
IOException JavaDoc ioex = new IOException JavaDoc("Unsupported encoding " + enc); // NOI18N
423
ErrorManager.getDefault().annotate(ioex,
424                     NbBundle.getMessage(SchemaEditorSupport.class,
425                     "MSG_SchemaEditorSupport_Unsupported_Encoding", enc));
426             throw ioex;
427         }
428     }
429     
430     /**
431      * This method allows the close behavior of CloneableEditorSupport to be
432      * invoked from the SourceMultiViewElement. The close method of
433      * CloneableEditorSupport at least clears the undo queue and releases
434      * the swing document.
435      */

436     public boolean silentClose() {
437         return super.close(false);
438     }
439     
440     public void saveDocument() throws IOException JavaDoc {
441         final StyledDocument JavaDoc doc = getDocument();
442         // Save document using encoding declared in XML prolog if possible,
443
// otherwise use UTF-8 (in such case it updates the prolog).
444
String JavaDoc enc = EncodingHelper.detectEncoding(doc);
445         if (enc == null) {
446             enc = "UTF8"; // NOI18N
447
}
448         try {
449             // Test the encoding on a dummy stream.
450
new OutputStreamWriter JavaDoc(new ByteArrayOutputStream JavaDoc(1), enc);
451             if (!checkCharsetConversion(Convertors.java2iana(enc))){
452                 return;
453             }
454             super.saveDocument();
455             getDataObject().setModified(false);
456             
457         } catch (UnsupportedEncodingException JavaDoc uee) {
458             NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
459                     java.text.MessageFormat.format(
460                     NbBundle.getMessage(SchemaEditorSupport.class,
461                     "MSG_SchemaEditorSupport_Use_UTF8"),
462                     new Object JavaDoc[] {enc}));
463             Object JavaDoc res = DialogDisplayer.getDefault().notify(descriptor);
464             
465             if (res.equals(NotifyDescriptor.YES_OPTION)) {
466                 // Update prolog to new valid encoding.
467
try {
468                     final int MAX_PROLOG = 1000;
469                     int maxPrologLen = Math.min(MAX_PROLOG, doc.getLength());
470                     final char prolog[] = doc.getText(0, maxPrologLen).toCharArray();
471                     int prologLen = 0;
472                     if (prolog[0] == '<' && prolog[1] == '?' && prolog[2] == 'x') {
473                         for (int i = 3; i < maxPrologLen; i++) {
474                             if (prolog[i] == '?' && prolog[i + 1] == '>') {
475                                 prologLen = i + 1;
476                                 break;
477                             }
478                         }
479                     }
480                     
481                     final int passPrologLen = prologLen;
482                     Runnable JavaDoc edit = new Runnable JavaDoc() {
483                         public void run() {
484                             try {
485                                 doc.remove(0, passPrologLen + 1);
486                                 doc.insertString(0, "<?xml version='1.0' encoding='UTF-8' ?>\n<!-- was: " +
487                                         new String JavaDoc(prolog, 0, passPrologLen + 1) + " -->", null); // NOI18N
488
} catch (BadLocationException JavaDoc ble) {
489                                 if (System.getProperty("netbeans.debug.exceptions") != null) // NOI18N
490
ble.printStackTrace();
491                             }
492                         }
493                     };
494                     NbDocument.runAtomic(doc, edit);
495                     
496                     super.saveDocument();
497                     getDataObject().setModified(false);
498                     
499                 } catch (BadLocationException JavaDoc lex) {
500                     ErrorManager.getDefault().notify(lex);
501                 }
502             }
503         }
504     }
505     
506     /**
507      * Validate the selected encoding to determine if it is usuable or not.
508      * If there is a problem, prompt the user to confirm the encoding.
509      *
510      * @param encoding the character set encoding to validate.
511      * @return true if encoding can be used, false otherwise.
512      */

513     private boolean checkCharsetConversion(String JavaDoc encoding) {
514         boolean value = true;
515         try {
516             java.nio.charset.CharsetEncoder JavaDoc coder =
517                     java.nio.charset.Charset.forName(encoding).newEncoder();
518             if (!coder.canEncode(getDocument().getText(0,
519                     getDocument().getLength()))){
520                 Object JavaDoc[] margs = new Object JavaDoc[] {
521                     getDataObject().getPrimaryFile().getNameExt(),
522                     encoding
523                 };
524                 String JavaDoc msg = NbBundle.getMessage(SchemaEditorSupport.class,
525                         "MSG_SchemaEditorSupport_BadCharConversion", margs);
526                 NotifyDescriptor nd = new NotifyDescriptor.Confirmation(msg,
527                         NotifyDescriptor.YES_NO_OPTION,
528                         NotifyDescriptor.WARNING_MESSAGE);
529                 nd.setValue(NotifyDescriptor.NO_OPTION);
530                 DialogDisplayer.getDefault().notify(nd);
531                 if (nd.getValue() != NotifyDescriptor.YES_OPTION) {
532                     value = false;
533                 }
534             }
535         } catch (BadLocationException JavaDoc ble) {
536             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ble);
537         }
538         return value;
539     }
540     
541     /**
542      * Have the schema model sync with the document.
543      */

544     public void syncModel() {
545         try {
546             SchemaModel model = getModel();
547             if (model != null) {
548                 model.sync();
549             }
550         } catch (IOException JavaDoc ioe) {
551             // The document cannot be parsed, ignore this error.
552
}
553     }
554     
555     public Task prepareDocument() {
556         Task task = super.prepareDocument();
557         // Avoid listening to the same task more than once.
558
if (task != prepareTask2) {
559             prepareTask2 = task;
560             task.addTaskListener(new TaskListener() {
561                 public void taskFinished(Task task) {
562                     QuietUndoManager undo = getUndoManager();
563                     StyledDocument JavaDoc doc = getDocument();
564                     synchronized (undo) {
565                         // Now that the document is ready, pass it to the manager.
566
undo.setDocument((AbstractDocument JavaDoc) doc);
567                         if (!undo.isCompound()) {
568                             // The superclass prepareDocument() adds the undo/redo
569
// manager as a listener -- we need to remove it since
570
// we will initially listen to the model instead.
571
doc.removeUndoableEditListener(undo);
572                             // If not listening to document, then listen to model.
573
addUndoManagerToModel(undo);
574                         }
575                     }
576                     prepareTask2 = null;
577                 }
578             });
579         }
580         return task;
581     }
582     
583     public Task reloadDocument() {
584         Task task = super.reloadDocument();
585         task.addTaskListener(new TaskListener() {
586             public void taskFinished(Task task) {
587                 EventQueue.invokeLater(new Runnable JavaDoc() {
588                     public void run() {
589                         QuietUndoManager undo = getUndoManager();
590                         StyledDocument JavaDoc doc = getDocument();
591                         // The superclass reloadDocument() adds the undo
592
// manager as an undoable edit listener.
593
synchronized (undo) {
594                             if (!undo.isCompound()) {
595                                 doc.removeUndoableEditListener(undo);
596                             }
597                         }
598                     }
599                 });
600             }
601         });
602         return task;
603     }
604     
605     protected void notifyClosed() {
606         // Stop listening to the undoable edit sources when we are closed.
607
QuietUndoManager undo = getUndoManager();
608         StyledDocument JavaDoc doc = getDocument();
609         synchronized (undo) {
610             // May be null when closing the editor.
611
if (doc != null) {
612                 doc.removeUndoableEditListener(undo);
613                 undo.endCompound();
614                 undo.setDocument(null);
615             }
616             try {
617                 SchemaModel model = getModel();
618                 if (model != null) {
619                     model.removeUndoableEditListener(undo);
620                     AXIModel aModel = AXIModelFactory.getDefault().getModel(model);
621                     undo.removeWrapperModel(aModel);
622                 }
623                 // Must unset the model when no longer listening to it.
624
undo.setModel(null);
625             } catch (IOException JavaDoc ioe) {
626                 // Model is gone, but just removing the listener is not
627
// going to matter anyway.
628
}
629         }
630         
631         super.notifyClosed();
632     }
633     
634     /**
635      * Env class extends SchemaEditorSupport.Env.
636      * overrides findSchemaEditorSupport
637      *
638      */

639     protected static class SchemaEditorEnv extends DataEditorSupport.Env {
640         
641         static final long serialVersionUID =1099957785497677206L;
642         
643         public SchemaEditorEnv(SchemaDataObject obj) {
644             super(obj);
645         }
646         
647         public CloneableEditorSupport findTextEditorSupport() {
648             return getSchemaDataObject().getSchemaEditorSupport();
649         }
650         
651         public SchemaDataObject getSchemaDataObject(){
652             return (SchemaDataObject) getDataObject();
653         }
654         
655         protected FileObject getFile() {
656             return getDataObject().getPrimaryFile();
657         }
658         
659         protected FileLock takeLock() throws IOException JavaDoc {
660             return getDataObject().getPrimaryFile().lock();
661         }
662     }
663     
664     /**
665      * Implementation of CloseOperationHandler for multiview. Ensures the
666      * editors correctly closed, data object is saved, etc. Holds a
667      * reference to DataObject only - to be serializable with the multiview
668      * TopComponent without problems.
669      */

670     public static class CloseHandler implements CloseOperationHandler, Serializable JavaDoc {
671         private static final long serialVersionUID = -3838395157610633251L;
672         private DataObject dataObject;
673         
674         private CloseHandler() {
675             super();
676         }
677         
678         public CloseHandler(DataObject schemaDO) {
679             dataObject = schemaDO;
680         }
681         
682         private SchemaEditorSupport getSchemaEditorSupport() {
683             return dataObject == null ? null :
684                 (SchemaEditorSupport) dataObject.getCookie(
685                     SchemaEditorSupport.class);
686         }
687         
688         public boolean resolveCloseOperation(CloseOperationState[] elements) {
689             SchemaEditorSupport schemaEditor = getSchemaEditorSupport();
690             boolean canClose = schemaEditor != null ? schemaEditor.canClose() : true;
691             // during the shutdown sequence this is called twice. The first time
692
// through the multi-view infrastructure. The second time is done through
693
// the TopComponent close. If the file is dirty and the user chooses
694
// to discard changes, the second time will also ask whether the
695
// to save or discard changes.
696
if (canClose) {
697                 dataObject.setModified(false);
698             }
699             return canClose;
700         }
701     }
702 }
703
Popular Tags