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