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