Source Code Cross Referenced for SchemaEditorSupport.java in  » IDE-Netbeans » xml » org » netbeans » modules » xml » schema » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » xml » org.netbeans.modules.xml.schema 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans.modules.xml.schema;
043:
044:        import java.awt.EventQueue;
045:        import java.io.ByteArrayOutputStream;
046:        import java.io.CharConversionException;
047:        import java.io.IOException;
048:        import java.io.InputStream;
049:        import java.io.InputStreamReader;
050:        import java.io.OutputStream;
051:        import java.io.OutputStreamWriter;
052:        import java.io.Reader;
053:        import java.io.Serializable;
054:        import java.io.UnsupportedEncodingException;
055:        import java.io.Writer;
056:        import java.util.ArrayList;
057:        import java.util.List;
058:        import java.util.Set;
059:        import javax.swing.text.AbstractDocument;
060:        import javax.swing.text.BadLocationException;
061:        import javax.swing.text.Document;
062:        import javax.swing.text.EditorKit;
063:        import javax.swing.text.StyledDocument;
064:        import org.netbeans.core.api.multiview.MultiViewHandler;
065:        import org.netbeans.core.api.multiview.MultiViews;
066:        import org.netbeans.core.spi.multiview.CloseOperationHandler;
067:        import org.netbeans.core.spi.multiview.CloseOperationState;
068:        import org.netbeans.modules.xml.api.EncodingUtil;
069:        import org.netbeans.modules.xml.axi.AXIModel;
070:        import org.netbeans.modules.xml.axi.AXIModelFactory;
071:        import org.netbeans.modules.xml.retriever.catalog.Utilities;
072:        import org.netbeans.modules.xml.xam.ModelSource;
073:        import org.netbeans.modules.xml.schema.multiview.SchemaMultiViewSupport;
074:        import org.netbeans.modules.xml.schema.model.SchemaModel;
075:        import org.netbeans.modules.xml.schema.model.SchemaModelFactory;
076:        import org.netbeans.modules.xml.schema.ui.basic.SchemaModelCookie;
077:        import org.netbeans.modules.xml.xam.ui.undo.QuietUndoManager;
078:        import org.openide.DialogDisplayer;
079:        import org.openide.ErrorManager;
080:        import org.openide.NotifyDescriptor;
081:        import org.openide.awt.UndoRedo;
082:        import org.openide.cookies.CloseCookie;
083:        import org.openide.cookies.EditCookie;
084:        import org.openide.cookies.EditorCookie;
085:        import org.openide.cookies.LineCookie;
086:        import org.openide.cookies.OpenCookie;
087:        import org.openide.cookies.PrintCookie;
088:        import org.openide.cookies.SaveCookie;
089:        import org.openide.filesystems.FileLock;
090:        import org.openide.filesystems.FileObject;
091:        import org.openide.loaders.DataObject;
092:        import org.openide.text.CloneableEditor;
093:        import org.openide.text.CloneableEditorSupport;
094:        import org.openide.text.CloneableEditorSupport.Pane;
095:        import org.openide.text.DataEditorSupport;
096:        import org.openide.text.NbDocument;
097:        import org.openide.util.NbBundle;
098:        import org.openide.util.Task;
099:        import org.openide.util.TaskListener;
100:        import org.openide.util.UserCancelException;
101:        import org.openide.windows.Mode;
102:        import org.openide.windows.TopComponent;
103:        import org.openide.windows.WindowManager;
104:
105:        /**
106:         * Editor support for the schema data object.
107:         *
108:         * @author Jeri Lockhart
109:         * @author Todd Fast, todd.fast@sun.com
110:         * @author Nathan Fiedler
111:         */
112:        public class SchemaEditorSupport extends DataEditorSupport implements 
113:                SchemaModelCookie, OpenCookie, EditCookie,
114:                EditorCookie.Observable, LineCookie, CloseCookie, PrintCookie {
115:            /** Used for managing the prepareTask listener. */
116:            private transient Task prepareTask2;
117:            /** Ignore the upcoming call to updateTitles() due to changes being
118:             * made to the document which cannot otherwise be ignored. */
119:            private transient boolean ignoreUpdateTitles;
120:            private transient SchemaModel model;
121:
122:            /**
123:             * Creates a new instance of SchemaEditorSupport.
124:             *
125:             * @param  dobj  schema data object to edit.
126:             */
127:            public SchemaEditorSupport(SchemaDataObject dobj) {
128:                super (dobj, new SchemaEditorEnv(dobj));
129:                setMIMEType(SchemaDataLoader.MIME_TYPE);
130:            }
131:
132:            /**
133:             *
134:             *
135:             */
136:            public SchemaEditorEnv getEnv() {
137:                return (SchemaEditorEnv) env;
138:            }
139:
140:            protected Pane createPane() {
141:                TopComponent tc = SchemaMultiViewSupport
142:                        .createMultiView((SchemaDataObject) getDataObject());
143:                // Note that initialization of the editor happens separately,
144:                // and we only need to handle that during the initial creation
145:                // of the text editor.
146:
147:                Mode editorMode = WindowManager.getDefault().findMode(
148:                        SchemaEditorSupport.EDITOR_MODE);
149:                if (editorMode != null) {
150:                    editorMode.dockInto(tc);
151:                }
152:
153:                return (Pane) tc;
154:            }
155:
156:            // Change method access to public
157:            public void initializeCloneableEditor(CloneableEditor editor) {
158:                super .initializeCloneableEditor(editor);
159:                // Force the title to update so the * left over from when the
160:                // modified data object was discarded is removed from the title.
161:                EventQueue.invokeLater(new Runnable() {
162:                    public void run() {
163:                        // Have to do this later to avoid infinite loop.
164:                        updateTitles();
165:                    }
166:                });
167:            }
168:
169:            /**
170:             * Request that the editor support ignore the subsequent call to
171:             * updateTitles(), which results from a change being made to the
172:             * document which should have otherwise been ignored, but could not.
173:             *
174:             * @param  ignore  true to ignore event, false to reset.
175:             */
176:            public void ignoreUpdateTitles(boolean ignore) {
177:                ignoreUpdateTitles = ignore;
178:                // Without doing this, the change made to the document causes
179:                // the notifyModified() to be called, which is fine and we do
180:                // not want to stop that, but it calls updateTitles() which
181:                // causes the MultiViewPeer to try to construct the MVE, which
182:                // is already in progress, so we want to avoid that if possible.
183:            }
184:
185:            protected void updateTitles() {
186:                // This method is invoked by DataEditorSupport.DataNodeListener
187:                // whenever the DataNode displayName property is changed. It is
188:                // also called when the CloneableEditorSupport is (un)modified.
189:                if (ignoreUpdateTitles) {
190:                    return;
191:                }
192:
193:                // Let the superclass handle the CloneableEditor instances.
194:                super .updateTitles();
195:
196:                // We need to get the title updated on the MultiViewTopComponent.
197:                EventQueue.invokeLater(new Runnable() {
198:                    public void run() {
199:                        // Create a list of TopComponents associated with the
200:                        // editor's data object, starting with the active
201:                        // TopComponent. Add all open TopComponents in any
202:                        // mode that are associated with the DataObject.
203:                        // [Note that EDITOR_MODE does not contain editors in
204:                        // split mode.]
205:                        List<TopComponent> associatedTCs = new ArrayList<TopComponent>();
206:                        DataObject targetDO = getDataObject();
207:                        TopComponent activeTC = TopComponent.getRegistry()
208:                                .getActivated();
209:                        if (activeTC != null
210:                                && targetDO == activeTC.getLookup().lookup(
211:                                        DataObject.class)) {
212:                            associatedTCs.add(activeTC);
213:                        }
214:                        Set openTCs = TopComponent.getRegistry().getOpened();
215:                        for (Object tc : openTCs) {
216:                            TopComponent tcc = (TopComponent) tc;
217:                            if (targetDO == tcc.getLookup().lookup(
218:                                    DataObject.class)) {
219:                                associatedTCs.add(tcc);
220:                            }
221:                        }
222:                        for (TopComponent tc : associatedTCs) {
223:                            // Make sure this is a multiview window, and not just some
224:                            // window that has our DataObject (e.g. Projects, Files).
225:                            MultiViewHandler mvh = MultiViews
226:                                    .findMultiViewHandler(tc);
227:                            if (mvh != null) {
228:                                tc.setHtmlDisplayName(messageHtmlName());
229:                                String name = messageName();
230:                                tc.setDisplayName(name);
231:                                tc.setName(name);
232:                                tc.setToolTipText(messageToolTip());
233:                            }
234:                        }
235:                    }
236:                });
237:            }
238:
239:            @Override
240:            protected UndoRedo.Manager createUndoRedoManager() {
241:                // Override so the superclass will use our proxy undo manager
242:                // instead of the default, then we can intercept edits.
243:                return new QuietUndoManager(super .createUndoRedoManager());
244:                // Note we cannot set the document on the undo manager right
245:                // now, as CES is probably trying to open the document.
246:            }
247:
248:            /**
249:             * Returns the UndoRedo.Manager instance managed by this editor support.
250:             *
251:             * @return specialized UndoRedo.Manager instance.
252:             */
253:            public QuietUndoManager getUndoManager() {
254:                return (QuietUndoManager) getUndoRedo();
255:            }
256:
257:            public SchemaModel getModel() throws IOException {
258:                if (model != null)
259:                    return model;
260:                SchemaDataObject dobj = getEnv().getSchemaDataObject();
261:                FileObject fobj = dobj.getPrimaryFile();
262:                ModelSource modelSource = Utilities.getModelSource(fobj, true);
263:                boolean validModelSource = modelSource != null
264:                        && modelSource.getLookup().lookup(Document.class) != null;
265:                if (!validModelSource) {
266:                    throw new IOException(NbBundle.getMessage(
267:                            SchemaEditorSupport.class,
268:                            "MSG_UnableToCreateModel"));
269:                }
270:                model = SchemaModelFactory.getDefault().getModel(modelSource);
271:                return model;
272:            }
273:
274:            /**
275:             * Adds the undo/redo manager to the document as an undoable edit
276:             * listener, so it receives the edits onto the queue. The manager
277:             * will be removed from the model as an undoable edit listener.
278:             *
279:             * <p>This method may be called repeatedly.</p>
280:             */
281:            public void addUndoManagerToDocument() {
282:                // This method may be called repeatedly.
283:                // Stop the undo manager from listening to the model, as it will
284:                // be listening to the document now.
285:                QuietUndoManager undo = getUndoManager();
286:                StyledDocument doc = getDocument();
287:                synchronized (undo) {
288:                    try {
289:                        SchemaModel model = getModel();
290:                        if (model != null) {
291:                            model.removeUndoableEditListener(undo);
292:                        }
293:                        // Must unset the model when no longer listening to it.
294:                        undo.setModel(null);
295:                        AXIModel aModel = AXIModelFactory.getDefault()
296:                                .getModel(model);
297:                        undo.removeWrapperModel(aModel);
298:                    } catch (IOException ioe) {
299:                        // Model is gone, but just removing the listener is not
300:                        // going to matter anyway.
301:                    }
302:                    // Document may be null if the cloned views are not behaving correctly.
303:                    if (doc != null) {
304:                        // Ensure the listener is not added twice.
305:                        doc.removeUndoableEditListener(undo);
306:                        doc.addUndoableEditListener(undo);
307:                        // Start the compound mode of the undo manager, such that when
308:                        // we are hidden, we will treat all of the edits as a single
309:                        // compound edit. This avoids having the user invoke undo
310:                        // numerous times when in the model view.
311:                        undo.beginCompound();
312:                    }
313:                }
314:            }
315:
316:            /**
317:             * Removes the undo/redo manager undoable edit listener from the
318:             * document, to stop receiving undoable edits. The manager will
319:             * be added to the model as an undoable edit listener.
320:             *
321:             * <p>This method may be called repeatedly.</p>
322:             */
323:            public void removeUndoManagerFromDocument() {
324:                // This method may be called repeatedly.
325:                QuietUndoManager undo = getUndoManager();
326:                StyledDocument doc = getDocument();
327:                synchronized (undo) {
328:                    // May be null when closing the editor.
329:                    if (doc != null) {
330:                        doc.removeUndoableEditListener(undo);
331:                        undo.endCompound();
332:                    }
333:                    // Have the undo manager listen to the model when it is not
334:                    // listening to the document.
335:                    addUndoManagerToModel(undo);
336:                }
337:            }
338:
339:            /**
340:             * Add the undo/redo manager undoable edit listener to the model.
341:             *
342:             * <p>Caller should synchronize on the undo manager prior to calling
343:             * this method, to avoid thread concurrency issues.</p>
344:             *
345:             * @param  undo  the undo manager.
346:             */
347:            private void addUndoManagerToModel(QuietUndoManager undo) {
348:                // This method may be called repeatedly.
349:                try {
350:                    SchemaModel model = getModel();
351:                    if (model != null) {
352:                        // Ensure the listener is not added twice.
353:                        model.removeUndoableEditListener(undo);
354:                        model.addUndoableEditListener(undo);
355:                        // Ensure the model is sync'd when undo/redo is invoked,
356:                        // otherwise the edits are added to the queue and eventually
357:                        // cause exceptions.
358:                        undo.setModel(model);
359:                    }
360:                } catch (IOException ioe) {
361:                    // Model is gone, nothing will work, return immediately.
362:                }
363:            }
364:
365:            /**
366:             * Remove the undo/redo manager undoable edit listener from the model.
367:             *
368:             * <p>Caller should synchronize on the undo manager prior to calling
369:             * this method, to avoid thread concurrency issues.</p>
370:             *
371:             * @param  undo  the undo manager.
372:             */
373:            private void removeUndoManagerFromModel(QuietUndoManager undo) {
374:                // This method may be called repeatedly.
375:                try {
376:                    SchemaModel model = getModel();
377:                    if (model != null) {
378:                        model.removeUndoableEditListener(undo);
379:                        undo.setModel(null);
380:                    }
381:                } catch (IOException ioe) {
382:                    // Model is gone, nothing will work, return immediately.
383:                }
384:            }
385:
386:            /**
387:             * Remove the undo manager from both the model and document, such that
388:             * any changes made to either will not be added to the undo queue. The
389:             * caller should invoke <code>resumeUndoRedo()</code> once the changes
390:             * are completed.
391:             *
392:             * @return  a value that must be passed to <code>resumeUndoRedo()</code>.
393:             */
394:            public boolean suspendUndoRedo() {
395:                QuietUndoManager undo = getUndoManager();
396:                boolean compound;
397:                synchronized (undo) {
398:                    compound = undo.isCompound();
399:                    if (compound) {
400:                        removeUndoManagerFromDocument();
401:                    }
402:                    removeUndoManagerFromModel(undo);
403:                }
404:                return compound;
405:            }
406:
407:            /**
408:             * Add the undo manager as an undoable edit listener to either the
409:             * Swing document or the XAM model, and set up the compound mode if
410:             * that was in place previously.
411:             * 
412:             * @param  value  value returned from <code>suspendUndoRedo()</code>
413:             */
414:            public void resumeUndoRedo(boolean value) {
415:                if (value) {
416:                    addUndoManagerToDocument();
417:                } else {
418:                    QuietUndoManager undo = getUndoManager();
419:                    synchronized (undo) {
420:                        addUndoManagerToModel(undo);
421:                    }
422:                }
423:            }
424:
425:            protected void loadFromStreamToKit(StyledDocument doc,
426:                    InputStream in, EditorKit kit) throws IOException,
427:                    BadLocationException {
428:                // Detect the encoding to get optimized reader if UTF-8.
429:                String enc = EncodingUtil.detectEncoding(in);
430:                if (enc == null) {
431:                    enc = "UTF8"; // NOI18N
432:                }
433:                try {
434:                    Reader reader = new InputStreamReader(in, enc);
435:                    kit.read(reader, doc, 0);
436:                } catch (CharConversionException cce) {
437:                } catch (UnsupportedEncodingException uee) {
438:                }
439:            }
440:
441:            protected void saveFromKitToStream(StyledDocument doc,
442:                    EditorKit kit, OutputStream out) throws IOException,
443:                    BadLocationException {
444:                // Detect the encoding, using UTF8 if the encoding is not set.
445:                String enc = EncodingUtil.detectEncoding(doc);
446:                if (enc == null) {
447:                    enc = "UTF8"; // NOI18N
448:                }
449:                try {
450:                    // Test the encoding on a dummy stream.
451:                    new OutputStreamWriter(new ByteArrayOutputStream(1), enc);
452:                    // If that worked, we can go ahead with the encoding.
453:                    Writer writer = new OutputStreamWriter(out, enc);
454:                    kit.write(writer, doc, 0, doc.getLength());
455:                } catch (UnsupportedEncodingException uee) {
456:                    // Safest option is to write nothing, preserving the original file.
457:                    IOException ioex = new IOException("Unsupported encoding "
458:                            + enc); // NOI18N
459:                    ErrorManager
460:                            .getDefault()
461:                            .annotate(
462:                                    ioex,
463:                                    NbBundle
464:                                            .getMessage(
465:                                                    SchemaEditorSupport.class,
466:                                                    "MSG_SchemaEditorSupport_Unsupported_Encoding",
467:                                                    enc));
468:                    throw ioex;
469:                }
470:            }
471:
472:            /**
473:             * This method allows the close behavior of CloneableEditorSupport to be
474:             * invoked from the SourceMultiViewElement. The close method of
475:             * CloneableEditorSupport at least clears the undo queue and releases
476:             * the swing document.
477:             */
478:            public boolean silentClose() {
479:                return super .close(false);
480:            }
481:
482:            public void saveDocument() throws IOException {
483:                final StyledDocument doc = getDocument();
484:                // Save document using encoding declared in XML prolog if possible,
485:                // otherwise use UTF-8 (in such case it updates the prolog).
486:                String enc = EncodingUtil.detectEncoding(doc);
487:                if (enc == null) {
488:                    enc = "UTF8"; // NOI18N
489:                }
490:                try {
491:                    // Test the encoding on a dummy stream.
492:                    new OutputStreamWriter(new ByteArrayOutputStream(1), enc);
493:                    if (!checkCharsetConversion(EncodingUtil
494:                            .getJava2IANAMapping(enc))) {
495:                        return;
496:                    }
497:                    super .saveDocument();
498:                    getDataObject().setModified(false);
499:
500:                } catch (UnsupportedEncodingException uee) {
501:                    NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
502:                            java.text.MessageFormat.format(NbBundle.getMessage(
503:                                    SchemaEditorSupport.class,
504:                                    "MSG_SchemaEditorSupport_Use_UTF8"),
505:                                    new Object[] { enc }));
506:                    Object res = DialogDisplayer.getDefault()
507:                            .notify(descriptor);
508:
509:                    if (res.equals(NotifyDescriptor.YES_OPTION)) {
510:                        updateDocumentWithNewEncoding(doc);
511:                    } else {
512:                        throw new UserCancelException();
513:                    }
514:                }
515:            }
516:
517:            /**
518:             * update prolog to new valid encoding
519:             */
520:            private void updateDocumentWithNewEncoding(final StyledDocument doc)
521:                    throws IOException {
522:                try {
523:                    final int MAX_PROLOG = 1000;
524:                    int maxPrologLen = Math.min(MAX_PROLOG, doc.getLength());
525:                    final char prolog[] = doc.getText(0, maxPrologLen)
526:                            .toCharArray();
527:                    int prologLen = 0;
528:                    if (prolog[0] == '<' && prolog[1] == '?'
529:                            && prolog[2] == 'x') {
530:                        for (int i = 3; i < maxPrologLen; i++) {
531:                            if (prolog[i] == '?' && prolog[i + 1] == '>') {
532:                                prologLen = i + 1;
533:                                break;
534:                            }
535:                        }
536:                    }
537:
538:                    final int passPrologLen = prologLen;
539:                    Runnable edit = new Runnable() {
540:                        public void run() {
541:                            try {
542:                                doc.remove(0, passPrologLen + 1);
543:                                doc.insertString(0,
544:                                        "<?xml version='1.0' encoding='UTF-8' ?>\n<!-- was: "
545:                                                + new String(prolog, 0,
546:                                                        passPrologLen + 1)
547:                                                + " -->", null); // NOI18N
548:                            } catch (BadLocationException ble) {
549:                                if (System
550:                                        .getProperty("netbeans.debug.exceptions") != null) // NOI18N
551:                                    ble.printStackTrace();
552:                            }
553:                        }
554:                    };
555:                    NbDocument.runAtomic(doc, edit);
556:
557:                    super .saveDocument();
558:                    getDataObject().setModified(false);
559:
560:                } catch (BadLocationException lex) {
561:                    ErrorManager.getDefault().notify(lex);
562:                }
563:            }
564:
565:            /**
566:             * Validate the selected encoding to determine if it is usuable or not.
567:             * If there is a problem, prompt the user to confirm the encoding.
568:             *
569:             * @param  encoding  the character set encoding to validate.
570:             * @return  true if encoding can be used, false otherwise.
571:             */
572:            private boolean checkCharsetConversion(String encoding) {
573:                boolean value = true;
574:                try {
575:                    java.nio.charset.CharsetEncoder coder = java.nio.charset.Charset
576:                            .forName(encoding).newEncoder();
577:                    if (!coder.canEncode(getDocument().getText(0,
578:                            getDocument().getLength()))) {
579:                        Object[] margs = new Object[] {
580:                                getDataObject().getPrimaryFile().getNameExt(),
581:                                encoding };
582:                        String msg = NbBundle.getMessage(
583:                                SchemaEditorSupport.class,
584:                                "MSG_SchemaEditorSupport_BadCharConversion",
585:                                margs);
586:                        NotifyDescriptor nd = new NotifyDescriptor.Confirmation(
587:                                msg, NotifyDescriptor.YES_NO_OPTION,
588:                                NotifyDescriptor.WARNING_MESSAGE);
589:                        nd.setValue(NotifyDescriptor.NO_OPTION);
590:                        DialogDisplayer.getDefault().notify(nd);
591:                        if (nd.getValue() != NotifyDescriptor.YES_OPTION) {
592:                            value = false;
593:                        }
594:                    }
595:                } catch (BadLocationException ble) {
596:                    ErrorManager.getDefault().notify(
597:                            ErrorManager.INFORMATIONAL, ble);
598:                }
599:                return value;
600:            }
601:
602:            /**
603:             * Have the schema model sync with the document.
604:             */
605:            public void syncModel() {
606:                try {
607:                    SchemaModel model = getModel();
608:                    if (model != null) {
609:                        model.sync();
610:                    }
611:                } catch (IOException ioe) {
612:                    // The document cannot be parsed, ignore this error.
613:                }
614:            }
615:
616:            public Task prepareDocument() {
617:                Task task = super .prepareDocument();
618:                // Avoid listening to the same task more than once.
619:                if (task != prepareTask2) {
620:                    prepareTask2 = task;
621:                    task.addTaskListener(new TaskListener() {
622:                        public void taskFinished(Task task) {
623:                            QuietUndoManager undo = getUndoManager();
624:                            StyledDocument doc = getDocument();
625:                            if (doc == null)
626:                                return;
627:                            synchronized (undo) {
628:                                // Now that the document is ready, pass it to the manager.
629:                                undo.setDocument((AbstractDocument) doc);
630:                                if (!undo.isCompound()) {
631:                                    // The superclass prepareDocument() adds the undo/redo
632:                                    // manager as a listener -- we need to remove it since
633:                                    // we will initially listen to the model instead.
634:                                    doc.removeUndoableEditListener(undo);
635:                                    // If not listening to document, then listen to model.
636:                                    addUndoManagerToModel(undo);
637:                                }
638:                            }
639:                            prepareTask2 = null;
640:                        }
641:                    });
642:                }
643:                return task;
644:            }
645:
646:            public Task reloadDocument() {
647:                Task task = super .reloadDocument();
648:                task.addTaskListener(new TaskListener() {
649:                    public void taskFinished(Task task) {
650:                        EventQueue.invokeLater(new Runnable() {
651:                            public void run() {
652:                                QuietUndoManager undo = getUndoManager();
653:                                StyledDocument doc = getDocument();
654:                                // The superclass reloadDocument() adds the undo
655:                                // manager as an undoable edit listener.
656:                                synchronized (undo) {
657:                                    if (!undo.isCompound()) {
658:                                        doc.removeUndoableEditListener(undo);
659:                                    }
660:                                }
661:                            }
662:                        });
663:                    }
664:                });
665:                return task;
666:            }
667:
668:            protected void notifyClosed() {
669:                // Stop listening to the undoable edit sources when we are closed.
670:                QuietUndoManager undo = getUndoManager();
671:                StyledDocument doc = getDocument();
672:                synchronized (undo) {
673:                    // May be null when closing the editor.
674:                    if (doc != null) {
675:                        doc.removeUndoableEditListener(undo);
676:                        undo.endCompound();
677:                        undo.setDocument(null);
678:                    }
679:                    try {
680:                        SchemaModel model = getModel();
681:                        if (model != null) {
682:                            model.removeUndoableEditListener(undo);
683:                            AXIModel aModel = AXIModelFactory.getDefault()
684:                                    .getModel(model);
685:                            undo.removeWrapperModel(aModel);
686:                        }
687:                        // Must unset the model when no longer listening to it.
688:                        undo.setModel(null);
689:                    } catch (IOException ioe) {
690:                        // Model is gone, but just removing the listener is not
691:                        // going to matter anyway.
692:                    }
693:                }
694:                this .model = null;
695:                super .notifyClosed();
696:            }
697:
698:            /*
699:             * Update presence of SaveCookie on first keystroke.
700:             */
701:            protected boolean notifyModified() {
702:                boolean notify = super .notifyModified();
703:                if (!notify) {
704:                    return false;
705:                }
706:                SchemaDataObject obj = (SchemaDataObject) getDataObject();
707:                if (obj.getCookie(SaveCookie.class) == null) {
708:                    obj.addSaveCookie(new SaveCookie() {
709:                        public void save() throws java.io.IOException {
710:                            try {
711:                                saveDocument();
712:                            } catch (UserCancelException e) {
713:                                //just ignore
714:                            }
715:                        }
716:                    });
717:                }
718:                return true;
719:            }
720:
721:            /**
722:             * Env class extends SchemaEditorSupport.Env.
723:             * overrides findSchemaEditorSupport
724:             *
725:             */
726:            protected static class SchemaEditorEnv extends
727:                    DataEditorSupport.Env {
728:
729:                static final long serialVersionUID = 1099957785497677206L;
730:
731:                public SchemaEditorEnv(SchemaDataObject obj) {
732:                    super (obj);
733:                }
734:
735:                public CloneableEditorSupport findTextEditorSupport() {
736:                    return getSchemaDataObject().getSchemaEditorSupport();
737:                }
738:
739:                public SchemaDataObject getSchemaDataObject() {
740:                    return (SchemaDataObject) getDataObject();
741:                }
742:
743:                protected FileObject getFile() {
744:                    return getDataObject().getPrimaryFile();
745:                }
746:
747:                protected FileLock takeLock() throws IOException {
748:                    return getDataObject().getPrimaryFile().lock();
749:                }
750:            }
751:
752:            /**
753:             * Implementation of CloseOperationHandler for multiview. Ensures the
754:             * editors correctly closed, data object is saved, etc. Holds a
755:             * reference to DataObject only - to be serializable with the multiview
756:             * TopComponent without problems.
757:             */
758:            public static class CloseHandler implements  CloseOperationHandler,
759:                    Serializable {
760:                private static final long serialVersionUID = -3838395157610633251L;
761:                private DataObject dataObject;
762:
763:                private CloseHandler() {
764:                    super ();
765:                }
766:
767:                public CloseHandler(DataObject schemaDO) {
768:                    dataObject = schemaDO;
769:                }
770:
771:                private SchemaEditorSupport getSchemaEditorSupport() {
772:                    return dataObject == null ? null : dataObject
773:                            .getCookie(SchemaEditorSupport.class);
774:                }
775:
776:                public boolean resolveCloseOperation(
777:                        CloseOperationState[] elements) {
778:                    SchemaEditorSupport schemaEditor = getSchemaEditorSupport();
779:                    boolean canClose = schemaEditor != null ? schemaEditor
780:                            .canClose() : true;
781:                    // during the shutdown sequence this is called twice. The first time
782:                    // through the multi-view infrastructure. The second time is done through
783:                    // the TopComponent close. If the file is dirty and the user chooses
784:                    // to discard changes, the second time will also ask whether the
785:                    // to save or discard changes.
786:                    if (canClose) {
787:                        dataObject.setModified(false);
788:                    }
789:                    return canClose;
790:                }
791:            }
792:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.