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