Source Code Cross Referenced for DocumentParseSupport.java in  » IDE-Netbeans » performance » threaddemo » util » 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 » performance » threaddemo.util 
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-2006 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 threaddemo.util;
043:
044:        import java.beans.PropertyChangeEvent;
045:        import java.beans.PropertyChangeListener;
046:        import java.io.IOException;
047:        import java.util.ArrayList;
048:        import java.util.List;
049:        import java.util.logging.Logger;
050:        import javax.swing.event.DocumentEvent;
051:        import javax.swing.event.DocumentListener;
052:        import javax.swing.text.StyledDocument;
053:        import org.openide.ErrorManager;
054:        import org.openide.cookies.EditorCookie;
055:        import org.openide.text.NbDocument;
056:        import threaddemo.locking.RWLock;
057:        import threaddemo.locking.LockAction;
058:
059:        // XXX helper methods to parse/rewrite an entire document atomically using Reader/Writer
060:
061:        /**
062:         * Supports two-way parsing of an arbitrary model from a text document and
063:         * writing to the text document from the model.
064:         * <p>The underlying model is a text document. The deltas to the underlying model
065:         * in this implementation are document text changes or reload events, though that
066:         * fact should not matter to subclasses. The derived model must be defined by the
067:         * subclass.
068:         * @author Jesse Glick
069:         */
070:        public abstract class DocumentParseSupport<DM, DMD> extends
071:                TwoWaySupport<DM, DocumentParseSupportDelta, DMD> {
072:
073:            private static final Logger logger = Logger
074:                    .getLogger(DocumentParseSupport.class.getName());
075:
076:            private final EditorCookie.Observable edit;
077:
078:            /** document loaded; may be null initially */
079:            private StyledDocument document = null;
080:            private int listenerCount = 0; // for assertions only
081:            private int cookieListenerCount = 0; // for assertions only
082:            private final Listener listener;
083:
084:            /**
085:             * Create a support based on an editor cookie and lock.
086:             * @param edit the container for the document containing some parsable data
087:             * @param lock a lock
088:             */
089:            protected DocumentParseSupport(EditorCookie.Observable edit,
090:                    RWLock lock) {
091:                super (lock);
092:                this .edit = edit;
093:                listener = new Listener();
094:                edit.addPropertyChangeListener(listener);
095:                cookieListenerCount++;
096:            }
097:
098:            /**
099:             * In this implementation, deltas are either {@link PropertyChangeEvent}s
100:             * of {@link org.openide.cookies.EditorCookie.Observable#PROP_DOCUMENT} indicating that the whole
101:             * document changed (was reloaded, for example), or lists of {@link DocumentEvent}s.
102:             */
103:            protected final DocumentParseSupportDelta composeUnderlyingDeltas(
104:                    DocumentParseSupportDelta underlyingDelta1,
105:                    DocumentParseSupportDelta underlyingDelta2) {
106:                if (underlyingDelta1.changeEvent != null) {
107:                    // PROP_DOCUMENT that is. Need to recreate the whole thing generally.
108:                    return underlyingDelta1;
109:                } else if (underlyingDelta2.changeEvent != null) {
110:                    // Ditto.
111:                    return underlyingDelta2;
112:                } else {
113:                    // Append changes.
114:                    underlyingDelta1.documentEvents
115:                            .addAll(underlyingDelta2.documentEvents);
116:                    return underlyingDelta1;
117:                }
118:            }
119:
120:            /**
121:             * In this implementation, prepares the document so that it will soon be loaded,
122:             * if it is not already.
123:             */
124:            protected final void initiating() {
125:                if (requiresUnmodifiedDocument()) {
126:                    edit.prepareDocument();
127:                    logger.finer("initiating...");
128:                }
129:            }
130:
131:            /**
132:             * Make sure the correct document is open, and that the correct listeners
133:             * are attached to it and not its predecessor.
134:             * @param requireDocument if true, force a document to be loaded; if false,
135:             *                        permit {@link #document} to remain null, but refresh
136:             *                        it with a newer document if it has in fact changed
137:             */
138:            private void refreshDocument(boolean requireDocument)
139:                    throws IOException {
140:                logger.finer("rD begin");
141:                StyledDocument oldDocument = document;
142:                edit.removePropertyChangeListener(listener);
143:                assert --cookieListenerCount == 0;
144:                try {
145:                    //new Exception("will call " + (requireDocument ? "openDocument" : "getDocument") + " on " + this).printStackTrace();
146:                    document = requireDocument ? edit.openDocument()
147:                            : (document != null ? edit.getDocument() : null);
148:                    //new Exception("called " + (requireDocument ? "openDocument" : "getDocument") + " on " + this).printStackTrace();
149:                } finally {
150:                    edit.addPropertyChangeListener(listener);
151:                    assert ++cookieListenerCount == 1;
152:                }
153:                assert !requireDocument || document != null;
154:                if (document != oldDocument) {
155:                    if (oldDocument != null) {
156:                        oldDocument.removeDocumentListener(listener);
157:                        assert --listenerCount == 0;
158:                    }
159:                    if (document != null) {
160:                        document.addDocumentListener(listener);
161:                        assert ++listenerCount == 1 : listenerCount;
162:                    }
163:                }
164:                logger.finer("rD end");
165:            }
166:
167:            /**
168:             * Parse the document.
169:             * Calls {@link #doDerive(StyledDocument, List, Object)}.
170:             */
171:            protected final DerivationResult<DM, DMD> doDerive(
172:                    final DM oldValue,
173:                    final DocumentParseSupportDelta underlyingDelta)
174:                    throws Exception {
175:                if (document == null) {
176:                    refreshDocument(requiresUnmodifiedDocument());
177:                }
178:                final List<DerivationResult<DM, DMD>> val = new ArrayList<DerivationResult<DM, DMD>>(
179:                        1);
180:                final Exception[] exc = new Exception[1];
181:                Runnable r = new Runnable() {
182:                    public void run() {
183:                        try {
184:                            val
185:                                    .add(doDerive(
186:                                            document,
187:                                            underlyingDelta != null ? underlyingDelta.documentEvents
188:                                                    : null, oldValue));
189:                        } catch (Exception e) {
190:                            exc[0] = e;
191:                        }
192:                    }
193:                };
194:                if (document != null) {
195:                    document.render(r);
196:                } else {
197:                    r.run();
198:                }
199:                if (exc[0] != null) {
200:                    throw exc[0];
201:                }
202:                return val.get(0);
203:            }
204:
205:            /**
206:             * Declare whether the support always requires a document object, even to
207:             * parse an unmodified file.
208:             * <p>If true, {@link #doDerive(StyledDocument,List,Object)} is always given a
209:             * document; if the editor support had never been opened at all, it is
210:             * nonetheless opened (invisibly) just to provide this document to parse.
211:             * <p>If false, {@link #doDerive(StyledDocument,List,Object)} may be passed null for
212:             * its <code>document</code> parameter, meaning that the editor support has
213:             * not yet loaded a document. In this case the support is expected to run the
214:             * parse from the editor cookie's underlying storage, e.g. a file. This style
215:             * is potentially much more efficient when performing model reads from a large
216:             * number of (unmodified) files.
217:             * <p>Recreation always uses an open document regardless of this choice.
218:             * <p>The default value is true, i.e. always open the document for parsing.
219:             * @return true to always parse from a real document, or false to permit faster
220:             *         parses from underlying storage
221:             * @see EditorCookie#getDocument
222:             * @see EditorCookie#openDocument
223:             */
224:            protected boolean requiresUnmodifiedDocument() {
225:                return true;
226:            }
227:
228:            /**
229:             * Create the derived model from a text document.
230:             * Called with the read lock and with read access to the document.
231:             * @param document the text document to parse, or may be null if
232:             *                 {@link #requiresUnmodifiedDocument} if false
233:             * @param documentEvents a list of {@link DocumentEvent} that happened since
234:             *                       the last parse, or null if unknown (do a full reparse)
235:             * @param oldValue the last derived model value, or null
236:             * @return the new derived model value plus the change made to it
237:             * @throws Exception (checked) in case of parsing problems
238:             */
239:            protected abstract DerivationResult<DM, DMD> doDerive(
240:                    StyledDocument document,
241:                    List<DocumentEvent> documentEvents, DM oldValue)
242:                    throws Exception;
243:
244:            /**
245:             * Regenerates the document.
246:             * Calls {@link #doRecreate(StyledDocument, Object, Object)}.
247:             */
248:            protected final DM doRecreate(final DM oldValue,
249:                    final DMD derivedDelta) throws Exception {
250:                if (document == null) {
251:                    refreshDocument(true);
252:                }
253:                final List<DM> val = new ArrayList<DM>(1);
254:                final Exception[] exc = new Exception[1];
255:                Runnable r = new Runnable() {
256:                    public void run() {
257:                        document.removeDocumentListener(listener);
258:                        assert --listenerCount == 0;
259:                        try {
260:                            val
261:                                    .add(doRecreate(document, oldValue,
262:                                            derivedDelta));
263:                        } catch (Exception e) {
264:                            exc[0] = e;
265:                        } finally {
266:                            document.addDocumentListener(listener);
267:                            assert ++listenerCount == 1;
268:                        }
269:                    }
270:                };
271:                if (runAsUser(derivedDelta)) {
272:                    NbDocument.runAtomicAsUser(document, r);
273:                } else {
274:                    NbDocument.runAtomic(document, r);
275:                }
276:                if (exc[0] != null) {
277:                    throw exc[0];
278:                }
279:                return val.get(0);
280:            }
281:
282:            /**
283:             * Decide whether the given change to the derived model must occur in "user"
284:             * mode, that is, be prevented from modifying guard blocks.
285:             * The default implementation always returns false.
286:             * @return true to run using {@link NbDocument#runAtomicAsUser}, false for
287:             *              {@link NbDocument#runAtomic}
288:             */
289:            protected boolean runAsUser(Object derivedDelta) {
290:                return false;
291:            }
292:
293:            /**
294:             * Update the text document to reflect changes in the derived model.
295:             * Called with the write lock and holding a document lock if possible.
296:             * @param document the document to modify
297:             * @param oldValue the old derived model, if any
298:             * @param derivedDelta the change to the derived model
299:             * @return the new derived model
300:             * @see org.openide.text.NbDocument.WriteLockable
301:             */
302:            protected abstract DM doRecreate(StyledDocument document,
303:                    DM oldValue, DMD derivedDelta) throws Exception;
304:
305:            /**
306:             * Listens to changes in identity or content of the text document.
307:             */
308:            private final class Listener implements  DocumentListener,
309:                    PropertyChangeListener {
310:
311:                // XXX getting >1 i/rU for one change?
312:
313:                public void insertUpdate(DocumentEvent e) {
314:                    logger.finer("DPS.iU");
315:                    documentUpdate(e);
316:                }
317:
318:                public void removeUpdate(DocumentEvent e) {
319:                    logger.finer("DPS.rU");
320:                    documentUpdate(e);
321:                }
322:
323:                private void documentUpdate(DocumentEvent e) {
324:                    final List<DocumentEvent> l = new ArrayList<DocumentEvent>(
325:                            1);
326:                    l.add(e);
327:                    getLock().read(new LockAction<Void>() {
328:                        public Void run() {
329:                            invalidate(new DocumentParseSupportDelta(l));
330:                            return null;
331:                        }
332:                    });
333:                }
334:
335:                public void changedUpdate(DocumentEvent e) {
336:                    // attr change - ignore
337:                }
338:
339:                public void propertyChange(final PropertyChangeEvent evt) {
340:                    if (evt.getPropertyName().equals(
341:                            EditorCookie.Observable.PROP_DOCUMENT)) {
342:                        logger.finer("DPS.pC<PROP_DOCUMENT>");
343:                        //new Exception("got PROP_DOCUMENT on " + DocumentParseSupport.this).printStackTrace();
344:                        try {
345:                            refreshDocument(true);
346:                        } catch (IOException e) {
347:                            ErrorManager.getDefault().notify(
348:                                    ErrorManager.INFORMATIONAL, e);
349:                        }
350:                        // Avoid blocking: because CES fires
351:                        // PROP_DOCUMENT from within a RP task, and we may already be locking
352:                        // the EQ with CES.open or .openDocument.
353:                        getLock().readLater(new Runnable() {
354:                            public void run() {
355:                                invalidate(new DocumentParseSupportDelta(evt));
356:                            }
357:                        });
358:                    }
359:                }
360:
361:            }
362:
363:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.