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