package railo.runtime.tag; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.Cookie; import javax.servlet.jsp.tagext.Tag; import railo.commons.io.DevNullOutputStream; import railo.commons.lang.Pair; import railo.commons.lang.StringUtil; import railo.runtime.Component; import railo.runtime.ComponentImpl; import railo.runtime.ComponentWrap; import railo.runtime.Page; import railo.runtime.PageContext; import railo.runtime.PageContextImpl; import railo.runtime.PageSource; import railo.runtime.component.ComponentLoader; import railo.runtime.config.ConfigWebImpl; import railo.runtime.engine.ThreadLocalPageContext; import railo.runtime.exp.ApplicationException; import railo.runtime.exp.PageException; import railo.runtime.ext.tag.DynamicAttributes; import railo.runtime.op.Caster; import railo.runtime.reflection.Reflector; import railo.runtime.reflection.pairs.MethodInstance; import railo.runtime.thread.ThreadUtil; import railo.runtime.type.Collection; import railo.runtime.type.Collection.Key; import railo.runtime.type.KeyImpl; import railo.runtime.type.Struct; import railo.runtime.type.StructImpl; import railo.runtime.type.util.ArrayUtil; import railo.runtime.type.util.KeyConstants; import railo.transformer.library.tag.TagLib; import railo.transformer.library.tag.TagLibTag; import railo.transformer.library.tag.TagLibTagAttr; public class TagUtil { public static final short ORIGINAL_CASE = 0; public static final short UPPER_CASE = 1; public static final short LOWER_CASE = 2; //private static final String "invalid call of the function ["+tlt.getName()+", you can not mix named on regular arguments]" = "invalid argument for function, only named arguments are allowed like struct(name:\"value\",name2:\"value2\")"; public static void setAttributeCollection(PageContext pc,Tag tag, MissingAttribute[] missingAttrs, Struct attrs, int attrType) throws PageException { // check missing tags if(!ArrayUtil.isEmpty(missingAttrs)){ Object value; for(int i=0;i<missingAttrs.length;i++) { value=attrs.get( missingAttrs[i].getName() ,null); if(value==null) throw new ApplicationException("attribute "+missingAttrs[i].getName().getString()+" is required but missing"); //throw new ApplicationException("attribute "+missingAttrs[i].getName().getString()+" is required for tag "+tag.getFullName()); attrs.put(missingAttrs[i].getName(), Caster.castTo(pc, missingAttrs[i].getType(), value, false)); } } //Key[] keys = attrs.keys(); Iterator<Entry<Key, Object>> it; Entry<Key, Object> e; if(TagLibTag.ATTRIBUTE_TYPE_DYNAMIC==attrType) { DynamicAttributes da=(DynamicAttributes) tag; it = attrs.entryIterator(); while(it.hasNext()) { e = it.next(); da.setDynamicAttribute(null, e.getKey(),e.getValue()); } } else if(TagLibTag.ATTRIBUTE_TYPE_FIXED==attrType) { Object value; it = attrs.entryIterator(); while(it.hasNext()) { e = it.next(); value=e.getValue(); if(value!=null)Reflector.callSetterEL(tag, e.getKey().getString(),value); //}catch(PageException pe){} } } else if(TagLibTag.ATTRIBUTE_TYPE_MIXED==attrType) { MethodInstance setter; it = attrs.entryIterator(); while(it.hasNext()) { e = it.next(); setter = Reflector.getSetter(tag, e.getKey().getString(),e.getValue(),null); if(setter!=null) { try { setter.invoke(tag); } catch (Exception _e) { throw Caster.toPageException(_e); } } else { DynamicAttributes da=(DynamicAttributes) tag; da.setDynamicAttribute(null, e.getKey(),e.getValue()); } } } } public static void setDynamicAttribute(StructImpl attributes,Collection.Key name, Object value, short caseType) { if(name.equalsIgnoreCase(KeyConstants._attributecollection)) { if(value instanceof railo.runtime.type.Collection) { railo.runtime.type.Collection coll=(railo.runtime.type.Collection)value; Iterator<Entry<Key, Object>> it = coll.entryIterator(); Entry<Key, Object> e; while(it.hasNext()) { e = it.next(); if(attributes.get(e.getKey(),null)==null) attributes.setEL(e.getKey(),e.getValue()); } return; } else if(value instanceof Map) { Map map=(Map) value; Iterator it = map.entrySet().iterator(); Map.Entry entry; Key key; while(it.hasNext()) { entry=(Entry) it.next(); key = Caster.toKey(entry.getKey(),null); if(!attributes.containsKey(key)){ attributes.setEL(key,entry.getValue()); } } return; } } if(LOWER_CASE==caseType)name=KeyImpl.init(name.getLowerString()); else if(UPPER_CASE==caseType)name=KeyImpl.init(name.getUpperString()); attributes.setEL(name, value); } /** * load metadata from cfc based custom tags and add the info to the tag * @param cs * @param config */ public static void addTagMetaData(ConfigWebImpl cw) { if(true) return; PageContextImpl pc=null; try{ pc = ThreadUtil.createPageContext(cw, DevNullOutputStream.DEV_NULL_OUTPUT_STREAM, "localhost", "/","", new Cookie[0], new Pair[0], new Pair[0], new StructImpl()); } catch(Throwable t){ return; } PageContext orgPC = ThreadLocalPageContext.get(); ThreadLocalPageContext.register(pc); try{ TagLibTagAttr attrFileName,attrIsWeb; String filename; Boolean isWeb; TagLibTag tlt; TagLib[] tlds = cw.getTLDs(); for(int i=0;i<tlds.length;i++){ Map<String, TagLibTag> tags = tlds[i].getTags(); Iterator<TagLibTag> it = tags.values().iterator(); while(it.hasNext()){ tlt = it.next(); if("railo.runtime.tag.CFTagCore".equals(tlt.getTagClassName())) { attrFileName = tlt.getAttribute("__filename"); attrIsWeb = tlt.getAttribute("__isweb"); if(attrFileName!=null && attrIsWeb!=null) { filename = Caster.toString(attrFileName.getDefaultValue(),null); isWeb=Caster.toBoolean(attrIsWeb.getDefaultValue(),null); if(filename!=null && isWeb!=null) { addTagMetaData(pc, tlds[i], tlt, filename,isWeb.booleanValue()); } } } } } } catch(Throwable t){ //t.printStackTrace(); } finally{ pc.release(); ThreadLocalPageContext.register(orgPC); } } private static void addTagMetaData(PageContext pc,TagLib tl, TagLibTag tlt, String filename, boolean isWeb) { if(pc==null) return; try{ ConfigWebImpl config=(ConfigWebImpl) pc.getConfig(); PageSource ps = isWeb? config.getTagMapping().getPageSource(filename): config.getServerTagMapping().getPageSource(filename); Page p = ps.loadPage(pc); ComponentImpl c = ComponentLoader.loadComponent(pc, p, ps, filename, true,true); ComponentWrap cw = ComponentWrap.toComponentWrap(Component.ACCESS_PRIVATE,c); Struct meta = Caster.toStruct( cw.get(KeyConstants._metadata,null),null); // TODO handle all metadata here and make checking at runtime useless if(meta!=null) { // parse body boolean rtexprvalue=Caster.toBooleanValue(meta.get(KeyConstants._parsebody,Boolean.FALSE),false); tlt.setParseBody(rtexprvalue); // hint String hint=Caster.toString(meta.get(KeyConstants._hint,null),null); if(!StringUtil.isEmpty(hint))tlt.setDescription(hint); } } catch (Throwable t) { //t.printStackTrace(); } } }