View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.struts2.jasper.compiler;
18  
19  import org.apache.struts2.jasper.JasperException;
20  import org.apache.struts2.jasper.Options;
21  
22  /***
23   */
24  public class TextOptimizer {
25  
26      /***
27       * A visitor to concatenate contiguous template texts.
28       */
29      static class TextCatVisitor extends Node.Visitor {
30  
31          private Options options;
32          private int textNodeCount = 0;
33          private Node.TemplateText firstTextNode = null;
34          private StringBuffer textBuffer;
35          private final String emptyText = new String("");
36  
37          public TextCatVisitor(Compiler compiler) {
38              options = compiler.getCompilationContext().getOptions();
39          }
40  
41          public void doVisit(Node n) throws JasperException {
42              collectText();
43          }
44  
45          /*
46          * The following directis are ignored in text concatenation
47          */
48  
49          public void visit(Node.PageDirective n) throws JasperException {
50          }
51  
52          public void visit(Node.TagDirective n) throws JasperException {
53          }
54  
55          public void visit(Node.TaglibDirective n) throws JasperException {
56          }
57  
58          public void visit(Node.AttributeDirective n) throws JasperException {
59          }
60  
61          public void visit(Node.VariableDirective n) throws JasperException {
62          }
63  
64          /*
65           * Don't concatenate text across body boundaries
66           */
67          public void visitBody(Node n) throws JasperException {
68              super.visitBody(n);
69              collectText();
70          }
71  
72          public void visit(Node.TemplateText n) throws JasperException {
73  
74              if (options.getTrimSpaces() && n.isAllSpace()) {
75                  n.setText(emptyText);
76                  return;
77              }
78  
79              if (textNodeCount++ == 0) {
80                  firstTextNode = n;
81                  textBuffer = new StringBuffer(n.getText());
82              } else {
83                  // Append text to text buffer
84                  textBuffer.append(n.getText());
85                  n.setText(emptyText);
86              }
87          }
88  
89          /***
90           * This method breaks concatenation mode.  As a side effect it copies
91           * the concatenated string to the first text node
92           */
93          private void collectText() {
94  
95              if (textNodeCount > 1) {
96                  // Copy the text in buffer into the first template text node.
97                  firstTextNode.setText(textBuffer.toString());
98              }
99              textNodeCount = 0;
100         }
101 
102     }
103 
104     public static void concatenate(Compiler compiler, Node.Nodes page)
105             throws JasperException {
106 
107         TextCatVisitor v = new TextCatVisitor(compiler);
108         page.visit(v);
109 
110         // Cleanup, in case the page ends with a template text
111         v.collectText();
112     }
113 }