| 39 | | private final StringBuffer buffer; |
|---|
| 40 | | |
|---|
| 41 | | private final StringBuffer textBuffer; |
|---|
| 42 | | |
|---|
| 43 | | private final List instructionBuffer; |
|---|
| 44 | | |
|---|
| 45 | | private final Stack tags; |
|---|
| 46 | | |
|---|
| 47 | | private final List children; |
|---|
| 48 | | |
|---|
| 49 | | private boolean startTagOpen; |
|---|
| 50 | | |
|---|
| 51 | | private final String alias; |
|---|
| 52 | | |
|---|
| 53 | | public TextUnit(String alias) { |
|---|
| 54 | | this.alias = alias; |
|---|
| 55 | | this.buffer = new StringBuffer(); |
|---|
| 56 | | this.textBuffer = new StringBuffer(); |
|---|
| 57 | | this.instructionBuffer = new ArrayList(); |
|---|
| 58 | | this.tags = new Stack(); |
|---|
| 59 | | this.children = new ArrayList(); |
|---|
| 60 | | this.startTagOpen = false; |
|---|
| 61 | | } |
|---|
| 62 | | |
|---|
| 63 | | public TemplateHandler createTemplateHandler() { |
|---|
| 64 | | this.flushBufferToConfig(true); |
|---|
| 65 | | |
|---|
| 66 | | if (this.children.size() == 0) { |
|---|
| 67 | | return LEAF; |
|---|
| 68 | | } |
|---|
| 69 | | |
|---|
| 70 | | TemplateHandler[] h = new TemplateHandler[this.children.size()]; |
|---|
| 71 | | Object obj; |
|---|
| 72 | | for (int i = 0; i < h.length; i++) { |
|---|
| 73 | | obj = this.children.get(i); |
|---|
| 74 | | if (obj instanceof TemplateHandler) { |
|---|
| 75 | | h[i] = (TemplateHandler) obj; |
|---|
| 76 | | } else { |
|---|
| 77 | | h[i] = ((CompilationUnit) obj).createTemplateHandler(); |
|---|
| 78 | | } |
|---|
| 79 | | } |
|---|
| 80 | | if (h.length == 1) { |
|---|
| 81 | | return h[0]; |
|---|
| 82 | | } |
|---|
| 83 | | return new CompositeTemplateHandler(h); |
|---|
| 84 | | } |
|---|
| 85 | | |
|---|
| 86 | | private void addInstruction(Instruction instruction) { |
|---|
| 87 | | this.flushTextBuffer(false); |
|---|
| 88 | | this.instructionBuffer.add(instruction); |
|---|
| 89 | | } |
|---|
| 90 | | |
|---|
| 91 | | private void flushTextBuffer(boolean child) { |
|---|
| 92 | | if (this.textBuffer.length() > 0) { |
|---|
| 93 | | String s = this.textBuffer.toString(); |
|---|
| 94 | | |
|---|
| 95 | | if (child) { |
|---|
| 96 | | s = trimRight(s); |
|---|
| 97 | | } |
|---|
| 98 | | if (s.length() > 0) { |
|---|
| 99 | | ELText txt = ELText.parse(s); |
|---|
| 100 | | if (txt != null) { |
|---|
| 101 | | if (txt.isLiteral()) { |
|---|
| 102 | | this.instructionBuffer.add(new LiteralTextInstruction( |
|---|
| 103 | | txt.toString())); |
|---|
| 104 | | } else { |
|---|
| 105 | | this.instructionBuffer.add(new TextInstruction( |
|---|
| 106 | | this.alias, txt)); |
|---|
| 107 | | } |
|---|
| 108 | | } |
|---|
| 109 | | } |
|---|
| 110 | | |
|---|
| 111 | | } |
|---|
| 112 | | this.textBuffer.setLength(0); |
|---|
| 113 | | } |
|---|
| 114 | | |
|---|
| 115 | | public void write(String text) { |
|---|
| 116 | | this.finishStartTag(); |
|---|
| 117 | | this.textBuffer.append(text); |
|---|
| 118 | | this.buffer.append(text); |
|---|
| 119 | | } |
|---|
| 120 | | |
|---|
| 121 | | public void writeInstruction(String text) { |
|---|
| 122 | | this.finishStartTag(); |
|---|
| 123 | | ELText el = ELText.parse(text); |
|---|
| 124 | | if (el.isLiteral()) { |
|---|
| 125 | | this.addInstruction(new LiteralXMLInstruction(text)); |
|---|
| 126 | | } else { |
|---|
| 127 | | this.addInstruction(new XMLInstruction(el)); |
|---|
| 128 | | } |
|---|
| 129 | | this.buffer.append(text); |
|---|
| 130 | | } |
|---|
| 131 | | |
|---|
| 132 | | public void writeComment(String text) { |
|---|
| 133 | | this.finishStartTag(); |
|---|
| 134 | | |
|---|
| 135 | | ELText el = ELText.parse(text); |
|---|
| 136 | | if (el.isLiteral()) { |
|---|
| 137 | | this.addInstruction(new LiteralCommentInstruction(text)); |
|---|
| 138 | | } else { |
|---|
| 139 | | this.addInstruction(new CommentInstruction(el)); |
|---|
| 140 | | } |
|---|
| 141 | | |
|---|
| 142 | | this.buffer.append("<!--" + text + "-->"); |
|---|
| 143 | | } |
|---|
| 144 | | |
|---|
| 145 | | public void startTag(Tag tag) { |
|---|
| 146 | | |
|---|
| 147 | | // finish any previously written tags |
|---|
| 148 | | this.finishStartTag(); |
|---|
| 149 | | |
|---|
| 150 | | // push this tag onto the stack |
|---|
| 151 | | this.tags.push(tag); |
|---|
| 152 | | |
|---|
| 153 | | // write it out |
|---|
| 154 | | this.buffer.append('<'); |
|---|
| 155 | | this.buffer.append(tag.getQName()); |
|---|
| 156 | | |
|---|
| 157 | | this.addInstruction(new StartElementInstruction(tag.getQName())); |
|---|
| 158 | | |
|---|
| 159 | | TagAttribute[] attrs = tag.getAttributes().getAll(); |
|---|
| 160 | | if (attrs.length > 0) { |
|---|
| 161 | | for (int i = 0; i < attrs.length; i++) { |
|---|
| 162 | | String qname = attrs[i].getQName(); |
|---|
| 163 | | String value = attrs[i].getValue(); |
|---|
| 164 | | this.buffer.append(' ').append(qname).append("=\"").append( |
|---|
| 165 | | value).append("\""); |
|---|
| 166 | | |
|---|
| 167 | | ELText txt = ELText.parse(value); |
|---|
| 168 | | if (txt != null) { |
|---|
| 169 | | if (txt.isLiteral()) { |
|---|
| 170 | | this.addInstruction(new LiteralAttributeInstruction( |
|---|
| 171 | | qname, txt.toString())); |
|---|
| 172 | | } else { |
|---|
| 173 | | this.addInstruction(new AttributeInstruction( |
|---|
| 174 | | this.alias, qname, txt)); |
|---|
| 175 | | } |
|---|
| 176 | | } |
|---|
| 177 | | } |
|---|
| 178 | | } |
|---|
| 179 | | |
|---|
| 180 | | // notify that we have an open tag |
|---|
| 181 | | this.startTagOpen = true; |
|---|
| 182 | | } |
|---|
| 183 | | |
|---|
| 184 | | private void finishStartTag() { |
|---|
| 185 | | if (this.tags.size() > 0 && this.startTagOpen) { |
|---|
| 186 | | this.buffer.append(">"); |
|---|
| 187 | | this.startTagOpen = false; |
|---|
| 188 | | } |
|---|
| 189 | | } |
|---|
| 190 | | |
|---|
| 191 | | public void endTag() { |
|---|
| 192 | | Tag tag = (Tag) this.tags.pop(); |
|---|
| 193 | | |
|---|
| 194 | | this.addInstruction(new EndElementInstruction(tag.getQName())); |
|---|
| 195 | | |
|---|
| 196 | | if (this.startTagOpen) { |
|---|
| 197 | | this.buffer.append("/>"); |
|---|
| 198 | | this.startTagOpen = false; |
|---|
| 199 | | } else { |
|---|
| 200 | | this.buffer.append("</").append(tag.getQName()).append('>'); |
|---|
| 201 | | } |
|---|
| 202 | | } |
|---|
| 203 | | |
|---|
| 204 | | public void addChild(CompilationUnit unit) { |
|---|
| 205 | | // if we are adding some other kind of unit |
|---|
| 206 | | // then we need to capture our buffer into a UITextHandler |
|---|
| 207 | | this.finishStartTag(); |
|---|
| 208 | | this.flushBufferToConfig(true); |
|---|
| 209 | | this.children.add(unit); |
|---|
| 210 | | } |
|---|
| 211 | | |
|---|
| 212 | | protected void flushBufferToConfig(boolean child) { |
|---|
| 213 | | |
|---|
| 214 | | // NEW IMPLEMENTATION |
|---|
| 215 | | if (true) { |
|---|
| 216 | | |
|---|
| 217 | | this.flushTextBuffer(child); |
|---|
| 218 | | |
|---|
| 219 | | int size = this.instructionBuffer.size(); |
|---|
| 220 | | if (size > 0) { |
|---|
| 221 | | try { |
|---|
| 222 | | String s = this.buffer.toString(); |
|---|
| 223 | | if (child) |
|---|
| 224 | | s = trimRight(s); |
|---|
| 225 | | ELText txt = ELText.parse(s); |
|---|
| 226 | | if (txt != null) { |
|---|
| 227 | | Instruction[] instructions = (Instruction[]) this.instructionBuffer |
|---|
| 228 | | .toArray(new Instruction[size]); |
|---|
| 229 | | this.children.add(new UIInstructionHandler(this.alias, |
|---|
| 230 | | instructions, txt)); |
|---|
| 231 | | this.instructionBuffer.clear(); |
|---|
| 232 | | } |
|---|
| 233 | | |
|---|
| 234 | | } catch (ELException e) { |
|---|
| 235 | | if (this.tags.size() > 0) { |
|---|
| 236 | | throw new TagException((Tag) this.tags.peek(), e |
|---|
| 237 | | .getMessage()); |
|---|
| 238 | | } else { |
|---|
| 239 | | throw new ELException(this.alias + ": " |
|---|
| 240 | | + e.getMessage(), e.getCause()); |
|---|
| 241 | | } |
|---|
| 242 | | } |
|---|
| 243 | | } |
|---|
| 244 | | |
|---|
| 245 | | // KEEP THESE SEPARATE SO LOGIC DOESN'T GET FUBARED |
|---|
| 246 | | } else if (this.buffer.length() > 0) { |
|---|
| 247 | | String s = this.buffer.toString(); |
|---|
| 248 | | if (s.trim().length() > 0) { |
|---|
| 249 | | if (child) { |
|---|
| 250 | | s = trimRight(s); |
|---|
| 251 | | } |
|---|
| 252 | | if (s.length() > 0) { |
|---|
| 253 | | try { |
|---|
| 254 | | ELText txt = ELText.parse(s); |
|---|
| 255 | | if (txt != null) { |
|---|
| 256 | | if (txt.isLiteral()) { |
|---|
| 257 | | this.children.add(new UILiteralTextHandler(txt |
|---|
| 258 | | .toString())); |
|---|
| 259 | | } else { |
|---|
| 260 | | this.children.add(new UITextHandler(this.alias, |
|---|
| 261 | | txt)); |
|---|
| 262 | | } |
|---|
| 263 | | } |
|---|
| 264 | | } catch (ELException e) { |
|---|
| 265 | | if (this.tags.size() > 0) { |
|---|
| 266 | | throw new TagException((Tag) this.tags.peek(), e |
|---|
| 267 | | .getMessage()); |
|---|
| 268 | | } else { |
|---|
| 269 | | throw new ELException(this.alias + ": " |
|---|
| 270 | | + e.getMessage(), e.getCause()); |
|---|
| 271 | | } |
|---|
| 272 | | } |
|---|
| 273 | | } |
|---|
| 274 | | } |
|---|
| 275 | | } |
|---|
| 276 | | |
|---|
| 277 | | // ALWAYS CLEAR FOR BOTH IMPL |
|---|
| 278 | | this.buffer.setLength(0); |
|---|
| 279 | | } |
|---|
| 280 | | |
|---|
| 281 | | public boolean isClosed() { |
|---|
| 282 | | return this.tags.empty(); |
|---|
| 283 | | } |
|---|
| 284 | | |
|---|
| 285 | | private final static String trimRight(String s) { |
|---|
| 286 | | int i = s.length() - 1; |
|---|
| 287 | | while (i >= 0 && Character.isWhitespace(s.charAt(i))) { |
|---|
| 288 | | i--; |
|---|
| 289 | | } |
|---|
| 290 | | if (i == s.length() - 1) { |
|---|
| 291 | | return s; |
|---|
| 292 | | } else { |
|---|
| 293 | | return s.substring(0, i + 1); |
|---|
| 294 | | } |
|---|
| 295 | | } |
|---|
| 296 | | |
|---|
| 297 | | public String toString() { |
|---|
| 298 | | return "TextUnit[" + this.children.size() + "]"; |
|---|
| 299 | | } |
|---|
| | 36 | private final StringBuffer buffer; |
|---|
| | 37 | |
|---|
| | 38 | private final StringBuffer textBuffer; |
|---|
| | 39 | |
|---|
| | 40 | private final List instructionBuffer; |
|---|
| | 41 | |
|---|
| | 42 | private final Stack tags; |
|---|
| | 43 | |
|---|
| | 44 | private final List children; |
|---|
| | 45 | |
|---|
| | 46 | private boolean startTagOpen; |
|---|
| | 47 | |
|---|
| | 48 | private final String alias; |
|---|
| | 49 | |
|---|
| | 50 | public TextUnit(String alias) { |
|---|
| | 51 | this.alias = alias; |
|---|
| | 52 | this.buffer = new StringBuffer(); |
|---|
| | 53 | this.textBuffer = new StringBuffer(); |
|---|
| | 54 | this.instructionBuffer = new ArrayList(); |
|---|
| | 55 | this.tags = new Stack(); |
|---|
| | 56 | this.children = new ArrayList(); |
|---|
| | 57 | this.startTagOpen = false; |
|---|
| | 58 | } |
|---|
| | 59 | |
|---|
| | 60 | public TemplateHandler createTemplateHandler() { |
|---|
| | 61 | this.flushBufferToConfig(); |
|---|
| | 62 | |
|---|
| | 63 | if (this.children.size() == 0) { |
|---|
| | 64 | return LEAF; |
|---|
| | 65 | } |
|---|
| | 66 | |
|---|
| | 67 | TemplateHandler[] h = new TemplateHandler[this.children.size()]; |
|---|
| | 68 | Object obj; |
|---|
| | 69 | for (int i = 0; i < h.length; i++) { |
|---|
| | 70 | obj = this.children.get(i); |
|---|
| | 71 | if (obj instanceof TemplateHandler) { |
|---|
| | 72 | h[i] = (TemplateHandler) obj; |
|---|
| | 73 | } else { |
|---|
| | 74 | h[i] = ((CompilationUnit) obj).createTemplateHandler(); |
|---|
| | 75 | } |
|---|
| | 76 | } |
|---|
| | 77 | if (h.length == 1) { |
|---|
| | 78 | return h[0]; |
|---|
| | 79 | } |
|---|
| | 80 | return new CompositeTemplateHandler(h); |
|---|
| | 81 | } |
|---|
| | 82 | |
|---|
| | 83 | private void addInstruction(Instruction instruction) { |
|---|
| | 84 | this.flushTextBuffer(); |
|---|
| | 85 | this.instructionBuffer.add(instruction); |
|---|
| | 86 | } |
|---|
| | 87 | |
|---|
| | 88 | private void flushTextBuffer() { |
|---|
| | 89 | if (this.textBuffer.length() > 0) { |
|---|
| | 90 | String s = this.textBuffer.toString(); |
|---|
| | 91 | |
|---|
| | 92 | if (s.length() > 0) { |
|---|
| | 93 | ELText txt = ELText.parse(s); |
|---|
| | 94 | if (txt != null) { |
|---|
| | 95 | if (txt.isLiteral()) { |
|---|
| | 96 | this.instructionBuffer.add(new LiteralTextInstruction( |
|---|
| | 97 | txt.toString())); |
|---|
| | 98 | } else { |
|---|
| | 99 | this.instructionBuffer.add(new TextInstruction( |
|---|
| | 100 | this.alias, txt)); |
|---|
| | 101 | } |
|---|
| | 102 | } |
|---|
| | 103 | } |
|---|
| | 104 | |
|---|
| | 105 | } |
|---|
| | 106 | this.textBuffer.setLength(0); |
|---|
| | 107 | } |
|---|
| | 108 | |
|---|
| | 109 | public void write(String text) { |
|---|
| | 110 | this.finishStartTag(); |
|---|
| | 111 | this.textBuffer.append(text); |
|---|
| | 112 | this.buffer.append(text); |
|---|
| | 113 | } |
|---|
| | 114 | |
|---|
| | 115 | public void writeInstruction(String text) { |
|---|
| | 116 | this.finishStartTag(); |
|---|
| | 117 | ELText el = ELText.parse(text); |
|---|
| | 118 | if (el.isLiteral()) { |
|---|
| | 119 | this.addInstruction(new LiteralXMLInstruction(text)); |
|---|
| | 120 | } else { |
|---|
| | 121 | this.addInstruction(new XMLInstruction(el)); |
|---|
| | 122 | } |
|---|
| | 123 | this.buffer.append(text); |
|---|
| | 124 | } |
|---|
| | 125 | |
|---|
| | 126 | public void writeComment(String text) { |
|---|
| | 127 | this.finishStartTag(); |
|---|
| | 128 | |
|---|
| | 129 | ELText el = ELText.parse(text); |
|---|
| | 130 | if (el.isLiteral()) { |
|---|
| | 131 | this.addInstruction(new LiteralCommentInstruction(text)); |
|---|
| | 132 | } else { |
|---|
| | 133 | this.addInstruction(new CommentInstruction(el)); |
|---|
| | 134 | } |
|---|
| | 135 | |
|---|
| | 136 | this.buffer.append("<!--" + text + "-->"); |
|---|
| | 137 | } |
|---|
| | 138 | |
|---|
| | 139 | public void startTag(Tag tag) { |
|---|
| | 140 | |
|---|
| | 141 | // finish any previously written tags |
|---|
| | 142 | this.finishStartTag(); |
|---|
| | 143 | |
|---|
| | 144 | // push this tag onto the stack |
|---|
| | 145 | this.tags.push(tag); |
|---|
| | 146 | |
|---|
| | 147 | // write it out |
|---|
| | 148 | this.buffer.append('<'); |
|---|
| | 149 | this.buffer.append(tag.getQName()); |
|---|
| | 150 | |
|---|
| | 151 | this.addInstruction(new StartElementInstruction(tag.getQName())); |
|---|
| | 152 | |
|---|
| | 153 | TagAttribute[] attrs = tag.getAttributes().getAll(); |
|---|
| | 154 | if (attrs.length > 0) { |
|---|
| | 155 | for (int i = 0; i < attrs.length; i++) { |
|---|
| | 156 | String qname = attrs[i].getQName(); |
|---|
| | 157 | String value = attrs[i].getValue(); |
|---|
| | 158 | this.buffer.append(' ').append(qname).append("=\"").append( |
|---|
| | 159 | value).append("\""); |
|---|
| | 160 | |
|---|
| | 161 | ELText txt = ELText.parse(value); |
|---|
| | 162 | if (txt != null) { |
|---|
| | 163 | if (txt.isLiteral()) { |
|---|
| | 164 | this.addInstruction(new LiteralAttributeInstruction( |
|---|
| | 165 | qname, txt.toString())); |
|---|
| | 166 | } else { |
|---|
| | 167 | this.addInstruction(new AttributeInstruction( |
|---|
| | 168 | this.alias, qname, txt)); |
|---|
| | 169 | } |
|---|
| | 170 | } |
|---|
| | 171 | } |
|---|
| | 172 | } |
|---|
| | 173 | |
|---|
| | 174 | // notify that we have an open tag |
|---|
| | 175 | this.startTagOpen = true; |
|---|
| | 176 | } |
|---|
| | 177 | |
|---|
| | 178 | private void finishStartTag() { |
|---|
| | 179 | if (this.tags.size() > 0 && this.startTagOpen) { |
|---|
| | 180 | this.buffer.append(">"); |
|---|
| | 181 | this.startTagOpen = false; |
|---|
| | 182 | } |
|---|
| | 183 | } |
|---|
| | 184 | |
|---|
| | 185 | public void endTag() { |
|---|
| | 186 | Tag tag = (Tag) this.tags.pop(); |
|---|
| | 187 | |
|---|
| | 188 | this.addInstruction(new EndElementInstruction(tag.getQName())); |
|---|
| | 189 | |
|---|
| | 190 | if (this.startTagOpen) { |
|---|
| | 191 | this.buffer.append("/>"); |
|---|
| | 192 | this.startTagOpen = false; |
|---|
| | 193 | } else { |
|---|
| | 194 | this.buffer.append("</").append(tag.getQName()).append('>'); |
|---|
| | 195 | } |
|---|
| | 196 | } |
|---|
| | 197 | |
|---|
| | 198 | public void addChild(CompilationUnit unit) { |
|---|
| | 199 | // if we are adding some other kind of unit |
|---|
| | 200 | // then we need to capture our buffer into a UITextHandler |
|---|
| | 201 | this.finishStartTag(); |
|---|
| | 202 | this.flushBufferToConfig(); |
|---|
| | 203 | this.children.add(unit); |
|---|
| | 204 | } |
|---|
| | 205 | |
|---|
| | 206 | protected void flushBufferToConfig() { |
|---|
| | 207 | |
|---|
| | 208 | this.flushTextBuffer(); |
|---|
| | 209 | |
|---|
| | 210 | int size = this.instructionBuffer.size(); |
|---|
| | 211 | if (size > 0) { |
|---|
| | 212 | try { |
|---|
| | 213 | String s = this.buffer.toString(); |
|---|
| | 214 | ELText txt = ELText.parse(s); |
|---|
| | 215 | if (txt != null) { |
|---|
| | 216 | Instruction[] instructions = (Instruction[]) this.instructionBuffer |
|---|
| | 217 | .toArray(new Instruction[size]); |
|---|
| | 218 | this.children.add(new UIInstructionHandler(this.alias, |
|---|
| | 219 | instructions, txt)); |
|---|
| | 220 | this.instructionBuffer.clear(); |
|---|
| | 221 | } |
|---|
| | 222 | |
|---|
| | 223 | } catch (ELException e) { |
|---|
| | 224 | if (this.tags.size() > 0) { |
|---|
| | 225 | throw new TagException((Tag) this.tags.peek(), e |
|---|
| | 226 | .getMessage()); |
|---|
| | 227 | } else { |
|---|
| | 228 | throw new ELException(this.alias + ": " + e.getMessage(), e |
|---|
| | 229 | .getCause()); |
|---|
| | 230 | } |
|---|
| | 231 | } |
|---|
| | 232 | } |
|---|
| | 233 | this.buffer.setLength(0); |
|---|
| | 234 | } |
|---|
| | 235 | |
|---|
| | 236 | public boolean isClosed() { |
|---|
| | 237 | return this.tags.empty(); |
|---|
| | 238 | } |
|---|
| | 239 | |
|---|
| | 240 | public String toString() { |
|---|
| | 241 | return "TextUnit[" + this.children.size() + "]"; |
|---|
| | 242 | } |
|---|