package railo.transformer.library.tag; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import railo.commons.lang.ClassException; import railo.commons.lang.ClassUtil; import railo.commons.lang.Md5; import railo.runtime.exp.ExpressionException; import railo.runtime.exp.PageRuntimeException; import railo.transformer.cfml.ExprTransformer; /** * Die Klasse TagLib repaesentiert eine Komplette TLD, * mit ihrer Hilfe kann man alle Informationen, zu einer TLD Abfragen. */ public class TagLib implements Cloneable { public static final short STATUS_IMPLEMENTED=0; public static final short STATUS_DEPRECATED=1; public static final short STATUS_UNIMPLEMENTED=2; public static final short STATUS_HIDDEN=4; /** * Field <code>EXPR_TRANSFORMER</code> */ public static String EXPR_TRANSFORMER="railo.transformer.cfml.expression.CFMLExprTransformer"; private String shortName=""; private String displayName=null; private String type="cfml"; private String nameSpace; private String nameSpaceSeperator=":"; private String ELClass=EXPR_TRANSFORMER; private HashMap<String,TagLibTag> tags=new HashMap<String,TagLibTag>(); private HashMap<String,TagLibTag> appendixTags=new HashMap<String,TagLibTag>(); private ExprTransformer exprTransformer; private char[] nameSpaceAndNameSpaceSeperator; private boolean isCore; private String source; private URI uri; private String description; private TagLibTag[] scriptTags; private boolean ignoreUnknowTags; /** * Geschuetzer Konstruktor ohne Argumente. */ protected TagLib(boolean isCore) { this.isCore=isCore; } protected TagLib() { this(false); } /** * @param source the source to set */ public void setSource(String source) { this.source = source; } /** * Gibt den Name-Space einer TLD als String zurueck. * @return String Name der TLD. */ public String getNameSpace() { return nameSpace; } /** * Gibt den Trenner zwischen Name-Space und Name einer TLD zurueck. * @return Name zwischen Name-Space und Name. */ public String getNameSpaceSeparator() { return nameSpaceSeperator; } /** * Gibt den Name-Space inkl. dem Seperator zurueck. * @return String */ public String getNameSpaceAndSeparator() { return nameSpace+nameSpaceSeperator; } /** * Gibt den Name-Space inkl. dem Seperator zurueck. * @return String */ public char[] getNameSpaceAndSeperatorAsCharArray() { if(nameSpaceAndNameSpaceSeperator==null) { nameSpaceAndNameSpaceSeperator=getNameSpaceAndSeparator().toCharArray(); } return nameSpaceAndNameSpaceSeperator; } /** * Gibt einen Tag (TagLibTag)zurueck, dessen Name mit dem uebergebenen Wert uebereinstimmt, * falls keine �bereinstimmung gefunden wird, wird null zurueck gegeben. * @param name Name des Tag das zurueck gegeben werden soll. * @return TagLibTag Tag das auf den Namen passt. */ public TagLibTag getTag(String name) { return tags.get(name); } /** * Gibt einen Tag (TagLibTag)zurueck, welches definiert hat, dass es einen Appendix besitzt. * D.h. dass der Name des Tag mit weiteren Buchstaben erweitert sein kann, * also muss nur der erste Teil des Namen vom Tag mit dem uebergebenen Namen uebereinstimmen. * Wenn keine �bereinstimmung gefunden wird, wird null zurueck gegeben. * @param name Name des Tag inkl. Appendix das zurueck gegeben werden soll. * @return TagLibTag Tag das auf den Namen passt. */ public TagLibTag getAppendixTag(String name) { Iterator<String> it = appendixTags.keySet().iterator(); String match=""; while(it.hasNext()) { String tagName=it.next().toString(); if(match.length()<tagName.length() && name.indexOf(tagName)==0) { match=tagName; } } return getTag(match); } /** * Gibt alle Tags (TagLibTag) als HashMap zurueck. * @return Alle Tags als HashMap. */ public Map<String,TagLibTag> getTags() { return tags; } /** * Gibt die Klasse des ExprTransformer als Zeichenkette zurueck. * @return String */ public String getELClass() { return ELClass; } /** * L�dt den innerhalb der TagLib definierten ExprTransfomer und gibt diesen zur�ck. * Load Expression Transfomer defined in the tag library and return it. * @return ExprTransformer * @throws TagLibException */ public ExprTransformer getExprTransfomer() throws TagLibException { //Class cls; if(exprTransformer!=null) return exprTransformer; try { exprTransformer = (ExprTransformer)ClassUtil.loadInstance(ELClass); //exprTransformer = (ExprTransformer) cls.newInstance(); } catch (ClassException e) { throw new TagLibException(e); } return exprTransformer; } /** * Fuegt der TagLib einen weiteren Tag hinzu. * Diese Methode wird durch die Klasse TagLibFactory verwendet. * @param tag Neuer Tag. */ public void setTag(TagLibTag tag) { tag.setTagLib(this); tags.put(tag.getName(),tag); if(tag.hasAppendix()) appendixTags.put(tag.getName(),tag); else if(appendixTags.containsKey(tag.getName())) appendixTags.remove(tag.getName()); } /** * Fuegt der TagLib die Evaluator Klassendefinition als Zeichenkette hinzu. * Diese Methode wird durch die Klasse TagLibFactory verwendet. * @param eLClass Zeichenkette der Evaluator Klassendefinition. */ protected void setELClass(String eLClass) { ELClass = eLClass; } /** * Fuegt der TagLib die die Definition des Name-Space hinzu. * Diese Methode wird durch die Klasse TagLibFactory verwendet. * @param nameSpace Name-Space der TagLib. */ public void setNameSpace(String nameSpace) { this.nameSpace = nameSpace.toLowerCase(); } /** * Fuegt der TagLib die die Definition des Name-Space-Seperator hinzu. * Diese Methode wird durch die Klasse TagLibFactory verwendet. * @param nameSpaceSeperator Name-Space-Seperator der TagLib. */ public void setNameSpaceSeperator(String nameSpaceSeperator) { this.nameSpaceSeperator = nameSpaceSeperator; } /** * @return Returns the displayName. */ public String getDisplayName() { if(displayName==null)return shortName; return displayName; } /** * @param displayName The displayName to set. */ public void setDisplayName(String displayName) { this.displayName = displayName; } /** * @return Returns the shortName. */ public String getShortName() { return shortName; } /** * @param shortName The shortName to set. */ public void setShortName(String shortName) { this.shortName = shortName; if(nameSpace==null)nameSpace=shortName.toLowerCase(); } public void setIgnoreUnknowTags(boolean ignoreUnknowTags) { this.ignoreUnknowTags=ignoreUnknowTags; } public boolean getIgnoreUnknowTags() { return ignoreUnknowTags; } /** * @return Returns the type. */ public String getType() { return type; } /** * @param type The type to set. */ public void setType(String type) { this.type = type; } /** * @see java.lang.Object#toString() */ public String toString() { return getDisplayName()+":"+getShortName()+":"+super.toString(); } public String getHash() { StringBuffer sb=new StringBuffer(); Iterator<String> it = tags.keySet().iterator(); while(it.hasNext()) { //"__filename" sb.append((tags.get(it.next())).getHash()+"\n"); } try { return Md5.getDigestAsString(sb.toString()); } catch (IOException e) { return ""; } } public boolean isCore() { return isCore; } public void setIsCore(boolean isCore) { this.isCore=isCore; } /** * @see java.lang.Object#clone() */ public Object clone(){ return duplicate(false); } /** * duplicate the taglib, does not * @param deepCopy duplicate also the children (TagLibTag) of this TagLib * @return clone of this taglib */ public TagLib duplicate(boolean deepCopy) { TagLib tl = new TagLib(isCore); tl.appendixTags=duplicate(this.appendixTags,deepCopy); tl.displayName=this.displayName; tl.ELClass=this.ELClass; tl.exprTransformer=this.exprTransformer; tl.isCore=this.isCore; tl.nameSpace=this.nameSpace; tl.nameSpaceAndNameSpaceSeperator=this.nameSpaceAndNameSpaceSeperator; tl.nameSpaceSeperator=this.nameSpaceSeperator; tl.shortName=this.shortName; tl.tags=duplicate(this.tags,deepCopy); tl.type=this.type; tl.source=this.source; tl.ignoreUnknowTags=this.ignoreUnknowTags; return tl; } /** * duplcate a hashmap with TagLibTag's * @param tags * @param deepCopy * @return cloned map */ private HashMap<String,TagLibTag> duplicate(HashMap<String,TagLibTag> tags, boolean deepCopy) { if(deepCopy) throw new PageRuntimeException(new ExpressionException("deep copy not supported")); Iterator<Entry<String, TagLibTag>> it = tags.entrySet().iterator(); HashMap<String,TagLibTag> cm = new HashMap<String,TagLibTag>(); Entry<String, TagLibTag> entry; while(it.hasNext()){ entry = it.next(); cm.put( entry.getKey(), deepCopy? entry.getValue(): // TODO add support for deepcopy ((TagLibTag)entry.getValue()).duplicate(deepCopy): entry.getValue()); } return cm; } public String getSource() { return source; } public URI getUri() { // TODO Auto-generated method stub return uri; } public void setUri(String strUri) throws URISyntaxException { this.uri=new URI(strUri); } public void setUri(URI uri) { this.uri=uri; } public void setDescription(String description) { this.description=description; } public String getDescription() { return description; } public TagLibTag[] getScriptTags() { if(scriptTags==null) { Iterator<TagLibTag> it = getTags().values().iterator(); TagLibTag tag; TagLibTagScript script; List<TagLibTag> tags=new ArrayList<TagLibTag>(); while(it.hasNext()){ tag = it.next(); script = tag.getScript(); if(script!=null && script.getType()!=TagLibTagScript.TYPE_NONE) { tags.add(tag); //print.o(tag.getName()+":"+tag.getScript().getType()); } } scriptTags=tags.toArray(new TagLibTag[tags.size()]); } return scriptTags; } }