001 package railo.runtime.tag; 002 003 import java.io.OutputStream; 004 import java.util.Iterator; 005 import java.util.Map; 006 import java.util.Map.Entry; 007 008 import javax.servlet.http.Cookie; 009 import javax.servlet.jsp.tagext.Tag; 010 011 import railo.commons.io.DevNullOutputStream; 012 import railo.commons.lang.Pair; 013 import railo.commons.lang.StringUtil; 014 import railo.runtime.Component; 015 import railo.runtime.ComponentImpl; 016 import railo.runtime.ComponentWrap; 017 import railo.runtime.Page; 018 import railo.runtime.PageContext; 019 import railo.runtime.PageContextImpl; 020 import railo.runtime.PageSource; 021 import railo.runtime.component.ComponentLoader; 022 import railo.runtime.config.ConfigWeb; 023 import railo.runtime.config.ConfigWebImpl; 024 import railo.runtime.engine.ThreadLocalPageContext; 025 import railo.runtime.exp.ApplicationException; 026 import railo.runtime.exp.PageException; 027 import railo.runtime.ext.tag.DynamicAttributes; 028 import railo.runtime.op.Caster; 029 import railo.runtime.reflection.Reflector; 030 import railo.runtime.reflection.pairs.MethodInstance; 031 import railo.runtime.thread.ThreadUtil; 032 import railo.runtime.type.Collection; 033 import railo.runtime.type.Collection.Key; 034 import railo.runtime.type.KeyImpl; 035 import railo.runtime.type.Struct; 036 import railo.runtime.type.StructImpl; 037 import railo.runtime.type.UDFImpl; 038 import railo.runtime.type.util.ArrayUtil; 039 import railo.runtime.type.util.KeyConstants; 040 import railo.transformer.library.tag.TagLib; 041 import railo.transformer.library.tag.TagLibTag; 042 import railo.transformer.library.tag.TagLibTagAttr; 043 044 public class TagUtil { 045 046 public static final short ORIGINAL_CASE = 0; 047 public static final short UPPER_CASE = 1; 048 public static final short LOWER_CASE = 2; 049 050 //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\")"; 051 052 public static void setAttributeCollection(PageContext pc,Tag tag, MissingAttribute[] missingAttrs, Struct attrs, int attrType) throws PageException { 053 // check missing tags 054 if(!ArrayUtil.isEmpty(missingAttrs)){ 055 Object value; 056 for(int i=0;i<missingAttrs.length;i++) { 057 value=attrs.get( 058 missingAttrs[i].getName() 059 ,null); 060 if(value==null) 061 throw new ApplicationException("attribute "+missingAttrs[i].getName().getString()+" is required but missing"); 062 //throw new ApplicationException("attribute "+missingAttrs[i].getName().getString()+" is required for tag "+tag.getFullName()); 063 attrs.put(missingAttrs[i].getName(), Caster.castTo(pc, missingAttrs[i].getType(), value, false)); 064 } 065 } 066 067 068 //Key[] keys = attrs.keys(); 069 Iterator<Entry<Key, Object>> it; 070 Entry<Key, Object> e; 071 if(TagLibTag.ATTRIBUTE_TYPE_DYNAMIC==attrType) { 072 DynamicAttributes da=(DynamicAttributes) tag; 073 it = attrs.entryIterator(); 074 while(it.hasNext()) { 075 e = it.next(); 076 da.setDynamicAttribute(null, e.getKey(),e.getValue()); 077 } 078 } 079 else if(TagLibTag.ATTRIBUTE_TYPE_FIXED==attrType) { 080 Object value; 081 it = attrs.entryIterator(); 082 while(it.hasNext()) { 083 e = it.next(); 084 value=e.getValue(); 085 if(value!=null)Reflector.callSetterEL(tag, e.getKey().getString(),value); 086 //}catch(PageException pe){} 087 } 088 } 089 else if(TagLibTag.ATTRIBUTE_TYPE_MIXED==attrType) { 090 MethodInstance setter; 091 it = attrs.entryIterator(); 092 while(it.hasNext()) { 093 e = it.next(); 094 setter = Reflector.getSetter(tag, e.getKey().getString(),e.getValue(),null); 095 if(setter!=null) { 096 try { 097 setter.invoke(tag); 098 } 099 catch (Exception _e) { 100 throw Caster.toPageException(_e); 101 } 102 } 103 else { 104 DynamicAttributes da=(DynamicAttributes) tag; 105 da.setDynamicAttribute(null, e.getKey(),e.getValue()); 106 } 107 } 108 } 109 } 110 111 /* * 112 * sets dynamic attributes 113 * @param attributes 114 * @param name 115 * @param value 116 * / 117 public static void setDynamicAttribute(StructImpl attributes,String name, Object value, short caseType) { 118 if(LOWER_CASE==caseType)name=StringUtil.toLowerCase(name); 119 else if(UPPER_CASE==caseType)name=StringUtil.toUpperCase(name); 120 if(name.equals("attributecollection")) { 121 if(value instanceof railo.runtime.type.Collection) { 122 railo.runtime.type.Collection coll=(railo.runtime.type.Collection)value; 123 Iterator<Entry<Key, Object>> it = coll.entryIterator(); 124 Entry<Key, Object> e; 125 while(it.hasNext()) { 126 e = it.next(); 127 if(attributes.get(e.getKey(),null)==null) 128 attributes.setEL(e.getKey(),e.getValue()); 129 } 130 return; 131 } 132 else if(value instanceof Map) { 133 134 Map map=(Map) value; 135 Iterator it = map.entrySet().iterator(); 136 Map.Entry entry; 137 Key key; 138 while(it.hasNext()) { 139 entry=(Entry) it.next(); 140 key = UDFImpl.toKey(entry.getKey()); 141 if(!attributes.containsKey(key)){ 142 attributes.setEL(key,entry.getValue()); 143 } 144 } 145 return; 146 } 147 } 148 attributes.setEL(KeyImpl.getInstance(name), value); 149 }*/ 150 151 152 public static void setDynamicAttribute(StructImpl attributes,Collection.Key name, Object value, short caseType) { 153 if(name.equalsIgnoreCase(KeyConstants._attributecollection)) { 154 if(value instanceof railo.runtime.type.Collection) { 155 railo.runtime.type.Collection coll=(railo.runtime.type.Collection)value; 156 Iterator<Entry<Key, Object>> it = coll.entryIterator(); 157 Entry<Key, Object> e; 158 while(it.hasNext()) { 159 e = it.next(); 160 if(attributes.get(e.getKey(),null)==null) 161 attributes.setEL(e.getKey(),e.getValue()); 162 } 163 return; 164 } 165 else if(value instanceof Map) { 166 167 Map map=(Map) value; 168 Iterator it = map.entrySet().iterator(); 169 Map.Entry entry; 170 Key key; 171 while(it.hasNext()) { 172 entry=(Entry) it.next(); 173 key = UDFImpl.toKey(entry.getKey()); 174 if(!attributes.containsKey(key)){ 175 attributes.setEL(key,entry.getValue()); 176 } 177 } 178 return; 179 } 180 } 181 if(LOWER_CASE==caseType)name=KeyImpl.init(name.getLowerString()); 182 else if(UPPER_CASE==caseType)name=KeyImpl.init(name.getUpperString()); 183 attributes.setEL(name, value); 184 } 185 186 /** 187 * load metadata from cfc based custom tags and add the info to the tag 188 * @param cs 189 * @param config 190 */ 191 public static void addTagMetaData(ConfigWebImpl cw) { 192 if(true) return; 193 194 PageContextImpl pc=null; 195 try{ 196 pc = ThreadUtil.createPageContext(cw, DevNullOutputStream.DEV_NULL_OUTPUT_STREAM, 197 "localhost", "/","", new Cookie[0], new Pair[0], new Pair[0], new StructImpl()); 198 199 } 200 catch(Throwable t){ 201 return; 202 } 203 PageContext orgPC = ThreadLocalPageContext.get(); 204 ThreadLocalPageContext.register(pc); 205 try{ 206 TagLibTagAttr attrFileName,attrIsWeb; 207 String filename; 208 Boolean isWeb; 209 TagLibTag tlt; 210 211 TagLib[] tlds = cw.getTLDs(); 212 for(int i=0;i<tlds.length;i++){ 213 Map<String, TagLibTag> tags = tlds[i].getTags(); 214 Iterator<TagLibTag> it = tags.values().iterator(); 215 while(it.hasNext()){ 216 tlt = it.next(); 217 if("railo.runtime.tag.CFTagCore".equals(tlt.getTagClassName())) { 218 attrFileName = tlt.getAttribute("__filename"); 219 attrIsWeb = tlt.getAttribute("__isweb"); 220 if(attrFileName!=null && attrIsWeb!=null) { 221 filename = Caster.toString(attrFileName.getDefaultValue(),null); 222 isWeb=Caster.toBoolean(attrIsWeb.getDefaultValue(),null); 223 if(filename!=null && isWeb!=null) { 224 addTagMetaData(pc, tlds[i], tlt, filename,isWeb.booleanValue()); 225 } 226 } 227 } 228 } 229 } 230 } 231 catch(Throwable t){ 232 //t.printStackTrace(); 233 } 234 finally{ 235 pc.release(); 236 ThreadLocalPageContext.register(orgPC); 237 } 238 } 239 240 private static void addTagMetaData(PageContext pc,TagLib tl, TagLibTag tlt, String filename, boolean isWeb) { 241 if(pc==null) return; 242 try{ 243 ConfigWebImpl config=(ConfigWebImpl) pc.getConfig(); 244 PageSource ps = isWeb? 245 config.getTagMapping().getPageSource(filename): 246 config.getServerTagMapping().getPageSource(filename); 247 248 Page p = ps.loadPage(pc); 249 ComponentImpl c = ComponentLoader.loadComponent(pc, p, ps, filename, true,true); 250 ComponentWrap cw = ComponentWrap.toComponentWrap(Component.ACCESS_PRIVATE,c); 251 Struct meta = Caster.toStruct( cw.get(KeyConstants._metadata,null),null); 252 253 // TODO handle all metadata here and make checking at runtime useless 254 if(meta!=null) { 255 256 // parse body 257 boolean rtexprvalue=Caster.toBooleanValue(meta.get(KeyConstants._parsebody,Boolean.FALSE),false); 258 tlt.setParseBody(rtexprvalue); 259 260 // hint 261 String hint=Caster.toString(meta.get(KeyConstants._hint,null),null); 262 if(!StringUtil.isEmpty(hint))tlt.setDescription(hint); 263 264 } 265 266 } 267 catch (Throwable t) { 268 //t.printStackTrace(); 269 } 270 } 271 272 }