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


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans.modules.editor.structure.formatting;
043:
044:        import java.io.IOException;
045:        import java.io.Writer;
046:        import java.util.ArrayList;
047:        import java.util.Arrays;
048:        import java.util.LinkedList;
049:        import java.util.List;
050:        import javax.swing.text.BadLocationException;
051:        import javax.swing.text.JTextComponent;
052:        import javax.swing.text.Position;
053:        import org.netbeans.editor.BaseDocument;
054:        import org.netbeans.editor.TokenItem;
055:        import org.netbeans.editor.Utilities;
056:        import org.netbeans.editor.ext.ExtFormatter;
057:        import org.netbeans.editor.ext.ExtSyntaxSupport;
058:        import org.openide.ErrorManager;
059:
060:        /**
061:         *
062:         * @author Tomasz.Slota@Sun.COM
063:         */
064:        @Deprecated
065:        // use TagBasedLexerFormatter instead
066:        public abstract class TagBasedFormatter extends ExtFormatter {
067:
068:            /** Creates a new instance of TagBases */
069:            public TagBasedFormatter(Class kitClass) {
070:                super (kitClass);
071:                ErrorManager.getDefault().log(
072:                        ErrorManager.WARNING,
073:                        "Class " + getClass().getName()
074:                                + " is deprecated, use *IndentTask");
075:            }
076:
077:            protected abstract ExtSyntaxSupport getSyntaxSupport(
078:                    BaseDocument doc);
079:
080:            protected abstract boolean isClosingTag(TokenItem token);
081:
082:            protected abstract boolean isUnformattableToken(TokenItem token);
083:
084:            protected abstract boolean isUnformattableTag(String tag);
085:
086:            protected abstract boolean isOpeningTag(TokenItem token);
087:
088:            protected abstract String extractTagName(TokenItem tknTag);
089:
090:            protected abstract boolean areTagNamesEqual(String tagName1,
091:                    String tagName2);
092:
093:            protected abstract boolean isClosingTagRequired(BaseDocument doc,
094:                    String tagName);
095:
096:            protected abstract int getOpeningSymbolOffset(TokenItem tknTag);
097:
098:            protected abstract TokenItem getTagTokenEndingAtPosition(
099:                    BaseDocument doc, int position) throws BadLocationException;
100:
101:            protected abstract int getTagEndOffset(TokenItem token);
102:
103:            protected Writer extFormatterReformat(final BaseDocument doc,
104:                    final int startOffset, final int endOffset,
105:                    final boolean indentOnly) throws BadLocationException,
106:                    IOException {
107:                return super .reformat(doc, startOffset, endOffset, indentOnly);
108:            }
109:
110:            protected boolean isWSTag(TokenItem tag) {
111:                char chars[] = tag.getImage().toCharArray();
112:
113:                for (char c : chars) {
114:                    if (!Character.isWhitespace(c)) {
115:                        return false;
116:                    }
117:                }
118:
119:                return true;
120:            }
121:
122:            protected int getIndentForTagParameter(BaseDocument doc,
123:                    TokenItem tag) throws BadLocationException {
124:                int tagStartLine = Utilities
125:                        .getLineOffset(doc, tag.getOffset());
126:                TokenItem currentToken = tag.getNext();
127:
128:                /*
129:                 * Find the offset of the first attribute if it is specified on the same line as the opening of the tag
130:                 * e.g. <tag   |attr=
131:                 * 
132:                 */
133:                while (currentToken != null
134:                        && isWSTag(currentToken)
135:                        && tagStartLine == Utilities.getLineOffset(doc,
136:                                currentToken.getOffset())) {
137:                    currentToken = currentToken.getNext();
138:                }
139:
140:                if (tag != null
141:                        && !isWSTag(currentToken)
142:                        && tagStartLine == Utilities.getLineOffset(doc,
143:                                currentToken.getOffset())) {
144:                    return currentToken.getOffset()
145:                            - Utilities.getRowIndent(doc, currentToken
146:                                    .getOffset())
147:                            - Utilities.getRowStart(doc, currentToken
148:                                    .getOffset());
149:                }
150:
151:                return getShiftWidth(); // default;
152:            }
153:
154:            @Override
155:            public Writer reformat(BaseDocument doc, int startOffset,
156:                    int endOffset, boolean indentOnly)
157:                    throws BadLocationException {
158:
159:                if (!hasValidSyntaxSupport(doc)) {
160:                    return null;
161:                }
162:
163:                LinkedList<TagIndentationData> unprocessedOpeningTags = new LinkedList<TagIndentationData>();
164:                List<TagIndentationData> matchedOpeningTags = new ArrayList<TagIndentationData>();
165:                doc.atomicLock();
166:
167:                try {
168:                    int lastLine = Utilities
169:                            .getLineOffset(doc, doc.getLength());
170:                    int firstRefBlockLine = Utilities.getLineOffset(doc,
171:                            startOffset);
172:                    int lastRefBlockLine = Utilities.getLineOffset(doc,
173:                            endOffset);
174:                    int firstUnformattableLine = -1;
175:
176:                    boolean unformattableLines[] = new boolean[lastLine + 1];
177:                    int indentsWithinTags[] = new int[lastLine + 1];
178:
179:                    ExtSyntaxSupport sup = getSyntaxSupport(doc);
180:                    TokenItem token = sup.getTokenChain(0, doc.getLength() - 1);
181:
182:                    if (token != null) {
183:                        // calc line indents - pass 1
184:                        do {
185:                            boolean isOpenTag = isOpeningTag(token);
186:                            boolean isCloseTag = isClosingTag(token);
187:
188:                            if (isOpenTag || isCloseTag) {
189:
190:                                String tagName = extractTagName(token);
191:                                int tagEndOffset = getTagEndOffset(token);
192:
193:                                if (tagEndOffset == -1) {
194:                                    break; // incomplete closing tag
195:                                }
196:
197:                                int lastTagLine = Utilities.getLineOffset(doc,
198:                                        tagEndOffset);
199:
200:                                if (isOpenTag) {
201:
202:                                    TagIndentationData tagData = new TagIndentationData(
203:                                            tagName, lastTagLine);
204:                                    unprocessedOpeningTags.add(tagData);
205:
206:                                    // format lines within tag
207:                                    int firstTagLine = Utilities.getLineOffset(
208:                                            doc, token.getOffset());
209:
210:                                    if (firstTagLine < lastTagLine) { // performance!
211:                                        int indentWithinTag = getIndentForTagParameter(
212:                                                doc, token);
213:
214:                                        for (int i = firstTagLine + 1; i <= lastTagLine; i++) {
215:                                            indentsWithinTags[i] = indentWithinTag;
216:                                        }
217:
218:                                        // if there is only the closing symbol on the last line of tag do not indent it
219:                                        TokenItem currentToken = token
220:                                                .getNext();
221:                                        while (Utilities.getLineOffset(doc,
222:                                                currentToken.getOffset()) < lastTagLine
223:                                                || isWSTag(currentToken)) {
224:
225:                                            currentToken = currentToken
226:                                                    .getNext();
227:                                        }
228:
229:                                        if (currentToken.getOffset() == tagEndOffset) {
230:                                            indentsWithinTags[lastTagLine] = 0;
231:                                        }
232:                                    }
233:                                } else {
234:                                    // isCloseTag - find matching opening tag record
235:                                    LinkedList<TagIndentationData> tagsToBeRemoved = new LinkedList<TagIndentationData>();
236:
237:                                    while (!unprocessedOpeningTags.isEmpty()) {
238:                                        TagIndentationData processedTD = unprocessedOpeningTags
239:                                                .removeLast();
240:
241:                                        if (areTagNamesEqual(tagName,
242:                                                processedTD.getTagName())) {
243:                                            processedTD
244:                                                    .setClosedOnLine(lastTagLine);
245:                                            matchedOpeningTags.add(processedTD);
246:
247:                                            // mark all the stuff between unformattable tag as unformattable
248:                                            if (isUnformattableTag(tagName)) {
249:                                                for (int i = lastTagLine - 1; i > processedTD
250:                                                        .getLine(); i--) {
251:                                                    unformattableLines[i] = true;
252:                                                }
253:                                            }
254:
255:                                            // forgetting preceding tags permanently
256:                                            tagsToBeRemoved.clear();
257:                                            break;
258:                                        } else {
259:                                            tagsToBeRemoved.add(processedTD);
260:                                        }
261:                                    }
262:
263:                                    // if matching opening tag was not found on the stack put all the tags back
264:                                    unprocessedOpeningTags
265:                                            .addAll(tagsToBeRemoved);
266:                                }
267:                            }
268:
269:                            boolean wasPreviousTokenUnformattable = isUnformattableToken(token);
270:
271:                            if (wasPreviousTokenUnformattable
272:                                    && firstUnformattableLine == -1) {
273:                                firstUnformattableLine = Utilities
274:                                        .getLineOffset(doc, token.getOffset());
275:                            }
276:
277:                            token = token.getNext();
278:
279:                            // detect an end of unformattable block; mark it
280:                            if (firstUnformattableLine > -1
281:                                    && (!wasPreviousTokenUnformattable || token == null)) {
282:
283:                                int lastUnformattableLine = token == null ? lastLine
284:                                        : Utilities.getLineOffset(doc, token
285:                                                .getOffset() - 1);
286:
287:                                for (int i = firstUnformattableLine + 1; i < lastUnformattableLine; i++) {
288:                                    unformattableLines[i] = true;
289:                                }
290:
291:                                firstUnformattableLine = -1;
292:                            }
293:                        } while (token != null);
294:                    }
295:
296:                    // calc line indents - pass 2
297:                    // TODO: optimize it
298:                    int indentLevels[] = new int[lastLine + 1];
299:                    Arrays.fill(indentLevels, 0);
300:
301:                    for (TagIndentationData td : matchedOpeningTags) {
302:                        // increase indent from one line after the opening tag
303:                        // up to one line before the closing tag
304:
305:                        for (int i = td.getLine() + 1; i <= td
306:                                .getClosedOnLine() - 1; i++) {
307:                            indentLevels[i]++;
308:                        }
309:                    }
310:
311:                    // when reformatting only a part of file
312:                    // we need to take into account the local bias
313:                    InitialIndentData initialIndentData = new InitialIndentData(
314:                            doc, indentLevels, indentsWithinTags,
315:                            firstRefBlockLine, lastRefBlockLine);
316:
317:                    // apply line indents
318:                    for (int line = firstRefBlockLine; line <= lastRefBlockLine; line++) {
319:                        int lineStart = Utilities.getRowStartFromLineOffset(
320:                                doc, line);
321:
322:                        if (!unformattableLines[line]
323:                                && initialIndentData.isEligibleToIndent(line)) {
324:                            changeRowIndent(doc, lineStart, initialIndentData
325:                                    .getIndent(line));
326:                        }
327:                    }
328:                } finally {
329:                    doc.atomicUnlock();
330:                }
331:
332:                return null;
333:            }
334:
335:            protected void enterPressed(JTextComponent txtComponent, int dotPos)
336:                    throws BadLocationException {
337:                BaseDocument doc = Utilities.getDocument(txtComponent);
338:                int lineNumber = Utilities.getLineOffset(doc, dotPos);
339:                int initialIndent = getInitialIndentFromPreviousLine(doc,
340:                        lineNumber);
341:                int endOfPreviousLine = Utilities.getFirstNonWhiteBwd(doc,
342:                        dotPos);
343:                endOfPreviousLine = endOfPreviousLine == -1 ? 0
344:                        : endOfPreviousLine;
345:
346:                // workaround for \n passed from code completion to reformatter
347:                if (lineNumber == Utilities.getLineOffset(doc,
348:                        endOfPreviousLine)) {
349:                    return;
350:                }
351:
352:                TokenItem tknOpeningTag = getTagTokenEndingAtPosition(doc,
353:                        endOfPreviousLine);
354:
355:                if (isOpeningTag(tknOpeningTag)) {
356:                    TokenItem tknClosingTag = getNextClosingTag(doc, dotPos + 1);
357:
358:                    if (tknClosingTag != null) {
359:                        TokenItem tknMatchingOpeningTag = getMatchingOpeningTag(tknClosingTag);
360:
361:                        if (tknMatchingOpeningTag != null
362:                                && tknMatchingOpeningTag.getOffset() == tknOpeningTag
363:                                        .getOffset()) {
364:
365:                            int openingTagLine = Utilities.getLineOffset(doc,
366:                                    tknOpeningTag.getOffset());
367:                            int closingTagLine = Utilities.getLineOffset(doc,
368:                                    tknClosingTag.getOffset());
369:
370:                            if (closingTagLine == Utilities.getLineOffset(doc,
371:                                    dotPos)) {
372:
373:                                if (openingTagLine == closingTagLine - 1) {
374:                                    /* "smart enter"
375:                                     * <t>|optional text</t>
376:                                     */
377:                                    Position closingTagPos = doc
378:                                            .createPosition(getOpeningSymbolOffset(tknClosingTag));
379:                                    changeRowIndent(doc, dotPos, initialIndent
380:                                            + doc.getShiftWidth());
381:                                    doc.insertString(closingTagPos.getOffset(),
382:                                            "\n", null); //NOI18N
383:                                    int newCaretPos = closingTagPos.getOffset() - 1;
384:                                    changeRowIndent(doc, closingTagPos
385:                                            .getOffset() + 1, initialIndent);
386:                                    newCaretPos = Utilities.getRowEnd(doc,
387:                                            newCaretPos);
388:                                    txtComponent.setCaretPosition(newCaretPos);
389:                                } else {
390:                                    /*  <t>
391:                                     *
392:                                     *  |</t>
393:                                     */
394:                                    changeRowIndent(doc, dotPos, initialIndent);
395:                                }
396:                            }
397:                        }
398:
399:                        int indent = initialIndent;
400:
401:                        if (isClosingTagRequired(doc,
402:                                extractTagName(tknOpeningTag))) {
403:                            indent += doc.getShiftWidth();
404:                        }
405:
406:                        changeRowIndent(doc, dotPos, indent);
407:                    }
408:                } else {
409:                    int indent = initialIndent;
410:
411:                    if (isJustBeforeClosingTag(doc, dotPos)) {
412:                        indent -= doc.getShiftWidth();
413:                        indent = indent < 0 ? 0 : indent;
414:                    }
415:
416:                    // preceeding token is not opening tag, keep same indentation
417:                    changeRowIndent(doc, dotPos, indent);
418:                }
419:            }
420:
421:            @Override
422:            public int[] getReformatBlock(JTextComponent target,
423:                    String typedText) {
424:                BaseDocument doc = Utilities.getDocument(target);
425:
426:                if (!hasValidSyntaxSupport(doc)) {
427:                    return null;
428:                }
429:
430:                char lastChar = typedText.charAt(typedText.length() - 1);
431:
432:                try {
433:                    int dotPos = target.getCaret().getDot();
434:
435:                    if (lastChar == '>') {
436:                        TokenItem tknPrecedingToken = getTagTokenEndingAtPosition(
437:                                doc, dotPos - 1);
438:
439:                        if (isClosingTag(tknPrecedingToken)) {
440:                            // the user has just entered a closing tag
441:                            // - reformat it unless matching opening tag is on the same line 
442:
443:                            TokenItem tknOpeningTag = getMatchingOpeningTag(tknPrecedingToken);
444:
445:                            if (tknOpeningTag != null) {
446:                                int openingTagLine = Utilities.getLineOffset(
447:                                        doc, tknOpeningTag.getOffset());
448:                                int closingTagSymbolLine = Utilities
449:                                        .getLineOffset(doc, dotPos);
450:
451:                                if (openingTagLine != closingTagSymbolLine) {
452:                                    return new int[] {
453:                                            tknPrecedingToken.getOffset(),
454:                                            dotPos };
455:                                }
456:                            }
457:                        }
458:                    }
459:
460:                    else if (lastChar == '\n') {
461:                        // just pressed enter
462:                        enterPressed(target, dotPos);
463:                    }
464:
465:                } catch (Exception e) {
466:                    ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
467:                }
468:
469:                return null;
470:            }
471:
472:            protected TokenItem getMatchingOpeningTag(TokenItem tknClosingTag) {
473:                String searchedTagName = extractTagName(tknClosingTag);
474:                TokenItem token = tknClosingTag.getPrevious();
475:                int balance = 0;
476:
477:                while (token != null) {
478:                    if (areTagNamesEqual(searchedTagName, extractTagName(token))) {
479:                        if (isOpeningTag(token)) {
480:                            if (balance == 0) {
481:                                return token;
482:                            }
483:
484:                            balance--;
485:                        } else if (isClosingTag(token)) {
486:                            balance++;
487:                        }
488:                    }
489:
490:                    token = token.getPrevious();
491:                }
492:
493:                return null;
494:            }
495:
496:            protected int getInitialIndentFromPreviousLine(
497:                    final BaseDocument doc, final int line)
498:                    throws BadLocationException {
499:
500:                // get initial indent from the previous line
501:                int initialIndent = 0;
502:
503:                if (line > 0) {
504:                    int lineStart = Utilities.getRowStartFromLineOffset(doc,
505:                            line);
506:                    int previousNonWhiteLineEnd = Utilities
507:                            .getFirstNonWhiteBwd(doc, lineStart);
508:
509:                    if (previousNonWhiteLineEnd > 0) {
510:                        initialIndent = Utilities.getRowIndent(doc,
511:                                previousNonWhiteLineEnd);
512:                    }
513:                }
514:
515:                return initialIndent;
516:            }
517:
518:            private int getInitialIndentFromNextLine(final BaseDocument doc,
519:                    final int line) throws BadLocationException {
520:
521:                // get initial indent from the next line
522:                int initialIndent = 0;
523:
524:                int lineStart = Utilities.getRowStartFromLineOffset(doc, line);
525:                int lineEnd = Utilities.getRowEnd(doc, lineStart);
526:                int nextNonWhiteLineStart = Utilities.getFirstNonWhiteFwd(doc,
527:                        lineEnd);
528:
529:                if (nextNonWhiteLineStart > 0) {
530:                    initialIndent = Utilities.getRowIndent(doc,
531:                            nextNonWhiteLineStart, true);
532:                }
533:
534:                return initialIndent;
535:            }
536:
537:            private boolean hasValidSyntaxSupport(BaseDocument doc) {
538:                ExtSyntaxSupport sup = getSyntaxSupport(doc);
539:
540:                if (sup == null) {
541:                    ErrorManager
542:                            .getDefault()
543:                            .log(
544:                                    ErrorManager.WARNING,
545:                                    "TagBasedFormatter: failed to retrieve SyntaxSupport for document;"
546:                                            + //NOI18N
547:                                            " probably attempt to use incompatible indentation engine"); //NOI18N
548:
549:                    return false;
550:                }
551:
552:                return true;
553:            }
554:
555:            protected static int getNumberOfLines(BaseDocument doc)
556:                    throws BadLocationException {
557:                return Utilities.getLineOffset(doc, doc.getLength() - 1) + 1;
558:            }
559:
560:            protected TokenItem getNextClosingTag(BaseDocument doc, int offset)
561:                    throws BadLocationException {
562:                ExtSyntaxSupport sup = getSyntaxSupport(doc);
563:                TokenItem token = sup.getTokenChain(offset, offset + 1);
564:
565:                while (token != null) {
566:                    if (isClosingTag(token)) {
567:                        return token;
568:                    }
569:
570:                    token = token.getNext();
571:                }
572:
573:                return null;
574:            }
575:
576:            protected boolean isJustBeforeClosingTag(BaseDocument doc, int pos)
577:                    throws BadLocationException {
578:                ExtSyntaxSupport sup = getSyntaxSupport(doc);
579:                TokenItem tknTag = sup.getTokenChain(pos, pos + 1);
580:
581:                if (isClosingTag(tknTag)) {
582:                    return true;
583:                }
584:
585:                return false;
586:            }
587:
588:            protected class InitialIndentData {
589:                private final int indentLevelBias;
590:                private final int indentBias;
591:                private final int indentLevels[];
592:                private final int indentsWithinTags[];
593:                private BaseDocument doc;
594:
595:                public InitialIndentData(BaseDocument doc, int indentLevels[],
596:                        int indentsWithinTags[], int firstRefBlockLine,
597:                        int lastRefBlockLine) throws BadLocationException {
598:
599:                    int initialIndent = getInitialIndentFromPreviousLine(doc,
600:                            firstRefBlockLine);
601:                    int indentLevelBiasFromTheTop = initialIndent
602:                            / doc.getShiftWidth()
603:                            - (firstRefBlockLine > 0 ? indentLevels[firstRefBlockLine - 1]
604:                                    : 0);
605:
606:                    int initialIndentFromTheBottom = getInitialIndentFromNextLine(
607:                            doc, lastRefBlockLine);
608:                    int indentLevelBiasFromTheBottom = initialIndentFromTheBottom
609:                            / doc.getShiftWidth()
610:                            - (lastRefBlockLine < getNumberOfLines(doc) - 1 ? indentLevels[lastRefBlockLine + 1]
611:                                    : 0);
612:
613:                    if (indentLevelBiasFromTheBottom > indentLevelBiasFromTheTop) {
614:                        indentLevelBias = indentLevelBiasFromTheBottom;
615:                        initialIndent = initialIndentFromTheBottom;
616:                    } else {
617:                        indentLevelBias = indentLevelBiasFromTheTop;
618:                    }
619:
620:                    indentBias = initialIndent % doc.getShiftWidth();
621:                    this .indentLevels = indentLevels;
622:                    this .indentsWithinTags = indentsWithinTags;
623:                    this .doc = doc;
624:                }
625:
626:                public boolean isEligibleToIndent(int line) {
627:                    return getActualIndentLevel(line) >= 0;
628:                }
629:
630:                public int getIndent(int line) {
631:                    return indentBias + indentsWithinTags[line]
632:                            + getActualIndentLevel(line) * doc.getShiftWidth();
633:                }
634:
635:                private int getActualIndentLevel(int line) {
636:                    return indentLevels[line] + indentLevelBias;
637:                }
638:            }
639:
640:            protected static class TagIndentationData {
641:                private final String tagName;
642:                private final int line;
643:                private int closedOnLine;
644:
645:                public TagIndentationData(String tagName, int line) {
646:                    this .tagName = tagName;
647:                    this .line = line;
648:                }
649:
650:                public String getTagName() {
651:                    return tagName;
652:                }
653:
654:                public int getLine() {
655:                    return line;
656:                }
657:
658:                public int getClosedOnLine() {
659:                    return closedOnLine;
660:                }
661:
662:                public void setClosedOnLine(int closedOnLine) {
663:                    this.closedOnLine = closedOnLine;
664:                }
665:            }
666:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.