001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019/** 020 * Implements the CFML Function getfunctiondescription 021 */ 022package lucee.runtime.functions.other; 023 024import java.util.Iterator; 025import java.util.Map.Entry; 026 027import lucee.commons.lang.ExceptionUtil; 028import lucee.commons.lang.StringUtil; 029import lucee.runtime.Component; 030import lucee.runtime.ComponentSpecificAccess; 031import lucee.runtime.PageContext; 032import lucee.runtime.PageContextImpl; 033import lucee.runtime.component.ComponentLoader; 034import lucee.runtime.config.ConfigImpl; 035import lucee.runtime.customtag.InitFile; 036import lucee.runtime.exp.ExpressionException; 037import lucee.runtime.exp.PageException; 038import lucee.runtime.ext.function.Function; 039import lucee.runtime.op.Caster; 040import lucee.runtime.tag.CFTagCore; 041import lucee.runtime.type.Collection.Key; 042import lucee.runtime.type.Struct; 043import lucee.runtime.type.StructImpl; 044import lucee.runtime.type.util.KeyConstants; 045import lucee.runtime.type.util.ListUtil; 046import lucee.transformer.library.tag.TagLib; 047import lucee.transformer.library.tag.TagLibFactory; 048import lucee.transformer.library.tag.TagLibTag; 049import lucee.transformer.library.tag.TagLibTagAttr; 050import lucee.transformer.library.tag.TagLibTagScript; 051 052public final class GetTagData implements Function { 053 054 public static Struct call(PageContext pc , String nameSpace, String strTagName) throws PageException { 055 TagLib[] tlds; 056 tlds = ((ConfigImpl)pc.getConfig()).getTLDs(); 057 058 059 TagLib tld=null; 060 TagLibTag tag=null; 061 for(int i=0;i<tlds.length;i++) { 062 tld=tlds[i]; 063 if(tld.getNameSpaceAndSeparator().equalsIgnoreCase(nameSpace)) { 064 tag = tld.getTag(strTagName.toLowerCase()); 065 if(tag!=null)break; 066 } 067 068 } 069 if(tag == null) throw new ExpressionException("tag ["+nameSpace+strTagName+"] is not a built in tag"); 070 071 // CFML Based Function 072 Class clazz=null; 073 try{ 074 clazz=tag.getClazz(); 075 } 076 catch(Throwable t){ 077 ExceptionUtil.rethrowIfNecessary(t); 078 } 079 080 if(clazz==CFTagCore.class){ 081 PageContextImpl pci=(PageContextImpl) pc; 082 boolean prior = pci.useSpecialMappings(true); 083 try{ 084 return cfmlBasedTag(pc,tld,tag); 085 } 086 finally { 087 pci.useSpecialMappings(prior); 088 } 089 090 } 091 return javaBasedTag(tld,tag); 092 093 094 095 096 097 } 098 099 private static Struct cfmlBasedTag(PageContext pc, TagLib tld, TagLibTag tag) throws PageException { 100 101 //Map attrs = tag.getAttributes(); 102 103 TagLibTagAttr attrFilename = tag.getAttribute("__filename"); 104 //TagLibTagAttr attrName = tag.getAttribute("__name"); 105 TagLibTagAttr attrIsWeb = tag.getAttribute("__isweb"); 106 107 String filename = Caster.toString(attrFilename.getDefaultValue()); 108 String name = Caster.toString(attrFilename.getDefaultValue()); 109 boolean isWeb = Caster.toBooleanValue(attrIsWeb.getDefaultValue()); 110 InitFile source = CFTagCore.createInitFile(pc, isWeb, filename); 111 112 Component cfc = ComponentLoader.loadComponent(pc,null,source.getPageSource(), source.getFilename().substring(0,source.getFilename().length()-(pc.getConfig().getCFCExtension().length()+1)), false,true); 113 ComponentSpecificAccess cw=ComponentSpecificAccess.toComponentSpecificAccess(Component.ACCESS_PRIVATE, cfc); 114 Struct metadata=Caster.toStruct(cw.get("metadata",null),null,false); 115 116 117 Struct sct=new StructImpl(); 118 sct.set("nameSpaceSeperator",tld.getNameSpaceSeparator()); 119 sct.set("nameSpace",tld.getNameSpace()); 120 sct.set(KeyConstants._name,name.substring(0,name.lastIndexOf('.'))); 121 sct.set("hasNameAppendix",Boolean.FALSE); 122 sct.set(KeyConstants._status,"implemeted"); 123 sct.set(KeyConstants._type,"cfml"); 124 125 sct.set("bodyType",getBodyType(tag)); 126 sct.set("attrMin",Caster.toDouble(0)); 127 sct.set("attrMax",Caster.toDouble(0)); 128 sct.set("attributeCollection",getSupportAttributeCollection(tag)); 129 130 // TODO add support for script for cfml tags 131 Struct scp=new StructImpl(); 132 sct.set(KeyConstants._script,scp); 133 scp.set("rtexpr", Boolean.FALSE); 134 scp.set(KeyConstants._type, "none"); 135 136 137 138 139 if(metadata!=null) { 140 sct.set(KeyConstants._description,metadata.get("hint","")); 141 sct.set("attributeType",metadata.get("attributeType","")); 142 sct.set("parseBody",Caster.toBoolean(metadata.get("parseBody",Boolean.FALSE),Boolean.FALSE)); 143 144 Struct _attrs=new StructImpl(); 145 sct.set(KeyConstants._attributes,_attrs); 146 147 Struct srcAttrs = Caster.toStruct(metadata.get(KeyConstants._attributes,null),null,false); 148 Struct src; 149 if(srcAttrs!=null){ 150 //Key[] keys = srcAttrs.keys(); 151 Iterator<Entry<Key, Object>> it = srcAttrs.entryIterator(); 152 Entry<Key, Object> e; 153 while(it.hasNext()){ 154 e = it.next(); 155 src = Caster.toStruct(e.getValue(),null,false); 156 if(Caster.toBooleanValue(src.get(KeyConstants._hidden,null),false))continue; 157 Struct _attr=new StructImpl(); 158 _attr.set(KeyConstants._status,"implemeted"); 159 _attr.set(KeyConstants._description,src.get(KeyConstants._hint,"")); 160 _attr.set(KeyConstants._type,src.get(KeyConstants._type,"any")); 161 _attr.set(KeyConstants._required,Caster.toBoolean(src.get(KeyConstants._required,""),null)); 162 _attr.set("scriptSupport","none"); 163 _attrs.setEL(e.getKey().getLowerString(),_attr); 164 165 } 166 } 167 168 } 169 170 171 /* ///////////////////// 172 173 174 Map atts = tag.getAttributes(); 175 Iterator it = atts.keySet().iterator(); 176 177 while(it.hasNext()) { 178 Object key = it.next(); 179 TagLibTagAttr attr=(TagLibTagAttr) atts.get(key); 180 if(attr.getHidden()) continue; 181 //for(int i=0;i<args.size();i++) { 182 Struct _arg=new StructImpl(); 183 _arg.set("status",TagLibFactory.toStatus(attr.getStatus())); 184 _arg.set("description",attr.getDescription()); 185 _arg.set("type",attr.getType()); 186 _arg.set("required",attr.isRequired()?Boolean.TRUE:Boolean.FALSE); 187 _args.setEL(attr.getName(),_arg); 188 } 189 */ 190 191 192 193 return sct; 194 } 195 196 private static Struct javaBasedTag(TagLib tld, TagLibTag tag) throws PageException { 197 Struct sct=new StructImpl(); 198 sct.set("nameSpaceSeperator",tld.getNameSpaceSeparator()); 199 sct.set("nameSpace",tld.getNameSpace()); 200 sct.set(KeyConstants._name,tag.getName()); 201 sct.set(KeyConstants._description,tag.getDescription()); 202 sct.set(KeyConstants._status,TagLibFactory.toStatus(tag.getStatus())); 203 204 sct.set("attributeType",getAttributeType(tag)); 205 sct.set("parseBody",Caster.toBoolean(tag.getParseBody())); 206 sct.set("bodyType",getBodyType(tag)); 207 sct.set("attrMin",Caster.toDouble(tag.getMin())); 208 sct.set("attrMax",Caster.toDouble(tag.getMax())); 209 sct.set("hasNameAppendix",Caster.toBoolean(tag.hasAppendix())); 210 sct.set("attributeCollection",getSupportAttributeCollection(tag)); 211 212 // script 213 TagLibTagScript script = tag.getScript(); 214 if(script!=null) { 215 Struct scp=new StructImpl(); 216 sct.set(KeyConstants._script,scp); 217 scp.set("rtexpr", Caster.toBoolean(script.getRtexpr())); 218 scp.set(KeyConstants._type, script.getTypeAsString()); 219 if(script.getType()==TagLibTagScript.TYPE_SINGLE) { 220 TagLibTagAttr attr = script.getSingleAttr(); 221 if(attr!=null)scp.set("singletype", attr.getScriptSupportAsString()); 222 else scp.set("singletype", "none"); 223 } 224 } 225 226 227 sct.set(KeyConstants._type,"java"); 228 229 Struct _args=new StructImpl(); 230 sct.set(KeyConstants._attributes,_args); 231 232 //Map<String,TagLibTagAttr> atts = tag.getAttributes(); 233 Iterator<Entry<String, TagLibTagAttr>> it = tag.getAttributes().entrySet().iterator(); 234 Entry<String, TagLibTagAttr> e; 235 while(it.hasNext()) { 236 e = it.next(); 237 TagLibTagAttr attr=e.getValue(); 238 if(attr.getHidden()) continue; 239 //for(int i=0;i<args.size();i++) { 240 Struct _arg=new StructImpl(); 241 _arg.set(KeyConstants._status,TagLibFactory.toStatus(attr.getStatus())); 242 _arg.set(KeyConstants._description,attr.getDescription()); 243 _arg.set(KeyConstants._type,attr.getType()); 244 if(attr.getAlias()!=null)_arg.set(KeyConstants._alias,ListUtil.arrayToList(attr.getAlias(), ",")); 245 if(attr.getValues()!=null)_arg.set(KeyConstants._values,Caster.toArray(attr.getValues())); 246 if(attr.getDefaultValue()!=null)_arg.set("defaultValue",attr.getDefaultValue()); 247 _arg.set(KeyConstants._required,attr.isRequired()?Boolean.TRUE:Boolean.FALSE); 248 _arg.set("scriptSupport",attr.getScriptSupportAsString()); 249 _args.setEL(attr.getName(),_arg); 250 } 251 return sct; 252 } 253 254 private static String getBodyType(TagLibTag tag) { 255 if(!tag.getHasBody()) return "prohibited"; 256 if(tag.isBodyFree()) return "free"; 257 return "required"; 258 } 259 260 private static String getAttributeType(TagLibTag tag) { 261 int type = tag.getAttributeType(); 262 if(TagLibTag.ATTRIBUTE_TYPE_DYNAMIC==type) return "dynamic"; 263 if(TagLibTag.ATTRIBUTE_TYPE_FIXED==type) return "fixed"; 264 if(TagLibTag.ATTRIBUTE_TYPE_MIXED==type) return "mixed"; 265 if(TagLibTag.ATTRIBUTE_TYPE_NONAME==type) return "noname"; 266 267 return "fixed"; 268 } 269 270 271 private static Boolean getSupportAttributeCollection(TagLibTag tag) { 272 return StringUtil.isEmpty(tag.getTttClassName())?Boolean.TRUE:Boolean.FALSE; 273 } 274}