001 package railo.transformer.library.tag; 002 003 import java.io.IOException; 004 import java.net.URI; 005 import java.net.URISyntaxException; 006 import java.util.ArrayList; 007 import java.util.HashMap; 008 import java.util.Iterator; 009 import java.util.List; 010 import java.util.Map; 011 import java.util.Map.Entry; 012 013 import railo.commons.lang.ClassException; 014 import railo.commons.lang.ClassUtil; 015 import railo.commons.lang.Md5; 016 import railo.runtime.exp.ExpressionException; 017 import railo.runtime.exp.PageRuntimeException; 018 import railo.transformer.cfml.ExprTransformer; 019 020 021 /** 022 * Die Klasse TagLib repaesentiert eine Komplette TLD, 023 * mit ihrer Hilfe kann man alle Informationen, zu einer TLD Abfragen. 024 */ 025 public class TagLib implements Cloneable { 026 027 public static final short STATUS_IMPLEMENTED=0; 028 public static final short STATUS_DEPRECATED=1; 029 public static final short STATUS_UNIMPLEMENTED=2; 030 public static final short STATUS_HIDDEN=4; 031 032 033 /** 034 * Field <code>EXPR_TRANSFORMER</code> 035 */ 036 public static String EXPR_TRANSFORMER="railo.transformer.cfml.expression.CFMLExprTransformer"; 037 038 private String shortName=""; 039 private String displayName=null; 040 private String type="cfml"; 041 private String nameSpace; 042 private String nameSpaceSeperator=":"; 043 private String ELClass=EXPR_TRANSFORMER; 044 private HashMap<String,TagLibTag> tags=new HashMap<String,TagLibTag>(); 045 private HashMap<String,TagLibTag> appendixTags=new HashMap<String,TagLibTag>(); 046 private ExprTransformer exprTransformer; 047 048 private char[] nameSpaceAndNameSpaceSeperator; 049 050 private boolean isCore; 051 052 private String source; 053 054 private URI uri; 055 056 private String description; 057 private TagLibTag[] scriptTags; 058 private boolean ignoreUnknowTags; 059 060 061 /** 062 * Geschuetzer Konstruktor ohne Argumente. 063 */ 064 protected TagLib(boolean isCore) { 065 this.isCore=isCore; 066 } 067 protected TagLib() { 068 this(false); 069 } 070 071 /** 072 * @param source the source to set 073 */ 074 public void setSource(String source) { 075 this.source = source; 076 } 077 078 /** 079 * Gibt den Name-Space einer TLD als String zurueck. 080 * @return String Name der TLD. 081 */ 082 public String getNameSpace() { 083 084 return nameSpace; 085 } 086 087 /** 088 * Gibt den Trenner zwischen Name-Space und Name einer TLD zurueck. 089 * @return Name zwischen Name-Space und Name. 090 */ 091 public String getNameSpaceSeparator() { 092 return nameSpaceSeperator; 093 } 094 095 /** 096 * Gibt den Name-Space inkl. dem Seperator zurueck. 097 * @return String 098 */ 099 public String getNameSpaceAndSeparator() { 100 return nameSpace+nameSpaceSeperator; 101 } 102 103 /** 104 * Gibt den Name-Space inkl. dem Seperator zurueck. 105 * @return String 106 */ 107 public char[] getNameSpaceAndSeperatorAsCharArray() { 108 if(nameSpaceAndNameSpaceSeperator==null) { 109 nameSpaceAndNameSpaceSeperator=getNameSpaceAndSeparator().toCharArray(); 110 } 111 return nameSpaceAndNameSpaceSeperator; 112 } 113 114 /** 115 * Gibt einen Tag (TagLibTag)zurueck, dessen Name mit dem uebergebenen Wert uebereinstimmt, 116 * falls keine �bereinstimmung gefunden wird, wird null zurueck gegeben. 117 * @param name Name des Tag das zurueck gegeben werden soll. 118 * @return TagLibTag Tag das auf den Namen passt. 119 */ 120 public TagLibTag getTag(String name) { 121 return tags.get(name); 122 } 123 124 /** 125 * Gibt einen Tag (TagLibTag)zurueck, welches definiert hat, dass es einen Appendix besitzt. 126 * D.h. dass der Name des Tag mit weiteren Buchstaben erweitert sein kann, 127 * also muss nur der erste Teil des Namen vom Tag mit dem uebergebenen Namen uebereinstimmen. 128 * Wenn keine �bereinstimmung gefunden wird, wird null zurueck gegeben. 129 * @param name Name des Tag inkl. Appendix das zurueck gegeben werden soll. 130 * @return TagLibTag Tag das auf den Namen passt. 131 */ 132 public TagLibTag getAppendixTag(String name) { 133 Iterator<String> it = appendixTags.keySet().iterator(); 134 String match=""; 135 while(it.hasNext()) { 136 String tagName=it.next().toString(); 137 if(match.length()<tagName.length() && name.indexOf(tagName)==0) { 138 match=tagName; 139 } 140 } 141 return getTag(match); 142 } 143 144 /** 145 * Gibt alle Tags (TagLibTag) als HashMap zurueck. 146 * @return Alle Tags als HashMap. 147 */ 148 public Map<String,TagLibTag> getTags() { 149 return tags; 150 } 151 152 /** 153 * Gibt die Klasse des ExprTransformer als Zeichenkette zurueck. 154 * @return String 155 */ 156 public String getELClass() { 157 return ELClass; 158 } 159 160 /** 161 * L�dt den innerhalb der TagLib definierten ExprTransfomer und gibt diesen zur�ck. 162 * Load Expression Transfomer defined in the tag library and return it. 163 * @return ExprTransformer 164 * @throws TagLibException 165 */ 166 public ExprTransformer getExprTransfomer() throws TagLibException { 167 //Class cls; 168 if(exprTransformer!=null) 169 return exprTransformer; 170 171 try { 172 exprTransformer = (ExprTransformer)ClassUtil.loadInstance(ELClass); 173 //exprTransformer = (ExprTransformer) cls.newInstance(); 174 } 175 catch (ClassException e) { 176 throw new TagLibException(e); 177 } 178 return exprTransformer; 179 } 180 181 /** 182 * Fuegt der TagLib einen weiteren Tag hinzu. 183 * Diese Methode wird durch die Klasse TagLibFactory verwendet. 184 * @param tag Neuer Tag. 185 */ 186 public void setTag(TagLibTag tag) { 187 tag.setTagLib(this); 188 tags.put(tag.getName(),tag); 189 190 if(tag.hasAppendix()) 191 appendixTags.put(tag.getName(),tag); 192 else if(appendixTags.containsKey(tag.getName())) 193 appendixTags.remove(tag.getName()); 194 } 195 196 /** 197 * Fuegt der TagLib die Evaluator Klassendefinition als Zeichenkette hinzu. 198 * Diese Methode wird durch die Klasse TagLibFactory verwendet. 199 * @param eLClass Zeichenkette der Evaluator Klassendefinition. 200 */ 201 protected void setELClass(String eLClass) { 202 ELClass = eLClass; 203 } 204 205 /** 206 * Fuegt der TagLib die die Definition des Name-Space hinzu. 207 * Diese Methode wird durch die Klasse TagLibFactory verwendet. 208 * @param nameSpace Name-Space der TagLib. 209 */ 210 public void setNameSpace(String nameSpace) { 211 this.nameSpace = nameSpace.toLowerCase(); 212 } 213 214 /** 215 * Fuegt der TagLib die die Definition des Name-Space-Seperator hinzu. 216 * Diese Methode wird durch die Klasse TagLibFactory verwendet. 217 * @param nameSpaceSeperator Name-Space-Seperator der TagLib. 218 */ 219 public void setNameSpaceSeperator(String nameSpaceSeperator) { 220 this.nameSpaceSeperator = nameSpaceSeperator; 221 } 222 223 /** 224 * @return Returns the displayName. 225 */ 226 public String getDisplayName() { 227 if(displayName==null)return shortName; 228 return displayName; 229 } 230 /** 231 * @param displayName The displayName to set. 232 */ 233 public void setDisplayName(String displayName) { 234 this.displayName = displayName; 235 } 236 /** 237 * @return Returns the shortName. 238 */ 239 public String getShortName() { 240 return shortName; 241 } 242 /** 243 * @param shortName The shortName to set. 244 */ 245 public void setShortName(String shortName) { 246 this.shortName = shortName; 247 if(nameSpace==null)nameSpace=shortName.toLowerCase(); 248 } 249 250 251 public void setIgnoreUnknowTags(boolean ignoreUnknowTags) { 252 this.ignoreUnknowTags=ignoreUnknowTags; 253 } 254 public boolean getIgnoreUnknowTags() { 255 return ignoreUnknowTags; 256 } 257 258 259 /** 260 * @return Returns the type. 261 */ 262 public String getType() { 263 return type; 264 } 265 /** 266 * @param type The type to set. 267 */ 268 public void setType(String type) { 269 this.type = type; 270 } 271 272 /** 273 * @see java.lang.Object#toString() 274 */ 275 public String toString() { 276 return getDisplayName()+":"+getShortName()+":"+super.toString(); 277 } 278 279 public String getHash() { 280 StringBuffer sb=new StringBuffer(); 281 Iterator<String> it = tags.keySet().iterator(); 282 while(it.hasNext()) { 283 //"__filename" 284 285 sb.append((tags.get(it.next())).getHash()+"\n"); 286 } 287 try { 288 return Md5.getDigestAsString(sb.toString()); 289 } catch (IOException e) { 290 return ""; 291 } 292 } 293 294 public boolean isCore() { 295 return isCore; 296 } 297 298 public void setIsCore(boolean isCore) { 299 this.isCore=isCore; 300 } 301 302 303 304 /** 305 * @see java.lang.Object#clone() 306 */ 307 public Object clone(){ 308 return duplicate(false); 309 } 310 311 /** 312 * duplicate the taglib, does not 313 * @param deepCopy duplicate also the children (TagLibTag) of this TagLib 314 * @return clone of this taglib 315 */ 316 public TagLib duplicate(boolean deepCopy) { 317 TagLib tl = new TagLib(isCore); 318 tl.appendixTags=duplicate(this.appendixTags,deepCopy); 319 tl.displayName=this.displayName; 320 tl.ELClass=this.ELClass; 321 tl.exprTransformer=this.exprTransformer; 322 tl.isCore=this.isCore; 323 tl.nameSpace=this.nameSpace; 324 tl.nameSpaceAndNameSpaceSeperator=this.nameSpaceAndNameSpaceSeperator; 325 tl.nameSpaceSeperator=this.nameSpaceSeperator; 326 tl.shortName=this.shortName; 327 tl.tags=duplicate(this.tags,deepCopy); 328 tl.type=this.type; 329 tl.source=this.source; 330 tl.ignoreUnknowTags=this.ignoreUnknowTags; 331 332 return tl; 333 } 334 335 /** 336 * duplcate a hashmap with TagLibTag's 337 * @param tags 338 * @param deepCopy 339 * @return cloned map 340 */ 341 private HashMap<String,TagLibTag> duplicate(HashMap<String,TagLibTag> tags, boolean deepCopy) { 342 if(deepCopy) throw new PageRuntimeException(new ExpressionException("deep copy not supported")); 343 344 Iterator<Entry<String, TagLibTag>> it = tags.entrySet().iterator(); 345 HashMap<String,TagLibTag> cm = new HashMap<String,TagLibTag>(); 346 Entry<String, TagLibTag> entry; 347 while(it.hasNext()){ 348 entry = it.next(); 349 cm.put( 350 entry.getKey(), 351 deepCopy? 352 entry.getValue(): // TODO add support for deepcopy ((TagLibTag)entry.getValue()).duplicate(deepCopy): 353 entry.getValue()); 354 } 355 return cm; 356 } 357 public String getSource() { 358 return source; 359 } 360 public URI getUri() { 361 // TODO Auto-generated method stub 362 return uri; 363 } 364 public void setUri(String strUri) throws URISyntaxException { 365 this.uri=new URI(strUri); 366 } 367 public void setUri(URI uri) { 368 this.uri=uri; 369 } 370 public void setDescription(String description) { 371 this.description=description; 372 } 373 374 public String getDescription() { 375 return description; 376 } 377 378 public TagLibTag[] getScriptTags() { 379 if(scriptTags==null) { 380 Iterator<TagLibTag> it = getTags().values().iterator(); 381 TagLibTag tag; 382 TagLibTagScript script; 383 List<TagLibTag> tags=new ArrayList<TagLibTag>(); 384 while(it.hasNext()){ 385 tag = it.next(); 386 script = tag.getScript(); 387 if(script!=null && script.getType()!=TagLibTagScript.TYPE_NONE) { 388 tags.add(tag); 389 //print.o(tag.getName()+":"+tag.getScript().getType()); 390 } 391 } 392 scriptTags=tags.toArray(new TagLibTag[tags.size()]); 393 } 394 return scriptTags; 395 } 396 397 }