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