001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.jasper.compiler;
017:
018: import org.apache.jasper.JasperException;
019: import org.apache.jasper.Options;
020:
021: /**
022: */
023: public class TextOptimizer {
024:
025: /**
026: * A visitor to concatenate contiguous template texts.
027: */
028: static class TextCatVisitor extends Node.Visitor {
029:
030: private Options options;
031: private int textNodeCount = 0;
032: private Node.TemplateText firstTextNode = null;
033: private StringBuffer textBuffer;
034: private final String emptyText = new String("");
035:
036: public TextCatVisitor(Compiler compiler) {
037: options = compiler.getCompilationContext().getOptions();
038: }
039:
040: public void doVisit(Node n) throws JasperException {
041: collectText();
042: }
043:
044: /*
045: * The following directis are ignored in text concatenation
046: */
047:
048: public void visit(Node.PageDirective n) throws JasperException {
049: }
050:
051: public void visit(Node.TagDirective n) throws JasperException {
052: }
053:
054: public void visit(Node.TaglibDirective n)
055: throws JasperException {
056: }
057:
058: public void visit(Node.AttributeDirective n)
059: throws JasperException {
060: }
061:
062: public void visit(Node.VariableDirective n)
063: throws JasperException {
064: }
065:
066: /*
067: * Don't concatenate text across body boundaries
068: */
069: public void visitBody(Node n) throws JasperException {
070: super .visitBody(n);
071: collectText();
072: }
073:
074: public void visit(Node.TemplateText n) throws JasperException {
075:
076: if (options.getTrimSpaces() && n.isAllSpace()) {
077: n.setText(emptyText);
078: return;
079: }
080:
081: if (textNodeCount++ == 0) {
082: firstTextNode = n;
083: textBuffer = new StringBuffer(n.getText());
084: } else {
085: // Append text to text buffer
086: textBuffer.append(n.getText());
087: n.setText(emptyText);
088: }
089: }
090:
091: /**
092: * This method breaks concatenation mode. As a side effect it copies
093: * the concatenated string to the first text node
094: */
095: private void collectText() {
096:
097: if (textNodeCount > 1) {
098: // Copy the text in buffer into the first template text node.
099: firstTextNode.setText(textBuffer.toString());
100: }
101: textNodeCount = 0;
102: }
103:
104: }
105:
106: public static void concatenate(Compiler compiler, Node.Nodes page)
107: throws JasperException {
108:
109: TextCatVisitor v = new TextCatVisitor(compiler);
110: page.visit(v);
111:
112: // Cleanup, in case the page ends with a template text
113: v.collectText();
114: }
115: }
|