001 package railo.runtime; 002 003 import java.util.ArrayList; 004 import java.util.HashMap; 005 import java.util.Iterator; 006 import java.util.List; 007 import java.util.Map; 008 import java.util.Map.Entry; 009 import java.util.Set; 010 011 import railo.commons.lang.StringUtil; 012 import railo.runtime.component.ComponentLoader; 013 import railo.runtime.dump.DumpData; 014 import railo.runtime.dump.DumpProperties; 015 import railo.runtime.dump.DumpTable; 016 import railo.runtime.dump.DumpTablePro; 017 import railo.runtime.dump.Dumpable; 018 import railo.runtime.engine.ThreadLocalPageContext; 019 import railo.runtime.exp.PageException; 020 import railo.runtime.type.Array; 021 import railo.runtime.type.ArrayImpl; 022 import railo.runtime.type.Collection; 023 import railo.runtime.type.KeyImpl; 024 import railo.runtime.type.Struct; 025 import railo.runtime.type.StructImpl; 026 import railo.runtime.type.UDF; 027 import railo.runtime.type.UDFImpl; 028 import railo.runtime.type.UDFProperties; 029 import railo.runtime.type.util.ArrayUtil; 030 031 /** 032 * 033 * MUST add handling for new attributes (style, namespace, serviceportname, porttypename, wsdlfile, bindingname, and output) 034 */ 035 public class InterfaceImpl implements Dumpable { // FUTURE to a Interface for this and a base interface for this and Coponent 036 037 private static final InterfaceImpl[] EMPTY = new InterfaceImpl[]{}; 038 039 //private InterfacePage page; 040 private PageSource pageSource; 041 private String extend; 042 private String hint; 043 private String dspName; 044 private String callPath; 045 private boolean realPath; 046 private Map meta; 047 048 private InterfaceImpl[] superInterfaces; 049 050 private Map<Collection.Key,UDF> udfs=new HashMap<Collection.Key,UDF>(); 051 private Map<Collection.Key,UDF> interfacesUDFs; 052 053 /** 054 * Constructor of the Component 055 * @param output 056 * @param extend 057 * @param hint 058 * @param dspName 059 */ 060 public InterfaceImpl(InterfacePage page,String extend, String hint, String dspName,String callPath, boolean realPath,Map interfacesUDFs) { 061 this(page.getPageSource(),extend, hint, dspName,callPath, realPath,interfacesUDFs,null); 062 } 063 public InterfaceImpl(InterfacePage page,String extend, String hint, String dspName,String callPath, boolean realPath,Map interfacesUDFs, Map meta) { 064 this(page.getPageSource(),extend, hint, dspName,callPath, realPath,interfacesUDFs,meta); 065 } 066 public InterfaceImpl(PageSource pageSource,String extend, String hint, String dspName,String callPath, boolean realPath,Map interfacesUDFs) { 067 this(pageSource, extend, hint, dspName, callPath, realPath, interfacesUDFs, null); 068 } 069 public InterfaceImpl(PageSource pageSource,String extend, String hint, String dspName,String callPath, boolean realPath,Map interfacesUDFs, Map meta) { 070 this.pageSource=pageSource; 071 this.extend=extend; 072 this.hint=hint; 073 this.dspName=dspName; 074 this.callPath=callPath; 075 this.realPath=realPath; 076 this.interfacesUDFs=interfacesUDFs; 077 this.meta=meta; 078 } 079 080 081 082 083 084 private static void init(PageContext pc,InterfaceImpl icfc) throws PageException { 085 086 if(!StringUtil.isEmpty(icfc.extend) && (icfc.superInterfaces==null || icfc.superInterfaces.length==0)) { 087 icfc.superInterfaces=loadImplements(ThreadLocalPageContext.get(pc),icfc.extend,icfc.interfacesUDFs); 088 } 089 else icfc.superInterfaces=EMPTY; 090 } 091 092 093 public static InterfaceImpl[] loadImplements(PageContext pc, String lstExtend, Map interfaceUdfs) throws PageException { 094 List<InterfaceImpl> interfaces=new ArrayList<InterfaceImpl>(); 095 loadImplements(pc, lstExtend, interfaces, interfaceUdfs); 096 return (InterfaceImpl[]) interfaces.toArray(new InterfaceImpl[interfaces.size()]); 097 098 } 099 100 private static void loadImplements(PageContext pc, String lstExtend,List interfaces, Map interfaceUdfs) throws PageException { 101 102 Array arr = railo.runtime.type.List.listToArrayRemoveEmpty(lstExtend, ','); 103 Iterator<?> it = arr.iterator(); 104 InterfaceImpl ic; 105 String extend; 106 107 while(it.hasNext()) { 108 extend=((String) it.next()).trim(); 109 ic=ComponentLoader.loadInterface(pc,extend,interfaceUdfs); 110 interfaces.add(ic); 111 ic.setUDFListener(interfaceUdfs); 112 if(!StringUtil.isEmpty(ic.extend)) { 113 loadImplements(pc,ic.extend,interfaces,interfaceUdfs); 114 } 115 } 116 } 117 118 private void setUDFListener(Map<Collection.Key,UDF> interfacesUDFs) { 119 this.interfacesUDFs=interfacesUDFs; 120 } 121 122 123 124 /*public boolean instanceOf(String type) { 125 boolean b = _instanceOf(type); 126 print.out("instanceOf("+type+"):"+page+":"+b); 127 return b; 128 }*/ 129 public boolean instanceOf(String type) { 130 if(realPath) { 131 if(type.equalsIgnoreCase(callPath)) return true; 132 if(type.equalsIgnoreCase(pageSource.getComponentName())) return true; 133 if(type.equalsIgnoreCase(_getName())) return true; 134 } 135 else { 136 if(type.equalsIgnoreCase(callPath)) return true; 137 if(type.equalsIgnoreCase(_getName())) return true; 138 } 139 if(superInterfaces==null){ 140 try { 141 init(null,this); 142 } catch (PageException e) { 143 superInterfaces=EMPTY; 144 } 145 } 146 for(int i=0;i<superInterfaces.length;i++){ 147 if(superInterfaces[i].instanceOf(type))return true; 148 } 149 return false; 150 } 151 152 153 /** 154 * @return the callPath 155 */ 156 public String getCallPath() { 157 return callPath; 158 } 159 160 161 162 private String _getName() { // MUST nicht so toll 163 if(callPath==null) return ""; 164 return railo.runtime.type.List.last(callPath,"./",true); 165 } 166 167 public void registerUDF(String key, UDF udf) { 168 udfs.put(KeyImpl.init(key),udf); 169 interfacesUDFs.put(KeyImpl.init(key), udf); 170 } 171 172 public void registerUDF(Collection.Key key, UDF udf) { 173 udfs.put(key,udf); 174 interfacesUDFs.put(key, udf); 175 } 176 177 public void registerUDF(String key, UDFProperties props) { 178 registerUDF(key, new UDFImpl(props)); 179 } 180 181 public void registerUDF(Collection.Key key, UDFProperties props) { 182 registerUDF(key, new UDFImpl(props)); 183 } 184 185 186 187 188 189 190 191 192 /** 193 * @see railo.runtime.dump.Dumpable#toDumpData(railo.runtime.PageContext, int) 194 */ 195 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) { 196 DumpTable table = new DumpTablePro("interface","#99cc99","#ffffff","#000000"); 197 table.setTitle("Interface "+callPath+""+(" "+StringUtil.escapeHTML(dspName))); 198 table.setComment("Interface can not directly invoked as a object"); 199 //if(top.properties.extend.length()>0)table.appendRow(1,new SimpleDumpData("Extends"),new SimpleDumpData(top.properties.extend)); 200 //if(top.properties.hint.trim().length()>0)table.appendRow(1,new SimpleDumpData("Hint"),new SimpleDumpData(top.properties.hint)); 201 202 //table.appendRow(1,new SimpleDumpData(""),_toDumpData(top,pageContext,maxlevel,access)); 203 return table; 204 } 205 206 /* * 207 * @return the page 208 * / 209 public InterfacePage getPage() { 210 return page; 211 }*/ 212 213 public PageSource getPageSource() { 214 return pageSource; 215 } 216 217 218 public Struct getMetaData(PageContext pc) throws PageException { 219 return _getMetaData(pc,this); 220 } 221 private static Struct _getMetaData(PageContext pc,InterfaceImpl icfc) throws PageException { 222 Struct sct=new StructImpl(); 223 ArrayImpl arr=new ArrayImpl(); 224 { 225 Iterator<UDF> it = icfc.udfs.values().iterator(); 226 while(it.hasNext()) { 227 arr.append(it.next().getMetaData(pc)); 228 } 229 } 230 231 if(icfc.meta!=null) { 232 Iterator it = icfc.meta.entrySet().iterator(); 233 Map.Entry entry; 234 while(it.hasNext()){ 235 entry=(Entry) it.next(); 236 sct.setEL(KeyImpl.toKey(entry.getKey()), entry.getValue()); 237 } 238 } 239 240 241 if(!StringUtil.isEmpty(icfc.hint,true))sct.set(KeyImpl.HINT,icfc.hint); 242 if(!StringUtil.isEmpty(icfc.dspName,true))sct.set(ComponentImpl.DISPLAY_NAME,icfc.dspName); 243 init(pc,icfc); 244 if(!ArrayUtil.isEmpty(icfc.superInterfaces)){ 245 Set<String> _set = railo.runtime.type.List.listToSet(icfc.extend,',',true); 246 Struct ex=new StructImpl(); 247 sct.set(ComponentImpl.EXTENDS,ex); 248 for(int i=0;i<icfc.superInterfaces.length;i++){ 249 if(!_set.contains(icfc.superInterfaces[i].getCallPath())) continue; 250 ex.setEL(KeyImpl.init(icfc.superInterfaces[i].getCallPath()),_getMetaData(pc,icfc.superInterfaces[i])); 251 } 252 253 } 254 255 if(arr.size()!=0)sct.set(ComponentImpl.FUNCTIONS,arr); 256 PageSource ps = icfc.pageSource; 257 sct.set(KeyImpl.NAME,ps.getComponentName()); 258 sct.set(ComponentImpl.FULLNAME,ps.getComponentName()); 259 260 sct.set(KeyImpl.PATH,ps.getDisplayPath()); 261 sct.set(KeyImpl.TYPE,"interface"); 262 return sct; 263 } 264 265 }