##### Coverage Report - org.webmacro.engine.BlockBuilder

Classes in this File | Line Coverage | Branch Coverage | Complexity
BlockBuilder |
81% | 62/76
72% | 13/18
| 1.6;1.6
BlockBuilder$BBIterator |
90% | 9/10
100% | 2/2
| 1.6;1.6
BlockBuilder$BlockIterator |
N/A | N/A
N/A | N/A
| 1.6;1.6

1 |  |
     /*
2 |  |
      * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
3 |  |
      *
4 |  |
      * Redistribution and use in source and binary forms, with or without
5 |  |
      * modification, are permitted under the terms of either of the following
6 |  |
      * Open Source licenses:
7 |  |
      *
8 |  |
      * The GNU General Public License, version 2, or any later version, as
9 |  |
      * published by the Free Software Foundation
10 |  |
      * (http://www.fsf.org/copyleft/gpl.html);
11 |  |
      *
12 |  |
      *  or
13 |  |
      *
14 |  |
      * The Semiotek Public License (http://webmacro.org/LICENSE.)
15 |  |
      *
16 |  |
      * This software is provided "as is", with NO WARRANTY, not even the
17 |  |
      * implied warranties of fitness to purpose, or merchantability. You
18 |  |
      * assume all risks and liabilities associated with its use.
19 |  |
      *
20 |  |
      * See www.webmacro.org for more information on the WebMacro project.
21 |  |
      */
22 |  |
23 |  |
     package org.webmacro.engine;
24 |  |
25 |  |
     import org.webmacro.Context;
26 |  |
     import org.webmacro.Macro;
27 |  |
28 |  |
     import java.util.ArrayList;
29 |  |
     import java.util.Iterator;
30 |  |
     import java.util.Stack;
31 |  |
32 |  |
     /**
33 |  |
      * A block represents the text between two {}'s in a template, or else
34 |  |
      * the text that begins at the start of the template and runs until its
35 |  |
      * end ({}'s around the whole document are not required). It contains
36 |  |
      * all of the other directives, strings, etc. that can be in a template.
37 |  |
      */
38 | 30024 |
     public class BlockBuilder implements Builder
39 |  |
     {
40 |  |
41 |  |
         private static final int INITIAL_SIZE = 64;
42 |  |
43 | 2 |
         private static Macro[] mArray = new Macro[0];
44 | 2 |
         private static String[] sArray = new String[0];
45 |  |
46 | 1488 |
         private ArrayList elements = new ArrayList();
47 | 1488 |
         private int[] lineNos = new int[INITIAL_SIZE];
48 | 1488 |
         private int[] colNos = new int[INITIAL_SIZE];
49 |  |
50 | 1488 |
         private String name = "unknown";
51 |  |
52 |  |
         public BlockBuilder ()
53 | 0 |
         {
54 | 0 |
         }
55 |  |
56 |  |
         public BlockBuilder (String name)
57 | 1488 |
         {
58 | 1488 |
             this.name = name;
59 | 1488 |
         }
60 |  |
61 |  |
         /** Iterate over a Block.   */
62 |  |
         public interface BlockIterator extends Iterator
63 |  |
         {
64 |  |
65 |  |
             public String getName ();
66 |  |
67 |  |
             public int getLineNo ();
68 |  |
69 |  |
             public int getColNo ();
70 |  |
         }
71 |  |
72 |  |
         /** BlockBuilder iterator.   */
73 |  |
         public class BBIterator implements BlockIterator
74 |  |
         {
75 |  |
76 |  |
             private int size, i;
77 |  |
78 |  |
             public BBIterator ()
79 | 1484 |
             {
80 | 1484 |
                 size = elements.size();
81 | 1484 |
                 i = 0;
82 | 1484 |
             }
83 |  |
84 |  |
             public String getName ()
85 |  |
             {
86 | 3782 |
                 return name;
87 |  |
             }
88 |  |
89 |  |
             public boolean hasNext ()
90 |  |
             {
91 | 20744 |
                 return (i < size);
92 |  |
             }
93 |  |
94 |  |
             public Object next ()
95 |  |
             {
96 | 9630 |
                 return elements.get(i++);
97 |  |
             }
98 |  |
99 |  |
             public int getLineNo ()
100 |  |
             {
101 | 7564 |
                 return lineNos[i - 1];
102 |  |
             }
103 |  |
104 |  |
             public int getColNo ()
105 |  |
             {
106 | 7564 |
                 return colNos[i - 1];
107 |  |
             }
108 |  |
109 |  |
             public void remove ()
110 |  |
             {
111 | 0 |
                 throw new UnsupportedOperationException();
112 |  |
             }
113 |  |
         }
114 |  |
115 |  |
         final public Object build (BuildContext bc) throws BuildException
116 |  |
         {
117 | 1484 |
             ArrayList strings = new ArrayList((elements.size()));
118 | 1484 |
             ArrayList macros = new ArrayList((elements.size()));
119 | 1484 |
             int[] ln = new int[elements.size()];
120 | 1484 |
             int[] cn = new int[elements.size()];
121 | 1484 |
             Stack iterStack = new Stack();
122 | 1484 |
             StringBuffer s = new StringBuffer();
123 | 1484 |
             Context.TemplateEvaluationContext tec = bc.getTemplateEvaluationContext();
124 |  |
125 |  |
             // flatten everything and view the content as being:
126 |  |
             //        string (macro string)* string
127 |  |
             // store that as an array of strings and an array of
128 |  |
             // Macro objects and create a block.
129 |  |
130 | 1484 |
             BlockIterator iter = new BBIterator();
131 | 11114 |
             while (iter.hasNext())
132 |  |
             {
133 | 9630 |
                 Object o = iter.next();
134 |  |
135 | 9630 |
                 if (o instanceof Builder)
136 |  |
                 {
137 |  |
                     // track line/column numbers in the build context
138 |  |
                     // so that bc.getCurrentLocation() stays current
139 | 3782 |
                     tec._templateName = iter.getName();
140 | 3782 |
                     tec._lineNo = iter.getLineNo();
141 | 3782 |
                     tec._columnNo = iter.getColNo();
142 |  |
143 |  |
                     try
144 |  |
                     {
145 | 3782 |
                         o = ((Builder) o).build(bc);
146 |  |
                     }
147 | 0 |
                     catch (BuildException be)
148 |  |
                     {
149 |  |
                         // restore line/column info to what it was before
150 |  |
                         // we tried to build the block
151 | 0 |
                         tec._templateName = iter.getName();
152 | 0 |
                         tec._lineNo = iter.getLineNo();
153 | 0 |
                         tec._columnNo = iter.getColNo();
154 |  |
155 |  |
                         // and rethrow the exception
156 | 0 |
                         throw be;
157 | 3782 |
                     }
158 |  |
                 }
159 |  |
160 | 9630 |
                 if (o instanceof Block)
161 |  |
                 {
162 | 0 |
                     iterStack.push(iter);
163 | 0 |
                     iter = ((Block) o).getBlockIterator();
164 |  |
                 }
165 |  |
                 else
166 |  |
                 {
167 | 9630 |
                     if (o instanceof Macro)
168 |  |
                     {
169 | 3782 |
                         strings.add(s.toString());
170 | 3782 |
                         s = new StringBuffer();
171 |  |
                         // do not reuse StringBuffer,
172 |  |
                         // otherwise all strings will contain char[] of max length!!
173 | 3782 |
                         macros.add(o);
174 |  |
175 |  |
                         // Now deal with the line numbers
176 | 3782 |
                         int size = macros.size();
177 | 3782 |
                         if (ln.length < size)
178 |  |
                         {
179 | 0 |
                             ln = resizeIntArray(ln, ln.length * 2);
180 | 0 |
                             cn = resizeIntArray(cn, cn.length * 2);
181 |  |
                         }
182 | 3782 |
                         ln[size - 1] = iter.getLineNo();
183 | 3782 |
                         cn[size - 1] = iter.getColNo();
184 | 3782 |
                     }
185 | 5848 |
                     else if (o != null)
186 |  |
                     {
187 | 5848 |
                         s.append(o.toString());
188 |  |
                     }
189 |  |
                 }
190 | 9630 |
                 while (!iter.hasNext() && !iterStack.empty())
191 | 0 |
                     iter = (BlockIterator) iterStack.pop();
192 | 9630 |
             }
193 | 1484 |
             strings.add(s.toString());
194 |  |
195 | 1484 |
             Macro finalMacros[] = (Macro[]) macros.toArray(mArray);
196 | 1484 |
             String finalStrings[] = (String[]) strings.toArray(sArray);
197 | 1484 |
             int finalLines[] = resizeIntArray(ln, macros.size());
198 | 1484 |
             int finalCols[] = resizeIntArray(cn, macros.size());
199 | 1484 |
             return new Block(name, finalStrings, finalMacros, finalLines, finalCols);
200 |  |
         }
201 |  |
202 |  |
         private static int[] resizeIntArray (int[] ia, int size)
203 |  |
         {
204 | 2968 |
             int[] temp = new int[size];
205 | 2968 |
             System.arraycopy(ia, 0, temp, 0, Math.min(ia.length, size));
206 | 2968 |
             return temp;
207 |  |
         }
208 |  |
209 |  |
         // Methods that look like Vector methods
210 |  |
211 |  |
         public void addElement (Object o)
212 |  |
         {
213 | 13096 |
             elements.add(o);
214 | 13096 |
         }
215 |  |
216 |  |
         public void addElement (Object o, int lineNo, int colNo)
217 |  |
         {
218 | 3890 |
             elements.add(o);
219 |  |
220 | 3890 |
             int size = elements.size();
221 | 3890 |
             if (lineNos.length < size)
222 |  |
             {
223 | 0 |
                 lineNos = resizeIntArray(lineNos, Math.max(lineNos.length * 2,
224 |  |
                         size + INITIAL_SIZE));
225 | 0 |
                 colNos = resizeIntArray(colNos, Math.max(colNos.length * 2,
226 |  |
                         size + INITIAL_SIZE));
227 |  |
             }
228 | 3890 |
             lineNos[size - 1] = lineNo;
229 | 3890 |
             colNos[size - 1] = colNo;
230 | 3890 |
         }
231 |  |
232 |  |
         public int size ()
233 |  |
         {
234 | 44016 |
             return elements.size();
235 |  |
         }
236 |  |
237 |  |
         public void remove (int i)
238 |  |
         {
239 | 7356 |
             elements.remove(i);
240 | 7356 |
         }
241 |  |
242 |  |
         public Object elementAt (int i)
243 |  |
         {
244 | 17620 |
             return elements.get(i);
245 |  |
         }
246 |  |
247 |  |
         public Object setElementAt (Object o, int i)
248 |  |
         {
249 | 1184 |
             return elements.set(i, o);
250 |  |
         }
251 |  |
252 |  |
     }
253 |  |