001 package railo.runtime; 002 003 import java.io.Externalizable; 004 import java.io.IOException; 005 import java.io.ObjectInput; 006 import java.io.ObjectOutput; 007 import java.lang.ref.SoftReference; 008 import java.net.URL; 009 import java.util.ArrayList; 010 import java.util.Date; 011 import java.util.HashMap; 012 import java.util.HashSet; 013 import java.util.Iterator; 014 import java.util.LinkedHashMap; 015 import java.util.Map; 016 import java.util.Set; 017 018 import javax.servlet.http.Cookie; 019 import javax.servlet.http.HttpServletRequest; 020 021 import railo.commons.io.DevNullOutputStream; 022 import railo.commons.lang.CFTypes; 023 import railo.commons.lang.ExceptionUtil; 024 import railo.commons.lang.Pair; 025 import railo.commons.lang.SizeOf; 026 import railo.commons.lang.StringUtil; 027 import railo.commons.lang.types.RefBoolean; 028 import railo.commons.lang.types.RefBooleanImpl; 029 import railo.commons.util.mod.MapFactory; 030 import railo.commons.util.mod.MapPro; 031 import railo.runtime.component.ComponentLoader; 032 import railo.runtime.component.DataMember; 033 import railo.runtime.component.InterfaceCollection; 034 import railo.runtime.component.Member; 035 import railo.runtime.component.Property; 036 import railo.runtime.config.ConfigImpl; 037 import railo.runtime.config.ConfigWeb; 038 import railo.runtime.config.ConfigWebImpl; 039 import railo.runtime.config.NullSupportHelper; 040 import railo.runtime.converter.ScriptConverter; 041 import railo.runtime.debug.DebugEntryTemplate; 042 import railo.runtime.dump.DumpData; 043 import railo.runtime.dump.DumpProperties; 044 import railo.runtime.dump.DumpTable; 045 import railo.runtime.dump.DumpUtil; 046 import railo.runtime.dump.SimpleDumpData; 047 import railo.runtime.engine.ThreadLocalPageContext; 048 import railo.runtime.exp.ApplicationException; 049 import railo.runtime.exp.ExpressionException; 050 import railo.runtime.exp.PageException; 051 import railo.runtime.functions.system.ContractPath; 052 import railo.runtime.interpreter.CFMLExpressionInterpreter; 053 import railo.runtime.op.Caster; 054 import railo.runtime.op.Duplicator; 055 import railo.runtime.op.Operator; 056 import railo.runtime.op.ThreadLocalDuplication; 057 import railo.runtime.op.date.DateCaster; 058 import railo.runtime.thread.ThreadUtil; 059 import railo.runtime.type.ArrayImpl; 060 import railo.runtime.type.Collection; 061 import railo.runtime.type.FunctionArgument; 062 import railo.runtime.type.KeyImpl; 063 import railo.runtime.type.Sizeable; 064 import railo.runtime.type.Struct; 065 import railo.runtime.type.StructImpl; 066 import railo.runtime.type.UDF; 067 import railo.runtime.type.UDFGSProperty; 068 import railo.runtime.type.UDFImpl; 069 import railo.runtime.type.UDFProperties; 070 import railo.runtime.type.UDFPropertiesImpl; 071 import railo.runtime.type.cfc.ComponentAccess; 072 import railo.runtime.type.cfc.ComponentAccessEntryIterator; 073 import railo.runtime.type.cfc.ComponentAccessValueIterator; 074 import railo.runtime.type.comparator.ArrayOfStructComparator; 075 import railo.runtime.type.dt.DateTime; 076 import railo.runtime.type.it.StringIterator; 077 import railo.runtime.type.scope.Argument; 078 import railo.runtime.type.scope.ArgumentImpl; 079 import railo.runtime.type.scope.ArgumentIntKey; 080 import railo.runtime.type.scope.Variables; 081 import railo.runtime.type.util.ArrayUtil; 082 import railo.runtime.type.util.ComponentUtil; 083 import railo.runtime.type.util.KeyConstants; 084 import railo.runtime.type.util.ListUtil; 085 import railo.runtime.type.util.PropertyFactory; 086 import railo.runtime.type.util.StructSupport; 087 import railo.runtime.type.util.StructUtil; 088 089 /** 090 * %**% 091 * MUST add handling for new attributes (style, namespace, serviceportname, porttypename, wsdlfile, bindingname, and output) 092 */ 093 public final class ComponentImpl extends StructSupport implements Externalizable,ComponentAccess,coldfusion.runtime.TemplateProxy,Sizeable { 094 095 096 private ComponentProperties properties; 097 private Map<Key,Member> _data; 098 private Map<Key,UDF> _udfs; 099 100 ComponentImpl top=this; 101 ComponentImpl base; 102 //private ComponentPage componentPage; 103 private PageSource pageSource; 104 private ComponentScope scope; 105 106 // for all the same 107 private int dataMemberDefaultAccess; 108 private Boolean _triggerDataMember; 109 110 // state control of component 111 boolean isInit=false; 112 113 private InterfaceCollection interfaceCollection; 114 115 private boolean useShadow; 116 boolean afterConstructor; 117 private Map<Key,UDF> constructorUDFs; 118 private boolean loaded; 119 120 121 122 123 public long sizeOf() { 124 return 125 SizeOf.size(properties)+ 126 SizeOf.size(_data)+ 127 SizeOf.size(scope)+ 128 SizeOf.size(dataMemberDefaultAccess)+ 129 SizeOf.size(false)+ 130 SizeOf.size(interfaceCollection)+ 131 SizeOf.size(useShadow)+ 132 SizeOf.size(afterConstructor)+ 133 SizeOf.size(base); 134 } 135 136 /** 137 * Constructor of the Component, USED ONLY FOR DESERIALIZE 138 */ 139 public ComponentImpl() { 140 } 141 142 /** 143 * Constructor of the class 144 * @param componentPage 145 * @param output 146 * @param _synchronized 147 * @param extend 148 * @param implement 149 * @param hint 150 * @param dspName 151 * @param callPath 152 * @param realPath 153 * @param style 154 * @param meta 155 * @throws ApplicationException 156 */ 157 158 public ComponentImpl(ComponentPage componentPage,Boolean output,boolean _synchronized, 159 String extend, String implement, String hint, String dspName,String callPath, boolean realPath, 160 String style,StructImpl meta) throws ApplicationException { 161 this(componentPage,output,_synchronized, 162 extend, implement, hint, dspName,callPath, realPath, style,false, false,meta); 163 } 164 165 public ComponentImpl(ComponentPage componentPage,Boolean output,boolean _synchronized, 166 String extend, String implement, String hint, String dspName,String callPath, boolean realPath, 167 String style,boolean persistent,StructImpl meta) throws ApplicationException { 168 this(componentPage,output,_synchronized, 169 extend, implement, hint, dspName,callPath, realPath, style,persistent, false,meta); 170 } 171 172 public ComponentImpl(ComponentPage componentPage,Boolean output,boolean _synchronized, 173 String extend, String implement, String hint, String dspName,String callPath, boolean realPath, 174 String style,boolean persistent,boolean accessors,StructImpl meta) throws ApplicationException { 175 this.properties=new ComponentProperties(dspName,extend.trim(),implement,hint,output,callPath,realPath,_synchronized,null,persistent,accessors,meta); 176 //this.componentPage=componentPage instanceof ComponentPageProxy?componentPage:PageProxy.toProxy(componentPage); 177 this.pageSource=componentPage.getPageSource(); 178 179 if(!StringUtil.isEmpty(style) && !"rpc".equals(style)) 180 throw new ApplicationException("style ["+style+"] is not supported, only the following styles are supported: [rpc]"); 181 } 182 183 184 @Override 185 186 public Collection duplicate(boolean deepCopy) { 187 ComponentImpl top= _duplicate(deepCopy,true); 188 setTop(top,top); 189 190 191 return top; 192 } 193 194 195 196 197 private ComponentImpl _duplicate( boolean deepCopy, boolean isTop) { 198 ComponentImpl trg=new ComponentImpl(); 199 ThreadLocalDuplication.set(this, trg); 200 try{ 201 // attributes 202 trg.pageSource=pageSource; 203 trg._triggerDataMember=_triggerDataMember; 204 trg.useShadow=useShadow; 205 trg.afterConstructor=afterConstructor; 206 trg.dataMemberDefaultAccess=dataMemberDefaultAccess; 207 trg.properties=properties.duplicate(); 208 trg.isInit=isInit; 209 trg.interfaceCollection=interfaceCollection; 210 211 boolean useShadow=scope instanceof ComponentScopeShadow; 212 if(!useShadow)trg.scope=new ComponentScopeThis(trg); 213 214 if(base!=null){ 215 trg.base=base._duplicate(deepCopy,false); 216 217 trg._data=trg.base._data; 218 trg._udfs=duplicateUTFMap(this,trg, _udfs,new HashMap<Key,UDF>(trg.base._udfs)); 219 220 if(useShadow) trg.scope=new ComponentScopeShadow(trg,(ComponentScopeShadow)trg.base.scope,false); 221 } 222 else { 223 // clone data member, ignore udfs for the moment 224 trg._data=duplicateDataMember(trg, _data, new HashMap(), deepCopy); 225 trg._udfs=duplicateUTFMap(this,trg, _udfs,new HashMap<Key, UDF>()); 226 227 if(useShadow) { 228 ComponentScopeShadow css = (ComponentScopeShadow)scope; 229 trg.scope=new ComponentScopeShadow(trg,(MapPro)duplicateDataMember(trg,css.getShadow(),MapFactory.getConcurrentMap(),deepCopy)); 230 } 231 } 232 233 // at the moment this makes no sense, becuae this map is no more used after constructor has runned and for a clone the constructo is not executed, but perhaps this is used in future 234 if(constructorUDFs!=null){ 235 trg.constructorUDFs=new HashMap<Collection.Key, UDF>(); 236 addUDFS(trg, constructorUDFs, trg.constructorUDFs); 237 } 238 239 240 if(isTop) { 241 setTop(trg,trg); 242 243 addUDFS(trg,_data,trg._data); 244 if(useShadow){ 245 addUDFS(trg,((ComponentScopeShadow)scope).getShadow(),((ComponentScopeShadow)trg.scope).getShadow()); 246 } 247 } 248 249 250 251 252 } 253 finally { 254 // ThreadLocalDuplication.remove(this); removed "remove" to catch sisters and brothers 255 } 256 257 return trg; 258 } 259 260 261 private static void addUDFS(ComponentImpl trgComp, Map src, Map trg) { 262 Iterator it = src.entrySet().iterator(); 263 Map.Entry entry; 264 Object key,value; 265 UDF udf; 266 ComponentImpl comp,owner; 267 boolean done; 268 while(it.hasNext()){ 269 entry=(Entry) it.next(); 270 key=entry.getKey(); 271 value=entry.getValue(); 272 if(value instanceof UDF) { 273 udf=(UDF) value; 274 done=false; 275 // get udf from _udf 276 owner = (ComponentImpl)udf.getOwnerComponent(); 277 if(owner!=null) { 278 comp=trgComp; 279 do{ 280 if(owner.pageSource==comp.pageSource) 281 break; 282 } 283 while((comp=comp.base)!=null); 284 if(comp!=null) { 285 value=comp._udfs.get(key); 286 trg.put(key, value); 287 done=true; 288 } 289 } 290 // udf with no owner 291 if(!done) 292 trg.put(key, udf.duplicate()); 293 294 //print.o(owner.pageSource.getComponentName()+":"+udf.getFunctionName()); 295 } 296 } 297 } 298 299 /** 300 * duplicate the datamember in the map, ignores the udfs 301 * @param c 302 * @param map 303 * @param newMap 304 * @param deepCopy 305 * @return 306 */ 307 public static Map duplicateDataMember(ComponentImpl c,Map map,Map newMap,boolean deepCopy){ 308 Iterator it=map.entrySet().iterator(); 309 Map.Entry entry; 310 Object value; 311 while(it.hasNext()) { 312 entry=(Entry) it.next(); 313 value=entry.getValue(); 314 315 if(!(value instanceof UDF)) { 316 if(deepCopy) value=Duplicator.duplicate(value,deepCopy); 317 newMap.put(entry.getKey(),value); 318 } 319 } 320 return newMap; 321 } 322 323 public static Map<Key, UDF> duplicateUTFMap(ComponentImpl src,ComponentImpl trg,Map<Key,UDF> srcMap, Map<Key, UDF> trgMap){ 324 Iterator<Entry<Key, UDF>> it = srcMap.entrySet().iterator(); 325 Map.Entry<Key, UDF> entry; 326 UDF udf; 327 while(it.hasNext()) { 328 entry=it.next(); 329 udf=entry.getValue(); 330 331 if(udf.getOwnerComponent()==src) { 332 udf=((UDFImpl)entry.getValue()).duplicate(trg); 333 trgMap.put(entry.getKey(),udf); 334 } 335 336 } 337 return trgMap; 338 } 339 340 341 /** 342 * initalize the Component 343 * @param pageContext 344 * @param componentPage 345 * @throws PageException 346 */ 347 public void init(PageContext pageContext, ComponentPage componentPage) throws PageException { 348 //this.componentPage=componentPage; 349 this.pageSource=componentPage.getPageSource(); 350 351 // extends 352 if(!StringUtil.isEmpty(properties.extend)) { 353 base= ComponentLoader.loadComponent(pageContext,properties.extend,Boolean.TRUE,null); 354 } 355 else { 356 Page p=((ConfigWebImpl)pageContext.getConfig()).getBaseComponentPage(pageContext); 357 if(!componentPage.getPageSource().equals(p.getPageSource())) { 358 base=ComponentLoader.loadComponent(pageContext,p,p.getPageSource(),"Component",false); 359 } 360 } 361 362 if(base!=null){ 363 this.dataMemberDefaultAccess=base.dataMemberDefaultAccess; 364 this._triggerDataMember=base._triggerDataMember; 365 _data=base._data; 366 _udfs=new HashMap<Key,UDF>(base._udfs); 367 setTop(this,base); 368 } 369 else { 370 this.dataMemberDefaultAccess=pageContext.getConfig().getComponentDataMemberDefaultAccess(); 371 // TODO get per CFC setting this._triggerDataMember=pageContext.getConfig().getTriggerComponentDataMember(); 372 _udfs=new HashMap<Key,UDF>(); 373 _data=MapFactory.getConcurrentMap(); 374 } 375 376 // implements 377 if(!StringUtil.isEmpty(properties.implement)) { 378 interfaceCollection=new InterfaceCollection((PageContextImpl)pageContext,properties.implement); 379 } 380 381 // scope 382 if(useShadow=pageContext.getConfig().useComponentShadow()) { 383 if(base==null) scope=new ComponentScopeShadow(this,MapFactory.getConcurrentMap()); 384 else scope=new ComponentScopeShadow(this,(ComponentScopeShadow)base.scope,false); 385 } 386 else { 387 scope=new ComponentScopeThis(this); 388 } 389 initProperties(); 390 } 391 392 public void checkInterface(PageContext pc, ComponentPage componentPage) throws PageException { 393 if(interfaceCollection==null || interfaceCollection.lastUpdate()<=componentPage.lastCheck()) return; 394 395 Iterator it = interfaceCollection.getUdfs().entrySet().iterator(); 396 Map.Entry entry; 397 UDFImpl iUdf,cUdf; 398 FunctionArgument[] iFA,cFA; 399 while(it.hasNext()){ 400 401 entry=(Entry) it.next(); 402 iUdf=(UDFImpl) entry.getValue(); 403 cUdf=(UDFImpl) _udfs.get(entry.getKey()); 404 405 // UDF does not exist 406 if(cUdf==null ) { 407 throw new ExpressionException( 408 "component ["+componentPage.getPageSource().getDisplayPath()+ 409 "] does not implement the function ["+iUdf.toString().toLowerCase()+"] of the interface ["+ 410 iUdf.getPageSource().getDisplayPath()+"]"); 411 412 } 413 414 iFA=iUdf.getFunctionArguments(); 415 cFA=cUdf.getFunctionArguments(); 416 // access 417 if(cUdf.getAccess()>Component.ACCESS_PUBLIC){ 418 throw new ExpressionException( _getErrorMessage(cUdf,iUdf), 419 "access ["+ComponentUtil.toStringAccess(cUdf.getAccess())+"] has to be at least [public]"); 420 } 421 422 // return type 423 if(iUdf.getReturnType()!=cUdf.getReturnType()){ 424 throw new ExpressionException( _getErrorMessage(cUdf,iUdf), 425 "return type ["+cUdf.getReturnTypeAsString()+"] does not match interface function return type ["+iUdf.getReturnTypeAsString()+"]"); 426 } 427 // none base types 428 if(iUdf.getReturnType()==CFTypes.TYPE_UNKNOW && !iUdf.getReturnTypeAsString().equalsIgnoreCase(cUdf.getReturnTypeAsString())) { 429 throw new ExpressionException( _getErrorMessage(cUdf,iUdf), 430 "return type ["+cUdf.getReturnTypeAsString()+"] does not match interface function return type ["+iUdf.getReturnTypeAsString()+"]"); 431 } 432 // output 433 if(iUdf.getOutput()!=cUdf.getOutput()){ 434 throw new ExpressionException( _getErrorMessage(cUdf,iUdf), 435 "output does not match interface function output definition"); 436 } 437 438 // arguments 439 if(iFA.length!=cFA.length) { 440 throw new ExpressionException( _getErrorMessage(cUdf,iUdf),"not the same argument count"); 441 } 442 443 for(int i=0;i<iFA.length;i++) { 444 // type 445 if(iFA[i].getType()!=cFA[i].getType()){ 446 throw new ExpressionException( _getErrorMessage(cUdf,iUdf), 447 "argument type ["+cFA[i].getTypeAsString()+"] does not match interface function argument type ["+iFA[i].getTypeAsString()+"]"); 448 } 449 // none base types 450 if(iFA[i].getType()==CFTypes.TYPE_UNKNOW && !iFA[i].getTypeAsString().equalsIgnoreCase(cFA[i].getTypeAsString())) { 451 throw new ExpressionException( _getErrorMessage(cUdf,iUdf), 452 "argument type ["+cFA[i].getTypeAsString()+"] does not match interface function argument type ["+iFA[i].getTypeAsString()+"]"); 453 } 454 // name 455 if(!iFA[i].getName().equalsIgnoreCase(cFA[i].getName())){ 456 throw new ExpressionException( _getErrorMessage(cUdf,iUdf), 457 "argument name ["+cFA[i].getName()+"] does not match interface function argument name ["+iFA[i].getName()+"]"); 458 } 459 // required 460 if(iFA[i].isRequired()!=cFA[i].isRequired()){ 461 throw new ExpressionException( _getErrorMessage(cUdf,iUdf), 462 "argument ["+cFA[i].getName()+"] should "+(iFA[i].isRequired()?"":"not ")+"be required"); 463 } 464 } 465 } 466 componentPage.ckecked(); 467 } 468 469 private String _getErrorMessage(UDFImpl cUdf,UDFImpl iUdf) { 470 return "function ["+cUdf.toString().toLowerCase()+"] of component " + 471 "["+pageSource.getDisplayPath()+"]" + 472 " does not match the function declaration ["+iUdf.toString().toLowerCase()+"] of the interface " + 473 "["+iUdf.getPageSource().getDisplayPath()+"]"; 474 } 475 476 477 private static void setTop(ComponentImpl top,ComponentImpl trg) { 478 while(trg!=null){ 479 trg.top=top; 480 trg=trg.base; 481 } 482 } 483 484 Object _call(PageContext pc, Collection.Key key, Struct namedArgs, Object[] args,boolean superAccess) throws PageException { 485 Member member=getMember(pc,key,false, superAccess); 486 if(member instanceof UDF) { 487 return _call(pc,(UDF)member,namedArgs,args); 488 } 489 return onMissingMethod(pc, -1, member, key.getString(), args, namedArgs, superAccess); 490 } 491 492 Object _call(PageContext pc, int access, Collection.Key key, Struct namedArgs, Object[] args,boolean superAccess) throws PageException { 493 Member member=getMember(access,key,false,superAccess); 494 if(member instanceof UDF) { 495 return _call(pc,(UDF)member,namedArgs,args); 496 } 497 return onMissingMethod(pc, access, member, key.getString(), args, namedArgs, superAccess); 498 } 499 500 public Object onMissingMethod(PageContext pc, int access,Member member,String name,Object _args[],Struct _namedArgs, boolean superAccess) throws PageException { 501 Member ommm = access==-1? 502 getMember(pc,KeyConstants._onmissingmethod,false, superAccess): 503 getMember(access,KeyConstants._onmissingmethod,false, superAccess); 504 if(ommm instanceof UDF) { 505 Argument args=new ArgumentImpl(); 506 if(_args!=null) { 507 for(int i=0;i<_args.length;i++) { 508 args.setEL(ArgumentIntKey.init(i+1), _args[i]); 509 } 510 } 511 else if(_namedArgs!=null) { 512 UDFImpl.argumentCollection(_namedArgs, new FunctionArgument[]{}); 513 514 Iterator<Entry<Key, Object>> it = _namedArgs.entryIterator(); 515 Entry<Key, Object> e; 516 while(it.hasNext()){ 517 e = it.next(); 518 args.setEL(e.getKey(),e.getValue()); 519 } 520 521 } 522 523 //Struct newArgs=new StructImpl(StructImpl.TYPE_SYNC); 524 //newArgs.setEL(MISSING_METHOD_NAME, name); 525 //newArgs.setEL(MISSING_METHOD_ARGS, args); 526 Object[] newArgs=new Object[]{name,args}; 527 528 return _call(pc,(UDF)ommm,null,newArgs); 529 } 530 if(member==null)throw ComponentUtil.notFunction(this, KeyImpl.init(name), null,access); 531 throw ComponentUtil.notFunction(this, KeyImpl.init(name), member.getValue(),access); 532 } 533 534 Object _call(PageContext pc, UDF udf, Struct namedArgs, Object[] args) throws PageException { 535 536 Object rtn=null; 537 Variables parent=null; 538 539 // INFO duplicate code is for faster execution -> less contions 540 541 542 // debug yes 543 if(pc.getConfig().debug()) { 544 DebugEntryTemplate debugEntry=pc.getDebugger().getEntry(pc,pageSource,udf.getFunctionName());//new DebugEntry(src,udf.getFunctionName()); 545 int currTime=pc.getExecutionTime(); 546 long time=System.nanoTime(); 547 548 // sync yes 549 if(top.properties._synchronized){ 550 synchronized (this) { 551 try { 552 parent=beforeCall(pc); 553 if(args!=null)rtn=udf.call(pc,args,true); 554 else rtn=udf.callWithNamedValues(pc,namedArgs,true); 555 } 556 finally { 557 pc.setVariablesScope(parent); 558 int diff= ((int)(System.nanoTime()-time)-(pc.getExecutionTime()-currTime)); 559 pc.setExecutionTime(pc.getExecutionTime()+diff); 560 debugEntry.updateExeTime(diff); 561 } 562 } 563 } 564 565 // sync no 566 else { 567 try { 568 parent=beforeCall(pc); 569 if(args!=null)rtn=udf.call(pc,args,true); 570 else rtn=udf.callWithNamedValues(pc,namedArgs,true); 571 } 572 finally { 573 pc.setVariablesScope(parent); 574 int diff= ((int)(System.nanoTime()-time)-(pc.getExecutionTime()-currTime)); 575 pc.setExecutionTime(pc.getExecutionTime()+diff); 576 debugEntry.updateExeTime(diff); 577 } 578 } 579 580 581 } 582 583 // debug no 584 else { 585 586 // sync yes 587 if(top.properties._synchronized){ 588 synchronized (this) { 589 try { 590 parent=beforeCall(pc); 591 if(args!=null)rtn=udf.call(pc,args,true); 592 else rtn=udf.callWithNamedValues(pc,namedArgs,true); 593 } 594 finally { 595 pc.setVariablesScope(parent); 596 } 597 } 598 } 599 600 // sync no 601 else { 602 try { 603 parent=beforeCall(pc); 604 if(args!=null)rtn=udf.call(pc,args,true); 605 else rtn=udf.callWithNamedValues(pc,namedArgs,true); 606 } 607 finally { 608 pc.setVariablesScope(parent); 609 } 610 } 611 } 612 return rtn; 613 } 614 615 /** 616 * will be called before executing method or constructor 617 * @param pc 618 * @return the old scope map 619 */ 620 public Variables beforeCall(PageContext pc) { 621 Variables parent=pc.variablesScope(); 622 pc.setVariablesScope(scope); 623 return parent; 624 } 625 626 /** 627 * will be called after invoking constructor, only invoked by constructor (component body execution) 628 * @param pc 629 * @param parent 630 */ 631 public void afterConstructor(PageContext pc, Variables parent) { 632 pc.setVariablesScope(parent); 633 this.afterConstructor=true; 634 635 if(constructorUDFs!=null){ 636 Iterator<Entry<Key, UDF>> it = constructorUDFs.entrySet().iterator(); 637 Map.Entry<Key, UDF> entry; 638 Key key; 639 UDFImpl udf; 640 while(it.hasNext()){ 641 entry=it.next(); 642 key=entry.getKey(); 643 udf=(UDFImpl) entry.getValue(); 644 registerUDF(key, udf,false,true); 645 } 646 } 647 } 648 649 /** 650 * this function may be called by generated code inside a ra file 651 * @deprecated replaced with <code>afterConstructor(PageContext pc, Variables parent)</code> 652 * @param pc 653 * @param parent 654 */ 655 public void afterCall(PageContext pc, Variables parent) { 656 afterConstructor(pc, parent); 657 } 658 659 /** 660 * sets the callpath 661 * @param callPath 662 * / 663 public void setCallPath(String callPath) { 664 properties.callPath=callPath; 665 }*/ 666 667 /** 668 * rerturn the size 669 * @param access 670 * @return size 671 */ 672 public int size(int access) { 673 return keys(access).length; 674 } 675 676 /** 677 * list of keys 678 * @param c 679 * @param access 680 * @param doBase 681 * @return key set 682 */ 683 public Set<Key> keySet(int access) { 684 HashSet<Key> set=new HashSet<Key>(); 685 Map.Entry<Key, Member> entry; 686 Iterator<Entry<Key, Member>> it = _data.entrySet().iterator(); 687 while(it.hasNext()) { 688 entry=it.next(); 689 if(entry.getValue().getAccess()<=access)set.add(entry.getKey()); 690 } 691 return set; 692 } 693 694 /*protected Set<Key> udfKeySet(int access) { 695 Set<Key> set=new HashSet<Key>(); 696 Member m; 697 Map.Entry<Key, UDF> entry; 698 Iterator<Entry<Key, UDF>> it = _udfs.entrySet().iterator(); 699 while(it.hasNext()) { 700 entry= it.next(); 701 m=entry.getValue(); 702 if(m.getAccess()<=access)set.add(entry.getKey()); 703 } 704 return set; 705 }*/ 706 707 708 protected java.util.List<Member> getMembers(int access) { 709 java.util.List<Member> members=new ArrayList<Member>(); 710 Member e; 711 Iterator<Entry<Key, Member>> it = _data.entrySet().iterator(); 712 while(it.hasNext()) { 713 e=it.next().getValue(); 714 if(e.getAccess()<=access)members.add(e); 715 } 716 return members; 717 } 718 719 720 @Override 721 public Iterator<Collection.Key> keyIterator(int access) { 722 return keySet(access).iterator(); 723 } 724 725 @Override 726 public Iterator<String> keysAsStringIterator(int access) { 727 return new StringIterator(keys(access)); 728 } 729 730 @Override 731 public Iterator<Entry<Key, Object>> entryIterator(int access) { 732 return new ComponentAccessEntryIterator(this, keys(access),access); 733 } 734 735 @Override 736 public Iterator<Object> valueIterator(int access) { 737 return new ComponentAccessValueIterator(this,keys(access),access); 738 } 739 740 741 @Override 742 public Iterator<Object> valueIterator() { 743 return valueIterator(getAccess(ThreadLocalPageContext.get())); 744 } 745 746 @Override 747 public Collection.Key[] keys(int access) { 748 Set<Key> set = keySet(access); 749 return set.toArray(new Collection.Key[set.size()]); 750 } 751 752 @Override 753 public void clear() { 754 _data.clear(); 755 _udfs.clear(); 756 } 757 758 @Override 759 public Member getMember(int access,Collection.Key key, boolean dataMember,boolean superAccess) { 760 // check super 761 if(dataMember && access==ACCESS_PRIVATE && key.equalsIgnoreCase(KeyConstants._super)) { 762 return SuperComponent.superMember((ComponentImpl)ComponentUtil.getActiveComponent(ThreadLocalPageContext.get(),this)._base()); 763 //return SuperComponent . superMember(base); 764 } 765 if(superAccess) { 766 return _udfs.get(key); 767 } 768 // check data 769 Member member=_data.get(key); 770 if(member!=null) { 771 if(member.getAccess()<=access)return member; 772 return null; 773 } 774 return null; 775 } 776 777 778 /** 779 * get entry matching key 780 * @param access 781 * @param keyLowerCase key lower case (case sensitive) 782 * @param doBase do check also base component 783 * @param dataMember do also check if key super 784 * @return matching entry if exists otherwise null 785 */ 786 protected Member getMember(PageContext pc, Collection.Key key, boolean dataMember,boolean superAccess) { 787 // check super 788 if(dataMember && isPrivate(pc) && key.equalsIgnoreCase(KeyConstants._super)) { 789 return SuperComponent.superMember((ComponentImpl)ComponentUtil.getActiveComponent(pc,this)._base()); 790 } 791 if(superAccess) 792 return _udfs.get(key); 793 794 // check data 795 Member member=_data.get(key); 796 if(isAccessible(pc,member)) return member; 797 return null; 798 } 799 800 private boolean isAccessible(PageContext pc, Member member) { 801 // TODO geschwindigkeit 802 if(member!=null) { 803 int access=member.getAccess(); 804 if(access<=ACCESS_PUBLIC) return true; 805 else if(access==ACCESS_PRIVATE && isPrivate(pc)) return true; 806 else if(access==ACCESS_PACKAGE && isPackage(pc)) return true; 807 } 808 return false; 809 } 810 811 private boolean isAccessible(PageContext pc, int access) { 812 if(access<=ACCESS_PUBLIC) return true; 813 else if(access==ACCESS_PRIVATE && isPrivate(pc)) return true; 814 else if(access==ACCESS_PACKAGE && isPackage(pc)) return true; 815 return false; 816 } 817 818 /** 819 * @param pc 820 * @return returns if is private 821 */ 822 private boolean isPrivate(PageContext pc) { 823 if(pc==null) return true; 824 Component ac = pc.getActiveComponent(); 825 return (ac!=null && (ac==this || 826 ((ComponentImpl)ac).top.pageSource.equals(top.pageSource))) ; 827 } 828 /** 829 * @param pc 830 * @return returns if is package 831 */ 832 private boolean isPackage(PageContext pc) { 833 Component ac = pc.getActiveComponent(); 834 if(ac!=null) { 835 if(ac==this) return true; 836 ComponentImpl aci = ((ComponentImpl)ac); 837 if(aci.top.pageSource.equals(top.pageSource))return true; 838 839 int index; 840 String other=aci.top.getAbsName(); 841 index=other.lastIndexOf('.'); 842 if(index==-1)other=""; 843 else other=other.substring(0,index); 844 845 String my=top.getAbsName(); 846 index=my.lastIndexOf('.'); 847 if(index==-1)my=""; 848 else my=my.substring(0,index); 849 850 return my.equalsIgnoreCase(other); 851 } 852 return false; 853 } 854 855 /** 856 * return the access of a member 857 * @param key 858 * @return returns the access (Component.ACCESS_REMOTE, ACCESS_PUBLIC, ACCESS_PACKAGE,Component.ACCESS_PRIVATE) 859 */ 860 private int getAccess(Collection.Key key){ 861 Member member=getMember(ACCESS_PRIVATE,key,false,false); 862 if(member==null) return Component.ACCESS_PRIVATE; 863 return member.getAccess(); 864 } 865 866 /** 867 * returns current access to this component 868 * @param pc 869 * @return access 870 */ 871 private int getAccess(PageContext pc) { 872 if(pc==null) return ACCESS_PUBLIC; 873 874 if(isPrivate(pc)) return ACCESS_PRIVATE; 875 if(isPackage(pc)) return ACCESS_PACKAGE; 876 return ACCESS_PUBLIC; 877 } 878 879 @Override 880 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) { 881 return toDumpData(pageContext,maxlevel,dp,getAccess(pageContext)); 882 } 883 884 885 /** 886 * to html output print only with access less than given access 887 * @param pageContext 888 * @param access 889 * @return html output 890 */ 891 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp, int access) { 892 DumpTable table = new DumpTable("component","#99cc99","#ccffcc","#000000"); 893 table.setTitle("Component "+getCallPath()+""+(" "+StringUtil.escapeHTML(top.properties.dspName))); 894 table.setComment("Only the functions and data members that are accessible from your location are displayed"); 895 if(top.properties.extend.length()>0)table.appendRow(1,new SimpleDumpData("Extends"),new SimpleDumpData(top.properties.extend)); 896 if(top.properties.hint.trim().length()>0)table.appendRow(1,new SimpleDumpData("Hint"),new SimpleDumpData(top.properties.hint)); 897 898 DumpTable content = _toDumpData(top,pageContext,maxlevel,dp,access); 899 if(!content.isEmpty())table.appendRow(1,new SimpleDumpData(""),content); 900 return table; 901 } 902 903 static DumpTable _toDumpData(ComponentImpl ci,PageContext pc, int maxlevel, DumpProperties dp,int access) { 904 maxlevel--; 905 ComponentWrap cw=new ComponentWrap(Component.ACCESS_PRIVATE, ci); 906 Collection.Key[] keys= cw.keys(); 907 908 909 910 DumpTable[] accesses=new DumpTable[4]; 911 accesses[Component.ACCESS_PRIVATE] = new DumpTable("#ff6633","#ff9966","#000000"); 912 accesses[Component.ACCESS_PRIVATE].setTitle("private"); 913 accesses[Component.ACCESS_PRIVATE].setWidth("100%"); 914 //accesses[Component.ACCESS_PRIVATE].setRow(1,"100%"); 915 accesses[Component.ACCESS_PACKAGE] = new DumpTable("#ff9966","#ffcc99","#000000"); 916 accesses[Component.ACCESS_PACKAGE].setTitle("package"); 917 accesses[Component.ACCESS_PACKAGE].setWidth("100%"); 918 accesses[Component.ACCESS_PUBLIC] = new DumpTable("#ffcc99","#ffffcc","#000000"); 919 accesses[Component.ACCESS_PUBLIC].setTitle("public"); 920 accesses[Component.ACCESS_PUBLIC].setWidth("100%"); 921 accesses[Component.ACCESS_REMOTE] = new DumpTable("#ccffcc","#ffffff","#000000"); 922 accesses[Component.ACCESS_REMOTE].setTitle("remote"); 923 accesses[Component.ACCESS_REMOTE].setWidth("100%"); 924 925 Collection.Key key; 926 for(int i=0;i<keys.length;i++) { 927 key=keys[i]; 928 int a=ci.getAccess(key); 929 DumpTable box=accesses[a]; 930 Object o=cw.get(key,null); 931 if(o==ci)o="[this]"; 932 if(DumpUtil.keyValid(dp,maxlevel, key)) 933 box.appendRow(1,new SimpleDumpData(key.getString()),DumpUtil.toDumpData(o,pc,maxlevel,dp)); 934 } 935 936 937 DumpTable table=new DumpTable("#ffffff","#cccccc","#000000"); 938 939 // properties 940 if(ci.top.properties.persistent || ci.top.properties.accessors){ 941 Property[] properties=ci.getProperties(false); 942 DumpTable prop = new DumpTable("#99cc99","#ccffcc","#000000"); 943 944 prop.setTitle("Properties"); 945 prop.setWidth("100%"); 946 Property p; 947 Object child; 948 for(int i=0;i<properties.length;i++) { 949 p=properties[i]; 950 child = ci.scope.get(KeyImpl.init(p.getName()),null); 951 DumpData dd; 952 if(child instanceof Component) { 953 DumpTable t = new DumpTable("component","#99cc99","#ffffff","#000000"); 954 t.appendRow(1,new SimpleDumpData("Component"),new SimpleDumpData(((Component)child).getCallName())); 955 dd=t; 956 957 } 958 else 959 dd=DumpUtil.toDumpData(child, pc, maxlevel-1, dp); 960 961 962 963 prop.appendRow(1, new SimpleDumpData(p.getName()),dd); 964 } 965 966 if(access>=ACCESS_PUBLIC && !prop.isEmpty()) { 967 table.appendRow(0,prop); 968 } 969 } 970 971 972 973 974 if(!accesses[ACCESS_REMOTE].isEmpty()) { 975 table.appendRow(0,accesses[Component.ACCESS_REMOTE]); 976 } 977 if(!accesses[ACCESS_PUBLIC].isEmpty()) { 978 table.appendRow(0,accesses[Component.ACCESS_PUBLIC]); 979 } 980 if(!accesses[ACCESS_PACKAGE].isEmpty()) { 981 table.appendRow(0,accesses[Component.ACCESS_PACKAGE]); 982 } 983 if(!accesses[ACCESS_PRIVATE].isEmpty()) { 984 table.appendRow(0,accesses[Component.ACCESS_PRIVATE]); 985 } 986 return table; 987 } 988 989 /** 990 * @return return call path 991 */ 992 protected String getCallPath() { 993 if(StringUtil.isEmpty(top.properties.callPath)) return getName(); 994 try { 995 return "("+ListUtil.arrayToList(ListUtil.listToArrayTrim(top.properties.callPath.replace('/','.').replace('\\','.'),"."),".")+")"; 996 } catch (PageException e) { 997 return top.properties.callPath; 998 } 999 } 1000 1001 @Override 1002 public String getDisplayName() { 1003 return top.properties.dspName; 1004 } 1005 1006 @Override 1007 public String getExtends() { 1008 return top.properties.extend; 1009 } 1010 public String getBaseAbsName() { 1011 return top.base.pageSource.getComponentName(); 1012 } 1013 1014 public boolean isBasePeristent() { 1015 return top.base!=null && top.base.properties.persistent; 1016 } 1017 1018 1019 @Override 1020 public String getHint() { 1021 return top.properties.hint; 1022 } 1023 1024 @Override 1025 public String getWSDLFile() { 1026 return top.properties.getWsdlFile(); 1027 } 1028 1029 @Override 1030 public String getName() { 1031 if(top.properties.callPath==null) return ""; 1032 return ListUtil.last(top.properties.callPath,"./",true); 1033 } 1034 public String _getName() { // MUST nicht so toll 1035 if(properties.callPath==null) return ""; 1036 return ListUtil.last(properties.callPath,"./",true); 1037 } 1038 public PageSource _getPageSource() { 1039 return pageSource; 1040 } 1041 1042 @Override 1043 public String getCallName() { 1044 return top.properties.callPath; 1045 } 1046 1047 @Override 1048 public String getAbsName() { 1049 return top.pageSource.getComponentName(); 1050 } 1051 1052 1053 @Override 1054 public boolean getOutput() { 1055 if(top.properties.output==null) return true; 1056 return top.properties.output.booleanValue(); 1057 } 1058 1059 @Override 1060 public boolean instanceOf(String type) { 1061 1062 ComponentImpl c=top; 1063 do { 1064 if(type.equalsIgnoreCase(c.properties.callPath)) return true; 1065 if(type.equalsIgnoreCase(c.pageSource.getComponentName())) return true; 1066 if(type.equalsIgnoreCase(c._getName())) return true; 1067 1068 // check interfaces 1069 if(c.interfaceCollection!=null){ 1070 InterfaceImpl[] interfaces = c.interfaceCollection.getInterfaces(); 1071 if(interfaces!=null)for(int i=0;i<interfaces.length;i++){ 1072 if(interfaces[i].instanceOf(type))return true; 1073 } 1074 } 1075 c=c.base; 1076 } 1077 while(c!=null); 1078 if(StringUtil.endsWithIgnoreCase(type, "component")){ 1079 if(type.equalsIgnoreCase("component")) return true; 1080 if(type.equalsIgnoreCase("web-inf.cftags.component")) return true; 1081 //if(type.equalsIgnoreCase("web-inf.railo.context.component")) return true; 1082 1083 } 1084 return false; 1085 } 1086 1087 public boolean equalTo(String type) { 1088 ComponentImpl c=top; 1089 1090 if(type.equalsIgnoreCase(c.properties.callPath)) return true; 1091 if(type.equalsIgnoreCase(c.pageSource.getComponentName())) return true; 1092 if(type.equalsIgnoreCase(c._getName())) return true; 1093 1094 // check interfaces 1095 if(c.interfaceCollection!=null){ 1096 InterfaceImpl[] interfaces = c.interfaceCollection.getInterfaces(); 1097 if(interfaces!=null)for(int i=0;i<interfaces.length;i++){ 1098 if(interfaces[i].instanceOf(type))return true; 1099 } 1100 } 1101 1102 if(StringUtil.endsWithIgnoreCase(type, "component")){ 1103 if(type.equalsIgnoreCase("component")) return true; 1104 if(type.equalsIgnoreCase("web-inf.cftags.component")) return true; 1105 } 1106 return false; 1107 } 1108 1109 1110 @Override 1111 public boolean isValidAccess(int access) { 1112 return !(access <0 || access>ACCESS_COUNT); 1113 } 1114 1115 @Override 1116 public PageSource getPageSource() { 1117 return top.pageSource; 1118 } 1119 1120 1121 @Override 1122 public String castToString() throws PageException { 1123 return castToString(false); 1124 } 1125 1126 @Override 1127 public String castToString(String defaultValue) { 1128 return castToString(false,defaultValue); 1129 } 1130 1131 String castToString(boolean superAccess) throws PageException { 1132 // magic function 1133 PageContext pc = ThreadLocalPageContext.get(); 1134 if(pc!=null) { 1135 Member member = getMember(pc,KeyConstants.__toString,true,superAccess); 1136 //Object o = get(pc,"_toString",null); 1137 if(member instanceof UDF) { 1138 UDF udf = (UDF)member; 1139 if(udf.getReturnType()==CFTypes.TYPE_STRING && udf.getFunctionArguments().length==0) { 1140 return Caster.toString(_call(pc, udf, null, new Object[0])); 1141 } 1142 } 1143 } 1144 1145 1146 throw ExceptionUtil.addHint(new ExpressionException("Can't cast Component ["+getName()+"] to String"),"Add a User-Defined-Function to Component with the following pattern [_toString():String] to cast it to a String or use Built-In-Function \"serialize(Component):String\" to convert it to a serialized String"); 1147 1148 } 1149 1150 1151 1152 1153 String castToString(boolean superAccess,String defaultValue) { 1154 // magic function 1155 PageContext pc = ThreadLocalPageContext.get(); 1156 if(pc!=null) { 1157 Member member = getMember(pc,KeyConstants.__toString,true,superAccess); 1158 //Object o = get(pc,"_toString",null); 1159 if(member instanceof UDF) { 1160 UDF udf = (UDF)member; 1161 if(udf.getReturnType()==CFTypes.TYPE_STRING && udf.getFunctionArguments().length==0) { 1162 try { 1163 return Caster.toString(_call(pc, udf, null, new Object[0]),defaultValue); 1164 } catch (PageException e) { 1165 return defaultValue; 1166 } 1167 } 1168 } 1169 } 1170 return defaultValue; 1171 } 1172 1173 @Override 1174 public boolean castToBooleanValue() throws PageException { 1175 return castToBooleanValue(false); 1176 } 1177 1178 @Override 1179 public Boolean castToBoolean(Boolean defaultValue) { 1180 return castToBoolean(false, defaultValue); 1181 } 1182 1183 boolean castToBooleanValue(boolean superAccess) throws PageException { 1184 // magic function 1185 PageContext pc = ThreadLocalPageContext.get(); 1186 if(pc!=null) { 1187 Member member = getMember(pc,KeyConstants.__toBoolean,true,superAccess); 1188 //Object o = get(pc,"_toBoolean",null); 1189 if(member instanceof UDF) { 1190 UDF udf = (UDF)member; 1191 if(udf.getReturnType()==CFTypes.TYPE_BOOLEAN && udf.getFunctionArguments().length==0) { 1192 return Caster.toBooleanValue(_call(pc, udf, null, new Object[0])); 1193 } 1194 } 1195 } 1196 1197 throw ExceptionUtil.addHint(new ExpressionException("Can't cast Component ["+getName()+"] to a boolean value"), 1198 "Add a User-Defined-Function to Component with the following pattern [_toBoolean():boolean] to cast it to a boolean value"); 1199 } 1200 1201 Boolean castToBoolean(boolean superAccess,Boolean defaultValue) { 1202 // magic function 1203 PageContext pc = ThreadLocalPageContext.get(); 1204 if(pc!=null) { 1205 Member member = getMember(pc,KeyConstants.__toBoolean,true,superAccess); 1206 //Object o = get(pc,"_toBoolean",null); 1207 if(member instanceof UDF) { 1208 UDF udf = (UDF)member; 1209 if(udf.getReturnType()==CFTypes.TYPE_BOOLEAN && udf.getFunctionArguments().length==0) { 1210 try { 1211 return Caster.toBoolean(_call(pc, udf, null, new Object[0]),defaultValue); 1212 } catch (PageException e) { 1213 return defaultValue; 1214 } 1215 } 1216 } 1217 } 1218 return defaultValue; 1219 } 1220 1221 @Override 1222 public double castToDoubleValue() throws PageException { 1223 return castToDoubleValue(false); 1224 } 1225 1226 @Override 1227 public double castToDoubleValue(double defaultValue) { 1228 return castToDoubleValue(false, defaultValue); 1229 } 1230 1231 1232 double castToDoubleValue(boolean superAccess) throws PageException { 1233 // magic function 1234 PageContext pc = ThreadLocalPageContext.get(); 1235 if(pc!=null) { 1236 Member member = getMember(pc,KeyConstants.__toNumeric,true,superAccess); 1237 //Object o = get(pc,"_toNumeric",null); 1238 if(member instanceof UDF) { 1239 UDF udf = (UDF)member; 1240 if(udf.getReturnType()==CFTypes.TYPE_NUMERIC && udf.getFunctionArguments().length==0) { 1241 return Caster.toDoubleValue(_call(pc, udf, null, new Object[0])); 1242 } 1243 } 1244 } 1245 1246 throw ExceptionUtil.addHint(new ExpressionException("Can't cast Component ["+getName()+"] to a numeric value"), 1247 "Add a User-Defined-Function to Component with the following pattern [_toNumeric():numeric] to cast it to a numeric value"); 1248 } 1249 double castToDoubleValue(boolean superAccess,double defaultValue) { 1250 // magic function 1251 PageContext pc = ThreadLocalPageContext.get(); 1252 if(pc!=null) { 1253 Member member = getMember(pc,KeyConstants.__toNumeric,true,superAccess); 1254 //Object o = get(pc,"_toNumeric",null); 1255 if(member instanceof UDF) { 1256 UDF udf = (UDF)member; 1257 if(udf.getReturnType()==CFTypes.TYPE_NUMERIC && udf.getFunctionArguments().length==0) { 1258 try { 1259 return Caster.toDoubleValue(_call(pc, udf, null, new Object[0]),defaultValue); 1260 } catch (PageException e) { 1261 return defaultValue; 1262 } 1263 } 1264 } 1265 } 1266 return defaultValue; 1267 } 1268 1269 @Override 1270 public DateTime castToDateTime() throws PageException { 1271 return castToDateTime(false); 1272 } 1273 1274 @Override 1275 public DateTime castToDateTime(DateTime defaultValue) { 1276 return castToDateTime(false, defaultValue); 1277 } 1278 1279 DateTime castToDateTime(boolean superAccess) throws PageException { 1280 // magic function 1281 PageContext pc = ThreadLocalPageContext.get(); 1282 if(pc!=null) { 1283 Member member = getMember(pc,KeyConstants.__toDateTime,true,superAccess); 1284 //Object o = get(pc,"_toDateTime",null); 1285 if(member instanceof UDF) { 1286 UDF udf = (UDF)member; 1287 if(udf.getReturnType()==CFTypes.TYPE_DATETIME && udf.getFunctionArguments().length==0) { 1288 return Caster.toDate(_call(pc, udf, null, new Object[0]),pc.getTimeZone()); 1289 } 1290 } 1291 } 1292 1293 throw ExceptionUtil.addHint(new ExpressionException("Can't cast Component ["+getName()+"] to a date"), 1294 "Add a User-Defined-Function to Component with the following pattern [_toDateTime():datetime] to cast it to a date"); 1295 } 1296 DateTime castToDateTime(boolean superAccess,DateTime defaultValue) { 1297 // magic function 1298 PageContext pc = ThreadLocalPageContext.get(); 1299 if(pc!=null) { 1300 Member member = getMember(pc,KeyConstants.__toDateTime,true,superAccess); 1301 //Object o = get(pc,"_toDateTime",null); 1302 if(member instanceof UDF) { 1303 UDF udf = (UDF)member; 1304 if(udf.getReturnType()==CFTypes.TYPE_DATETIME && udf.getFunctionArguments().length==0) { 1305 1306 try { 1307 return DateCaster.toDateAdvanced(_call(pc, udf, null, new Object[0]),true,pc.getTimeZone(),defaultValue); 1308 } catch (PageException e) { 1309 return defaultValue; 1310 } 1311 1312 } 1313 } 1314 } 1315 return defaultValue; 1316 } 1317 1318 @Override 1319 public synchronized Struct getMetaData(PageContext pc) throws PageException { 1320 return getMetaData(ACCESS_PRIVATE,pc,top); 1321 } 1322 1323 1324 public synchronized Object getMetaStructItem(Collection.Key name) { 1325 if(top.properties.meta!=null) { 1326 return top.properties.meta.get(name,null); 1327 } 1328 return null; 1329 } 1330 1331 protected static Struct getMetaData(int access,PageContext pc, ComponentImpl comp) throws PageException { 1332 // Cache 1333 Page page = ((PageSourceImpl)comp.pageSource).getPage(); 1334 if(page==null) page = comp.pageSource.loadPage(pc.getConfig()); 1335 if(page.metaData!=null && page.metaData.get()!=null) { 1336 return page.metaData.get(); 1337 1338 } 1339 1340 StructImpl sct=new StructImpl(); 1341 1342 // fill udfs 1343 metaUDFs(pc, comp, sct,access); 1344 1345 // meta 1346 if(comp.properties.meta!=null) 1347 StructUtil.copy(comp.properties.meta, sct, true); 1348 1349 String hint=comp.properties.hint; 1350 String displayname=comp.properties.dspName; 1351 if(!StringUtil.isEmpty(hint))sct.set(KeyConstants._hint,hint); 1352 if(!StringUtil.isEmpty(displayname))sct.set(KeyConstants._displayname,displayname); 1353 1354 sct.set(KeyConstants._persistent,comp.properties.persistent); 1355 sct.set(KeyConstants._hashCode,comp.hashCode()); 1356 sct.set(KeyConstants._accessors,comp.properties.accessors); 1357 sct.set(KeyConstants._synchronized,comp.properties._synchronized); 1358 if(comp.properties.output!=null) 1359 sct.set(KeyConstants._output,comp.properties.output); 1360 1361 // extends 1362 Struct ex=null; 1363 if(comp.base!=null) ex=getMetaData(access,pc,comp.base); 1364 if(ex!=null)sct.set(KeyConstants._extends,ex); 1365 1366 // implements 1367 InterfaceCollection ic = comp.interfaceCollection; 1368 if(ic!=null){ 1369 Set<String> set = ListUtil.listToSet(comp.properties.implement, ",",true); 1370 InterfaceImpl[] interfaces = comp.interfaceCollection.getInterfaces(); 1371 if(!ArrayUtil.isEmpty(interfaces)){ 1372 Struct imp=new StructImpl(); 1373 for(int i=0;i<interfaces.length;i++){ 1374 if(!set.contains(interfaces[i].getCallPath())) continue; 1375 //print.e("-"+interfaces[i].getCallPath()); 1376 imp.setEL(KeyImpl.init(interfaces[i].getCallPath()), interfaces[i].getMetaData(pc)); 1377 } 1378 sct.set(KeyConstants._implements,imp); 1379 } 1380 } 1381 1382 // PageSource 1383 PageSource ps = comp.pageSource; 1384 sct.set(KeyConstants._fullname,ps.getComponentName()); 1385 sct.set(KeyConstants._name,ps.getComponentName()); 1386 sct.set(KeyConstants._path,ps.getDisplayPath()); 1387 sct.set(KeyConstants._type,"component"); 1388 1389 Class skeleton = comp.getJavaAccessClass(pc,new RefBooleanImpl(false),((ConfigImpl)pc.getConfig()).getExecutionLogEnabled(),false,false,((ConfigImpl)pc.getConfig()).getSupressWSBeforeArg()); 1390 if(skeleton !=null)sct.set(KeyConstants._skeleton, skeleton); 1391 1392 HttpServletRequest req = pc.getHttpServletRequest(); 1393 try { 1394 String path=ContractPath.call(pc, ps.getDisplayPath()); // MUST better impl !!! 1395 sct.set("remoteAddress",""+new URL(req.getScheme(),req.getServerName(),req.getServerPort(),req.getContextPath()+path+"?wsdl")); 1396 } catch (Throwable t) {} 1397 1398 1399 // Properties 1400 if(comp.properties.properties!=null) { 1401 ArrayImpl parr = new ArrayImpl(); 1402 Property p; 1403 Iterator<Entry<String, Property>> pit = comp.properties.properties.entrySet().iterator(); 1404 while(pit.hasNext()){ 1405 p=pit.next().getValue(); 1406 parr.add(p.getMetaData()); 1407 } 1408 parr.sort(new ArrayOfStructComparator(KeyConstants._name)); 1409 sct.set(KeyConstants._properties,parr); 1410 } 1411 page.metaData=new SoftReference<Struct>(sct); 1412 return page.metaData.get(); 1413 } 1414 1415 private static void metaUDFs(PageContext pc,ComponentImpl comp,Struct sct, int access) throws PageException { 1416 ArrayImpl arr=new ArrayImpl(); 1417 //Collection.Key name; 1418 1419 Page page = ((PageSourceImpl)comp._getPageSource()).getPage(); 1420 if(page!=null && page.udfs!=null){ 1421 for(int i=0;i<page.udfs.length;i++){ 1422 if(page.udfs[i].getAccess()>access) continue; 1423 arr.add(ComponentUtil.getMetaData(pc,(UDFPropertiesImpl) page.udfs[i])); 1424 } 1425 } 1426 1427 // property functions 1428 Iterator<Entry<Key, UDF>> it = comp._udfs.entrySet().iterator(); 1429 Entry<Key, UDF> entry; 1430 UDF udf; 1431 while(it.hasNext()) { 1432 entry= it.next(); 1433 udf=entry.getValue(); 1434 if(udf.getAccess()>access || !(udf instanceof UDFGSProperty)) continue; 1435 if(comp.base!=null) { 1436 if(udf==comp.base.getMember(access,entry.getKey(),true,true)) 1437 continue; 1438 } 1439 arr.append(udf.getMetaData(pc)); 1440 1441 } 1442 if(arr.size()!=0)sct.set(KeyConstants._functions,arr); 1443 } 1444 1445 public boolean isInitalized() { 1446 return isInit; 1447 } 1448 1449 public void setInitalized(boolean isInit) { 1450 this.isInit=isInit;; 1451 } 1452 1453 1454 /** 1455 * sets a value to the current Component, dont to base Component 1456 * @param key 1457 * @param value 1458 * @return value set 1459 * @throws ExpressionException 1460 */ 1461 private synchronized Object _set(PageContext pc,Collection.Key key, Object value) throws ExpressionException { 1462 //print.out("set:"+key); 1463 if(value instanceof UDFImpl) { 1464 UDFImpl udf = (UDFImpl)((UDF)value).duplicate(); 1465 //udf.isComponentMember(true);///+++ 1466 udf.setOwnerComponent(this); 1467 if(udf.getAccess()>Component.ACCESS_PUBLIC) 1468 udf.setAccess(Component.ACCESS_PUBLIC); 1469 _data.put(key,udf); 1470 _udfs.put(key,udf); 1471 1472 } 1473 else { 1474 if(loaded && !isAccessible(ThreadLocalPageContext.get(pc), dataMemberDefaultAccess)) 1475 throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+key+"]","enable [trigger data member] in admininistrator to also invoke getters and setters"); 1476 1477 _data.put(key,new DataMember(dataMemberDefaultAccess,value)); 1478 } 1479 return value; 1480 } 1481 1482 1483 1484 public void reg(Collection.Key key, UDFImpl udf) { 1485 registerUDF(key, udf,useShadow,false); 1486 } 1487 public void reg(String key, UDFImpl udf) { 1488 registerUDF(KeyImpl.init(key), udf,useShadow,false); 1489 } 1490 1491 public void registerUDF(String key, UDF udf) { 1492 registerUDF(KeyImpl.init(key), (UDFImpl) udf,useShadow,false); 1493 } 1494 public void registerUDF(String key, UDFProperties prop) { 1495 registerUDF(KeyImpl.init(key), new UDFImpl( prop),useShadow,false); 1496 } 1497 1498 public void registerUDF(Collection.Key key, UDF udf) { 1499 registerUDF(key, (UDFImpl) udf,useShadow,false); 1500 } 1501 public void registerUDF(Collection.Key key, UDFProperties prop) { 1502 registerUDF(key, new UDFImpl( prop),useShadow,false); 1503 } 1504 1505 /* 1506 * @deprecated injected is not used 1507 */ 1508 public void registerUDF(Collection.Key key, UDFImpl udf,boolean useShadow,boolean injected) { 1509 udf.setOwnerComponent(this);//+++ 1510 _udfs.put(key,udf); 1511 _data.put(key,udf); 1512 if(useShadow)scope.setEL(key, udf); 1513 } 1514 1515 @Override 1516 public Object remove(Key key) throws PageException { 1517 return _data.remove(key); 1518 } 1519 1520 public Object removeEL(Collection.Key key) { 1521 // MUST access muss beruecksichtigt werden 1522 return _data.remove(key); 1523 } 1524 1525 /*public Object set(PageContext pc, String name, Object value) throws PageException { 1526 return set(pc, KeyImpl.init(name), value); 1527 }*/ 1528 1529 @Override 1530 public Object set(PageContext pc, Collection.Key key, Object value) throws PageException { 1531 if(pc==null)pc=ThreadLocalPageContext.get(); 1532 if(triggerDataMember(pc) && isInit) { 1533 if(!isPrivate(pc)) { 1534 return callSetter(pc, key, value); 1535 } 1536 } 1537 return _set(pc,key,value); 1538 } 1539 1540 @Override 1541 public Object set(Collection.Key key, Object value) throws PageException { 1542 return set(null,key,value); 1543 } 1544 1545 /*public Object setEL(PageContext pc, String name, Object value) { 1546 try {return set(pc, name, value);} 1547 catch (PageException e) {return null;} 1548 }*/ 1549 1550 @Override 1551 public Object setEL(PageContext pc, Collection.Key name, Object value) { 1552 try {return set(pc, name, value);} 1553 catch (PageException e) {return null;} 1554 } 1555 1556 @Override 1557 public Object setEL(Key key, Object value) { 1558 return setEL(null, key, value); 1559 } 1560 1561 /*public Object get(PageContext pc, String name) throws PageException { 1562 return get(pc, KeyImpl.init(name)); 1563 }*/ 1564 1565 public Object get(PageContext pc, Collection.Key key) throws PageException { 1566 Member member=getMember(pc,key,true,false); 1567 if(member!=null) return member.getValue(); 1568 1569 // trigger 1570 if(triggerDataMember(pc) && !isPrivate(pc)) { 1571 return callGetter(pc,key); 1572 } 1573 throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+key+"]","enable [trigger data member] in admininistrator to also invoke getters and setters"); 1574 //throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+name+"]"); 1575 } 1576 1577 private Object callGetter(PageContext pc,Collection.Key key) throws PageException { 1578 Member member=getMember(pc,KeyImpl.getInstance("get"+key.getLowerString()),false,false); 1579 if(member instanceof UDF) { 1580 UDF udf = (UDF)member; 1581 if(udf.getFunctionArguments().length==0 && udf.getReturnType()!=CFTypes.TYPE_VOID) { 1582 return _call(pc,udf,null,ArrayUtil.OBJECT_EMPTY); 1583 } 1584 } 1585 throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+key+"]"); 1586 } 1587 1588 private Object callGetter(PageContext pc,Collection.Key key, Object defaultValue) { 1589 Member member=getMember(pc,KeyImpl.getInstance("get"+key.getLowerString()),false,false); 1590 if(member instanceof UDF) { 1591 UDF udf = (UDF)member; 1592 if(udf.getFunctionArguments().length==0 && udf.getReturnType()!=CFTypes.TYPE_VOID) { 1593 try { 1594 return _call(pc,udf,null,ArrayUtil.OBJECT_EMPTY); 1595 } catch (PageException e) { 1596 return defaultValue; 1597 } 1598 } 1599 } 1600 return defaultValue; 1601 } 1602 1603 private Object callSetter(PageContext pc,Collection.Key key, Object value) throws PageException { 1604 Member member=getMember(pc,KeyImpl.getInstance("set"+key.getLowerString()),false,false); 1605 if(member instanceof UDF) { 1606 UDF udf = (UDF)member; 1607 if(udf.getFunctionArguments().length==1 && (udf.getReturnType()==CFTypes.TYPE_VOID) || udf.getReturnType()==CFTypes.TYPE_ANY ) {// TDOO support int return type 1608 return _call(pc,udf,null,new Object[]{value}); 1609 } 1610 } 1611 return _set(pc,key,value); 1612 } 1613 1614 1615 /** 1616 * return element that has at least given access or null 1617 * @param access 1618 * @param name 1619 * @return matching value 1620 * @throws PageException 1621 */ 1622 public Object get(int access, String name) throws PageException { 1623 return get(access, KeyImpl.init(name)); 1624 } 1625 1626 public Object get(int access, Collection.Key key) throws PageException { 1627 Member member=getMember(access,key,true,false); 1628 if(member!=null) return member.getValue(); 1629 1630 // Trigger 1631 PageContext pc = ThreadLocalPageContext.get(); 1632 if(triggerDataMember(pc) && !isPrivate(pc)) { 1633 return callGetter(pc,key); 1634 } 1635 throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+key+"]"); 1636 } 1637 1638 /*public Object get(PageContext pc, String name, Object defaultValue) { 1639 return get(pc, KeyImpl.init(name), defaultValue); 1640 }*/ 1641 1642 @Override 1643 public Object get(PageContext pc, Collection.Key key, Object defaultValue) { 1644 Member member=getMember(pc,key,true,false); 1645 if(member!=null) return member.getValue(); 1646 1647 // trigger 1648 if(triggerDataMember(pc) && !isPrivate(pc)) { 1649 return callGetter(pc,key,defaultValue); 1650 } 1651 return defaultValue; 1652 } 1653 1654 /** 1655 * return element that has at least given access or null 1656 * @param access 1657 * @param name 1658 * @return matching value 1659 */ 1660 protected Object get(int access, String name, Object defaultValue) { 1661 return get(access, KeyImpl.init(name), defaultValue); 1662 } 1663 1664 /** 1665 * @param access 1666 * @param key 1667 * @param defaultValue 1668 * @return 1669 */ 1670 public Object get(int access, Collection.Key key, Object defaultValue) { 1671 Member member=getMember(access,key,true,false); 1672 if(member!=null) return member.getValue(); 1673 1674 // trigger 1675 PageContext pc = ThreadLocalPageContext.get(); 1676 if(triggerDataMember(pc) && !isPrivate(pc)) { 1677 return callGetter(pc,key,defaultValue); 1678 } 1679 return defaultValue; 1680 } 1681 1682 @Override 1683 public Object get(Collection.Key key) throws PageException { 1684 return get(ThreadLocalPageContext.get(),key); 1685 } 1686 1687 @Override 1688 public Object get(Collection.Key key, Object defaultValue) { 1689 return get(ThreadLocalPageContext.get(),key,defaultValue); 1690 } 1691 1692 @Override 1693 public Object call(PageContext pc, String name, Object[] args) throws PageException { 1694 return _call(pc,KeyImpl.init(name),null,args,false); 1695 } 1696 1697 public Object call(PageContext pc, Collection.Key name, Object[] args) throws PageException { 1698 return _call(pc,name,null,args,false); 1699 } 1700 1701 protected Object call(PageContext pc, int access, String name, Object[] args) throws PageException { 1702 return _call(pc,access,KeyImpl.init(name),null,args,false); 1703 } 1704 1705 public Object call(PageContext pc, int access, Collection.Key name, Object[] args) throws PageException { 1706 return _call(pc,access,name,null,args,false); 1707 } 1708 1709 @Override 1710 public Object callWithNamedValues(PageContext pc, String name, Struct args) throws PageException { 1711 return _call(pc,KeyImpl.init(name),args,null,false); 1712 } 1713 1714 public Object callWithNamedValues(PageContext pc, Collection.Key methodName, Struct args) throws PageException { 1715 return _call(pc,methodName,args,null,false); 1716 } 1717 1718 protected Object callWithNamedValues(PageContext pc, int access, String name, Struct args) throws PageException { 1719 return _call(pc,access,KeyImpl.init(name),args,null,false); 1720 } 1721 1722 public Object callWithNamedValues(PageContext pc, int access, Collection.Key name, Struct args) throws PageException { 1723 return _call(pc,access,name,args,null,false); 1724 } 1725 1726 public boolean contains(PageContext pc,String name) { 1727 return get(getAccess(pc),name,NullSupportHelper.NULL())!=NullSupportHelper.NULL(); 1728 } 1729 1730 /** 1731 * @param pc 1732 * @param key 1733 * @return 1734 */ 1735 public boolean contains(PageContext pc,Key key) { 1736 return get(getAccess(pc),key,NullSupportHelper.NULL())!=NullSupportHelper.NULL(); 1737 } 1738 1739 @Override 1740 public boolean containsKey(Key key) { 1741 return contains(ThreadLocalPageContext.get(),key); 1742 } 1743 1744 public boolean contains(int access,String name) { 1745 return get(access,name,NullSupportHelper.NULL())!=NullSupportHelper.NULL(); 1746 } 1747 1748 public boolean contains(int access,Key name) { 1749 return get(access,name,NullSupportHelper.NULL())!=NullSupportHelper.NULL(); 1750 } 1751 1752 @Override 1753 public Iterator<Collection.Key> keyIterator() { 1754 return keyIterator(getAccess(ThreadLocalPageContext.get())); 1755 } 1756 1757 @Override 1758 public Iterator<String> keysAsStringIterator() { 1759 return keysAsStringIterator(getAccess(ThreadLocalPageContext.get())); 1760 } 1761 1762 @Override 1763 public Iterator<Entry<Key, Object>> entryIterator() { 1764 return entryIterator(getAccess(ThreadLocalPageContext.get())); 1765 } 1766 1767 public Collection.Key[] keys() { 1768 return keys(getAccess(ThreadLocalPageContext.get())); 1769 } 1770 1771 @Override 1772 public int size() { 1773 return size(getAccess(ThreadLocalPageContext.get())); 1774 } 1775 1776 1777 @Override 1778 public Class getJavaAccessClass(RefBoolean isNew) throws PageException { 1779 return getJavaAccessClass(ThreadLocalPageContext.get(),isNew, false,true,true,true); 1780 } 1781 1782 public Class getJavaAccessClass(PageContext pc,RefBoolean isNew) throws PageException { 1783 return getJavaAccessClass(pc,isNew, false,true,true,true); 1784 } 1785 1786 public Class getJavaAccessClass(PageContext pc,RefBoolean isNew,boolean writeLog, boolean takeTop, boolean create, boolean supressWSbeforeArg) throws PageException { 1787 isNew.setValue(false); 1788 ComponentProperties props =(takeTop)?top.properties:properties; 1789 if(props.javaAccessClass==null) { 1790 props.javaAccessClass=ComponentUtil.getComponentJavaAccess(pc,this,isNew,create,writeLog,supressWSbeforeArg); 1791 } 1792 return props.javaAccessClass; 1793 } 1794 1795 public boolean isPersistent() { 1796 return top.properties.persistent; 1797 } 1798 1799 public boolean isAccessors() { 1800 return top.properties.accessors; 1801 } 1802 1803 public void setProperty(Property property) throws PageException { 1804 top.properties.properties.put(StringUtil.toLowerCase(property.getName()),property); 1805 if(top.properties.persistent || top.properties.accessors){ 1806 if(property.getDefault()!=null)scope.setEL(KeyImpl.init(property.getName()), property.getDefault()); 1807 PropertyFactory.createPropertyUDFs(this,property); 1808 } 1809 } 1810 1811 1812 1813 private void initProperties() throws PageException { 1814 top.properties.properties=new LinkedHashMap<String,Property>(); 1815 1816 // MappedSuperClass 1817 if(isPersistent() && !isBasePeristent() && top.base!=null && top.base.properties.properties!=null && top.base.properties.meta!=null) { 1818 boolean msc = Caster.toBooleanValue(top.base.properties.meta.get(KeyConstants._mappedSuperClass,Boolean.FALSE),false); 1819 if(msc){ 1820 Property p; 1821 Iterator<Entry<String, Property>> it = top.base.properties.properties.entrySet().iterator(); 1822 while(it.hasNext()) { 1823 p = it.next().getValue(); 1824 if(p.isPeristent()) { 1825 1826 setProperty(p); 1827 } 1828 } 1829 } 1830 } 1831 } 1832 1833 public Property[] getProperties(boolean onlyPeristent) { 1834 return getProperties(onlyPeristent, false,false,false); 1835 } 1836 1837 public Property[] getProperties(boolean onlyPeristent, boolean includeBaseProperties, boolean preferBaseProperties, boolean inheritedMappedSuperClassOnly) { 1838 Map<String,Property> props=new LinkedHashMap<String,Property>(); 1839 _getProperties(top,props,onlyPeristent, includeBaseProperties, preferBaseProperties, inheritedMappedSuperClassOnly); 1840 return props.values().toArray(new Property[props.size()]); 1841 } 1842 1843 private static void _getProperties(ComponentImpl c,Map<String,Property> props,boolean onlyPeristent, boolean includeBaseProperties, boolean preferBaseProperties, boolean inheritedMappedSuperClassOnly) { 1844 //if(c.properties.properties==null) return new Property[0]; 1845 1846 // collect with filter 1847 if(c.properties.properties!=null){ 1848 Property p; 1849 Iterator<Entry<String, Property>> it = c.properties.properties.entrySet().iterator(); 1850 while(it.hasNext()) { 1851 p = it.next().getValue(); 1852 if(!onlyPeristent || p.isPeristent()) { 1853 if (!preferBaseProperties || !props.containsKey(p.getName().toLowerCase())) { 1854 props.put(p.getName().toLowerCase(),p); 1855 } 1856 } 1857 } 1858 } 1859 1860 // MZ: Moved to the bottom to allow base properties to override inherited versions 1861 if(includeBaseProperties && c.base!=null) { 1862 if (!inheritedMappedSuperClassOnly || (c.base.properties.meta != null && Caster.toBooleanValue(c.base.properties.meta.get(KeyConstants._mappedSuperClass, Boolean.FALSE), false))) { 1863 _getProperties(c.base, props, onlyPeristent, includeBaseProperties, preferBaseProperties, inheritedMappedSuperClassOnly); 1864 } 1865 } 1866 1867 } 1868 1869 public ComponentScope getComponentScope() { 1870 return scope; 1871 } 1872 1873 1874 @Override 1875 public int compareTo(boolean b) throws PageException { 1876 return Operator.compare(castToBooleanValue(), b); 1877 } 1878 1879 @Override 1880 public int compareTo(DateTime dt) throws PageException { 1881 return Operator.compare((Date)castToDateTime(), (Date)dt); 1882 } 1883 1884 @Override 1885 public int compareTo(double d) throws PageException { 1886 return Operator.compare(castToDoubleValue(), d); 1887 } 1888 1889 @Override 1890 public int compareTo(String str) throws PageException { 1891 return Operator.compare(castToString(), str); 1892 } 1893 1894 public void addConstructorUDF(Key key, UDF value) { 1895 if(constructorUDFs==null) 1896 constructorUDFs=new HashMap<Key,UDF>(); 1897 constructorUDFs.put(key, value); 1898 } 1899 1900 // MUST more native impl 1901 public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException { 1902 boolean pcCreated=false; 1903 PageContext pc = ThreadLocalPageContext.get(); 1904 // MUST this is just a workaround 1905 if(pc==null){ 1906 pcCreated=true; 1907 ConfigWeb config = (ConfigWeb) ThreadLocalPageContext.getConfig(); 1908 Pair[] parr = new Pair[0]; 1909 pc=ThreadUtil.createPageContext(config, DevNullOutputStream.DEV_NULL_OUTPUT_STREAM, "localhost", "/","", new Cookie[0], parr, parr, new StructImpl()); 1910 } 1911 1912 try { 1913 // MUST do serialisation more like the cloning way 1914 ComponentImpl other=(ComponentImpl) new CFMLExpressionInterpreter().interpret(pc,in.readUTF()); 1915 1916 1917 this._data=other._data; 1918 this._udfs=other._udfs; 1919 setOwner(_udfs); 1920 setOwner(_data); 1921 this.afterConstructor=other.afterConstructor; 1922 this.base=other.base; 1923 //this.componentPage=other.componentPage; 1924 this.pageSource=other.pageSource; 1925 this.constructorUDFs=other.constructorUDFs; 1926 this.dataMemberDefaultAccess=other.dataMemberDefaultAccess; 1927 this.interfaceCollection=other.interfaceCollection; 1928 this.isInit=other.isInit; 1929 this.properties=other.properties; 1930 this.scope=other.scope; 1931 this.top=this; 1932 this._triggerDataMember=other._triggerDataMember; 1933 this.useShadow=other.useShadow; 1934 1935 1936 } catch (PageException e) { 1937 throw new IOException(e.getMessage()); 1938 } 1939 finally { 1940 if(pcCreated)ThreadLocalPageContext.release(); 1941 } 1942 } 1943 1944 private void setOwner(Map<Key,? extends Member> data) { 1945 Member m; 1946 Iterator<? extends Member> it = data.values().iterator(); 1947 while(it.hasNext()){ 1948 m=it.next(); 1949 if(m instanceof UDFImpl) { 1950 ((UDFImpl)m).setOwnerComponent(this); 1951 } 1952 } 1953 } 1954 1955 public void writeExternal(ObjectOutput out) throws IOException { 1956 try { 1957 out.writeUTF(new ScriptConverter().serialize(this)); 1958 } 1959 catch (Throwable t) { 1960 //print.printST(t); 1961 } 1962 1963 } 1964 1965 @Override 1966 public ComponentAccess _base() { 1967 return base; 1968 } 1969 1970 1971 1972 private boolean triggerDataMember(PageContext pc) { 1973 if(_triggerDataMember!=null) return _triggerDataMember.booleanValue(); 1974 if(pc==null || pc.getApplicationContext()==null){ 1975 //print.ds(""+(pc==null));// TODO why this is true sometimes? 1976 return false; 1977 } 1978 return pc.getApplicationContext().getTriggerComponentDataMember(); 1979 } 1980 1981 public void setLoaded(boolean loaded) { 1982 this.loaded=loaded; 1983 } 1984 }