Source Code Cross Referenced for EmbeddingContainer.java in  » IDE-Netbeans » lexer » org » netbeans » lib » lexer » 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 » lexer » org.netbeans.lib.lexer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans.lib.lexer;
043:
044:        import org.netbeans.api.lexer.Language;
045:        import org.netbeans.api.lexer.LanguagePath;
046:        import org.netbeans.api.lexer.TokenHierarchyEventType;
047:        import org.netbeans.api.lexer.TokenId;
048:        import org.netbeans.lib.lexer.inc.TokenChangeInfo;
049:        import org.netbeans.lib.lexer.inc.TokenHierarchyEventInfo;
050:        import org.netbeans.spi.lexer.LanguageEmbedding;
051:        import org.netbeans.lib.lexer.token.AbstractToken;
052:        import org.netbeans.spi.lexer.EmbeddingPresence;
053:        import org.netbeans.spi.lexer.LanguageHierarchy;
054:
055:        /**
056:         * Embedding info contains information about all the embeddings
057:         * for a particular token in a token list.
058:         * <br>
059:         * There can be one or more {@link EmbeddedTokenList} instances for each
060:         * cotnained embedding.
061:         * <p>
062:         * There is an intent to not degrade performance significantly
063:         * with each extra language embedding level so the token list maintains direct
064:         * link to the root level.
065:         * 
066:         * @author Miloslav Metelka
067:         * @version 1.00
068:         */
069:
070:        public final class EmbeddingContainer<T extends TokenId> {
071:
072:            /**
073:             * Get embedded token list.
074:             *
075:             * @param tokenList non-null token list in which the token for which the embedding
076:             *  should be obtained resides.
077:             * @param index &gt;=0 index of the token in the token list where the embedding
078:             *  should be obtained.
079:             * @param language whether only language embeddding of the particular language
080:             *  was requested. It may be null if any embedding should be returned.
081:             */
082:            public static <T extends TokenId, ET extends TokenId> EmbeddedTokenList<ET> embeddedTokenList(
083:                    TokenList<T> tokenList, int index,
084:                    Language<ET> embeddedLanguage) {
085:                EmbeddingContainer<T> ec;
086:                AbstractToken<T> token;
087:                EmbeddingPresence ep;
088:                TokenList<?> rootTokenList = tokenList.root();
089:                synchronized (rootTokenList) {
090:                    Object tokenOrEmbeddingContainer = tokenList
091:                            .tokenOrEmbeddingContainer(index);
092:                    if (tokenOrEmbeddingContainer.getClass() == EmbeddingContainer.class) {
093:                        // Embedding container exists
094:                        @SuppressWarnings("unchecked")
095:                        EmbeddingContainer<T> ecUC = (EmbeddingContainer<T>) tokenOrEmbeddingContainer;
096:                        ec = ecUC;
097:                        token = ec.token();
098:                        ep = null;
099:
100:                    } else { // No embedding was created yet
101:                        ec = null;
102:                        @SuppressWarnings("unchecked")
103:                        AbstractToken<T> t = (AbstractToken<T>) tokenOrEmbeddingContainer;
104:                        token = t;
105:                        // Check embedding presence
106:                        ep = LexerUtilsConstants.innerLanguageOperation(
107:                                tokenList.languagePath()).embeddingPresence(
108:                                token.id());
109:                        if (ep == EmbeddingPresence.NONE) {
110:                            return null;
111:                        }
112:                    }
113:
114:                    // Now either ec == null for no embedding yet or linked list of embedded token lists of ec
115:                    // need to be processed to find the embedded token list for requested language.
116:                    EmbeddedTokenList<?> prevEtl;
117:                    if (ec != null) {
118:                        ec.updateStatusImpl();
119:                        EmbeddedTokenList<?> etl = ec.firstEmbeddedTokenList();
120:                        prevEtl = null;
121:                        while (etl != null) {
122:                            if (embeddedLanguage == null
123:                                    || etl.languagePath().innerLanguage() == embeddedLanguage) {
124:                                @SuppressWarnings("unchecked")
125:                                EmbeddedTokenList<ET> etlUC = (EmbeddedTokenList<ET>) etl;
126:                                return etlUC;
127:                            }
128:                            prevEtl = etl;
129:                            etl = etl.nextEmbeddedTokenList();
130:                        }
131:                        // Requested etl not found
132:                        if (ec.defaultEmbeddedTokenList() != null) { // Already created or NO_DEFAULT_EMBEDDING
133:                            return null;
134:                        }
135:
136:                    } else { // No embedding yet
137:                        prevEtl = null;
138:                    }
139:
140:                    // If the tokenList is removed then do not create the embedding
141:                    if (tokenList.isRemoved())
142:                        return null;
143:
144:                    // Attempt to create the default embedding
145:                    LanguagePath languagePath = tokenList.languagePath();
146:                    LanguageHierarchy<T> languageHierarchy = LexerUtilsConstants
147:                            .innerLanguageHierarchy(languagePath);
148:                    @SuppressWarnings("unchecked")
149:                    LanguageEmbedding<ET> embedding = (LanguageEmbedding<ET>) LexerUtilsConstants
150:                            .findEmbedding(languageHierarchy, token,
151:                                    languagePath, tokenList.inputAttributes());
152:                    if (ep == null) { // Needs to be retrieved to check for CACHED_FIRST_QUERY
153:                        ep = LexerUtilsConstants.innerLanguageOperation(
154:                                tokenList.languagePath()).embeddingPresence(
155:                                token.id());
156:                    }
157:                    if (embedding != null) {
158:                        // Update the embedding presence ALWAYS_QUERY
159:                        if (ep == EmbeddingPresence.CACHED_FIRST_QUERY) {
160:                            LexerUtilsConstants.innerLanguageOperation(
161:                                    tokenList.languagePath())
162:                                    .setEmbeddingPresence(token.id(),
163:                                            EmbeddingPresence.ALWAYS_QUERY);
164:                        }
165:                        // Check whether the token contains enough text to satisfy embedding's start and end skip lengths
166:                        CharSequence text = token.text(); // Should not be null here but rather check
167:                        if (text == null
168:                                || embedding.startSkipLength()
169:                                        + embedding.endSkipLength() > text
170:                                        .length()) {
171:                            return null;
172:                        }
173:                        if (ec == null) {
174:                            ec = new EmbeddingContainer<T>(token, rootTokenList);
175:                            tokenList.wrapToken(index, ec);
176:                        }
177:                        LanguagePath embeddedLanguagePath = LanguagePath.get(
178:                                languagePath, embedding.language());
179:                        EmbeddedTokenList<ET> etl = new EmbeddedTokenList<ET>(
180:                                ec, embeddedLanguagePath, embedding, null);
181:                        // Preceding code should ensure that (prevEtl.nextEmbeddedTokenList == null)
182:                        // so no need to call etl.setNextEmbeddedTokenList(prevEtl.nextEmbeddedTokenList())
183:                        ec.addEmbeddedTokenList(prevEtl, etl, true);
184:                        return (embeddedLanguage == null || embeddedLanguage == embedding
185:                                .language()) ? etl : null;
186:                    }
187:                    // Update embedding presence to NONE
188:                    if (ep == EmbeddingPresence.CACHED_FIRST_QUERY) {
189:                        LexerUtilsConstants.innerLanguageOperation(
190:                                tokenList.languagePath()).setEmbeddingPresence(
191:                                token.id(), EmbeddingPresence.NONE);
192:                    }
193:                    return null;
194:                }
195:            }
196:
197:            /**
198:             * Create custom embedding.
199:             *
200:             * @param tokenList non-null token list in which the token for which the embedding
201:             *  should be created resides.
202:             * @param index &gt;=0 index of the token in the token list where the embedding
203:             *  should be created.
204:             * @param embeddedLanguage non-null embedded language.
205:             * @param startSkipLength &gt;=0 number of characters in an initial part of the token
206:             *  for which the language embedding is being create that should be excluded
207:             *  from the embedded section. The excluded characters will not be lexed
208:             *  and there will be no tokens created for them.
209:             * @param endSkipLength &gt;=0 number of characters at the end of the token
210:             *  for which the language embedding is defined that should be excluded
211:             *  from the embedded section. The excluded characters will not be lexed
212:             *  and there will be no tokens created for them.
213:             */
214:            public static <T extends TokenId, ET extends TokenId> boolean createEmbedding(
215:                    TokenList<T> tokenList, int index,
216:                    Language<ET> embeddedLanguage, int startSkipLength,
217:                    int endSkipLength, boolean joinSections) {
218:                TokenList<?> rootTokenList = tokenList.root();
219:                // Only create embedddings for valid operations so not e.g. for removed token list
220:                AbstractToken<T> token;
221:                EmbeddingContainer<T> ec;
222:                EmbeddedTokenList<ET> etl;
223:                LanguageEmbedding<ET> embedding;
224:                TokenHierarchyOperation<?, ?> tokenHierarchyOperation;
225:                int tokenStartOffset;
226:                TokenHierarchyEventInfo eventInfo;
227:                synchronized (rootTokenList) {
228:                    // Check TL.isRemoved() under syncing of rootTokenList
229:                    if (tokenList.isRemoved()) // Do not create embedding for removed TLs
230:                        return false;
231:                    // If not removed then THO should be non-null
232:                    tokenHierarchyOperation = tokenList
233:                            .tokenHierarchyOperation();
234:                    tokenHierarchyOperation.ensureWriteLocked();
235:
236:                    Object tokenOrEmbeddingContainer = tokenList
237:                            .tokenOrEmbeddingContainer(index);
238:                    if (tokenOrEmbeddingContainer.getClass() == EmbeddingContainer.class) {
239:                        // Embedding container exists
240:                        @SuppressWarnings("unchecked")
241:                        EmbeddingContainer<T> ecUC = (EmbeddingContainer<T>) tokenOrEmbeddingContainer;
242:                        ec = ecUC;
243:                        EmbeddedTokenList etl2 = ec.firstEmbeddedTokenList();
244:                        while (etl2 != null) {
245:                            if (embeddedLanguage == etl2.languagePath()
246:                                    .innerLanguage()) {
247:                                return false; // already exists
248:                            }
249:                            etl2 = etl2.nextEmbeddedTokenList();
250:                        }
251:                        token = ec.token();
252:                    } else {
253:                        @SuppressWarnings("unchecked")
254:                        AbstractToken<T> t = (AbstractToken<T>) tokenOrEmbeddingContainer;
255:                        token = t;
256:                        if (token.isFlyweight()) { // embedding cannot exist for this flyweight token
257:                            return false;
258:                        }
259:                        ec = new EmbeddingContainer<T>(token, rootTokenList);
260:                        tokenList.wrapToken(index, ec);
261:                    }
262:
263:                    // Token is now wrapped with the EmbeddingContainer and the embedding can be added
264:                    if (startSkipLength + endSkipLength > token.length()) // Check for appropriate size
265:                        return false;
266:                    // Add the new embedding as the first one in the single-linked list
267:                    embedding = LanguageEmbedding.create(embeddedLanguage,
268:                            startSkipLength, endSkipLength, joinSections);
269:                    LanguagePath languagePath = tokenList.languagePath();
270:                    LanguagePath embeddedLanguagePath = LanguagePath.get(
271:                            languagePath, embeddedLanguage);
272:                    tokenHierarchyOperation
273:                            .addLanguagePath(embeddedLanguagePath);
274:                    // Make the embedded token list to be the first in the list
275:                    etl = new EmbeddedTokenList<ET>(ec, embeddedLanguagePath,
276:                            embedding, ec.firstEmbeddedTokenList());
277:                    ec.addEmbeddedTokenList(null, etl, false);
278:
279:                    // Fire the embedding creation to the clients
280:                    // Threading model may need to be changed if necessary
281:                    tokenStartOffset = ec.tokenStartOffset();
282:                    eventInfo = new TokenHierarchyEventInfo(
283:                            tokenHierarchyOperation,
284:                            TokenHierarchyEventType.EMBEDDING_CREATED,
285:                            tokenStartOffset, 0, "", 0);
286:                    eventInfo.setMaxAffectedEndOffset(tokenStartOffset
287:                            + token.length());
288:
289:                    // Check presence of token list list for the embedded language path
290:                    // When joining sections ensure that the token list list gets created
291:                    // and the embedded tokens get created because they must exist
292:                    // before possible next updating of the token list.
293:                    TokenListList tll = tokenHierarchyOperation
294:                            .existingTokenListList(etl.languagePath());
295:                    if (tll != null) {
296:                        // Update tll by embedding creation
297:                        new TokenHierarchyUpdate(eventInfo)
298:                                .updateCreateEmbedding(etl);
299:                    } else { // tll == null
300:                        if (embedding.joinSections()) {
301:                            // Force token list list creation only when joining sections
302:                            tll = tokenHierarchyOperation.tokenListList(etl
303:                                    .languagePath());
304:                        }
305:                    }
306:
307:                }
308:
309:                // Construct outer token change info
310:                TokenChangeInfo<T> info = new TokenChangeInfo<T>(tokenList);
311:                info.setIndex(index);
312:                info.setOffset(tokenStartOffset);
313:                //info.setAddedTokenCount(0);
314:                eventInfo.setTokenChangeInfo(info);
315:
316:                TokenChangeInfo<ET> embeddedInfo = new TokenChangeInfo<ET>(etl);
317:                embeddedInfo.setIndex(0);
318:                embeddedInfo.setOffset(tokenStartOffset
319:                        + embedding.startSkipLength());
320:                // Should set number of added tokens directly?
321:                //  - would prevent further lazy embedded lexing so leave to zero for now
322:                //info.setAddedTokenCount(0);
323:                info.addEmbeddedChange(embeddedInfo);
324:
325:                // Fire the change
326:                tokenHierarchyOperation.fireTokenHierarchyChanged(eventInfo);
327:                return true;
328:            }
329:
330:            public static <T extends TokenId, ET extends TokenId> boolean removeEmbedding(
331:                    TokenList<T> tokenList, int index,
332:                    Language<ET> embeddedLanguage) {
333:                TokenList<?> rootTokenList = tokenList.root();
334:                // Only create embedddings for valid operations so not e.g. for removed token list
335:                EmbeddingContainer<T> ec;
336:                synchronized (rootTokenList) {
337:                    // Check TL.isRemoved() under syncing of rootTokenList
338:                    if (tokenList.isRemoved()) // Do not create embedding for removed TLs
339:                        return false;
340:                    // If TL is not removed then THO should be non-null
341:                    TokenHierarchyOperation<?, ?> tokenHierarchyOperation = tokenList
342:                            .tokenHierarchyOperation();
343:                    tokenHierarchyOperation.ensureWriteLocked();
344:
345:                    Object tokenOrEmbeddingContainer = tokenList
346:                            .tokenOrEmbeddingContainer(index);
347:                    if (tokenOrEmbeddingContainer.getClass() == EmbeddingContainer.class) {
348:                        // Embedding container exists
349:                        @SuppressWarnings("unchecked")
350:                        EmbeddingContainer<T> ecUC = (EmbeddingContainer<T>) tokenOrEmbeddingContainer;
351:                        ec = ecUC;
352:                        ec.updateStatusImpl();
353:                        EmbeddedTokenList<?> etl = ec.firstEmbeddedTokenList();
354:                        EmbeddedTokenList<?> prevEtl = null;
355:                        while (etl != null) {
356:                            if (embeddedLanguage == etl.languagePath()
357:                                    .innerLanguage()) {
358:                                // The embedding with the given language exists
359:                                // Remove it from the chain
360:                                ec.removeEmbeddedTokenList(prevEtl, etl);
361:                                // Do not increase the version of the hierarchy since
362:                                // all the existing token sequences would be invalidated.
363:                                // Instead invalidate only TSes for the etl only and all its children.
364:                                // Construct special EC just for the removed token list.
365:                                ec = new EmbeddingContainer<T>(ec);
366:                                // State that the removed embedding was not default - should not matter anyway
367:                                ec.addEmbeddedTokenList(null, etl, false);
368:                                etl.setEmbeddingContainer(ec);
369:                                ec.invalidateChildren();
370:
371:                                // Fire the embedding creation to the clients
372:                                int startOffset = ec.tokenStartOffset();
373:                                TokenHierarchyEventInfo eventInfo = new TokenHierarchyEventInfo(
374:                                        tokenHierarchyOperation,
375:                                        TokenHierarchyEventType.EMBEDDING_REMOVED,
376:                                        startOffset, 0, "", 0
377:
378:                                );
379:                                eventInfo.setMaxAffectedEndOffset(startOffset
380:                                        + ec.token().length());
381:                                // Construct outer token change info
382:                                TokenChangeInfo<T> info = new TokenChangeInfo<T>(
383:                                        tokenList);
384:                                info.setIndex(index);
385:                                info.setOffset(startOffset);
386:                                //info.setAddedTokenCount(0);
387:                                eventInfo.setTokenChangeInfo(info);
388:
389:                                @SuppressWarnings("unchecked")
390:                                EmbeddedTokenList<ET> etlET = (EmbeddedTokenList<ET>) etl;
391:                                TokenChangeInfo<ET> embeddedInfo = new TokenChangeInfo<ET>(
392:                                        etlET);
393:                                embeddedInfo.setIndex(0);
394:                                embeddedInfo.setOffset(startOffset
395:                                        + etl.embedding().startSkipLength());
396:                                // For now do not set the removed contents (requires RemovedTokenList)
397:                                info.addEmbeddedChange(embeddedInfo);
398:
399:                                // Check for presence of etl in a token list list
400:                                TokenListList tll = tokenHierarchyOperation
401:                                        .existingTokenListList(etl
402:                                                .languagePath());
403:                                if (tll != null) {
404:                                    // update-status already called
405:                                    new TokenHierarchyUpdate(eventInfo)
406:                                            .updateRemoveEmbedding(etl);
407:                                }
408:
409:                                // Fire the change
410:                                tokenHierarchyOperation
411:                                        .fireTokenHierarchyChanged(eventInfo);
412:                                return true;
413:                            }
414:                            etl = etl.nextEmbeddedTokenList();
415:                        }
416:                    }
417:                }
418:                return false;
419:            }
420:
421:            private AbstractToken<T> token; // 12 bytes (8-super + 4)
422:
423:            /**
424:             * Cached modification count allows to determine whether the start offset
425:             * needs to be recomputed.
426:             */
427:            private int cachedModCount; // 16 bytes
428:
429:            /**
430:             * Root token list of the hierarchy.
431:             * 
432:             */
433:            private final TokenList<?> rootTokenList; // 20 bytes
434:
435:            /**
436:             * The root embedding container to which this embedding container relates.
437:             * <br/>
438:             * It's used for getting of the start offset of the contained tokens
439:             * and for getting of their text.
440:             */
441:            private AbstractToken<?> rootToken; // 24 bytes
442:
443:            /**
444:             * Cached start offset of the token for which this embedding container
445:             * was created.
446:             */
447:            private int tokenStartOffset; // 28 bytes
448:
449:            /**
450:             * First embedded token list in the single-linked list.
451:             */
452:            private EmbeddedTokenList<?> firstEmbeddedTokenList; // 32 bytes
453:
454:            /**
455:             * Difference between start offset of the first token in this token list
456:             * against the start offset of the root token.
457:             * <br>
458:             * The offset gets refreshed upon <code>updateStartOffset()</code>.
459:             */
460:            private int offsetShiftFromRootToken; // 36 bytes
461:
462:            /**
463:             * Embedded token list that represents the default embedding.
464:             * It may be <code>EmbeddedTokenList.NO_DEFAULT_EMBEDDING</code>
465:             * for failed attempt to create a default embedding.
466:             */
467:            private EmbeddedTokenList<?> defaultEmbeddedTokenList; // 40 bytes
468:
469:            EmbeddingContainer(AbstractToken<T> token,
470:                    TokenList<?> rootTokenList) {
471:                this .token = token;
472:                this .rootTokenList = rootTokenList;
473:                this .rootToken = token; // Has to be non-null since updateStatusImpl() would not update null rootToken
474:                // cachedModCount must differ from root's one to sync offsets
475:                // Root mod count can be >= 0 or -1 for non-incremental token lists
476:                this .cachedModCount = -2;
477:                // Update the tokenStartOffset etc. - this assumes that the token
478:                // is already parented till the root token list.
479:                updateStatusImpl();
480:            }
481:
482:            /**
483:             * Constructor used when a custom embedding gets removed.
484:             * Such removal does not increase token hierarchy version
485:             * (to not destroy existing token sequences) but need to invalidate
486:             * token sequences over the removed embedded token list and all its children.
487:             * <br/>
488:             * A new special embedding container gets created in such case
489:             * that will carry null root token since begining and will have a special modCount
490:             * so that the token sequences become invalid.
491:             * 
492:             * @param ec non-null existing embedding container.
493:             */
494:            EmbeddingContainer(EmbeddingContainer<T> ec) {
495:                this (ec.token(), ec.rootTokenList()); // Force init of tokenStartOffset and rootTokenOffsetShift
496:                invalidate();
497:            }
498:
499:            private void invalidate() {
500:                this .rootToken = null;
501:                // Set cachedModCount to -2 which should not occur for regular cases
502:                // which should force existing token sequences to be invalidated.
503:                this .cachedModCount = -2;
504:            }
505:
506:            void invalidateChildren() {
507:                EmbeddedTokenList etl = firstEmbeddedTokenList;
508:                while (etl != null
509:                        && etl != EmbeddedTokenList.NO_DEFAULT_EMBEDDING) {
510:                    for (int i = etl.tokenCountCurrent() - 1; i >= 0; i--) {
511:                        Object tokenOrEC = etl
512:                                .tokenOrEmbeddingContainerUnsync(i);
513:                        if (tokenOrEC.getClass() == EmbeddingContainer.class) {
514:                            ((EmbeddingContainer) tokenOrEC)
515:                                    .invalidateChildren();
516:                        }
517:                    }
518:                    etl = etl.nextEmbeddedTokenList();
519:                }
520:            }
521:
522:            public int cachedModCount() {
523:                return cachedModCount;
524:            }
525:
526:            /**
527:             * Check if this embedding container is up-to-date (updateStatusImpl() was called on it)
528:             * which is useful for missing-update-status checks.
529:             */
530:            public void checkStatusUpdated() {
531:                if (cachedModCount != -2
532:                        && cachedModCount != rootTokenList.modCount()
533:                        && !checkStatusUpdatedThrowingException) {
534:                    // Prevent OOME because of nested throwing of exc
535:                    checkStatusUpdatedThrowingException = true;
536:                    String excMsg = "!!!INTERNAL ERROR!!! Status not updated on "
537:                            + this 
538:                            + "\nin token hierarchy\n"
539:                            + rootTokenList.tokenHierarchyOperation();
540:                    checkStatusUpdatedThrowingException = false;
541:                    throw new IllegalStateException(excMsg);
542:                }
543:            }
544:
545:            private static boolean checkStatusUpdatedThrowingException;
546:
547:            public AbstractToken<T> token() {
548:                return token;
549:            }
550:
551:            /**
552:             * Make this container serve a different token.
553:             * The updateStatusImpl() should be called afterwards to update tokenStartOffset etc.
554:             */
555:            public void reinit(AbstractToken<T> token) {
556:                this .token = token;
557:                TokenList<?> parentTokenList = token.tokenList();
558:                assert (parentTokenList != null);
559:                if (parentTokenList.getClass() == EmbeddedTokenList.class) {
560:                    rootToken = ((EmbeddedTokenList<?>) parentTokenList)
561:                            .rootToken();
562:                } else { // parent is a root token list: rootToken == token
563:                    rootToken = token;
564:                }
565:                updateStatusImpl();
566:            }
567:
568:            public TokenList<?> rootTokenList() {
569:                return rootTokenList;
570:            }
571:
572:            public AbstractToken<?> rootToken() {
573:                return rootToken;
574:            }
575:
576:            public int tokenStartOffset() {
577:                //        checkStatusUpdated();
578:                return tokenStartOffset;
579:            }
580:
581:            public int rootTokenOffsetShift() {
582:                //        checkStatusUpdated();
583:                return offsetShiftFromRootToken;
584:            }
585:
586:            public char charAt(int tokenRelOffset) {
587:                //        checkStatusUpdated();
588:                return rootToken.charAt(offsetShiftFromRootToken
589:                        + tokenRelOffset);
590:            }
591:
592:            public EmbeddedTokenList<?> firstEmbeddedTokenList() {
593:                return firstEmbeddedTokenList;
594:            }
595:
596:            /**
597:             * Add a new embedded token list to this container.
598:             * 
599:             * @param prevEtl token list preceding the place of addition.
600:             *  Null means that the added one will be first in the chain.
601:             * @param etl non-null token list to be added.
602:             * @param defaultEmbedding whether the added etl is default embedding or not.
603:             */
604:            public void addEmbeddedTokenList(EmbeddedTokenList<?> prevEtl,
605:                    EmbeddedTokenList<?> etl, boolean defaultEmbedding) {
606:                if (prevEtl != null) {
607:                    etl.setNextEmbeddedTokenList(prevEtl
608:                            .nextEmbeddedTokenList());
609:                    prevEtl.setNextEmbeddedTokenList(etl);
610:                } else { // prevEtl is null
611:                    etl.setNextEmbeddedTokenList(firstEmbeddedTokenList);
612:                    firstEmbeddedTokenList = etl;
613:                }
614:                if (defaultEmbedding) {
615:                    defaultEmbeddedTokenList = etl;
616:                }
617:            }
618:
619:            /**
620:             * Remove embedded token list from this container.
621:             * Clear reference to next item in the removed token list.
622:             * 
623:             * @param prevEtl token list preceding the place of removal.
624:             *  Null means that the removed one is first in the chain.
625:             * @param etl non-null token list to be removed.
626:             * @return next token list linked originally to etl.
627:             */
628:            public EmbeddedTokenList<?> removeEmbeddedTokenList(
629:                    EmbeddedTokenList<?> prevEtl, EmbeddedTokenList<?> etl) {
630:                EmbeddedTokenList<?> next = etl.nextEmbeddedTokenList();
631:                if (prevEtl != null) {
632:                    prevEtl.setNextEmbeddedTokenList(next);
633:                } else {
634:                    firstEmbeddedTokenList = next;
635:                }
636:                etl.setNextEmbeddedTokenList(null);
637:                if (defaultEmbeddedTokenList == etl) {
638:                    defaultEmbeddedTokenList = null;
639:                }
640:                return next;
641:            }
642:
643:            public EmbeddedTokenList<?> defaultEmbeddedTokenList() {
644:                return defaultEmbeddedTokenList;
645:            }
646:
647:            /**
648:             * Check whether this embedding container is no longer present
649:             * in the token hierarchy.
650:             * <br/>
651:             * This method should only be called after updateStatusImpl() was called
652:             * (it updates rootToken variable).
653:             */
654:            public boolean isRemoved() {
655:                //        checkStatusUpdated();
656:                return (rootToken == null);
657:            }
658:
659:            public void updateStatusAndInvalidate() {
660:                updateStatusImpl();
661:                invalidate();
662:            }
663:
664:            public boolean updateStatus() {
665:                synchronized (rootTokenList) {
666:                    return (updateStatusImpl() != null);
667:                }
668:            }
669:
670:            /**
671:             * Update and return root token corresponding to this embedding container.
672:             */
673:            public AbstractToken<?> updateStatusImpl() {
674:                if (rootToken == null)
675:                    return null; // Removed from hierarchy
676:                int rootModCount;
677:                if (cachedModCount != (rootModCount = rootTokenList.modCount())) {
678:                    cachedModCount = rootModCount;
679:                    TokenList<?> parentTokenList = token.tokenList();
680:                    if (parentTokenList == null) {
681:                        rootToken = null;
682:                    } else if (parentTokenList.getClass() == EmbeddedTokenList.class) {
683:                        EmbeddedTokenList<?> parentEtl = (EmbeddedTokenList<?>) parentTokenList;
684:                        rootToken = parentEtl.embeddingContainer()
685:                                .updateStatusImpl();
686:                        tokenStartOffset = parentEtl
687:                                .childTokenOffsetNoUpdate(token.rawOffset());
688:                        EmbeddingContainer parentEC = parentEtl
689:                                .embeddingContainer();
690:                        offsetShiftFromRootToken = tokenStartOffset
691:                                - parentEC.tokenStartOffset()
692:                                + parentEC.rootTokenOffsetShift();
693:                    } else { // parent is a root token list: rootToken == token
694:                        rootToken = token;
695:                        tokenStartOffset = token.offset(null);
696:                        offsetShiftFromRootToken = 0;
697:                    }
698:                }
699:                return rootToken;
700:            }
701:
702:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.