Source Code Cross Referenced for AbstractDocument.java in  » IDE-Eclipse » text » org » eclipse » jface » text » 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 Eclipse » text » org.eclipse.jface.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jface.text;
0011:
0012:        import java.util.ArrayList;
0013:        import java.util.Arrays;
0014:        import java.util.HashMap;
0015:        import java.util.Iterator;
0016:        import java.util.List;
0017:        import java.util.Map;
0018:        import java.util.regex.PatternSyntaxException;
0019:
0020:        import org.eclipse.core.runtime.Assert;
0021:        import org.eclipse.core.runtime.ListenerList;
0022:
0023:        /**
0024:         * Abstract default implementation of <code>IDocument</code> and its extension
0025:         * interfaces {@link org.eclipse.jface.text.IDocumentExtension},
0026:         * {@link org.eclipse.jface.text.IDocumentExtension2},
0027:         * {@link org.eclipse.jface.text.IDocumentExtension3},
0028:         * {@link org.eclipse.jface.text.IDocumentExtension4}, as well as
0029:         * {@link org.eclipse.jface.text.IRepairableDocument}.
0030:         * <p>
0031:         *
0032:         * An <code>AbstractDocument</code> supports the following implementation
0033:         * plug-ins:
0034:         * <ul>
0035:         * <li>a text store implementing {@link org.eclipse.jface.text.ITextStore} for
0036:         *     storing and managing the document's content,</li>
0037:         * <li>a line tracker implementing {@link org.eclipse.jface.text.ILineTracker}
0038:         *     to map character positions to line numbers and vice versa</li>
0039:         * </ul>
0040:         * The document can dynamically change the text store when switching between
0041:         * sequential rewrite mode and normal mode.
0042:         * <p>
0043:         *
0044:         * This class must be subclassed. Subclasses must configure which implementation
0045:         * plug-ins the document instance should use. Subclasses are not intended to
0046:         * overwrite existing methods.
0047:         *
0048:         * @see org.eclipse.jface.text.ITextStore
0049:         * @see org.eclipse.jface.text.ILineTracker
0050:         */
0051:        public abstract class AbstractDocument implements  IDocument,
0052:                IDocumentExtension, IDocumentExtension2, IDocumentExtension3,
0053:                IDocumentExtension4, IRepairableDocument {
0054:
0055:            /**
0056:             * Tells whether this class is in debug mode.
0057:             * @since 3.1
0058:             */
0059:            private static final boolean DEBUG = false;
0060:
0061:            /**
0062:             * Inner class to bundle a registered post notification replace operation together with its
0063:             * owner.
0064:             *
0065:             * @since 2.0
0066:             */
0067:            static private class RegisteredReplace {
0068:                /** The owner of this replace operation. */
0069:                IDocumentListener fOwner;
0070:                /** The replace operation */
0071:                IDocumentExtension.IReplace fReplace;
0072:
0073:                /**
0074:                 * Creates a new bundle object.
0075:                 * @param owner the document listener owning the replace operation
0076:                 * @param replace the replace operation
0077:                 */
0078:                RegisteredReplace(IDocumentListener owner,
0079:                        IDocumentExtension.IReplace replace) {
0080:                    fOwner = owner;
0081:                    fReplace = replace;
0082:                }
0083:            }
0084:
0085:            /** The document's text store */
0086:            private ITextStore fStore;
0087:            /** The document's line tracker */
0088:            private ILineTracker fTracker;
0089:            /** The registered document listeners */
0090:            private ListenerList fDocumentListeners;
0091:            /** The registered pre-notified document listeners */
0092:            private ListenerList fPrenotifiedDocumentListeners;
0093:            /** The registered document partitioning listeners */
0094:            private ListenerList fDocumentPartitioningListeners;
0095:            /** All positions managed by the document */
0096:            private Map fPositions;
0097:            /** All registered document position updaters */
0098:            private List fPositionUpdaters;
0099:            /**
0100:             * The list of post notification changes
0101:             * @since 2.0
0102:             */
0103:            private List fPostNotificationChanges;
0104:            /**
0105:             * The reentrance count for post notification changes.
0106:             * @since 2.0
0107:             */
0108:            private int fReentranceCount = 0;
0109:            /**
0110:             * Indicates whether post notification change processing has been stopped.
0111:             * @since 2.0
0112:             */
0113:            private int fStoppedCount = 0;
0114:            /**
0115:             * Indicates whether the registration of post notification changes should be ignored.
0116:             * @since 2.1
0117:             */
0118:            private boolean fAcceptPostNotificationReplaces = true;
0119:            /**
0120:             * Indicates whether the notification of listeners has been stopped.
0121:             * @since 2.1
0122:             */
0123:            private int fStoppedListenerNotification = 0;
0124:            /**
0125:             * The document event to be sent after listener notification has been resumed.
0126:             * @since 2.1
0127:             */
0128:            private DocumentEvent fDeferredDocumentEvent;
0129:            /**
0130:             * The registered document partitioners.
0131:             * @since 3.0
0132:             */
0133:            private Map fDocumentPartitioners;
0134:            /**
0135:             * The partitioning changed event.
0136:             * @since 3.0
0137:             */
0138:            private DocumentPartitioningChangedEvent fDocumentPartitioningChangedEvent;
0139:            /**
0140:             * The find/replace document adapter.
0141:             * @since 3.0
0142:             */
0143:            private FindReplaceDocumentAdapter fFindReplaceDocumentAdapter;
0144:            /**
0145:             * The active document rewrite session.
0146:             * @since 3.1
0147:             */
0148:            private DocumentRewriteSession fDocumentRewriteSession;
0149:            /**
0150:             * The registered document rewrite session listeners.
0151:             * @since 3.1
0152:             */
0153:            private List fDocumentRewriteSessionListeners;
0154:            /**
0155:             * The current modification stamp.
0156:             * @since 3.1
0157:             */
0158:            private long fModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
0159:            /**
0160:             * Keeps track of next modification stamp.
0161:             * @since 3.1.1
0162:             */
0163:            private long fNextModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
0164:            /**
0165:             * This document's default line delimiter.
0166:             * @since 3.1
0167:             */
0168:            private String fInitialLineDelimiter;
0169:
0170:            /**
0171:             * The default constructor does not perform any configuration
0172:             * but leaves it to the clients who must first initialize the
0173:             * implementation plug-ins and then call <code>completeInitialization</code>.
0174:             * Results in the construction of an empty document.
0175:             */
0176:            protected AbstractDocument() {
0177:                fModificationStamp = getNextModificationStamp();
0178:            }
0179:
0180:            /**
0181:             * Returns the document's text store. Assumes that the
0182:             * document has been initialized with a text store.
0183:             *
0184:             * @return the document's text store
0185:             */
0186:            protected ITextStore getStore() {
0187:                Assert.isNotNull(fStore);
0188:                return fStore;
0189:            }
0190:
0191:            /**
0192:             * Returns the document's line tracker. Assumes that the
0193:             * document has been initialized with a line tracker.
0194:             *
0195:             * @return the document's line tracker
0196:             */
0197:            protected ILineTracker getTracker() {
0198:                Assert.isNotNull(fTracker);
0199:                return fTracker;
0200:            }
0201:
0202:            /**
0203:             * Returns the document's document listeners.
0204:             *
0205:             * @return the document's document listeners
0206:             */
0207:            protected List getDocumentListeners() {
0208:                return Arrays.asList(fDocumentListeners.getListeners());
0209:            }
0210:
0211:            /**
0212:             * Returns the document's partitioning listeners.
0213:             *
0214:             * @return the document's partitioning listeners
0215:             */
0216:            protected List getDocumentPartitioningListeners() {
0217:                return Arrays.asList(fDocumentPartitioningListeners
0218:                        .getListeners());
0219:            }
0220:
0221:            /**
0222:             * Returns all positions managed by the document grouped by category.
0223:             *
0224:             * @return the document's positions
0225:             */
0226:            protected Map getDocumentManagedPositions() {
0227:                return fPositions;
0228:            }
0229:
0230:            /*
0231:             * @see org.eclipse.jface.text.IDocument#getDocumentPartitioner()
0232:             */
0233:            public IDocumentPartitioner getDocumentPartitioner() {
0234:                return getDocumentPartitioner(DEFAULT_PARTITIONING);
0235:            }
0236:
0237:            //--- implementation configuration interface ------------
0238:
0239:            /**
0240:             * Sets the document's text store.
0241:             * Must be called at the beginning of the constructor.
0242:             *
0243:             * @param store the document's text store
0244:             */
0245:            protected void setTextStore(ITextStore store) {
0246:                fStore = store;
0247:            }
0248:
0249:            /**
0250:             * Sets the document's line tracker.
0251:             * Must be called at the beginning of the constructor.
0252:             *
0253:             * @param tracker the document's line tracker
0254:             */
0255:            protected void setLineTracker(ILineTracker tracker) {
0256:                fTracker = tracker;
0257:            }
0258:
0259:            /*
0260:             * @see org.eclipse.jface.text.IDocument#setDocumentPartitioner(org.eclipse.jface.text.IDocumentPartitioner)
0261:             */
0262:            public void setDocumentPartitioner(IDocumentPartitioner partitioner) {
0263:                setDocumentPartitioner(DEFAULT_PARTITIONING, partitioner);
0264:            }
0265:
0266:            /**
0267:             * Initializes document listeners, positions, and position updaters.
0268:             * Must be called inside the constructor after the implementation plug-ins
0269:             * have been set.
0270:             */
0271:            protected void completeInitialization() {
0272:
0273:                fPositions = new HashMap();
0274:                fPositionUpdaters = new ArrayList();
0275:                fDocumentListeners = new ListenerList();
0276:                fPrenotifiedDocumentListeners = new ListenerList();
0277:                fDocumentPartitioningListeners = new ListenerList();
0278:                fDocumentRewriteSessionListeners = new ArrayList();
0279:
0280:                addPositionCategory(DEFAULT_CATEGORY);
0281:                addPositionUpdater(new DefaultPositionUpdater(DEFAULT_CATEGORY));
0282:            }
0283:
0284:            //-------------------------------------------------------
0285:
0286:            /*
0287:             * @see org.eclipse.jface.text.IDocument#addDocumentListener(org.eclipse.jface.text.IDocumentListener)
0288:             */
0289:            public void addDocumentListener(IDocumentListener listener) {
0290:                Assert.isNotNull(listener);
0291:                fDocumentListeners.add(listener);
0292:            }
0293:
0294:            /*
0295:             * @see org.eclipse.jface.text.IDocument#removeDocumentListener(org.eclipse.jface.text.IDocumentListener)
0296:             */
0297:            public void removeDocumentListener(IDocumentListener listener) {
0298:                Assert.isNotNull(listener);
0299:                fDocumentListeners.remove(listener);
0300:            }
0301:
0302:            /*
0303:             * @see org.eclipse.jface.text.IDocument#addPrenotifiedDocumentListener(org.eclipse.jface.text.IDocumentListener)
0304:             */
0305:            public void addPrenotifiedDocumentListener(
0306:                    IDocumentListener listener) {
0307:                Assert.isNotNull(listener);
0308:                fPrenotifiedDocumentListeners.add(listener);
0309:            }
0310:
0311:            /*
0312:             * @see org.eclipse.jface.text.IDocument#removePrenotifiedDocumentListener(org.eclipse.jface.text.IDocumentListener)
0313:             */
0314:            public void removePrenotifiedDocumentListener(
0315:                    IDocumentListener listener) {
0316:                Assert.isNotNull(listener);
0317:                fPrenotifiedDocumentListeners.remove(listener);
0318:            }
0319:
0320:            /*
0321:             * @see org.eclipse.jface.text.IDocument#addDocumentPartitioningListener(org.eclipse.jface.text.IDocumentPartitioningListener)
0322:             */
0323:            public void addDocumentPartitioningListener(
0324:                    IDocumentPartitioningListener listener) {
0325:                Assert.isNotNull(listener);
0326:                fDocumentPartitioningListeners.add(listener);
0327:            }
0328:
0329:            /*
0330:             * @see org.eclipse.jface.text.IDocument#removeDocumentPartitioningListener(org.eclipse.jface.text.IDocumentPartitioningListener)
0331:             */
0332:            public void removeDocumentPartitioningListener(
0333:                    IDocumentPartitioningListener listener) {
0334:                Assert.isNotNull(listener);
0335:                fDocumentPartitioningListeners.remove(listener);
0336:            }
0337:
0338:            /*
0339:             * @see org.eclipse.jface.text.IDocument#addPosition(java.lang.String, org.eclipse.jface.text.Position)
0340:             */
0341:            public void addPosition(String category, Position position)
0342:                    throws BadLocationException, BadPositionCategoryException {
0343:
0344:                if ((0 > position.offset) || (0 > position.length)
0345:                        || (position.offset + position.length > getLength()))
0346:                    throw new BadLocationException();
0347:
0348:                if (category == null)
0349:                    throw new BadPositionCategoryException();
0350:
0351:                List list = (List) fPositions.get(category);
0352:                if (list == null)
0353:                    throw new BadPositionCategoryException();
0354:
0355:                list.add(computeIndexInPositionList(list, position.offset),
0356:                        position);
0357:            }
0358:
0359:            /*
0360:             * @see org.eclipse.jface.text.IDocument#addPosition(org.eclipse.jface.text.Position)
0361:             */
0362:            public void addPosition(Position position)
0363:                    throws BadLocationException {
0364:                try {
0365:                    addPosition(DEFAULT_CATEGORY, position);
0366:                } catch (BadPositionCategoryException e) {
0367:                }
0368:            }
0369:
0370:            /*
0371:             * @see org.eclipse.jface.text.IDocument#addPositionCategory(java.lang.String)
0372:             */
0373:            public void addPositionCategory(String category) {
0374:
0375:                if (category == null)
0376:                    return;
0377:
0378:                if (!containsPositionCategory(category))
0379:                    fPositions.put(category, new ArrayList());
0380:            }
0381:
0382:            /*
0383:             * @see org.eclipse.jface.text.IDocument#addPositionUpdater(org.eclipse.jface.text.IPositionUpdater)
0384:             */
0385:            public void addPositionUpdater(IPositionUpdater updater) {
0386:                insertPositionUpdater(updater, fPositionUpdaters.size());
0387:            }
0388:
0389:            /*
0390:             * @see org.eclipse.jface.text.IDocument#containsPosition(java.lang.String, int, int)
0391:             */
0392:            public boolean containsPosition(String category, int offset,
0393:                    int length) {
0394:
0395:                if (category == null)
0396:                    return false;
0397:
0398:                List list = (List) fPositions.get(category);
0399:                if (list == null)
0400:                    return false;
0401:
0402:                int size = list.size();
0403:                if (size == 0)
0404:                    return false;
0405:
0406:                int index = computeIndexInPositionList(list, offset);
0407:                if (index < size) {
0408:                    Position p = (Position) list.get(index);
0409:                    while (p != null && p.offset == offset) {
0410:                        if (p.length == length)
0411:                            return true;
0412:                        ++index;
0413:                        p = (index < size) ? (Position) list.get(index) : null;
0414:                    }
0415:                }
0416:
0417:                return false;
0418:            }
0419:
0420:            /*
0421:             * @see org.eclipse.jface.text.IDocument#containsPositionCategory(java.lang.String)
0422:             */
0423:            public boolean containsPositionCategory(String category) {
0424:                if (category != null)
0425:                    return fPositions.containsKey(category);
0426:                return false;
0427:            }
0428:
0429:            /**
0430:             * Computes the index in the list of positions at which a position with the given
0431:             * offset would be inserted. The position is supposed to become the first in this list
0432:             * of all positions with the same offset.
0433:             *
0434:             * @param positions the list in which the index is computed
0435:             * @param offset the offset for which the index is computed
0436:             * @return the computed index
0437:             *
0438:             * @see IDocument#computeIndexInCategory(String, int)
0439:             */
0440:            protected int computeIndexInPositionList(List positions, int offset) {
0441:
0442:                if (positions.size() == 0)
0443:                    return 0;
0444:
0445:                int left = 0;
0446:                int right = positions.size() - 1;
0447:                int mid = 0;
0448:                Position p = null;
0449:
0450:                while (left < right) {
0451:
0452:                    mid = (left + right) / 2;
0453:
0454:                    p = (Position) positions.get(mid);
0455:                    if (offset < p.getOffset()) {
0456:                        if (left == mid)
0457:                            right = left;
0458:                        else
0459:                            right = mid - 1;
0460:                    } else if (offset > p.getOffset()) {
0461:                        if (right == mid)
0462:                            left = right;
0463:                        else
0464:                            left = mid + 1;
0465:                    } else if (offset == p.getOffset()) {
0466:                        left = right = mid;
0467:                    }
0468:
0469:                }
0470:
0471:                int pos = left;
0472:                p = (Position) positions.get(pos);
0473:                if (offset > p.getOffset()) {
0474:                    // append to the end
0475:                    pos++;
0476:                } else {
0477:                    // entry will became the first of all entries with the same offset
0478:                    do {
0479:                        --pos;
0480:                        if (pos < 0)
0481:                            break;
0482:                        p = (Position) positions.get(pos);
0483:                    } while (offset == p.getOffset());
0484:                    ++pos;
0485:                }
0486:
0487:                Assert.isTrue(0 <= pos && pos <= positions.size());
0488:
0489:                return pos;
0490:            }
0491:
0492:            /*
0493:             * @see org.eclipse.jface.text.IDocument#computeIndexInCategory(java.lang.String, int)
0494:             */
0495:            public int computeIndexInCategory(String category, int offset)
0496:                    throws BadLocationException, BadPositionCategoryException {
0497:
0498:                if (0 > offset || offset > getLength())
0499:                    throw new BadLocationException();
0500:
0501:                List c = (List) fPositions.get(category);
0502:                if (c == null)
0503:                    throw new BadPositionCategoryException();
0504:
0505:                return computeIndexInPositionList(c, offset);
0506:            }
0507:
0508:            /**
0509:             * Fires the document partitioning changed notification to all registered
0510:             * document partitioning listeners. Uses a robust iterator.
0511:             *
0512:             * @deprecated as of 2.0. Use <code>fireDocumentPartitioningChanged(IRegion)</code> instead.
0513:             */
0514:            protected void fireDocumentPartitioningChanged() {
0515:                if (fDocumentPartitioningListeners == null)
0516:                    return;
0517:
0518:                Object[] listeners = fDocumentPartitioningListeners
0519:                        .getListeners();
0520:                for (int i = 0; i < listeners.length; i++)
0521:                    ((IDocumentPartitioningListener) listeners[i])
0522:                            .documentPartitioningChanged(this );
0523:            }
0524:
0525:            /**
0526:             * Fires the document partitioning changed notification to all registered
0527:             * document partitioning listeners. Uses a robust iterator.
0528:             *
0529:             * @param region the region in which partitioning has changed
0530:             *
0531:             * @see IDocumentPartitioningListenerExtension
0532:             * @since 2.0
0533:             * @deprecated as of 3.0. Use
0534:             *             <code>fireDocumentPartitioningChanged(DocumentPartitioningChangedEvent)</code>
0535:             *             instead.
0536:             */
0537:            protected void fireDocumentPartitioningChanged(IRegion region) {
0538:                if (fDocumentPartitioningListeners == null)
0539:                    return;
0540:
0541:                Object[] listeners = fDocumentPartitioningListeners
0542:                        .getListeners();
0543:                for (int i = 0; i < listeners.length; i++) {
0544:                    IDocumentPartitioningListener l = (IDocumentPartitioningListener) listeners[i];
0545:                    if (l instanceof  IDocumentPartitioningListenerExtension)
0546:                        ((IDocumentPartitioningListenerExtension) l)
0547:                                .documentPartitioningChanged(this , region);
0548:                    else
0549:                        l.documentPartitioningChanged(this );
0550:                }
0551:            }
0552:
0553:            /**
0554:             * Fires the document partitioning changed notification to all registered
0555:             * document partitioning listeners. Uses a robust iterator.
0556:             *
0557:             * @param event the document partitioning changed event
0558:             *
0559:             * @see IDocumentPartitioningListenerExtension2
0560:             * @since 3.0
0561:             */
0562:            protected void fireDocumentPartitioningChanged(
0563:                    DocumentPartitioningChangedEvent event) {
0564:                if (fDocumentPartitioningListeners == null)
0565:                    return;
0566:
0567:                Object[] listeners = fDocumentPartitioningListeners
0568:                        .getListeners();
0569:                for (int i = 0; i < listeners.length; i++) {
0570:                    IDocumentPartitioningListener l = (IDocumentPartitioningListener) listeners[i];
0571:                    if (l instanceof  IDocumentPartitioningListenerExtension2) {
0572:                        IDocumentPartitioningListenerExtension2 extension2 = (IDocumentPartitioningListenerExtension2) l;
0573:                        extension2.documentPartitioningChanged(event);
0574:                    } else if (l instanceof  IDocumentPartitioningListenerExtension) {
0575:                        IDocumentPartitioningListenerExtension extension = (IDocumentPartitioningListenerExtension) l;
0576:                        extension.documentPartitioningChanged(this , event
0577:                                .getCoverage());
0578:                    } else {
0579:                        l.documentPartitioningChanged(this );
0580:                    }
0581:                }
0582:            }
0583:
0584:            /**
0585:             * Fires the given document event to all registers document listeners informing them
0586:             * about the forthcoming document manipulation. Uses a robust iterator.
0587:             *
0588:             * @param event the event to be sent out
0589:             */
0590:            protected void fireDocumentAboutToBeChanged(DocumentEvent event) {
0591:
0592:                // IDocumentExtension
0593:                if (fReentranceCount == 0)
0594:                    flushPostNotificationChanges();
0595:
0596:                if (fDocumentPartitioners != null) {
0597:                    Iterator e = fDocumentPartitioners.values().iterator();
0598:                    while (e.hasNext()) {
0599:                        IDocumentPartitioner p = (IDocumentPartitioner) e
0600:                                .next();
0601:                        if (p instanceof  IDocumentPartitionerExtension3) {
0602:                            IDocumentPartitionerExtension3 extension = (IDocumentPartitionerExtension3) p;
0603:                            if (extension.getActiveRewriteSession() != null)
0604:                                continue;
0605:                        }
0606:                        p.documentAboutToBeChanged(event);
0607:                    }
0608:                }
0609:
0610:                Object[] listeners = fPrenotifiedDocumentListeners
0611:                        .getListeners();
0612:                for (int i = 0; i < listeners.length; i++)
0613:                    ((IDocumentListener) listeners[i])
0614:                            .documentAboutToBeChanged(event);
0615:
0616:                listeners = fDocumentListeners.getListeners();
0617:                for (int i = 0; i < listeners.length; i++)
0618:                    ((IDocumentListener) listeners[i])
0619:                            .documentAboutToBeChanged(event);
0620:            }
0621:
0622:            /**
0623:             * Updates document partitioning and document positions according to the
0624:             * specification given by the document event.
0625:             *
0626:             * @param event the document event describing the change to which structures must be adapted
0627:             */
0628:            protected void updateDocumentStructures(DocumentEvent event) {
0629:
0630:                if (fDocumentPartitioners != null) {
0631:                    fDocumentPartitioningChangedEvent = new DocumentPartitioningChangedEvent(
0632:                            this );
0633:                    Iterator e = fDocumentPartitioners.keySet().iterator();
0634:                    while (e.hasNext()) {
0635:                        String partitioning = (String) e.next();
0636:                        IDocumentPartitioner partitioner = (IDocumentPartitioner) fDocumentPartitioners
0637:                                .get(partitioning);
0638:
0639:                        if (partitioner instanceof  IDocumentPartitionerExtension3) {
0640:                            IDocumentPartitionerExtension3 extension = (IDocumentPartitionerExtension3) partitioner;
0641:                            if (extension.getActiveRewriteSession() != null)
0642:                                continue;
0643:                        }
0644:
0645:                        if (partitioner instanceof  IDocumentPartitionerExtension) {
0646:                            IDocumentPartitionerExtension extension = (IDocumentPartitionerExtension) partitioner;
0647:                            IRegion r = extension.documentChanged2(event);
0648:                            if (r != null)
0649:                                fDocumentPartitioningChangedEvent
0650:                                        .setPartitionChange(partitioning, r
0651:                                                .getOffset(), r.getLength());
0652:                        } else {
0653:                            if (partitioner.documentChanged(event))
0654:                                fDocumentPartitioningChangedEvent
0655:                                        .setPartitionChange(partitioning, 0,
0656:                                                event.getDocument().getLength());
0657:                        }
0658:                    }
0659:                }
0660:
0661:                if (fPositions.size() > 0)
0662:                    updatePositions(event);
0663:            }
0664:
0665:            /**
0666:             * Notifies all listeners about the given document change. Uses a robust
0667:             * iterator.
0668:             * <p>
0669:             * Executes all registered post notification replace operation.
0670:             *
0671:             * @param event the event to be sent out.
0672:             */
0673:            protected void doFireDocumentChanged(DocumentEvent event) {
0674:                boolean changed = fDocumentPartitioningChangedEvent != null
0675:                        && !fDocumentPartitioningChangedEvent.isEmpty();
0676:                IRegion change = changed ? fDocumentPartitioningChangedEvent
0677:                        .getCoverage() : null;
0678:                doFireDocumentChanged(event, changed, change);
0679:            }
0680:
0681:            /**
0682:             * Notifies all listeners about the given document change.
0683:             * Uses a robust iterator. <p>
0684:             * Executes all registered post notification replace operation.
0685:             *
0686:             * @param event the event to be sent out
0687:             * @param firePartitionChange <code>true</code> if a partition change notification should be sent
0688:             * @param partitionChange the region whose partitioning changed
0689:             * @since 2.0
0690:             * @deprecated as of 3.0. Use <code>doFireDocumentChanged2(DocumentEvent)</code> instead; this method will be removed.
0691:             */
0692:            protected void doFireDocumentChanged(DocumentEvent event,
0693:                    boolean firePartitionChange, IRegion partitionChange) {
0694:                doFireDocumentChanged2(event);
0695:            }
0696:
0697:            /**
0698:             * Notifies all listeners about the given document change. Uses a robust
0699:             * iterator.
0700:             * <p>
0701:             * Executes all registered post notification replace operation.
0702:             * <p>
0703:             * This method will be renamed to <code>doFireDocumentChanged</code>.
0704:             *
0705:             * @param event the event to be sent out
0706:             * @since 3.0
0707:             */
0708:            protected void doFireDocumentChanged2(DocumentEvent event) {
0709:
0710:                DocumentPartitioningChangedEvent p = fDocumentPartitioningChangedEvent;
0711:                fDocumentPartitioningChangedEvent = null;
0712:                if (p != null && !p.isEmpty())
0713:                    fireDocumentPartitioningChanged(p);
0714:
0715:                Object[] listeners = fPrenotifiedDocumentListeners
0716:                        .getListeners();
0717:                for (int i = 0; i < listeners.length; i++)
0718:                    ((IDocumentListener) listeners[i]).documentChanged(event);
0719:
0720:                listeners = fDocumentListeners.getListeners();
0721:                for (int i = 0; i < listeners.length; i++)
0722:                    ((IDocumentListener) listeners[i]).documentChanged(event);
0723:
0724:                // IDocumentExtension
0725:                ++fReentranceCount;
0726:                try {
0727:                    if (fReentranceCount == 1)
0728:                        executePostNotificationChanges();
0729:                } finally {
0730:                    --fReentranceCount;
0731:                }
0732:            }
0733:
0734:            /**
0735:             * Updates the internal document structures and informs all document listeners
0736:             * if listener notification has been enabled. Otherwise it remembers the event
0737:             * to be sent to the listeners on resume.
0738:             *
0739:             * @param event the document event to be sent out
0740:             */
0741:            protected void fireDocumentChanged(DocumentEvent event) {
0742:                updateDocumentStructures(event);
0743:
0744:                if (fStoppedListenerNotification == 0)
0745:                    doFireDocumentChanged(event);
0746:                else
0747:                    fDeferredDocumentEvent = event;
0748:            }
0749:
0750:            /*
0751:             * @see org.eclipse.jface.text.IDocument#getChar(int)
0752:             */
0753:            public char getChar(int pos) throws BadLocationException {
0754:                if ((0 > pos) || (pos >= getLength()))
0755:                    throw new BadLocationException();
0756:                return getStore().get(pos);
0757:            }
0758:
0759:            /*
0760:             * @see org.eclipse.jface.text.IDocument#getContentType(int)
0761:             */
0762:            public String getContentType(int offset)
0763:                    throws BadLocationException {
0764:                String contentType = null;
0765:                try {
0766:                    contentType = getContentType(DEFAULT_PARTITIONING, offset,
0767:                            false);
0768:                    Assert.isNotNull(contentType);
0769:                } catch (BadPartitioningException e) {
0770:                    Assert.isTrue(false);
0771:                }
0772:                return contentType;
0773:            }
0774:
0775:            /*
0776:             * @see org.eclipse.jface.text.IDocument#getLegalContentTypes()
0777:             */
0778:            public String[] getLegalContentTypes() {
0779:                String[] contentTypes = null;
0780:                try {
0781:                    contentTypes = getLegalContentTypes(DEFAULT_PARTITIONING);
0782:                    Assert.isNotNull(contentTypes);
0783:                } catch (BadPartitioningException e) {
0784:                    Assert.isTrue(false);
0785:                }
0786:                return contentTypes;
0787:            }
0788:
0789:            /*
0790:             * @see org.eclipse.jface.text.IDocument#getLength()
0791:             */
0792:            public int getLength() {
0793:                return getStore().getLength();
0794:            }
0795:
0796:            /*
0797:             * @see org.eclipse.jface.text.IDocument#getLineDelimiter(int)
0798:             */
0799:            public String getLineDelimiter(int line)
0800:                    throws BadLocationException {
0801:                return getTracker().getLineDelimiter(line);
0802:            }
0803:
0804:            /*
0805:             * @see org.eclipse.jface.text.IDocument#getLegalLineDelimiters()
0806:             */
0807:            public String[] getLegalLineDelimiters() {
0808:                return getTracker().getLegalLineDelimiters();
0809:            }
0810:
0811:            /*
0812:             * @see org.eclipse.jface.text.IDocumentExtension4#getDefaultLineDelimiter()
0813:             * @since 3.1
0814:             */
0815:            public String getDefaultLineDelimiter() {
0816:
0817:                String lineDelimiter = null;
0818:
0819:                try {
0820:                    lineDelimiter = getLineDelimiter(0);
0821:                } catch (BadLocationException x) {
0822:                }
0823:
0824:                if (lineDelimiter != null)
0825:                    return lineDelimiter;
0826:
0827:                if (fInitialLineDelimiter != null)
0828:                    return fInitialLineDelimiter;
0829:
0830:                String sysLineDelimiter = System.getProperty("line.separator"); //$NON-NLS-1$
0831:                String[] delimiters = getLegalLineDelimiters();
0832:                Assert.isTrue(delimiters.length > 0);
0833:                for (int i = 0; i < delimiters.length; i++) {
0834:                    if (delimiters[i].equals(sysLineDelimiter)) {
0835:                        lineDelimiter = sysLineDelimiter;
0836:                        break;
0837:                    }
0838:                }
0839:
0840:                if (lineDelimiter == null)
0841:                    lineDelimiter = delimiters[0];
0842:
0843:                return lineDelimiter;
0844:
0845:            }
0846:
0847:            /*
0848:             * @see org.eclipse.jface.text.IDocumentExtension4#setInitialLineDelimiter(java.lang.String)
0849:             * @since 3.1
0850:             */
0851:            public void setInitialLineDelimiter(String lineDelimiter) {
0852:                Assert.isNotNull(lineDelimiter);
0853:                fInitialLineDelimiter = lineDelimiter;
0854:            }
0855:
0856:            /*
0857:             * @see org.eclipse.jface.text.IDocument#getLineLength(int)
0858:             */
0859:            public int getLineLength(int line) throws BadLocationException {
0860:                return getTracker().getLineLength(line);
0861:            }
0862:
0863:            /*
0864:             * @see org.eclipse.jface.text.IDocument#getLineOfOffset(int)
0865:             */
0866:            public int getLineOfOffset(int pos) throws BadLocationException {
0867:                return getTracker().getLineNumberOfOffset(pos);
0868:            }
0869:
0870:            /*
0871:             * @see org.eclipse.jface.text.IDocument#getLineOffset(int)
0872:             */
0873:            public int getLineOffset(int line) throws BadLocationException {
0874:                return getTracker().getLineOffset(line);
0875:            }
0876:
0877:            /*
0878:             * @see org.eclipse.jface.text.IDocument#getLineInformation(int)
0879:             */
0880:            public IRegion getLineInformation(int line)
0881:                    throws BadLocationException {
0882:                return getTracker().getLineInformation(line);
0883:            }
0884:
0885:            /*
0886:             * @see org.eclipse.jface.text.IDocument#getLineInformationOfOffset(int)
0887:             */
0888:            public IRegion getLineInformationOfOffset(int offset)
0889:                    throws BadLocationException {
0890:                return getTracker().getLineInformationOfOffset(offset);
0891:            }
0892:
0893:            /*
0894:             * @see org.eclipse.jface.text.IDocument#getNumberOfLines()
0895:             */
0896:            public int getNumberOfLines() {
0897:                return getTracker().getNumberOfLines();
0898:            }
0899:
0900:            /*
0901:             * @see org.eclipse.jface.text.IDocument#getNumberOfLines(int, int)
0902:             */
0903:            public int getNumberOfLines(int offset, int length)
0904:                    throws BadLocationException {
0905:                return getTracker().getNumberOfLines(offset, length);
0906:            }
0907:
0908:            /*
0909:             * @see org.eclipse.jface.text.IDocument#computeNumberOfLines(java.lang.String)
0910:             */
0911:            public int computeNumberOfLines(String text) {
0912:                return getTracker().computeNumberOfLines(text);
0913:            }
0914:
0915:            /*
0916:             * @see org.eclipse.jface.text.IDocument#getPartition(int)
0917:             */
0918:            public ITypedRegion getPartition(int offset)
0919:                    throws BadLocationException {
0920:                ITypedRegion partition = null;
0921:                try {
0922:                    partition = getPartition(DEFAULT_PARTITIONING, offset,
0923:                            false);
0924:                    Assert.isNotNull(partition);
0925:                } catch (BadPartitioningException e) {
0926:                    Assert.isTrue(false);
0927:                }
0928:                return partition;
0929:            }
0930:
0931:            /*
0932:             * @see org.eclipse.jface.text.IDocument#computePartitioning(int, int)
0933:             */
0934:            public ITypedRegion[] computePartitioning(int offset, int length)
0935:                    throws BadLocationException {
0936:                ITypedRegion[] partitioning = null;
0937:                try {
0938:                    partitioning = computePartitioning(DEFAULT_PARTITIONING,
0939:                            offset, length, false);
0940:                    Assert.isNotNull(partitioning);
0941:                } catch (BadPartitioningException e) {
0942:                    Assert.isTrue(false);
0943:                }
0944:                return partitioning;
0945:            }
0946:
0947:            /*
0948:             * @see org.eclipse.jface.text.IDocument#getPositions(java.lang.String)
0949:             */
0950:            public Position[] getPositions(String category)
0951:                    throws BadPositionCategoryException {
0952:
0953:                if (category == null)
0954:                    throw new BadPositionCategoryException();
0955:
0956:                List c = (List) fPositions.get(category);
0957:                if (c == null)
0958:                    throw new BadPositionCategoryException();
0959:
0960:                Position[] positions = new Position[c.size()];
0961:                c.toArray(positions);
0962:                return positions;
0963:            }
0964:
0965:            /*
0966:             * @see org.eclipse.jface.text.IDocument#getPositionCategories()
0967:             */
0968:            public String[] getPositionCategories() {
0969:                String[] categories = new String[fPositions.size()];
0970:                Iterator keys = fPositions.keySet().iterator();
0971:                for (int i = 0; i < categories.length; i++)
0972:                    categories[i] = (String) keys.next();
0973:                return categories;
0974:            }
0975:
0976:            /*
0977:             * @see org.eclipse.jface.text.IDocument#getPositionUpdaters()
0978:             */
0979:            public IPositionUpdater[] getPositionUpdaters() {
0980:                IPositionUpdater[] updaters = new IPositionUpdater[fPositionUpdaters
0981:                        .size()];
0982:                fPositionUpdaters.toArray(updaters);
0983:                return updaters;
0984:            }
0985:
0986:            /*
0987:             * @see org.eclipse.jface.text.IDocument#get()
0988:             */
0989:            public String get() {
0990:                return getStore().get(0, getLength());
0991:            }
0992:
0993:            /*
0994:             * @see org.eclipse.jface.text.IDocument#get(int, int)
0995:             */
0996:            public String get(int pos, int length) throws BadLocationException {
0997:                int myLength = getLength();
0998:                if ((0 > pos) || (0 > length) || (pos + length > myLength))
0999:                    throw new BadLocationException();
1000:                return getStore().get(pos, length);
1001:            }
1002:
1003:            /*
1004:             * @see org.eclipse.jface.text.IDocument#insertPositionUpdater(org.eclipse.jface.text.IPositionUpdater, int)
1005:             */
1006:            public void insertPositionUpdater(IPositionUpdater updater,
1007:                    int index) {
1008:
1009:                for (int i = fPositionUpdaters.size() - 1; i >= 0; i--) {
1010:                    if (fPositionUpdaters.get(i) == updater)
1011:                        return;
1012:                }
1013:
1014:                if (index == fPositionUpdaters.size())
1015:                    fPositionUpdaters.add(updater);
1016:                else
1017:                    fPositionUpdaters.add(index, updater);
1018:            }
1019:
1020:            /*
1021:             * @see org.eclipse.jface.text.IDocument#removePosition(java.lang.String, org.eclipse.jface.text.Position)
1022:             */
1023:            public void removePosition(String category, Position position)
1024:                    throws BadPositionCategoryException {
1025:
1026:                if (position == null)
1027:                    return;
1028:
1029:                if (category == null)
1030:                    throw new BadPositionCategoryException();
1031:
1032:                List c = (List) fPositions.get(category);
1033:                if (c == null)
1034:                    throw new BadPositionCategoryException();
1035:
1036:                // remove based on identity not equality
1037:                int size = c.size();
1038:                for (int i = 0; i < size; i++) {
1039:                    if (position == c.get(i)) {
1040:                        c.remove(i);
1041:                        return;
1042:                    }
1043:                }
1044:            }
1045:
1046:            /*
1047:             * @see org.eclipse.jface.text.IDocument#removePosition(org.eclipse.jface.text.Position)
1048:             */
1049:            public void removePosition(Position position) {
1050:                try {
1051:                    removePosition(DEFAULT_CATEGORY, position);
1052:                } catch (BadPositionCategoryException e) {
1053:                }
1054:            }
1055:
1056:            /*
1057:             * @see org.eclipse.jface.text.IDocument#removePositionCategory(java.lang.String)
1058:             */
1059:            public void removePositionCategory(String category)
1060:                    throws BadPositionCategoryException {
1061:
1062:                if (category == null)
1063:                    return;
1064:
1065:                if (!containsPositionCategory(category))
1066:                    throw new BadPositionCategoryException();
1067:
1068:                fPositions.remove(category);
1069:            }
1070:
1071:            /*
1072:             * @see org.eclipse.jface.text.IDocument#removePositionUpdater(org.eclipse.jface.text.IPositionUpdater)
1073:             */
1074:            public void removePositionUpdater(IPositionUpdater updater) {
1075:                for (int i = fPositionUpdaters.size() - 1; i >= 0; i--) {
1076:                    if (fPositionUpdaters.get(i) == updater) {
1077:                        fPositionUpdaters.remove(i);
1078:                        return;
1079:                    }
1080:                }
1081:            }
1082:
1083:            private long getNextModificationStamp() {
1084:                if (fNextModificationStamp == Long.MAX_VALUE
1085:                        || fNextModificationStamp == IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP)
1086:                    fNextModificationStamp = 0;
1087:                else
1088:                    fNextModificationStamp = fNextModificationStamp + 1;
1089:
1090:                return fNextModificationStamp;
1091:            }
1092:
1093:            /*
1094:             * @see org.eclipse.jface.text.IDocumentExtension4#getModificationStamp()
1095:             * @since 3.1
1096:             */
1097:            public long getModificationStamp() {
1098:                return fModificationStamp;
1099:            }
1100:
1101:            /*
1102:             * @see org.eclipse.jface.text.IDocument#replace(int, int, java.lang.String)
1103:             * @since 3.1
1104:             */
1105:            public void replace(int pos, int length, String text,
1106:                    long modificationStamp) throws BadLocationException {
1107:                if ((0 > pos) || (0 > length) || (pos + length > getLength()))
1108:                    throw new BadLocationException();
1109:
1110:                DocumentEvent e = new DocumentEvent(this , pos, length, text);
1111:                fireDocumentAboutToBeChanged(e);
1112:
1113:                boolean mustRepairLineInformation = mustRepairLineInformation(
1114:                        pos, length, text);
1115:
1116:                getStore().replace(pos, length, text);
1117:
1118:                if (mustRepairLineInformation)
1119:                    repairLineInformation();
1120:                else
1121:                    getTracker().replace(pos, length, text);
1122:
1123:                fModificationStamp = modificationStamp;
1124:                fNextModificationStamp = Math.max(fModificationStamp,
1125:                        fNextModificationStamp);
1126:                e.fModificationStamp = fModificationStamp;
1127:
1128:                fireDocumentChanged(e);
1129:            }
1130:
1131:            /**
1132:             * Checks whether the line information needs to be repaired.
1133:             * 
1134:             * @param pos the start position to check
1135:             * @param length the length position to check
1136:             * @param text the substitution text to check
1137:             * @return <code>true</code> if the line information must be repaired
1138:             * @since 3.4
1139:             */
1140:            protected boolean mustRepairLineInformation(int pos, int length,
1141:                    String text) {
1142:                return false;
1143:            }
1144:
1145:            /*
1146:             * @see org.eclipse.jface.text.IDocument#replace(int, int, java.lang.String)
1147:             */
1148:            public void replace(int pos, int length, String text)
1149:                    throws BadLocationException {
1150:                if (length == 0 && (text == null || text.length() == 0))
1151:                    replace(pos, length, text, getModificationStamp());
1152:                else
1153:                    replace(pos, length, text, getNextModificationStamp());
1154:            }
1155:
1156:            /*
1157:             * @see org.eclipse.jface.text.IDocument#set(java.lang.String)
1158:             */
1159:            public void set(String text) {
1160:                set(text, getNextModificationStamp());
1161:            }
1162:
1163:            /*
1164:             * @see org.eclipse.jface.text.IDocument#set(java.lang.String, long)
1165:             */
1166:            public void set(String text, long modificationStamp) {
1167:                int length = getStore().getLength();
1168:
1169:                DocumentEvent e = new DocumentEvent(this , 0, length, text);
1170:                fireDocumentAboutToBeChanged(e);
1171:
1172:                getStore().set(text);
1173:                getTracker().set(text);
1174:
1175:                fModificationStamp = modificationStamp;
1176:                fNextModificationStamp = Math.max(fModificationStamp,
1177:                        fNextModificationStamp);
1178:                e.fModificationStamp = fModificationStamp;
1179:
1180:                fireDocumentChanged(e);
1181:            }
1182:
1183:            /**
1184:             * Updates all positions of all categories to the change described by the
1185:             * document event. All registered document updaters are called in the
1186:             * sequence they have been arranged. Uses a robust iterator.
1187:             *
1188:             * @param event the document event describing the change to which to adapt
1189:             *            the positions
1190:             */
1191:            protected void updatePositions(DocumentEvent event) {
1192:                List list = new ArrayList(fPositionUpdaters);
1193:                Iterator e = list.iterator();
1194:                while (e.hasNext()) {
1195:                    IPositionUpdater u = (IPositionUpdater) e.next();
1196:                    u.update(event);
1197:                }
1198:            }
1199:
1200:            /*
1201:             * @see org.eclipse.jface.text.IDocument#search(int, java.lang.String, boolean, boolean, boolean)
1202:             */
1203:            public int search(int startPosition, String findString,
1204:                    boolean forwardSearch, boolean caseSensitive,
1205:                    boolean wholeWord) throws BadLocationException {
1206:                try {
1207:                    IRegion region = getFindReplaceDocumentAdapter().find(
1208:                            startPosition, findString, forwardSearch,
1209:                            caseSensitive, wholeWord, false);
1210:                    return region == null ? -1 : region.getOffset();
1211:                } catch (IllegalStateException ex) {
1212:                    return -1;
1213:                } catch (PatternSyntaxException ex) {
1214:                    return -1;
1215:                }
1216:            }
1217:
1218:            /**
1219:             * Returns the find/replace adapter for this document.
1220:             *
1221:             * @return this document's find/replace document adapter
1222:             * @since 3.0
1223:             */
1224:            private FindReplaceDocumentAdapter getFindReplaceDocumentAdapter() {
1225:                if (fFindReplaceDocumentAdapter == null)
1226:                    fFindReplaceDocumentAdapter = new FindReplaceDocumentAdapter(
1227:                            this );
1228:
1229:                return fFindReplaceDocumentAdapter;
1230:            }
1231:
1232:            /**
1233:             * Flushes all registered post notification changes.
1234:             *
1235:             * @since 2.0
1236:             */
1237:            private void flushPostNotificationChanges() {
1238:                if (fPostNotificationChanges != null)
1239:                    fPostNotificationChanges.clear();
1240:            }
1241:
1242:            /**
1243:             * Executes all registered post notification changes. The process is
1244:             * repeated until no new post notification changes are added.
1245:             *
1246:             * @since 2.0
1247:             */
1248:            private void executePostNotificationChanges() {
1249:
1250:                if (fStoppedCount > 0)
1251:                    return;
1252:
1253:                while (fPostNotificationChanges != null) {
1254:                    List changes = fPostNotificationChanges;
1255:                    fPostNotificationChanges = null;
1256:
1257:                    Iterator e = changes.iterator();
1258:                    while (e.hasNext()) {
1259:                        RegisteredReplace replace = (RegisteredReplace) e
1260:                                .next();
1261:                        replace.fReplace.perform(this , replace.fOwner);
1262:                    }
1263:                }
1264:            }
1265:
1266:            /*
1267:             * @see org.eclipse.jface.text.IDocumentExtension2#acceptPostNotificationReplaces()
1268:             * @since 2.1
1269:             */
1270:            public void acceptPostNotificationReplaces() {
1271:                fAcceptPostNotificationReplaces = true;
1272:            }
1273:
1274:            /*
1275:             * @see org.eclipse.jface.text.IDocumentExtension2#ignorePostNotificationReplaces()
1276:             * @since 2.1
1277:             */
1278:            public void ignorePostNotificationReplaces() {
1279:                fAcceptPostNotificationReplaces = false;
1280:            }
1281:
1282:            /*
1283:             * @see org.eclipse.jface.text.IDocumentExtension#registerPostNotificationReplace(org.eclipse.jface.text.IDocumentListener, org.eclipse.jface.text.IDocumentExtension.IReplace)
1284:             * @since 2.0
1285:             */
1286:            public void registerPostNotificationReplace(
1287:                    IDocumentListener owner, IDocumentExtension.IReplace replace) {
1288:                if (fAcceptPostNotificationReplaces) {
1289:                    if (fPostNotificationChanges == null)
1290:                        fPostNotificationChanges = new ArrayList(1);
1291:                    fPostNotificationChanges.add(new RegisteredReplace(owner,
1292:                            replace));
1293:                }
1294:            }
1295:
1296:            /*
1297:             * @see org.eclipse.jface.text.IDocumentExtension#stopPostNotificationProcessing()
1298:             * @since 2.0
1299:             */
1300:            public void stopPostNotificationProcessing() {
1301:                ++fStoppedCount;
1302:            }
1303:
1304:            /*
1305:             * @see org.eclipse.jface.text.IDocumentExtension#resumePostNotificationProcessing()
1306:             * @since 2.0
1307:             */
1308:            public void resumePostNotificationProcessing() {
1309:                --fStoppedCount;
1310:                if (fStoppedCount == 0 && fReentranceCount == 0)
1311:                    executePostNotificationChanges();
1312:            }
1313:
1314:            /*
1315:             * @see org.eclipse.jface.text.IDocumentExtension#startSequentialRewrite(boolean)
1316:             * @since 2.0
1317:             */
1318:            public void startSequentialRewrite(boolean normalized) {
1319:            }
1320:
1321:            /*
1322:             * @see org.eclipse.jface.text.IDocumentExtension#stopSequentialRewrite()
1323:             * @since 2.0
1324:             */
1325:            public void stopSequentialRewrite() {
1326:            }
1327:
1328:            /*
1329:             * @see org.eclipse.jface.text.IDocumentExtension2#resumeListenerNotification()
1330:             * @since 2.1
1331:             */
1332:            public void resumeListenerNotification() {
1333:                --fStoppedListenerNotification;
1334:                if (fStoppedListenerNotification == 0) {
1335:                    resumeDocumentListenerNotification();
1336:                }
1337:            }
1338:
1339:            /*
1340:             * @see org.eclipse.jface.text.IDocumentExtension2#stopListenerNotification()
1341:             * @since 2.1
1342:             */
1343:            public void stopListenerNotification() {
1344:                ++fStoppedListenerNotification;
1345:            }
1346:
1347:            /**
1348:             * Resumes the document listener notification by sending out the remembered
1349:             * partition changed and document event.
1350:             *
1351:             * @since 2.1
1352:             */
1353:            private void resumeDocumentListenerNotification() {
1354:                if (fDeferredDocumentEvent != null) {
1355:                    DocumentEvent event = fDeferredDocumentEvent;
1356:                    fDeferredDocumentEvent = null;
1357:                    doFireDocumentChanged(event);
1358:                }
1359:            }
1360:
1361:            /*
1362:             * @see org.eclipse.jface.text.IDocumentExtension3#computeZeroLengthPartitioning(java.lang.String, int, int)
1363:             * @since 3.0
1364:             */
1365:            public ITypedRegion[] computePartitioning(String partitioning,
1366:                    int offset, int length, boolean includeZeroLengthPartitions)
1367:                    throws BadLocationException, BadPartitioningException {
1368:                if ((0 > offset) || (0 > length)
1369:                        || (offset + length > getLength()))
1370:                    throw new BadLocationException();
1371:
1372:                IDocumentPartitioner partitioner = getDocumentPartitioner(partitioning);
1373:
1374:                if (partitioner instanceof  IDocumentPartitionerExtension2) {
1375:                    checkStateOfPartitioner(partitioner, partitioning);
1376:                    return ((IDocumentPartitionerExtension2) partitioner)
1377:                            .computePartitioning(offset, length,
1378:                                    includeZeroLengthPartitions);
1379:                } else if (partitioner != null) {
1380:                    checkStateOfPartitioner(partitioner, partitioning);
1381:                    return partitioner.computePartitioning(offset, length);
1382:                } else if (DEFAULT_PARTITIONING.equals(partitioning))
1383:                    return new TypedRegion[] { new TypedRegion(offset, length,
1384:                            DEFAULT_CONTENT_TYPE) };
1385:                else
1386:                    throw new BadPartitioningException();
1387:            }
1388:
1389:            /*
1390:             * @see org.eclipse.jface.text.IDocumentExtension3#getZeroLengthContentType(java.lang.String, int)
1391:             * @since 3.0
1392:             */
1393:            public String getContentType(String partitioning, int offset,
1394:                    boolean preferOpenPartitions) throws BadLocationException,
1395:                    BadPartitioningException {
1396:                if ((0 > offset) || (offset > getLength()))
1397:                    throw new BadLocationException();
1398:
1399:                IDocumentPartitioner partitioner = getDocumentPartitioner(partitioning);
1400:
1401:                if (partitioner instanceof  IDocumentPartitionerExtension2) {
1402:                    checkStateOfPartitioner(partitioner, partitioning);
1403:                    return ((IDocumentPartitionerExtension2) partitioner)
1404:                            .getContentType(offset, preferOpenPartitions);
1405:                } else if (partitioner != null) {
1406:                    checkStateOfPartitioner(partitioner, partitioning);
1407:                    return partitioner.getContentType(offset);
1408:                } else if (DEFAULT_PARTITIONING.equals(partitioning))
1409:                    return DEFAULT_CONTENT_TYPE;
1410:                else
1411:                    throw new BadPartitioningException();
1412:            }
1413:
1414:            /*
1415:             * @see org.eclipse.jface.text.IDocumentExtension3#getDocumentPartitioner(java.lang.String)
1416:             * @since 3.0
1417:             */
1418:            public IDocumentPartitioner getDocumentPartitioner(
1419:                    String partitioning) {
1420:                return fDocumentPartitioners != null ? (IDocumentPartitioner) fDocumentPartitioners
1421:                        .get(partitioning)
1422:                        : null;
1423:            }
1424:
1425:            /*
1426:             * @see org.eclipse.jface.text.IDocumentExtension3#getLegalContentTypes(java.lang.String)
1427:             * @since 3.0
1428:             */
1429:            public String[] getLegalContentTypes(String partitioning)
1430:                    throws BadPartitioningException {
1431:                IDocumentPartitioner partitioner = getDocumentPartitioner(partitioning);
1432:                if (partitioner != null)
1433:                    return partitioner.getLegalContentTypes();
1434:                if (DEFAULT_PARTITIONING.equals(partitioning))
1435:                    return new String[] { DEFAULT_CONTENT_TYPE };
1436:                throw new BadPartitioningException();
1437:            }
1438:
1439:            /*
1440:             * @see org.eclipse.jface.text.IDocumentExtension3#getZeroLengthPartition(java.lang.String, int)
1441:             * @since 3.0
1442:             */
1443:            public ITypedRegion getPartition(String partitioning, int offset,
1444:                    boolean preferOpenPartitions) throws BadLocationException,
1445:                    BadPartitioningException {
1446:                if ((0 > offset) || (offset > getLength()))
1447:                    throw new BadLocationException();
1448:
1449:                IDocumentPartitioner partitioner = getDocumentPartitioner(partitioning);
1450:
1451:                if (partitioner instanceof  IDocumentPartitionerExtension2) {
1452:                    checkStateOfPartitioner(partitioner, partitioning);
1453:                    return ((IDocumentPartitionerExtension2) partitioner)
1454:                            .getPartition(offset, preferOpenPartitions);
1455:                } else if (partitioner != null) {
1456:                    checkStateOfPartitioner(partitioner, partitioning);
1457:                    return partitioner.getPartition(offset);
1458:                } else if (DEFAULT_PARTITIONING.equals(partitioning))
1459:                    return new TypedRegion(0, getLength(), DEFAULT_CONTENT_TYPE);
1460:                else
1461:                    throw new BadPartitioningException();
1462:            }
1463:
1464:            /*
1465:             * @see org.eclipse.jface.text.IDocumentExtension3#getPartitionings()
1466:             * @since 3.0
1467:             */
1468:            public String[] getPartitionings() {
1469:                if (fDocumentPartitioners == null)
1470:                    return new String[0];
1471:                String[] partitionings = new String[fDocumentPartitioners
1472:                        .size()];
1473:                fDocumentPartitioners.keySet().toArray(partitionings);
1474:                return partitionings;
1475:            }
1476:
1477:            /*
1478:             * @see org.eclipse.jface.text.IDocumentExtension3#setDocumentPartitioner(java.lang.String, org.eclipse.jface.text.IDocumentPartitioner)
1479:             * @since 3.0
1480:             */
1481:            public void setDocumentPartitioner(String partitioning,
1482:                    IDocumentPartitioner partitioner) {
1483:                if (partitioner == null) {
1484:                    if (fDocumentPartitioners != null) {
1485:                        fDocumentPartitioners.remove(partitioning);
1486:                        if (fDocumentPartitioners.size() == 0)
1487:                            fDocumentPartitioners = null;
1488:                    }
1489:                } else {
1490:                    if (fDocumentPartitioners == null)
1491:                        fDocumentPartitioners = new HashMap();
1492:                    fDocumentPartitioners.put(partitioning, partitioner);
1493:                }
1494:                DocumentPartitioningChangedEvent event = new DocumentPartitioningChangedEvent(
1495:                        this );
1496:                event.setPartitionChange(partitioning, 0, getLength());
1497:                fireDocumentPartitioningChanged(event);
1498:            }
1499:
1500:            /*
1501:             * @see org.eclipse.jface.text.IRepairableDocument#repairLineInformation()
1502:             * @since 3.0
1503:             */
1504:            public void repairLineInformation() {
1505:                getTracker().set(get());
1506:            }
1507:
1508:            /**
1509:             * Fires the given event to all registered rewrite session listeners. Uses robust iterators.
1510:             *
1511:             * @param event the event to be fired
1512:             * @since 3.1
1513:             */
1514:            protected void fireRewriteSessionChanged(
1515:                    DocumentRewriteSessionEvent event) {
1516:                if (fDocumentRewriteSessionListeners.size() > 0) {
1517:                    List list = new ArrayList(fDocumentRewriteSessionListeners);
1518:                    Iterator e = list.iterator();
1519:                    while (e.hasNext()) {
1520:                        IDocumentRewriteSessionListener l = (IDocumentRewriteSessionListener) e
1521:                                .next();
1522:                        l.documentRewriteSessionChanged(event);
1523:                    }
1524:                }
1525:            }
1526:
1527:            /*
1528:             * @see org.eclipse.jface.text.IDocumentExtension4#getActiveRewriteSession()
1529:             */
1530:            public final DocumentRewriteSession getActiveRewriteSession() {
1531:                return fDocumentRewriteSession;
1532:            }
1533:
1534:            /*
1535:             * @see org.eclipse.jface.text.IDocumentExtension4#startRewriteSession(org.eclipse.jface.text.DocumentRewriteSessionType)
1536:             * @since 3.1
1537:             */
1538:            public DocumentRewriteSession startRewriteSession(
1539:                    DocumentRewriteSessionType sessionType) {
1540:
1541:                if (getActiveRewriteSession() != null)
1542:                    throw new IllegalStateException();
1543:
1544:                fDocumentRewriteSession = new DocumentRewriteSession(
1545:                        sessionType);
1546:                if (DEBUG)
1547:                    System.out
1548:                            .println("AbstractDocument: Starting rewrite session: " + fDocumentRewriteSession); //$NON-NLS-1$
1549:
1550:                fireRewriteSessionChanged(new DocumentRewriteSessionEvent(this ,
1551:                        fDocumentRewriteSession,
1552:                        DocumentRewriteSessionEvent.SESSION_START));
1553:
1554:                startRewriteSessionOnPartitioners(fDocumentRewriteSession);
1555:
1556:                ILineTracker tracker = getTracker();
1557:                if (tracker instanceof  ILineTrackerExtension) {
1558:                    ILineTrackerExtension extension = (ILineTrackerExtension) tracker;
1559:                    extension.startRewriteSession(fDocumentRewriteSession);
1560:                }
1561:
1562:                if (DocumentRewriteSessionType.SEQUENTIAL == sessionType)
1563:                    startSequentialRewrite(false);
1564:                else if (DocumentRewriteSessionType.STRICTLY_SEQUENTIAL == sessionType)
1565:                    startSequentialRewrite(true);
1566:
1567:                return fDocumentRewriteSession;
1568:            }
1569:
1570:            /**
1571:             * Starts the given rewrite session.
1572:             *
1573:             * @param session the rewrite session
1574:             * @since 3.1
1575:             */
1576:            protected final void startRewriteSessionOnPartitioners(
1577:                    DocumentRewriteSession session) {
1578:                if (fDocumentPartitioners != null) {
1579:                    Iterator e = fDocumentPartitioners.values().iterator();
1580:                    while (e.hasNext()) {
1581:                        Object partitioner = e.next();
1582:                        if (partitioner instanceof  IDocumentPartitionerExtension3) {
1583:                            IDocumentPartitionerExtension3 extension = (IDocumentPartitionerExtension3) partitioner;
1584:                            extension.startRewriteSession(session);
1585:                        }
1586:                    }
1587:                }
1588:            }
1589:
1590:            /*
1591:             * @see org.eclipse.jface.text.IDocumentExtension4#stopRewriteSession(org.eclipse.jface.text.DocumentRewriteSession)
1592:             * @since 3.1
1593:             */
1594:            public void stopRewriteSession(DocumentRewriteSession session) {
1595:                if (fDocumentRewriteSession == session) {
1596:
1597:                    if (DEBUG)
1598:                        System.out
1599:                                .println("AbstractDocument: Stopping rewrite session: " + session); //$NON-NLS-1$
1600:
1601:                    DocumentRewriteSessionType sessionType = session
1602:                            .getSessionType();
1603:                    if (DocumentRewriteSessionType.SEQUENTIAL == sessionType
1604:                            || DocumentRewriteSessionType.STRICTLY_SEQUENTIAL == sessionType)
1605:                        stopSequentialRewrite();
1606:
1607:                    ILineTracker tracker = getTracker();
1608:                    if (tracker instanceof  ILineTrackerExtension) {
1609:                        ILineTrackerExtension extension = (ILineTrackerExtension) tracker;
1610:                        extension.stopRewriteSession(session, get());
1611:                    }
1612:
1613:                    stopRewriteSessionOnPartitioners(fDocumentRewriteSession);
1614:
1615:                    fDocumentRewriteSession = null;
1616:                    fireRewriteSessionChanged(new DocumentRewriteSessionEvent(
1617:                            this , session,
1618:                            DocumentRewriteSessionEvent.SESSION_STOP));
1619:                }
1620:            }
1621:
1622:            /**
1623:             * Stops the given rewrite session.
1624:             *
1625:             * @param session the rewrite session
1626:             * @since 3.1
1627:             */
1628:            protected final void stopRewriteSessionOnPartitioners(
1629:                    DocumentRewriteSession session) {
1630:                if (fDocumentPartitioners != null) {
1631:                    DocumentPartitioningChangedEvent event = new DocumentPartitioningChangedEvent(
1632:                            this );
1633:                    Iterator e = fDocumentPartitioners.keySet().iterator();
1634:                    while (e.hasNext()) {
1635:                        String partitioning = (String) e.next();
1636:                        IDocumentPartitioner partitioner = (IDocumentPartitioner) fDocumentPartitioners
1637:                                .get(partitioning);
1638:                        if (partitioner instanceof  IDocumentPartitionerExtension3) {
1639:                            IDocumentPartitionerExtension3 extension = (IDocumentPartitionerExtension3) partitioner;
1640:                            extension.stopRewriteSession(session);
1641:                            event.setPartitionChange(partitioning, 0,
1642:                                    getLength());
1643:                        }
1644:                    }
1645:                    if (!event.isEmpty())
1646:                        fireDocumentPartitioningChanged(event);
1647:                }
1648:            }
1649:
1650:            /*
1651:             * @see org.eclipse.jface.text.IDocumentExtension4#addDocumentRewriteSessionListener(org.eclipse.jface.text.IDocumentRewriteSessionListener)
1652:             * @since 3.1
1653:             */
1654:            public void addDocumentRewriteSessionListener(
1655:                    IDocumentRewriteSessionListener listener) {
1656:                Assert.isNotNull(listener);
1657:                if (!fDocumentRewriteSessionListeners.contains(listener))
1658:                    fDocumentRewriteSessionListeners.add(listener);
1659:            }
1660:
1661:            /*
1662:             * @see org.eclipse.jface.text.IDocumentExtension4#removeDocumentRewriteSessionListener(org.eclipse.jface.text.IDocumentRewriteSessionListener)
1663:             * @since 3.1
1664:             */
1665:            public void removeDocumentRewriteSessionListener(
1666:                    IDocumentRewriteSessionListener listener) {
1667:                Assert.isNotNull(listener);
1668:                fDocumentRewriteSessionListeners.remove(listener);
1669:            }
1670:
1671:            /**
1672:             * Checks the state for the given partitioner and stops the
1673:             * active rewrite session.
1674:             *
1675:             * @param partitioner the document partitioner to be checked
1676:             * @param partitioning the document partitioning the partitioner is registered for
1677:             * @since 3.1
1678:             */
1679:            protected final void checkStateOfPartitioner(
1680:                    IDocumentPartitioner partitioner, String partitioning) {
1681:                if (!(partitioner instanceof  IDocumentPartitionerExtension3))
1682:                    return;
1683:
1684:                IDocumentPartitionerExtension3 extension = (IDocumentPartitionerExtension3) partitioner;
1685:                DocumentRewriteSession session = extension
1686:                        .getActiveRewriteSession();
1687:                if (session != null) {
1688:                    extension.stopRewriteSession(session);
1689:
1690:                    if (DEBUG)
1691:                        System.out
1692:                                .println("AbstractDocument: Flushing rewrite session for partition type: " + partitioning); //$NON-NLS-1$
1693:
1694:                    DocumentPartitioningChangedEvent event = new DocumentPartitioningChangedEvent(
1695:                            this );
1696:                    event.setPartitionChange(partitioning, 0, getLength());
1697:                    fireDocumentPartitioningChanged(event);
1698:                }
1699:            }
1700:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.