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


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.editor.ext;
0043:
0044:        import java.util.HashMap;
0045:        import javax.swing.text.Document;
0046:        import javax.swing.text.Position;
0047:        import org.netbeans.editor.BaseDocument;
0048:        import org.netbeans.editor.Syntax;
0049:        import org.netbeans.editor.TokenID;
0050:        import org.netbeans.editor.TokenContextPath;
0051:        import org.netbeans.editor.TokenItem;
0052:        import org.netbeans.editor.Analyzer;
0053:
0054:        /**
0055:         * Format support presents a set of operations over the format-writer
0056:         * that is specific for the given set of formatting layers.
0057:         * It presents the way how to extend the low level methods
0058:         * offered by the format-writer.
0059:         * In general there can be more format-layers that use one type
0060:         * of the format-support. 
0061:         *
0062:         * @author Miloslav Metelka
0063:         * @version 1.00
0064:         */
0065:
0066:        public class FormatSupport {
0067:
0068:            /** Format-writer over which this support is constructed. */
0069:            private FormatWriter formatWriter;
0070:
0071:            public FormatSupport(FormatWriter formatWriter) {
0072:                this .formatWriter = formatWriter;
0073:            }
0074:
0075:            /** Getter for the format-writer associated with this format-support. */
0076:            public FormatWriter getFormatWriter() {
0077:                return formatWriter;
0078:            }
0079:
0080:            public int getTabSize() {
0081:                Document doc = formatWriter.getDocument();
0082:                return (doc instanceof  BaseDocument) ? ((BaseDocument) doc)
0083:                        .getTabSize() : formatWriter.getFormatter()
0084:                        .getTabSize();
0085:            }
0086:
0087:            public int getShiftWidth() {
0088:                Document doc = formatWriter.getDocument();
0089:                return (doc instanceof  BaseDocument) ? ((BaseDocument) doc)
0090:                        .getShiftWidth() : formatWriter.getFormatter()
0091:                        .getShiftWidth();
0092:            }
0093:
0094:            public boolean expandTabs() {
0095:                return formatWriter.getFormatter().expandTabs();
0096:            }
0097:
0098:            public int getSpacesPerTab() {
0099:                return formatWriter.getFormatter().getSpacesPerTab();
0100:            }
0101:
0102:            public Object getSettingValue(String settingName) {
0103:                return formatWriter.getFormatter().getSettingValue(settingName);
0104:            }
0105:
0106:            public Object getSettingValue(String settingName,
0107:                    Object defaultValue) {
0108:                Object value = getSettingValue(settingName);
0109:                return (value != null) ? value : defaultValue;
0110:            }
0111:
0112:            public boolean getSettingBoolean(String settingName,
0113:                    Boolean defaultValue) {
0114:                return ((Boolean) getSettingValue(settingName, defaultValue))
0115:                        .booleanValue();
0116:            }
0117:
0118:            public boolean getSettingBoolean(String settingName,
0119:                    boolean defaultValue) {
0120:                return ((Boolean) getSettingValue(settingName,
0121:                        (defaultValue ? Boolean.TRUE : Boolean.FALSE)))
0122:                        .booleanValue();
0123:            }
0124:
0125:            public int getSettingInteger(String settingName,
0126:                    Integer defaultValue) {
0127:                return ((Integer) getSettingValue(settingName, defaultValue))
0128:                        .intValue();
0129:            }
0130:
0131:            public int getSettingInteger(String settingName, int defaultValue) {
0132:                Object value = getSettingValue(settingName);
0133:                return (value instanceof  Integer) ? ((Integer) value)
0134:                        .intValue() : defaultValue;
0135:            }
0136:
0137:            /** Delegation to the same method in format-writer. */
0138:            public final boolean isIndentOnly() {
0139:                return formatWriter.isIndentOnly();
0140:            }
0141:
0142:            /** Delegation to the same method in format-writer. */
0143:            public FormatTokenPosition getFormatStartPosition() {
0144:                return formatWriter.getFormatStartPosition();
0145:            }
0146:
0147:            public FormatTokenPosition getTextStartPosition() {
0148:                return formatWriter.getTextStartPosition();
0149:            }
0150:
0151:            /** Get the first token in chain. */
0152:            public TokenItem findFirstToken(TokenItem token) {
0153:                return formatWriter.findFirstToken(token);
0154:            }
0155:
0156:            /** Delegation to the same method in format-writer. */
0157:            public TokenItem getLastToken() {
0158:                return formatWriter.getLastToken();
0159:            }
0160:
0161:            public FormatTokenPosition getLastPosition() {
0162:                TokenItem lt = findNonEmptyToken(getLastToken(), true);
0163:                return (lt == null) ? null : getPosition(lt, lt.getImage()
0164:                        .length() - 1);
0165:            }
0166:
0167:            /** Delegation to the same method in format-writer. */
0168:            public boolean canInsertToken(TokenItem beforeToken) {
0169:                return formatWriter.canInsertToken(beforeToken);
0170:            }
0171:
0172:            /** Delegation to the same method in format-writer. */
0173:            public TokenItem insertToken(TokenItem beforeToken,
0174:                    TokenID tokenID, TokenContextPath tokenContextPath,
0175:                    String tokenImage) {
0176:                return formatWriter.insertToken(beforeToken, tokenID,
0177:                        tokenContextPath, tokenImage);
0178:            }
0179:
0180:            public void insertSpaces(TokenItem beforeToken, int spaceCount) {
0181:                TokenID whitespaceTokenID = getWhitespaceTokenID();
0182:                if (whitespaceTokenID == null) {
0183:                    throw new IllegalStateException(
0184:                            "Valid whitespace token-id required."); // NOI18N
0185:                }
0186:
0187:                insertToken(beforeToken, whitespaceTokenID, null, new String(
0188:                        Analyzer.getSpacesBuffer(spaceCount), 0, spaceCount));
0189:            }
0190:
0191:            /** Whether the token-item can be removed. It can be removed
0192:             * only in case it doesn't come from the document's text
0193:             * and it wasn't yet written to the underlying writer.
0194:             */
0195:            public boolean canRemoveToken(TokenItem token) {
0196:                return formatWriter.canRemoveToken(token);
0197:            }
0198:
0199:            /** Remove the token-item from the chain. It can be removed
0200:             * only in case it doesn't come from the document's text
0201:             * and it wasn't yet written to the underlying writer.
0202:
0203:             */
0204:            public void removeToken(TokenItem token) {
0205:                formatWriter.removeToken(token);
0206:            }
0207:
0208:            /** Remove all the tokens between start and end token inclusive. */
0209:            public void removeTokenChain(TokenItem startToken,
0210:                    TokenItem endToken) {
0211:                while (startToken != null && startToken != endToken) {
0212:                    TokenItem t = startToken.getNext();
0213:                    removeToken(startToken);
0214:                    startToken = t;
0215:                }
0216:            }
0217:
0218:            public TokenItem splitStart(TokenItem token, int startLength,
0219:                    TokenID newTokenID, TokenContextPath newTokenContextPath) {
0220:                return formatWriter.splitStart(token, startLength, newTokenID,
0221:                        newTokenContextPath);
0222:            }
0223:
0224:            public TokenItem splitEnd(TokenItem token, int endLength,
0225:                    TokenID newTokenID, TokenContextPath newTokenContextPath) {
0226:                return formatWriter.splitEnd(token, endLength, newTokenID,
0227:                        newTokenContextPath);
0228:            }
0229:
0230:            public void insertString(TokenItem token, int offset, String text) {
0231:                formatWriter.insertString(token, offset, text);
0232:            }
0233:
0234:            public void insertString(FormatTokenPosition pos, String text) {
0235:                TokenItem token = pos.getToken();
0236:                int offset = pos.getOffset();
0237:
0238:                if (token == null) { // ending position
0239:                    token = getLastToken();
0240:                    if (token == null) {
0241:                        throw new IllegalStateException(
0242:                                "Cannot insert string. No tokens."); // NOI18N
0243:                    }
0244:                    offset = token.getImage().length();
0245:                }
0246:
0247:                insertString(token, offset, text);
0248:            }
0249:
0250:            public void remove(TokenItem token, int offset, int length) {
0251:                formatWriter.remove(token, offset, length);
0252:            }
0253:
0254:            public void remove(FormatTokenPosition pos, int length) {
0255:                remove(pos.getToken(), pos.getOffset(), length);
0256:            }
0257:
0258:            /** Check whether the given token has empty text and if so
0259:             * start searching for token with non-empty text in the given
0260:             * direction. If there's no non-empty token in the given direction
0261:             * the method returns null.
0262:             */
0263:            public TokenItem findNonEmptyToken(TokenItem token, boolean backward) {
0264:                return formatWriter.findNonEmptyToken(token, backward);
0265:            }
0266:
0267:            /** Get the token position that corresponds to the given token and offset.
0268:             * @param token token for which the token-position is being created.
0269:             * @param offset offset inside the token.
0270:             */
0271:            public FormatTokenPosition getPosition(TokenItem token, int offset) {
0272:                return getPosition(token, offset, Position.Bias.Forward);
0273:            }
0274:
0275:            public FormatTokenPosition getPosition(TokenItem token, int offset,
0276:                    Position.Bias bias) {
0277:                return formatWriter.getPosition(token, offset, bias);
0278:            }
0279:
0280:            /** Get the next position of the position given by parameters.
0281:             * It can be either just offset increasing but it can be movement
0282:             * to the next token for the token boundary.
0283:             * @return next token-position or null for the EOT position
0284:             */
0285:            public FormatTokenPosition getNextPosition(TokenItem token,
0286:                    int offset, Position.Bias bias) {
0287:                if (token == null) { // end of chain
0288:                    return null;
0289:
0290:                } else { // regular token
0291:                    offset++;
0292:
0293:                    if (offset >= token.getImage().length()) {
0294:                        token = token.getNext();
0295:                        offset = 0;
0296:                    }
0297:
0298:                    return getPosition(token, offset, bias);
0299:                }
0300:            }
0301:
0302:            /** Get the previous position of the position given by parameters.
0303:             * It can be either just offset decreasing but it can be movement
0304:             * to the previous token for the token boundary.
0305:             * @return next token-position or null for the first position in the chain
0306:             */
0307:            public FormatTokenPosition getPreviousPosition(TokenItem token,
0308:                    int offset, Position.Bias bias) {
0309:                FormatTokenPosition ret = null;
0310:                if (token == null) { // end of chain
0311:                    TokenItem lastToken = findNonEmptyToken(getLastToken(),
0312:                            true);
0313:                    if (lastToken != null) { // regular last token
0314:                        ret = getPosition(lastToken, lastToken.getImage()
0315:                                .length() - 1, Position.Bias.Forward);
0316:                    }
0317:
0318:                } else { // regular token
0319:                    offset--;
0320:
0321:                    if (offset < 0) {
0322:                        token = token.getPrevious();
0323:                        if (token != null) { // was first pos in first token
0324:                            ret = getPosition(token,
0325:                                    token.getImage().length() - 1,
0326:                                    Position.Bias.Forward);
0327:                        }
0328:
0329:                    } else { // still inside token
0330:                        ret = getPosition(token, offset, Position.Bias.Forward);
0331:                    }
0332:                }
0333:
0334:                return ret;
0335:            }
0336:
0337:            /** Get the token-position preceeding the given one. Use the same
0338:             * bias like the given position has.
0339:             */
0340:            public FormatTokenPosition getPreviousPosition(
0341:                    FormatTokenPosition pos) {
0342:                return getPreviousPosition(pos.getToken(), pos.getOffset(), pos
0343:                        .getBias());
0344:            }
0345:
0346:            /** Get the token-position preceeding the given one.
0347:             * @param bias bias that the returned position will have.
0348:             */
0349:            public FormatTokenPosition getPreviousPosition(
0350:                    FormatTokenPosition pos, Position.Bias bias) {
0351:                return getPreviousPosition(pos.getToken(), pos.getOffset(),
0352:                        bias);
0353:            }
0354:
0355:            public FormatTokenPosition getPreviousPosition(TokenItem token,
0356:                    int offset) {
0357:                return getPreviousPosition(token, offset, Position.Bias.Forward);
0358:            }
0359:
0360:            /** Get the next successive token-position after the given one.
0361:             * Use the same bias like the given position has.
0362:             */
0363:            public FormatTokenPosition getNextPosition(FormatTokenPosition pos) {
0364:                return getNextPosition(pos.getToken(), pos.getOffset(), pos
0365:                        .getBias());
0366:            }
0367:
0368:            /** Get the token-position preceeding the given one.
0369:             * @param bias bias that the returned position will have.
0370:             */
0371:            public FormatTokenPosition getNextPosition(FormatTokenPosition pos,
0372:                    Position.Bias bias) {
0373:                return getNextPosition(pos.getToken(), pos.getOffset(), bias);
0374:            }
0375:
0376:            public FormatTokenPosition getNextPosition(TokenItem token,
0377:                    int offset) {
0378:                return getNextPosition(token, offset, Position.Bias.Forward);
0379:            }
0380:
0381:            public boolean isAfter(TokenItem testedToken, TokenItem afterToken) {
0382:                return formatWriter.isAfter(testedToken, afterToken);
0383:            }
0384:
0385:            public boolean isAfter(FormatTokenPosition testedPosition,
0386:                    FormatTokenPosition afterPosition) {
0387:                return formatWriter.isAfter(testedPosition, afterPosition);
0388:            }
0389:
0390:            public boolean isChainStartPosition(FormatTokenPosition pos) {
0391:                return formatWriter.isChainStartPosition(pos);
0392:            }
0393:
0394:            /** Whether the given token can be replaced or not. It's
0395:             * identical to whether the token can be removed.
0396:             */
0397:            public boolean canReplaceToken(TokenItem token) {
0398:                return canRemoveToken(token);
0399:            }
0400:
0401:            /** Replace the given token with the new token.
0402:             * @param originalToken original token to be replaced.
0403:             * @param tokenID token-id of the new token-item
0404:             * @param tokenContextPath token-context-path of the new token-item
0405:             * @param tokenImage token-text of the new token-item
0406:             */
0407:            public void replaceToken(TokenItem originalToken, TokenID tokenID,
0408:                    TokenContextPath tokenContextPath, String tokenImage) {
0409:                if (!canReplaceToken(originalToken)) {
0410:                    throw new IllegalStateException(
0411:                            "Cannot insert token into chain"); // NOI18N
0412:                }
0413:
0414:                TokenItem next = originalToken.getNext();
0415:                removeToken(originalToken);
0416:                insertToken(next, tokenID, tokenContextPath, tokenImage);
0417:            }
0418:
0419:            /** Delegation to the same method in format-writer. */
0420:            public boolean isRestartFormat() {
0421:                return formatWriter.isRestartFormat();
0422:            }
0423:
0424:            /** Delegation to the same method in format-writer. */
0425:            public void setRestartFormat(boolean restartFormat) {
0426:                formatWriter.setRestartFormat(restartFormat);
0427:            }
0428:
0429:            /** Delegation to the same method in format-writer. */
0430:            public int getIndentShift() {
0431:                return formatWriter.getIndentShift();
0432:            }
0433:
0434:            /** Delegation to the same method in format-writer. */
0435:            public void setIndentShift(int indentShift) {
0436:                formatWriter.setIndentShift(indentShift);
0437:            }
0438:
0439:            /** Compare token-id of the compare-token with the given token-id.
0440:             * Token text and token-context-path are ignored in comparison.
0441:             * @param compareToken token to compare
0442:             * @param withTokenID token-id with which the token's token-id is compared
0443:             * @return true if the token-ids match, false otherwise
0444:             */
0445:            public boolean tokenEquals(TokenItem compareToken,
0446:                    TokenID withTokenID) {
0447:                return tokenEquals(compareToken, withTokenID, null, null);
0448:            }
0449:
0450:            /** Compare token-id of the compare-token with the given token-id and
0451:             * token-context-path. Token text is ignored in comparison.
0452:             * @param compareToken token to compare
0453:             * @param withTokenID token-id with which the token's token-id is compared.
0454:             * @param withTokenContextPath token-context-path to which
0455:             *  the token's token-context-path is compared.
0456:             * @return true if the token-ids match, false otherwise
0457:             */
0458:            public boolean tokenEquals(TokenItem compareToken,
0459:                    TokenID withTokenID, TokenContextPath withTokenContextPath) {
0460:                return tokenEquals(compareToken, withTokenID,
0461:                        withTokenContextPath, null);
0462:            }
0463:
0464:            /** Compare token-id of the compare-token with the given token-id and
0465:             * given token-text.
0466:             * @param compareToken token to compare
0467:             * @param withTokenID token-id with which the token's token-id is compared.
0468:             *  It can be null in which case the token-id is ignored from comparison.
0469:             * @param withTokenContextPath token-context-path to which
0470:             *  the token's token-context-path is compared.
0471:             *  It can be null in which case the token-context-path is ignored from comparison.
0472:             * @param withTokenImage token-text with which the token's token-text is compared.
0473:             *  It can be null in which case the token-text is ignored from comparison.
0474:             * @return true if the token-ids and token-texts match, false otherwise
0475:             */
0476:            public boolean tokenEquals(TokenItem compareToken,
0477:                    TokenID withTokenID, TokenContextPath withTokenContextPath,
0478:                    String withTokenImage) {
0479:                return (withTokenID == null || compareToken.getTokenID() == withTokenID)
0480:                        && (withTokenContextPath == null || compareToken
0481:                                .getTokenContextPath() == withTokenContextPath)
0482:                        && (withTokenImage == null || compareToken.getImage()
0483:                                .equals(withTokenImage));
0484:            }
0485:
0486:            /** Decide whether the character at the given offset in the given token
0487:             * is whitespace.
0488:             */
0489:            public boolean isWhitespace(TokenItem token, int offset) {
0490:                return Character.isWhitespace(token.getImage().charAt(offset));
0491:            }
0492:
0493:            public boolean isWhitespace(FormatTokenPosition pos) {
0494:                return isWhitespace(pos.getToken(), pos.getOffset());
0495:            }
0496:
0497:            /** Get the starting position of the line. It searches for the new-line
0498:             * character in backward direction and returns the position
0499:             * of the character following
0500:             * the new-line character or the first character of the first token
0501:             * in the chain.
0502:             * @param pos any token-position on the line.
0503:             */
0504:            public FormatTokenPosition findLineStart(FormatTokenPosition pos) {
0505:                if (isChainStartPosition(pos)) { // begining of the chain
0506:                    return pos;
0507:                }
0508:
0509:                // Go to the previous char
0510:                pos = getPreviousPosition(pos);
0511:
0512:                TokenItem token = pos.getToken();
0513:                int offset = pos.getOffset();
0514:
0515:                while (true) {
0516:                    String text = token.getImage();
0517:                    while (offset >= 0) {
0518:                        if (text.charAt(offset) == '\n') {
0519:                            return getNextPosition(token, offset);
0520:                        }
0521:
0522:                        offset--;
0523:                    }
0524:
0525:                    if (token.getPrevious() == null) {
0526:                        // This is the first token in chain, return position 0
0527:                        return getPosition(token, 0);
0528:                    }
0529:                    token = token.getPrevious();
0530:                    offset = token.getImage().length() - 1;
0531:                }
0532:            }
0533:
0534:            /** Get the ending position of the line. It searches for the new-line
0535:             * character and returns the position of it
0536:             * or the position after the last character of the last token
0537:             * in the chain.
0538:             * @param pos any token-position on the line.
0539:             */
0540:            public FormatTokenPosition findLineEnd(FormatTokenPosition pos) {
0541:                TokenItem token = pos.getToken();
0542:                int offset = pos.getOffset();
0543:
0544:                if (token == null) { // end of whole chain is EOL too
0545:                    return pos;
0546:                }
0547:
0548:                while (true) {
0549:                    String text = token.getImage();
0550:                    int textLen = text.length();
0551:                    while (offset < textLen) {
0552:                        if (text.charAt(offset) == '\n') {
0553:                            return getPosition(token, offset);
0554:                        }
0555:
0556:                        offset++;
0557:                    }
0558:
0559:                    if (token.getNext() == null) {
0560:                        // This is the first token in chain, return end position
0561:                        return getPosition(null, 0);
0562:                    }
0563:
0564:                    token = token.getNext();
0565:                    offset = 0;
0566:                }
0567:            }
0568:
0569:            /** Return the first non-whitespace character on the line
0570:             * or null if there is no non-WS char on the line.
0571:             */
0572:            public FormatTokenPosition findLineFirstNonWhitespace(
0573:                    FormatTokenPosition pos) {
0574:                pos = findLineStart(pos);
0575:                TokenItem token = pos.getToken();
0576:                int offset = pos.getOffset();
0577:
0578:                if (token == null) { // no line start, no WS
0579:                    return null;
0580:                }
0581:
0582:                while (true) {
0583:                    String text = token.getImage();
0584:                    int textLen = text.length();
0585:                    while (offset < textLen) {
0586:                        if (text.charAt(offset) == '\n') {
0587:                            return null;
0588:                        }
0589:
0590:                        if (!isWhitespace(token, offset)) {
0591:                            return getPosition(token, offset);
0592:                        }
0593:
0594:                        offset++;
0595:                    }
0596:
0597:                    if (token.getNext() == null) {
0598:                        return null;
0599:                    }
0600:
0601:                    token = token.getNext();
0602:                    offset = 0;
0603:                }
0604:            }
0605:
0606:            /** Return the ending whitespace on the line or null
0607:             * if there's no such token on the given line.
0608:             */
0609:            public FormatTokenPosition findLineEndWhitespace(
0610:                    FormatTokenPosition pos) {
0611:                pos = findLineEnd(pos);
0612:                if (isChainStartPosition(pos)) { // empty first line
0613:                    return pos;
0614:
0615:                } else {
0616:                    pos = getPreviousPosition(pos);
0617:                }
0618:
0619:                TokenItem token = pos.getToken();
0620:                int offset = pos.getOffset();
0621:                while (true) {
0622:                    String text = token.getImage();
0623:                    int textLen = text.length();
0624:                    while (offset >= 0) {
0625:                        if (offset < textLen
0626:                                && ((text.charAt(offset) == '\n') || !isWhitespace(
0627:                                        token, offset))) {
0628:                            return getNextPosition(token, offset);
0629:                        }
0630:
0631:                        offset--;
0632:                    }
0633:
0634:                    if (token.getPrevious() == null) {
0635:                        // This is the first token in chain, return position 0
0636:                        return getPosition(token, 0);
0637:                    }
0638:
0639:                    token = token.getPrevious();
0640:                    offset = token.getImage().length() - 1;
0641:                }
0642:            }
0643:
0644:            /** Get the first EOL in backward direction. The current position
0645:             * is ignored by the search.
0646:             * @return first EOL in backward direction or null if there
0647:             *  is no such token.
0648:             */
0649:            public FormatTokenPosition findPreviousEOL(FormatTokenPosition pos) {
0650:                pos = getPreviousPosition(pos);
0651:                if (pos == null) { // was the start position
0652:                    return null;
0653:                }
0654:
0655:                TokenItem token = pos.getToken();
0656:                int offset = pos.getOffset();
0657:
0658:                while (true) {
0659:                    String text = token.getImage();
0660:                    while (offset >= 0) {
0661:                        if (text.charAt(offset) == '\n') {
0662:                            return getPosition(token, offset);
0663:                        }
0664:
0665:                        offset--;
0666:                    }
0667:
0668:                    if (token.getPrevious() == null) {
0669:                        return null;
0670:                    }
0671:
0672:                    token = token.getPrevious();
0673:                    offset = token.getImage().length() - 1;
0674:                }
0675:            }
0676:
0677:            /** Get the first EOL in forward direction.
0678:             * @param pos starting token-position that is ignored by the search
0679:             *  so it can be even EOL.
0680:             * @return first EOL token-position in the forward direction or null if there
0681:             *  is no such token.
0682:             */
0683:            public FormatTokenPosition findNextEOL(FormatTokenPosition pos) {
0684:                pos = getNextPosition(pos);
0685:                if (pos == null) {
0686:                    return null;
0687:                }
0688:
0689:                TokenItem token = pos.getToken();
0690:                int offset = pos.getOffset();
0691:
0692:                if (token == null) { // right at the end
0693:                    return null;
0694:                }
0695:
0696:                while (true) {
0697:                    String text = token.getImage();
0698:                    int textLen = text.length();
0699:                    while (offset < textLen) {
0700:                        if (text.charAt(offset) == '\n') {
0701:                            return getPosition(token, offset);
0702:                        }
0703:
0704:                        offset++;
0705:                    }
0706:
0707:                    if (token.getNext() == null) {
0708:                        return null;
0709:                    }
0710:
0711:                    token = token.getNext();
0712:                    offset = 0;
0713:                }
0714:            }
0715:
0716:            /** Check whether there are no tokens except the ending EOL
0717:             * on the given line.
0718:             * @param pos any position on the line
0719:             */
0720:            public boolean isLineEmpty(FormatTokenPosition pos) {
0721:                return findLineStart(pos).equals(findLineEnd(pos));
0722:            }
0723:
0724:            /** Check whether there are only the whitespace tokens
0725:             * on the given line.
0726:             * @param token any token on the line. It doesn't have to be the first one.
0727:             */
0728:            public boolean isLineWhite(FormatTokenPosition pos) {
0729:                FormatTokenPosition lineStart = findLineStart(pos);
0730:                return findLineEndWhitespace(pos).equals(lineStart);
0731:            }
0732:
0733:            /** Get the column-offset of the tokenItem on its line. The tabs
0734:             * are expanded according to the tab-size.
0735:             */
0736:            public int getVisualColumnOffset(FormatTokenPosition pos) {
0737:                TokenItem targetToken = pos.getToken();
0738:                int targetOffset = pos.getOffset();
0739:
0740:                FormatTokenPosition lineStart = findLineStart(pos);
0741:                TokenItem token = lineStart.getToken();
0742:                int offset = lineStart.getOffset();
0743:
0744:                int col = 0;
0745:                int tabSize = formatWriter.getFormatter().getTabSize();
0746:
0747:                while (token != null) {
0748:                    String text = token.getImage();
0749:                    int textLen = text.length();
0750:                    while (offset < textLen) {
0751:                        if (token == targetToken && offset == targetOffset) {
0752:                            return col;
0753:                        }
0754:
0755:                        switch (text.charAt(offset)) {
0756:                        case '\t':
0757:                            col = (col + tabSize) / tabSize * tabSize;
0758:                            break;
0759:                        default:
0760:                            col++;
0761:                        }
0762:
0763:                        offset++;
0764:                    }
0765:
0766:                    token = token.getNext();
0767:                    offset = 0;
0768:                }
0769:
0770:                return col;
0771:            }
0772:
0773:            /** Get the first non-whitespace position in the given direction.
0774:             * @param startPosition position at which the search starts.
0775:             *  For the backward search the character right at startPosition
0776:             *  is not considered as part of the search.
0777:             * @param limitPosition the token where the search will be broken
0778:             *  reporting that nothing was found. It can be null to search
0779:             *  till the end or begining of the chain (depending on direction).
0780:             *  For forward search the char at the limitPosition
0781:             *  is not considered to be part of search,
0782:             *  but for backward search it is.
0783:             * @param stopOnEOL whether stop and return EOL position
0784:             *  or continue search if EOL token is found.
0785:             * @param backward whether search in backward direction.
0786:             * @return first non-whitespace position or EOL or null if all the tokens
0787:             *  till the begining of the chain are whitespaces.
0788:             */
0789:            public FormatTokenPosition findNonWhitespace(
0790:                    FormatTokenPosition startPosition,
0791:                    FormatTokenPosition limitPosition, boolean stopOnEOL,
0792:                    boolean backward) {
0793:
0794:                // Return immediately for equal positions
0795:                if (startPosition.equals(limitPosition)) {
0796:                    return null;
0797:                }
0798:
0799:                if (backward) { // Backward search
0800:                    TokenItem limitToken;
0801:                    int limitOffset;
0802:
0803:                    if (limitPosition == null) {
0804:                        limitToken = null;
0805:                        limitOffset = 0;
0806:
0807:                    } else { // valid limit position
0808:                        limitPosition = getPreviousPosition(limitPosition);
0809:                        if (limitPosition == null) {
0810:                            limitToken = null;
0811:                            limitOffset = 0;
0812:
0813:                        } else { // valid limit position
0814:                            limitToken = limitPosition.getToken();
0815:                            limitOffset = limitPosition.getOffset();
0816:                        }
0817:                    }
0818:
0819:                    startPosition = getPreviousPosition(startPosition);
0820:                    if (startPosition == null) {
0821:                        return null;
0822:                    }
0823:
0824:                    TokenItem token = startPosition.getToken();
0825:                    int offset = startPosition.getOffset();
0826:
0827:                    while (true) {
0828:                        String text = token.getImage();
0829:                        while (offset >= 0) {
0830:                            if (stopOnEOL && text.charAt(offset) == '\n') {
0831:                                return null;
0832:                            }
0833:
0834:                            if (!isWhitespace(token, offset)) {
0835:                                return getPosition(token, offset);
0836:                            }
0837:
0838:                            if (token == limitToken && offset == limitOffset) {
0839:                                return null;
0840:                            }
0841:
0842:                            offset--;
0843:                        }
0844:
0845:                        token = token.getPrevious();
0846:                        if (token == null) {
0847:                            return null;
0848:                        }
0849:                        offset = token.getImage().length() - 1;
0850:                    }
0851:
0852:                } else { // Forward direction
0853:                    TokenItem limitToken;
0854:                    int limitOffset;
0855:
0856:                    if (limitPosition == null) {
0857:                        limitToken = null;
0858:                        limitOffset = 0;
0859:
0860:                    } else { // valid limit position
0861:                        limitToken = limitPosition.getToken();
0862:                        limitOffset = limitPosition.getOffset();
0863:                    }
0864:
0865:                    TokenItem token = startPosition.getToken();
0866:                    int offset = startPosition.getOffset();
0867:
0868:                    while (true) {
0869:                        String text = token.getImage();
0870:                        int textLen = text.length();
0871:                        while (offset < textLen) {
0872:                            if (token == limitToken && offset == limitOffset) {
0873:                                return null;
0874:                            }
0875:
0876:                            if (stopOnEOL && text.charAt(offset) == '\n') {
0877:                                return null;
0878:                            }
0879:
0880:                            if (!isWhitespace(token, offset)) {
0881:                                return getPosition(token, offset);
0882:                            }
0883:
0884:                            offset++;
0885:                        }
0886:
0887:                        token = token.getNext();
0888:                        if (token == null) {
0889:                            return null;
0890:                        }
0891:                        offset = 0;
0892:                    }
0893:                }
0894:            }
0895:
0896:            /** Get the previous token or last token if the argument is null. */
0897:            public TokenItem getPreviousToken(TokenItem token) {
0898:                return (token == null) ? getLastToken() : token.getPrevious();
0899:            }
0900:
0901:            /** Get the token-id that should be assigned to the token
0902:             * that consists of the indentation whitespace only. This method should
0903:             * be overriden in the descendants.
0904:             */
0905:            public TokenID getWhitespaceTokenID() {
0906:                return null;
0907:            }
0908:
0909:            /** Get the valid whitespace token-id by calling <tt>getWhitespaceTokenID()</tt>.
0910:             * Throw <tt>IllegalStateException</tt> if the whitespace-token-id is null.
0911:             */
0912:            public TokenID getValidWhitespaceTokenID() {
0913:                TokenID wsID = getWhitespaceTokenID();
0914:                if (wsID == null) {
0915:                    throw new IllegalStateException("Null whitespace token-id"); // NOI18N
0916:                }
0917:                return wsID;
0918:            }
0919:
0920:            /** Get the token-context-path that should be assigned to the token
0921:             * that consists of the indentation whitespace only. This method should
0922:             * be overriden in the descendants.
0923:             */
0924:            public TokenContextPath getWhitespaceTokenContextPath() {
0925:                return null;
0926:            }
0927:
0928:            /** Get the valid whitespace token-context-path
0929:             * by calling <tt>getWhitespaceTokenContextPath()</tt>.
0930:             * Throw <tt>IllegalStateException</tt> if the whitespace-token-id is null.
0931:             */
0932:            public TokenContextPath getValidWhitespaceTokenContextPath() {
0933:                TokenContextPath wsTCP = getWhitespaceTokenContextPath();
0934:                if (wsTCP == null) {
0935:                    throw new IllegalStateException(
0936:                            "Null whitespace token-context-path"); // NOI18N
0937:                }
0938:                return wsTCP;
0939:            }
0940:
0941:            /** Check whether the given token enables modifying
0942:             * of a whitespace in it. This method should be overriden
0943:             * in the descendants.
0944:             */
0945:            public boolean canModifyWhitespace(TokenItem inToken) {
0946:                return false;
0947:            }
0948:
0949:            /** This delegates to the same method in formatter. */
0950:            public String getIndentString(int indent) {
0951:                return formatWriter.getFormatter().getIndentString(indent);
0952:            }
0953:
0954:            /** Get the indentation of the line.
0955:             * @param formatTokenPosition any position on the line.
0956:             *   It doesn't have to be the first one.
0957:             * @param zeroForWSLine If set to true the method will return zero
0958:             *   in case the line consist of whitespace only. If false
0959:             *   the method will return the indentation even for whitespace
0960:             *   lines.
0961:             */
0962:            public int getLineIndent(FormatTokenPosition pos,
0963:                    boolean zeroForWSLine) {
0964:                FormatTokenPosition firstNWS = findLineFirstNonWhitespace(pos);
0965:                if (firstNWS == null) { // no non-WS char on the line
0966:                    if (zeroForWSLine) {
0967:                        return 0;
0968:
0969:                    } else { // return indent even for WS lines
0970:                        firstNWS = findLineEnd(pos);
0971:                    }
0972:                }
0973:
0974:                return getVisualColumnOffset(firstNWS);
0975:            }
0976:
0977:            /** Change the indentation of the line. This method should
0978:             * be always called for all the lines because it ensures
0979:             * that the indentation will contain exactly the characters from
0980:             * the indentation string.
0981:             * @param pos any position on the line being checked.
0982:             * @param indent the indentation for the line.
0983:             * @return some position on the line
0984:             */
0985:            public FormatTokenPosition changeLineIndent(
0986:                    FormatTokenPosition pos, int indent) {
0987:                pos = findLineStart(pos); // go to line begining
0988:                String indentString = getIndentString(indent);
0989:                int indentStringLen = indentString.length();
0990:                int indentStringInd = 0; // current index in the indentString
0991:                TokenItem token = pos.getToken();
0992:                int offset = pos.getOffset();
0993:
0994:                if (token == null) { // last line is empty, append the indent string
0995:                    if (indentString.length() > 0) {
0996:                        token = insertToken(null, getValidWhitespaceTokenID(),
0997:                                getValidWhitespaceTokenContextPath(),
0998:                                indentString);
0999:                    }
1000:                    return pos; // return original end-of-chain position
1001:                }
1002:
1003:                while (true) {
1004:
1005:                    String text = token.getImage();
1006:                    int textLen = text.length();
1007:
1008:                    while (indentStringInd < indentStringLen
1009:                            && offset < textLen) {
1010:                        if (indentString.charAt(indentStringInd) != text
1011:                                .charAt(offset)) {
1012:                            if (canModifyWhitespace(token)) {
1013:                                // modify token text to insert the whitespace
1014:                                insertString(token, offset, indentString
1015:                                        .substring(indentStringInd));
1016:                                offset += indentStringLen - indentStringInd; // skip WS
1017:                                indentStringInd = indentStringLen;
1018:
1019:                            } else { // cannot modify the whitespace of this token
1020:                                if (isWhitespace(token, offset) || offset > 0) {
1021:                                    throw new IllegalStateException(
1022:                                            "Cannot modify token=" + token); // NOI18N
1023:
1024:                                } else { // nonWS token at begining, will insert WS
1025:                                    insertToken(
1026:                                            token,
1027:                                            getValidWhitespaceTokenID(),
1028:                                            getValidWhitespaceTokenContextPath(),
1029:                                            indentString
1030:                                                    .substring(indentStringInd));
1031:                                    return getPosition(token, 0);
1032:                                }
1033:                            }
1034:
1035:                        } else { // current char matches indentString
1036:                            indentStringInd++; // advance inside indentString
1037:                            offset++;
1038:                        }
1039:                    }
1040:
1041:                    if (indentStringInd < indentStringLen) { // move to next token
1042:                        token = token.getNext();
1043:                        if (token == null) { // was last token, insert WS token
1044:                            token = insertToken(null,
1045:                                    getValidWhitespaceTokenID(),
1046:                                    getValidWhitespaceTokenContextPath(),
1047:                                    indentString.substring(indentStringInd));
1048:                            return getPosition(token, 0);
1049:
1050:                        } else { // non-null token
1051:                            offset = 0;
1052:                        }
1053:
1054:                    } else { // indent already done, need to remove all the resting WS
1055:
1056:                        while (true) {
1057:                            text = token.getImage();
1058:                            textLen = text.length();
1059:                            int removeInd = -1;
1060:
1061:                            while (offset < textLen) {
1062:                                if (!isWhitespace(token, offset)
1063:                                        || text.charAt(offset) == '\n') {
1064:                                    if (removeInd >= 0) {
1065:                                        remove(token, removeInd, offset
1066:                                                - removeInd);
1067:                                        offset = removeInd;
1068:                                    }
1069:
1070:                                    return getPosition(token, offset);
1071:
1072:                                } else { // whitespace char found
1073:                                    if (removeInd < 0) {
1074:                                        removeInd = offset;
1075:                                    }
1076:                                }
1077:                                offset++;
1078:                            }
1079:
1080:                            if (removeInd == -1) { // nothing to remove
1081:                                token = token.getNext(); // was right at the end
1082:
1083:                            } else if (removeInd == 0) { // remove whole token
1084:                                TokenItem nextToken = token.getNext();
1085:                                removeToken(token);
1086:                                token = nextToken;
1087:
1088:                            } else { // remove just end part of token
1089:                                remove(token, removeInd, textLen - removeInd);
1090:                                token = token.getNext();
1091:                            }
1092:                            offset = 0;
1093:
1094:                            if (token == null) {
1095:                                return getPosition(null, 0);
1096:                            }
1097:                        }
1098:                    }
1099:                }
1100:            }
1101:
1102:            /** Debug the current state of the chain.
1103:             * @param token mark this token as current one. It can be null.
1104:             */
1105:            public String chainToString(TokenItem token) {
1106:                return formatWriter.chainToString(token);
1107:            }
1108:
1109:            public String chainToString(TokenItem token, int maxDocumentTokens) {
1110:                return formatWriter.chainToString(token, maxDocumentTokens);
1111:            }
1112:
1113:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.