/**
* Copyright (c) 2014, the Railo Company Ltd.
* Copyright (c) 2015, Lucee Assosication Switzerland
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
package lucee.runtime;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import lucee.commons.collection.HashMapPro;
import lucee.commons.collection.MapFactory;
import lucee.commons.collection.MapPro;
import lucee.commons.digest.Hash;
import lucee.commons.io.DevNullOutputStream;
import lucee.commons.lang.CFTypes;
import lucee.commons.lang.ExceptionUtil;
import lucee.commons.lang.Pair;
import lucee.commons.lang.StringUtil;
import lucee.commons.lang.types.RefBoolean;
import lucee.commons.lang.types.RefBooleanImpl;
import lucee.loader.engine.CFMLEngine;
import lucee.runtime.component.AbstractFinal;
import lucee.runtime.component.ComponentLoader;
import lucee.runtime.component.DataMember;
import lucee.runtime.component.Member;
import lucee.runtime.component.MetaDataSoftReference;
import lucee.runtime.component.MetadataUtil;
import lucee.runtime.component.Property;
import lucee.runtime.config.Config;
import lucee.runtime.config.ConfigImpl;
import lucee.runtime.config.ConfigWeb;
import lucee.runtime.config.ConfigWebImpl;
import lucee.runtime.config.NullSupportHelper;
import lucee.runtime.debug.DebugEntryTemplate;
import lucee.runtime.dump.DumpData;
import lucee.runtime.dump.DumpProperties;
import lucee.runtime.dump.DumpRow;
import lucee.runtime.dump.DumpTable;
import lucee.runtime.dump.DumpUtil;
import lucee.runtime.dump.SimpleDumpData;
import lucee.runtime.engine.ThreadLocalPageContext;
import lucee.runtime.exp.ApplicationException;
import lucee.runtime.exp.ExpressionException;
import lucee.runtime.exp.PageException;
import lucee.runtime.functions.dynamicEvaluation.EvaluateComponent;
import lucee.runtime.functions.system.ContractPath;
import lucee.runtime.interpreter.CFMLExpressionInterpreter;
import lucee.runtime.op.Caster;
import lucee.runtime.op.Duplicator;
import lucee.runtime.op.Operator;
import lucee.runtime.op.ThreadLocalDuplication;
import lucee.runtime.op.date.DateCaster;
import lucee.runtime.thread.ThreadUtil;
import lucee.runtime.type.ArrayImpl;
import lucee.runtime.type.Collection;
import lucee.runtime.type.FunctionArgument;
import lucee.runtime.type.KeyImpl;
import lucee.runtime.type.Struct;
import lucee.runtime.type.StructImpl;
import lucee.runtime.type.UDF;
import lucee.runtime.type.UDFGSProperty;
import lucee.runtime.type.UDFImpl;
import lucee.runtime.type.UDFPlus;
import lucee.runtime.type.UDFProperties;
import lucee.runtime.type.UDFPropertiesBase;
import lucee.runtime.type.cfc.ComponentEntryIterator;
import lucee.runtime.type.cfc.ComponentValueIterator;
import lucee.runtime.type.comparator.ArrayOfStructComparator;
import lucee.runtime.type.dt.DateTime;
import lucee.runtime.type.it.ComponentIterator;
import lucee.runtime.type.it.StringIterator;
import lucee.runtime.type.scope.Argument;
import lucee.runtime.type.scope.ArgumentImpl;
import lucee.runtime.type.scope.ArgumentIntKey;
import lucee.runtime.type.scope.Scope;
import lucee.runtime.type.scope.Variables;
import lucee.runtime.type.util.ArrayUtil;
import lucee.runtime.type.util.ComponentUtil;
import lucee.runtime.type.util.KeyConstants;
import lucee.runtime.type.util.ListUtil;
import lucee.runtime.type.util.PropertyFactory;
import lucee.runtime.type.util.StructSupport;
import lucee.runtime.type.util.StructUtil;
import lucee.runtime.type.util.UDFUtil;
/**
* %**%
* MUST add handling for new attributes (style, namespace, serviceportname, porttypename, wsdlfile, bindingname, and output)
*/
public final class ComponentImpl extends StructSupport implements Externalizable,Component,coldfusion.runtime.TemplateProxy {
private static final long serialVersionUID = -245618330485511484L; // do not change this
private static final Interface[] EMPTY = new Interface[0];
/*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* Any change here must be changed in the method writeExternal,readExternal as well
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* */
ComponentProperties properties;
private MapPro<Key,Member> _data;
private MapPro<Key,UDF> _udfs;
ComponentImpl top=this;
ComponentImpl base;
private PageSource pageSource;
private ComponentScope scope;
// for all the same
private int dataMemberDefaultAccess;
//private final Boolean _triggerDataMember=null;
// state control of component
boolean isInit=false;
//private AbstractCollection abstrCollection;
private boolean useShadow;
private boolean entity;
boolean afterConstructor;
//private Map<Key,UDF> constructorUDFs;
private boolean loaded;
private boolean hasInjectedFunctions;
private boolean isExtended; // is this component extended by a other component?
StaticScope _static;
boolean insideStaticConstr;
private AbstractFinal absFin;
/**
* Constructor of the Component, USED ONLY FOR DESERIALIZE
*/
public ComponentImpl() {
}
/**
* constructor of the class
* @param componentPage
* @param output
* @param _synchronized
* @param extend
* @param implement
* @param hint
* @param dspName
* @param callPath
* @param realPath
* @param style
* @param persistent
* @param accessors
* @param modifier
* @param meta
* @throws ApplicationException
*/
public ComponentImpl(ComponentPageImpl componentPage,Boolean output,boolean _synchronized,
String extend, String implement, String hint, String dspName,String callPath, boolean realPath,
String style,boolean persistent,boolean accessors,int modifier,boolean isExtended,StructImpl meta) throws ApplicationException {
this.properties=new ComponentProperties(dspName,extend.trim(),implement,hint,output,callPath,realPath,_synchronized,null,persistent,accessors,modifier,meta);
//this.componentPage=componentPage instanceof ComponentPageProxy?componentPage:PageProxy.toProxy(componentPage);
this.pageSource=componentPage.getPageSource();
//if(modifier!=0)
if(!StringUtil.isEmpty(style) && !"rpc".equals(style))
throw new ApplicationException("style ["+style+"] is not supported, only the following styles are supported: [rpc]");
this.isExtended=isExtended;
}
@Override
public Collection duplicate(boolean deepCopy) {
ComponentImpl top= _duplicate(deepCopy,true);
setTop(top,top);
return top;
}
private ComponentImpl _duplicate( boolean deepCopy, boolean isTop) {
ComponentImpl trg=new ComponentImpl();
boolean inside=ThreadLocalDuplication.set(this, trg);
try{
// attributes
trg.pageSource=pageSource;
//trg._triggerDataMember=_triggerDataMember;
trg.useShadow=useShadow;
trg._static=_static;
trg.entity=entity;
trg.hasInjectedFunctions=hasInjectedFunctions;
trg.isExtended=isExtended;
trg.afterConstructor=afterConstructor;
trg.dataMemberDefaultAccess=dataMemberDefaultAccess;
trg.properties=properties.duplicate();
trg.isInit=isInit;
trg.absFin=absFin;
boolean useShadow=scope instanceof ComponentScopeShadow;
if(!useShadow)trg.scope=new ComponentScopeThis(trg);
if(base!=null){
trg.base=base._duplicate(deepCopy,false);
trg._data=trg.base._data;
trg._udfs=duplicateUTFMap(this,trg, _udfs,new HashMapPro<Key,UDF>(trg.base._udfs));
if(useShadow) trg.scope=new ComponentScopeShadow(trg,(ComponentScopeShadow)trg.base.scope,false);
}
else {
// clone data member, ignore udfs for the moment
trg._data=duplicateDataMember(trg, _data, new HashMapPro(), deepCopy);
trg._udfs=duplicateUTFMap(this,trg, _udfs,new HashMapPro<Key, UDF>());
if(useShadow) {
ComponentScopeShadow css = (ComponentScopeShadow)scope;
trg.scope=new ComponentScopeShadow(trg,duplicateDataMember(trg,css.getShadow(),MapFactory.getConcurrentMap(),deepCopy));
}
}
// 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
/*if(constructorUDFs!=null){
trg.constructorUDFs=new HashMap<Collection.Key, UDF>();
addUDFS(trg, constructorUDFs, trg.constructorUDFs);
}*/
if(isTop) {
setTop(trg,trg);
addUDFS(trg,_data,trg._data);
if(useShadow){
addUDFS(trg,((ComponentScopeShadow)scope).getShadow(),((ComponentScopeShadow)trg.scope).getShadow());
}
}
}
finally {
if(!inside)ThreadLocalDuplication.reset();
}
return trg;
}
private static void addUDFS(ComponentImpl trgComp, Map src, Map trg) {
Iterator it = src.entrySet().iterator();
Map.Entry entry;
Object key,value;
UDF udf;
ComponentImpl comp,owner;
boolean done;
while(it.hasNext()){
entry=(Entry) it.next();
key=entry.getKey();
value=entry.getValue();
if(value instanceof UDF) {
udf=(UDF) value;
done=false;
// get udf from _udf
owner = (ComponentImpl)udf.getOwnerComponent();
if(owner!=null) {
comp=trgComp;
do{
if(owner.pageSource==comp.pageSource)
break;
}
while((comp=comp.base)!=null);
if(comp!=null) {
value=comp._udfs.get(key);
trg.put(key, value);
done=true;
}
}
// udf with no owner
if(!done)
trg.put(key, udf.duplicate());
//print.o(owner.pageSource.getComponentName()+":"+udf.getFunctionName());
}
}
}
/**
* duplicate the datamember in the map, ignores the udfs
* @param c
* @param map
* @param newMap
* @param deepCopy
* @return
*/
public static MapPro duplicateDataMember(ComponentImpl c,MapPro map,MapPro newMap,boolean deepCopy){
Iterator it=map.entrySet().iterator();
Map.Entry entry;
Object value;
while(it.hasNext()) {
entry=(Entry) it.next();
value=entry.getValue();
if(!(value instanceof UDF)) {
if(deepCopy) value=Duplicator.duplicate(value,deepCopy);
newMap.put(entry.getKey(),value);
}
}
return newMap;
}
public static MapPro<Key, UDF> duplicateUTFMap(ComponentImpl src,ComponentImpl trg,MapPro<Key,UDF> srcMap, MapPro<Key, UDF> trgMap){
Iterator<Entry<Key, UDF>> it = srcMap.entrySet().iterator();
Entry<Key, UDF> entry;
UDF udf;
while(it.hasNext()) {
entry=it.next();
udf=entry.getValue();
if(udf.getOwnerComponent()==src) {
UDFPlus clone=(UDFPlus) entry.getValue().duplicate();
clone.setOwnerComponent(trg);
clone.setAccess(udf.getAccess());
trgMap.put(entry.getKey(),clone);
}
}
return trgMap;
}
/**
* initalize the Component
* @param pageContext
* @param componentPage
* @throws PageException
*/
public void init(PageContext pageContext, ComponentPageImpl componentPage,boolean executeConstr) throws PageException {
this.pageSource=componentPage.getPageSource();
// extends
if(!StringUtil.isEmpty(properties.extend)) {
base= ComponentLoader.searchComponent(pageContext,componentPage.getPageSource(),properties.extend,Boolean.TRUE,null,true,executeConstr);
}
else {
CIPage p=((ConfigWebImpl)pageContext.getConfig()).getBaseComponentPage(pageSource.getDialect(),pageContext);
if(!componentPage.getPageSource().equals(p.getPageSource())) {
base=ComponentLoader.loadComponent(pageContext,p,"Component",false,false,true,executeConstr);
}
}
if(base!=null){
this.dataMemberDefaultAccess=base.dataMemberDefaultAccess;
this._static=new StaticScope(base._static,this,componentPage,dataMemberDefaultAccess);
//this._triggerDataMember=base._triggerDataMember;
this.absFin=base.absFin;
_data=base._data;
_udfs=new HashMapPro<Key,UDF>(base._udfs);
setTop(this,base);
}
else {
this.dataMemberDefaultAccess=pageContext.getCurrentTemplateDialect()==CFMLEngine.DIALECT_CFML?
pageContext.getConfig().getComponentDataMemberDefaultAccess():
Component.ACCESS_PRIVATE;
this._static=new StaticScope(null,this,componentPage,dataMemberDefaultAccess);
// TODO get per CFC setting this._triggerDataMember=pageContext.getConfig().getTriggerComponentDataMember();
_udfs=new HashMapPro<Key,UDF>();
_data=MapFactory.getConcurrentMap();
}
// implements
if(!StringUtil.isEmpty(properties.implement)) {
if(absFin==null)absFin=new AbstractFinal();
absFin.add(InterfaceImpl.loadInterfaces(pageContext, getPageSource(), properties.implement));
//abstrCollection.implement(pageContext,getPageSource(),properties.implement);
}
/*print.e("--------------------------------------");
print.e(_getPageSource().getDisplayPath());
print.e(abstrCollection.getUdfs());*/
// scope
useShadow=base==null?
(pageSource.getDialect()==CFMLEngine.DIALECT_CFML?pageContext.getConfig().useComponentShadow():false):
base.useShadow;
if(useShadow) {
if(base==null) scope=new ComponentScopeShadow(this,MapFactory.getConcurrentMap());
else scope=new ComponentScopeShadow(this,(ComponentScopeShadow)base.scope,false);
}
else {
scope=new ComponentScopeThis(this);
}
initProperties();
// invoke static constructor
if(!componentPage._static.isInit()) {
componentPage._static.setInit(true);// this needs to happen before the call
try {
componentPage.staticConstructor(pageContext,this);
}
catch(Throwable t){
ExceptionUtil.rethrowIfNecessary(t);
componentPage._static.setInit(false);
throw Caster.toPageException(t);
}
}
}
public void checkInterface(PageContext pc, ComponentPageImpl componentPage) throws PageException {
/*print.e("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx "+ComponentUtil.toModifier(getModifier(), "none")+" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
print.e(componentPage.getPageSource().getDisplayPath());
print.e(getModifier()==MODIFIER_ABSTRACT);
if(_abstract!=null){
//print.e(_abstract.lastUpdate());
//print.e(componentPage.lastCheck());
//print.e(_abstract.lastUpdate()<=componentPage.lastCheck());
print.e(_abstract.getInterfaces());
print.e("has-udfs:"+_abstract.hasAbstractUDFs());
}*/
// no records == nothing to do
if(absFin==null || !absFin.hasUDFs()) return;
//if(getModifier()==MODIFIER_ABSTRACT || _abstract==null || !_abstract.hasAbstractUDFs()) return; // MUST add again cache, but also check change in all udfs from abstract cfc || _abstract.lastUpdate()<=componentPage.lastCheck()
// ABSTRACT: check if the component define all functions defined in interfaces and abstract components
if(getModifier()!=MODIFIER_ABSTRACT && absFin.hasAbstractUDFs()) {
Map<Key, UDF> udfs = absFin.removeAbstractUDFs();
//print.e(udfs);
Iterator<Entry<Key, UDF>> it = udfs.entrySet().iterator();
Entry<Key, UDF> entry;
UDFPlus iUdf,cUdf;
while(it.hasNext()){
entry = it.next();
iUdf=(UDFPlus) entry.getValue();
cUdf=(UDFPlus) _udfs.get(entry.getKey());
checkFunction(pc,componentPage,iUdf,cUdf);
}
}
// FINAL: does a function overwrite a final method
if(absFin.hasFinalUDFs()) {
Map<Key, UDF> udfs = absFin.getFinalUDFs();
Iterator<Entry<Key, UDF>> it = udfs.entrySet().iterator();
Entry<Key, UDF> entry;
UDFPlus iUdf,cUdf;
while(it.hasNext()){
entry = it.next();
iUdf=(UDFPlus) entry.getValue();
cUdf=(UDFPlus) _udfs.get(entry.getKey());
// if this is not the same, it was overwritten
if(iUdf!=cUdf)
throw new ApplicationException("the function ["+entry.getKey()+"] from component ["+
cUdf.getSource()+
"] tries to override a final method with the same name from component ["+
iUdf.getSource()+"]");
}
}
// MUST componentPage.ckecked();
}
private void checkFunction(PageContext pc, ComponentPageImpl componentPage,UDFPlus iUdf, UDFPlus cUdf) throws ApplicationException {
FunctionArgument[] iFA,cFA;
// UDF does not exist
if(cUdf==null ) {
throw new ApplicationException(
"component ["+componentPage.getComponentName()+
"] does not implement the function ["+iUdf.toString().toLowerCase()+"] of the "+
("abstract component/interface")+" ["+
iUdf.getSource()+"]");
}
iFA=iUdf.getFunctionArguments();
cFA=cUdf.getFunctionArguments();
// access
if(cUdf.getAccess()>Component.ACCESS_PUBLIC){
throw new ApplicationException( _getErrorMessage(cUdf,iUdf),
"access ["+ComponentUtil.toStringAccess(cUdf.getAccess())+"] has to be at least [public]");
}
// return type
if(iUdf.getReturnType()!=cUdf.getReturnType()){
throw new ApplicationException( _getErrorMessage(cUdf,iUdf),
"return type ["+cUdf.getReturnTypeAsString()+"] does not match the "+("abstract component/interface")+" function return type ["+iUdf.getReturnTypeAsString()+"]");
}
// none base types
if(iUdf.getReturnType()==CFTypes.TYPE_UNKNOW && !iUdf.getReturnTypeAsString().equalsIgnoreCase(cUdf.getReturnTypeAsString())) {
throw new ApplicationException( _getErrorMessage(cUdf,iUdf),
"return type ["+cUdf.getReturnTypeAsString()+"] does not match the "+("abstract component/interface")+" function return type ["+iUdf.getReturnTypeAsString()+"]");
}
// arguments
if(iFA.length!=cFA.length) {
throw new ApplicationException( _getErrorMessage(cUdf,iUdf),"not the same argument count");
}
for(int i=0;i<iFA.length;i++) {
// type
if(iFA[i].getType()!=cFA[i].getType()){
throw new ApplicationException( _getErrorMessage(cUdf,iUdf),
"argument type ["+cFA[i].getTypeAsString()+"] does not match the "+("abstract component/interface")+" function argument type ["+iFA[i].getTypeAsString()+"]");
}
// none base types
if(iFA[i].getType()==CFTypes.TYPE_UNKNOW && !iFA[i].getTypeAsString().equalsIgnoreCase(cFA[i].getTypeAsString())) {
throw new ApplicationException( _getErrorMessage(cUdf,iUdf),
"argument type ["+cFA[i].getTypeAsString()+"] does not match the "+("abstract component/interface")+" function argument type ["+iFA[i].getTypeAsString()+"]");
}
// name
if(!iFA[i].getName().equalsIgnoreCase(cFA[i].getName())){
throw new ApplicationException( _getErrorMessage(cUdf,iUdf),
"argument name ["+cFA[i].getName()+"] does not match the "+("abstract component/interface")+" function argument name ["+iFA[i].getName()+"]");
}
// required
if(iFA[i].isRequired()!=cFA[i].isRequired()){
throw new ApplicationException( _getErrorMessage(cUdf,iUdf),
"argument ["+cFA[i].getName()+"] should "+(iFA[i].isRequired()?"":"not ")+"be required");
}
}
}
private String _getErrorMessage(UDFPlus cUdf,UDFPlus iUdf) {
return "function ["+cUdf.toString().toLowerCase()+"] of component " +
"["+pageSource.getDisplayPath()+"]" +
" does not match the function declaration ["+iUdf.toString().toLowerCase()+"] of the "+("abstract component/interface")+" " +
"["+iUdf.getSource()+"]";
}
private static void setTop(ComponentImpl top,ComponentImpl trg) {
while(trg!=null){
trg.top=top;
trg=trg.base;
}
}
Object _call(PageContext pc, Collection.Key key, Struct namedArgs, Object[] args,boolean superAccess) throws PageException {
Member member=getMember(pc,key,false, superAccess);
if(member instanceof UDFPlus) {
return _call(pc,key,(UDFPlus)member,namedArgs,args);
}
return onMissingMethod(pc, -1, member, key.getString(), args, namedArgs, superAccess);
}
Object _call(PageContext pc, int access, Collection.Key key, Struct namedArgs, Object[] args,boolean superAccess) throws PageException {
Member member=getMember(access,key,false,superAccess);
if(member instanceof UDF) {
return _call(pc,key,(UDFPlus)member,namedArgs,args);
}
return onMissingMethod(pc, access, member, key.getString(), args, namedArgs, superAccess);
}
public Object onMissingMethod(PageContext pc, int access,Member member,String name,Object _args[],Struct _namedArgs, boolean superAccess) throws PageException {
Member ommm = access==-1?
getMember(pc,KeyConstants._onmissingmethod,false, superAccess):
getMember(access,KeyConstants._onmissingmethod,false, superAccess);
if(ommm instanceof UDF) {
Argument args=new ArgumentImpl();
if(_args!=null) {
for(int i=0;i<_args.length;i++) {
args.setEL(ArgumentIntKey.init(i+1), _args[i]);
}
}
else if(_namedArgs!=null) {
UDFUtil.argumentCollection(_namedArgs, new FunctionArgument[]{});
Iterator<Entry<Key, Object>> it = _namedArgs.entryIterator();
Entry<Key, Object> e;
while(it.hasNext()){
e = it.next();
args.setEL(e.getKey(),e.getValue());
}
}
//Struct newArgs=new StructImpl(StructImpl.TYPE_SYNC);
//newArgs.setEL(MISSING_METHOD_NAME, name);
//newArgs.setEL(MISSING_METHOD_ARGS, args);
Object[] newArgs=new Object[]{name,args};
return _call(pc,KeyConstants._onmissingmethod,(UDFPlus)ommm,null,newArgs);
}
if(member==null)throw ComponentUtil.notFunction(this, KeyImpl.init(name), null,access);
throw ComponentUtil.notFunction(this, KeyImpl.init(name), member.getValue(),access);
}
Object _call(PageContext pc, Collection.Key calledName,UDFPlus udf, Struct namedArgs, Object[] args) throws PageException {
Object rtn=null;
Variables parent=null;
// INFO duplicate code is for faster execution -> less contions
// debug yes
if(pc.getConfig().debug()) {
DebugEntryTemplate debugEntry=pc.getDebugger().getEntry(pc,pageSource,udf.getFunctionName());//new DebugEntry(src,udf.getFunctionName());
long currTime=pc.getExecutionTime();
long time=System.nanoTime();
// sync yes
if(top.properties._synchronized){
synchronized (this) {
try {
parent=beforeCall(pc);
if(args!=null)rtn=udf.call(pc,calledName,args,true);
else rtn=udf.callWithNamedValues(pc,calledName,namedArgs,true);
}
finally {
pc.setVariablesScope(parent);
long diff= ((System.nanoTime()-time)-(pc.getExecutionTime()-currTime));
pc.setExecutionTime(pc.getExecutionTime()+diff);
debugEntry.updateExeTime(diff);
}
}
}
// sync no
else {
try {
parent=beforeCall(pc);
if(args!=null)rtn=udf.call(pc,calledName,args,true);
else rtn=udf.callWithNamedValues(pc,calledName,namedArgs,true);
}
finally {
pc.setVariablesScope(parent);
long diff= ((System.nanoTime()-time)-(pc.getExecutionTime()-currTime));
pc.setExecutionTime(pc.getExecutionTime()+diff);
debugEntry.updateExeTime(diff);
}
}
}
// debug no
else {
// sync yes
if(top.properties._synchronized){
synchronized (this) {
try {
parent=beforeCall(pc);
if(args!=null)rtn=udf.call(pc,calledName,args,true);
else rtn=udf.callWithNamedValues(pc,calledName,namedArgs,true);
}
finally {
pc.setVariablesScope(parent);
}
}
}
// sync no 385|263
else {
try {
parent=beforeCall(pc);
if(args!=null)rtn=udf.call(pc,calledName,args,true);
else rtn=udf.callWithNamedValues(pc,calledName,namedArgs,true);
}
finally {
pc.setVariablesScope(parent);
}
}
}
return rtn;
}
@Override
public Variables beforeStaticConstructor(PageContext pc){
insideStaticConstr=true;
Variables parent=pc.variablesScope();
pc.setVariablesScope(_static);
return parent;
}
@Override
public void afterStaticConstructor(PageContext pc, Variables parent){
insideStaticConstr=false;
pc.setVariablesScope(parent);
}
/**
* will be called before executing method or constructor
* @param pc
* @return the old scope map
*/
public Variables beforeCall(PageContext pc) {
Variables parent=pc.variablesScope();
pc.setVariablesScope(scope);
return parent;
}
/**
* will be called after invoking constructor, only invoked by constructor (component body execution)
* @param pc
* @param parent
* @throws ApplicationException
*/
public void afterConstructor(PageContext pc, Variables parent) throws ApplicationException {
pc.setVariablesScope(parent);
this.afterConstructor=true;
/*if(constructorUDFs!=null){
Iterator<Entry<Key, UDF>> it = constructorUDFs.entrySet().iterator();
Map.Entry<Key, UDF> entry;
Key key;
UDFPlus udf;
PageSource ps;
while(it.hasNext()){
entry=it.next();
key=entry.getKey();
udf=(UDFPlus) entry.getValue();
ps=udf.getPageSource();
//if(ps!=null && ps.equals(getPageSource()))continue; // TODO can we avoid that udfs from the compinent itself are here?
registerUDF(key, udf,false,true);
}
}*/
}
/**
* this function may be called by generated code inside a ra file
* @deprecated replaced with <code>afterConstructor(PageContext pc, Variables parent)</code>
* @param pc
* @param parent
* @throws ApplicationException
*/
public void afterCall(PageContext pc, Variables parent) throws ApplicationException {
afterConstructor(pc, parent);
}
/**
* sets the callpath
* @param callPath
* /
public void setCallPath(String callPath) {
properties.callPath=callPath;
}*/
/**
* rerturn the size
* @param access
* @return size
*/
public int size(int access) {
return keys(access).length;
}
/**
* list of keys
* @param c
* @param access
* @param doBase
* @return key set
*/
public Set<Key> keySet(int access) {
Set<Key> set=new LinkedHashSet<Key>();
Map.Entry<Key, Member> entry;
Iterator<Entry<Key, Member>> it = _data.entrySet().iterator();
while(it.hasNext()) {
entry=it.next();
if(entry.getValue().getAccess()<=access)set.add(entry.getKey());
}
return set;
}
/*protected Set<Key> udfKeySet(int access) {
Set<Key> set=new HashSet<Key>();
Member m;
Map.Entry<Key, UDF> entry;
Iterator<Entry<Key, UDF>> it = _udfs.entrySet().iterator();
while(it.hasNext()) {
entry= it.next();
m=entry.getValue();
if(m.getAccess()<=access)set.add(entry.getKey());
}
return set;
}*/
protected java.util.List<Member> getMembers(int access) {
java.util.List<Member> members=new ArrayList<Member>();
Member e;
Iterator<Entry<Key, Member>> it = _data.entrySet().iterator();
while(it.hasNext()) {
e=it.next().getValue();
if(e.getAccess()<=access)members.add(e);
}
return members;
}
@Override
public Iterator<Collection.Key> keyIterator(int access) {
return keySet(access).iterator();
}
@Override
public Iterator<String> keysAsStringIterator(int access) {
return new StringIterator(keys(access));
}
@Override
public Iterator<Entry<Key, Object>> entryIterator(int access) {
return new ComponentEntryIterator(this, keys(access),access);
}
@Override
public Iterator<Object> valueIterator(int access) {
return new ComponentValueIterator(this,keys(access),access);
}
@Override
public Iterator<Object> valueIterator() {
return valueIterator(getAccess(ThreadLocalPageContext.get()));
}
@Override
public java.util.Iterator<?> getIterator() {
PageContext pc = ThreadLocalPageContext.get();
// do we have functions _hasNext,_next,_reset
if(
getMember(pc,KeyConstants.__hasNext,false,false)!=null &&
getMember(pc,KeyConstants.__next,false,false)!=null)
return new ComponentIterator(this);
return keysAsStringIterator();
}
@Override
public Collection.Key[] keys(int access) {
Set<Key> set = keySet(access);
return set.toArray(new Collection.Key[set.size()]);
}
@Override
public void clear() {
_data.clear();
_udfs.clear();
}
@Override
public Member getMember(int access,Collection.Key key, boolean dataMember,boolean superAccess) {
// check super
if(dataMember && access==ACCESS_PRIVATE && key.equalsIgnoreCase(KeyConstants._super)) {
Component ac =ComponentUtil.getActiveComponent(ThreadLocalPageContext.get(),this);
return SuperComponent.superMember((ComponentImpl)ac.getBaseComponent());
//return SuperComponent . superMember(base);
}
if(superAccess) {
return _udfs.get(key);
}
// check data
Member member=_data.get(key);
if(member!=null) {
if(member.getAccess()<=access)return member;
return null;
}
return null;
}
/**
* get entry matching key
* @param access
* @param keyLowerCase key lower case (case sensitive)
* @param doBase do check also base component
* @param dataMember do also check if key super
* @return matching entry if exists otherwise null
*/
protected Member getMember(PageContext pc, Collection.Key key, boolean dataMember,boolean superAccess) {
// check super
if(dataMember && key.equalsIgnoreCase(KeyConstants._super) && isPrivate(pc)) {
Component ac = ComponentUtil.getActiveComponent(pc,this);
return SuperComponent.superMember((ComponentImpl)ac.getBaseComponent());
}
if(superAccess)
return _udfs.get(key);
// check data
Member member=_data.get(key);
if(isAccessible(pc,member)) return member;
return null;
}
boolean isAccessible(PageContext pc, Member member) {
// TODO geschwindigkeit
if(member!=null) {
int access=member.getAccess();
if(access<=ACCESS_PUBLIC) return true;
else if(access==ACCESS_PRIVATE && isPrivate(pc)) return true;
else if(access==ACCESS_PACKAGE && isPackage(pc)) return true;
}
return false;
}
boolean isAccessible(PageContext pc, int access) {
if(access<=ACCESS_PUBLIC) return true;
else if(access==ACCESS_PRIVATE && isPrivate(pc)) return true;
else if(access==ACCESS_PACKAGE && isPackage(pc)) return true;
return false;
}
/**
* @param pc
* @return returns if is private
*/
private boolean isPrivate(PageContext pc) {
pc=ThreadLocalPageContext.get(pc);
if(pc==null) return true;
Component ac = pc.getActiveComponent();
return (ac!=null && (ac==this ||
((ComponentImpl)ac).top.pageSource.equals(this.top.pageSource))) ;
}
/**
* @param pc
* @return returns if is package
*/
private boolean isPackage(PageContext pc) {
pc=ThreadLocalPageContext.get(pc);
if(pc==null) return true;
Component ac = pc.getActiveComponent();
if(ac!=null) {
if(ac==this) return true;
ComponentImpl aci = ((ComponentImpl)ac);
if(aci.top.pageSource.equals(this.top.pageSource))return true;
int index;
String other=aci.top.getAbsName();
index=other.lastIndexOf('.');
if(index==-1)other="";
else other=other.substring(0,index);
String my=this.top.getAbsName();
index=my.lastIndexOf('.');
if(index==-1)my="";
else my=my.substring(0,index);
return my.equalsIgnoreCase(other);
}
return false;
}
/**
* return the access of a member
* @param key
* @return returns the access (Component.ACCESS_REMOTE, ACCESS_PUBLIC, ACCESS_PACKAGE,Component.ACCESS_PRIVATE)
*/
private int getAccess(Collection.Key key){
Member member=getMember(ACCESS_PRIVATE,key,false,false);
if(member==null) return Component.ACCESS_PRIVATE;
return member.getAccess();
}
/**
* returns current access to this component
* @param pc
* @return access
*/
int getAccess(PageContext pc) {
if(pc==null) return ACCESS_PUBLIC;
if(isPrivate(pc)) return ACCESS_PRIVATE;
if(isPackage(pc)) return ACCESS_PACKAGE;
return ACCESS_PUBLIC;
}
@Override
public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
return toDumpData(pageContext,maxlevel,dp,getAccess(pageContext));
}
@Override
public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp, int access) {
boolean isCFML=getPageSource().getDialect()==CFMLEngine.DIALECT_CFML;
DumpTable table = isCFML?new DumpTable("component","#ff4542","#ff9aad","#000000"):new DumpTable("component","#ca6b50","#e9bcac","#000000");
table.setTitle((isCFML?"Component":"Class")+" "+getCallPath()+""+(" "+StringUtil.escapeHTML(top.properties.dspName)));
table.setComment("Only the functions and data members that are accessible from your location are displayed");
// Extends
if(!StringUtil.isEmpty(top.properties.extend,true))
table.appendRow(1,new SimpleDumpData("Extends"),new SimpleDumpData(top.properties.extend));
// Interfaces
if(!StringUtil.isEmpty(top.properties.implement,true))
table.appendRow(1,new SimpleDumpData("Implements"),new SimpleDumpData(top.properties.implement));
if(top.properties.modifier!=Member.MODIFIER_NONE)
table.appendRow(1,new SimpleDumpData("Modifier"),new SimpleDumpData(ComponentUtil.toModifier(top.properties.modifier,"")));
if(top.properties.hint.trim().length()>0)
table.appendRow(1,new SimpleDumpData("Hint"),new SimpleDumpData(top.properties.hint));
// this
DumpTable thisScope = thisScope(top,pageContext,maxlevel,dp,access);
if(!thisScope.isEmpty())table.appendRow(1,new SimpleDumpData("this"),thisScope);
// static
DumpTable staticScope = _static._toDumpData(top,pageContext, maxlevel, dp,getAccess(pageContext));
if(!staticScope.isEmpty())table.appendRow(1,new SimpleDumpData("static"),staticScope);
return table;
}
static DumpTable thisScope(ComponentImpl ci, PageContext pc, int maxlevel, DumpProperties dp, int access){
DumpTable table = new DumpTable("#ffffff","#cccccc","#000000");
DumpTable[] accesses=new DumpTable[4];
accesses[Component.ACCESS_REMOTE] = new DumpTable("#ccffcc","#ffffff","#000000");
accesses[Component.ACCESS_REMOTE].setTitle("remote");
accesses[Component.ACCESS_PUBLIC] = new DumpTable("#ffcc99","#ffffcc","#000000");
accesses[Component.ACCESS_PUBLIC].setTitle("public");
accesses[Component.ACCESS_PACKAGE] = new DumpTable("#ff9966","#ffcc99","#000000");
accesses[Component.ACCESS_PACKAGE].setTitle("package");
accesses[Component.ACCESS_PRIVATE] = new DumpTable("#ff6633","#ff9966","#000000");
accesses[Component.ACCESS_PRIVATE].setTitle("private");
maxlevel--;
ComponentSpecificAccess cw = new ComponentSpecificAccess(Component.ACCESS_PRIVATE, ci);
Collection.Key[] keys = cw.keys();
List<DumpRow>[] drAccess = new List[4];
for (int i=0; i<drAccess.length; i++)
drAccess[i] = new ArrayList(); // ACCESS_REMOTE=0, ACCESS_PUBLIC=1, ACCESS_PACKAGE=2, ACCESS_PRIVATE=3
Collection.Key key;
for(int i=0; i<keys.length; i++){
key = keys[i];
List<DumpRow> box = drAccess[ci.getAccess(key)];
Object o = cw.get(key, null);
if (o == ci)
o = "[this]";
if (DumpUtil.keyValid(dp, maxlevel, key)){
String memberName = (o instanceof UDF) ? ((UDF)o).getFunctionName() : key.getString();
box.add(new DumpRow(1, new SimpleDumpData(memberName), DumpUtil.toDumpData(o, pc, maxlevel, dp)));
}
}
List<DumpRow> dumpRows;
for (int i=0; i<drAccess.length; i++){
dumpRows = drAccess[i];
if (!dumpRows.isEmpty()){
Collections.sort(dumpRows, new Comparator<DumpRow>() {
@Override
public int compare(DumpRow o1, DumpRow o2) {
DumpData[] rowItems1 = o1.getItems();
DumpData[] rowItems2 = o2.getItems();
if (rowItems1.length >= 0 && rowItems2.length > 0 && rowItems1[0] instanceof SimpleDumpData && rowItems2[0] instanceof SimpleDumpData)
return String.CASE_INSENSITIVE_ORDER.compare(rowItems1[0].toString(), rowItems2[0].toString());
return 0;
}
});
DumpTable dtAccess = accesses[i];
dtAccess.setWidth("100%");
for (DumpRow dr : dumpRows)
dtAccess.appendRow(dr);
table.appendRow(0, dtAccess);
}
}
// properties
if (ci.top.properties.persistent || ci.top.properties.accessors){
Property[] properties = ci.getProperties(false, true, false, false);
DumpTable prop = new DumpTable("#99cc99","#ccffcc","#000000");
prop.setTitle("Properties");
prop.setWidth("100%");
Property p;
Object child;
for (int i=0; i<properties.length; i++){
p=properties[i];
child = ci.scope.get(KeyImpl.init(p.getName()), null);
DumpData dd;
if(child instanceof Component) {
DumpTable t = new DumpTable("component","#99cc99","#ffffff","#000000");
t.appendRow(1
,new SimpleDumpData(((Component)child).getPageSource().getDialect() == CFMLEngine.DIALECT_CFML ? "Component":"Class")
,new SimpleDumpData(((Component)child).getCallName())
);
dd = t;
}
else {
dd = DumpUtil.toDumpData(child, pc, maxlevel-1, dp);
}
prop.appendRow(1, new SimpleDumpData(p.getName()), dd);
}
if(access>=ACCESS_PUBLIC && !prop.isEmpty()) {
table.appendRow(0, prop);
}
}
return table;
}
/**
* @return return call path
*/
protected String getCallPath() {
if(StringUtil.isEmpty(top.properties.callPath)) return getName();
try {
return "("+ListUtil.arrayToList(ListUtil.listToArrayTrim(top.properties.callPath.replace('/','.').replace('\\','.'),"."),".")+")";
} catch (PageException e) {
return top.properties.callPath;
}
}
@Override
public String getDisplayName() {
return top.properties.dspName;
}
@Override
public String getExtends() {
return top.properties.extend;
}
@Override
public int getModifier() {
return properties.modifier;
}
public String getBaseAbsName() {
return top.base.pageSource.getComponentName();
}
public boolean isBasePeristent() {
return top.base!=null && top.base.properties.persistent;
}
@Override
public String getHint() {
return top.properties.hint;
}
@Override
public String getWSDLFile() {
return top.properties.getWsdlFile();
}
@Override
public String getName() {
if(top.properties.callPath==null) return "";
return ListUtil.last(top.properties.callPath,"./",true);
}
public String _getName() { // MUST nicht so toll
if(properties.callPath==null) return "";
return ListUtil.last(properties.callPath,"./",true);
}
public PageSource _getPageSource() {
return pageSource;
}
@Override
public String getCallName() {
return top.properties.callPath;
}
@Override
public String getAbsName() {
return top.pageSource.getComponentName();
}
@Override
public boolean getOutput() {
if(top.properties.output==null) return true;
return top.properties.output.booleanValue();
}
@Override
public boolean instanceOf(String type) {
ComponentImpl c=top;
do {
if(type.equalsIgnoreCase(c.properties.callPath)) return true;
if(type.equalsIgnoreCase(c.pageSource.getComponentName())) return true;
if(type.equalsIgnoreCase(c._getName())) return true;
// check interfaces
if(c.absFin!=null){
Iterator<InterfaceImpl> it = c.absFin.getInterfaceIt();
while(it.hasNext()){
if(it.next().instanceOf(type))return true;
}
}
c=c.base;
}
while(c!=null);
if(StringUtil.endsWithIgnoreCase(type, "component")){
if(type.equalsIgnoreCase("component")) return true;
if(type.equalsIgnoreCase("web-inf.cftags.component")) return true;
//if(type.equalsIgnoreCase("web-inf.lucee.context.component")) return true;
}
return false;
}
public boolean equalTo(String type) {
ComponentImpl c=top;
if(type.equalsIgnoreCase(c.properties.callPath)) return true;
if(type.equalsIgnoreCase(c.pageSource.getComponentName())) return true;
if(type.equalsIgnoreCase(c._getName())) return true;
// check interfaces
if(c.absFin!=null){
Iterator<InterfaceImpl> it = c.absFin.getInterfaceIt();
while(it.hasNext()){
if(it.next().instanceOf(type))return true;
}
}
if(StringUtil.endsWithIgnoreCase(type, "component")){
if(type.equalsIgnoreCase("component")) return true;
if(type.equalsIgnoreCase("web-inf.cftags.component")) return true;
}
return false;
}
@Override
public boolean isValidAccess(int access) {
return access==ACCESS_PRIVATE || access==ACCESS_PACKAGE || access==ACCESS_PUBLIC || access==ACCESS_REMOTE;
}
@Override
public PageSource getPageSource() {
return top.pageSource;
}
@Override
public String castToString() throws PageException {
return castToString(false);
}
@Override
public String castToString(String defaultValue) {
return castToString(false,defaultValue);
}
String castToString(boolean superAccess) throws PageException {
// magic function
PageContext pc = ThreadLocalPageContext.get();
if(pc!=null) {
Member member = getMember(pc,KeyConstants.__toString,true,superAccess);
//Object o = get(pc,"_toString",null);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getReturnType()==CFTypes.TYPE_STRING && udf.getFunctionArguments().length==0) {
return Caster.toString(_call(pc, KeyConstants.__toString,udf, null, new Object[0]));
}
}
}
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");
}
String castToString(boolean superAccess,String defaultValue) {
// magic function
PageContext pc = ThreadLocalPageContext.get();
if(pc!=null) {
Member member = getMember(pc,KeyConstants.__toString,true,superAccess);
//Object o = get(pc,"_toString",null);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getReturnType()==CFTypes.TYPE_STRING && udf.getFunctionArguments().length==0) {
try {
return Caster.toString(_call(pc,KeyConstants.__toString, udf, null, new Object[0]),defaultValue);
} catch (PageException e) {
return defaultValue;
}
}
}
}
return defaultValue;
}
@Override
public boolean castToBooleanValue() throws PageException {
return castToBooleanValue(false);
}
@Override
public Boolean castToBoolean(Boolean defaultValue) {
return castToBoolean(false, defaultValue);
}
boolean castToBooleanValue(boolean superAccess) throws PageException {
// magic function
PageContext pc = ThreadLocalPageContext.get();
if(pc!=null) {
Member member = getMember(pc,KeyConstants.__toBoolean,true,superAccess);
//Object o = get(pc,"_toBoolean",null);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getReturnType()==CFTypes.TYPE_BOOLEAN && udf.getFunctionArguments().length==0) {
return Caster.toBooleanValue(_call(pc, KeyConstants.__toBoolean,udf, null, new Object[0]));
}
}
}
throw ExceptionUtil.addHint(new ExpressionException("Can't cast Component ["+getName()+"] to a boolean value"),
"Add a User-Defined-Function to Component with the following pattern [_toBoolean():boolean] to cast it to a boolean value");
}
Boolean castToBoolean(boolean superAccess,Boolean defaultValue) {
// magic function
PageContext pc = ThreadLocalPageContext.get();
if(pc!=null) {
Member member = getMember(pc,KeyConstants.__toBoolean,true,superAccess);
//Object o = get(pc,"_toBoolean",null);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getReturnType()==CFTypes.TYPE_BOOLEAN && udf.getFunctionArguments().length==0) {
try {
return Caster.toBoolean(_call(pc,KeyConstants.__toBoolean, udf, null, new Object[0]),defaultValue);
} catch (PageException e) {
return defaultValue;
}
}
}
}
return defaultValue;
}
@Override
public double castToDoubleValue() throws PageException {
return castToDoubleValue(false);
}
@Override
public double castToDoubleValue(double defaultValue) {
return castToDoubleValue(false, defaultValue);
}
double castToDoubleValue(boolean superAccess) throws PageException {
// magic function
PageContext pc = ThreadLocalPageContext.get();
if(pc!=null) {
Member member = getMember(pc,KeyConstants.__toNumeric,true,superAccess);
//Object o = get(pc,"_toNumeric",null);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getReturnType()==CFTypes.TYPE_NUMERIC && udf.getFunctionArguments().length==0) {
return Caster.toDoubleValue(_call(pc, KeyConstants.__toNumeric,udf, null, new Object[0]));
}
}
}
throw ExceptionUtil.addHint(new ExpressionException("Can't cast Component ["+getName()+"] to a numeric value"),
"Add a User-Defined-Function to Component with the following pattern [_toNumeric():numeric] to cast it to a numeric value");
}
double castToDoubleValue(boolean superAccess,double defaultValue) {
// magic function
PageContext pc = ThreadLocalPageContext.get();
if(pc!=null) {
Member member = getMember(pc,KeyConstants.__toNumeric,true,superAccess);
//Object o = get(pc,"_toNumeric",null);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getReturnType()==CFTypes.TYPE_NUMERIC && udf.getFunctionArguments().length==0) {
try {
return Caster.toDoubleValue(_call(pc, KeyConstants.__toNumeric,udf, null, new Object[0]),true,defaultValue);
} catch (PageException e) {
return defaultValue;
}
}
}
}
return defaultValue;
}
@Override
public DateTime castToDateTime() throws PageException {
return castToDateTime(false);
}
@Override
public DateTime castToDateTime(DateTime defaultValue) {
return castToDateTime(false, defaultValue);
}
DateTime castToDateTime(boolean superAccess) throws PageException {
// magic function
PageContext pc = ThreadLocalPageContext.get();
if(pc!=null) {
Member member = getMember(pc,KeyConstants.__toDateTime,true,superAccess);
//Object o = get(pc,"_toDateTime",null);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getReturnType()==CFTypes.TYPE_DATETIME && udf.getFunctionArguments().length==0) {
return Caster.toDate(_call(pc, KeyConstants.__toDateTime,udf, null, new Object[0]),pc.getTimeZone());
}
}
}
throw ExceptionUtil.addHint(new ExpressionException("Can't cast Component ["+getName()+"] to a date"),
"Add a User-Defined-Function to Component with the following pattern [_toDateTime():datetime] to cast it to a date");
}
DateTime castToDateTime(boolean superAccess,DateTime defaultValue) {
// magic function
PageContext pc = ThreadLocalPageContext.get();
if(pc!=null) {
Member member = getMember(pc,KeyConstants.__toDateTime,true,superAccess);
//Object o = get(pc,"_toDateTime",null);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getReturnType()==CFTypes.TYPE_DATETIME && udf.getFunctionArguments().length==0) {
try {
return DateCaster.toDateAdvanced(
_call(pc, KeyConstants.__toDateTime,udf, null, new Object[0])
,DateCaster.CONVERTING_TYPE_OFFSET
,pc.getTimeZone()
,defaultValue);
} catch (PageException e) {
return defaultValue;
}
}
}
}
return defaultValue;
}
@Override
public synchronized Struct getMetaData(PageContext pc) throws PageException {
return getMetaData(ACCESS_PRIVATE,pc,top,false);
}
public synchronized Object getMetaStructItem(Collection.Key name) {
if(top.properties.meta!=null) {
return top.properties.meta.get(name,null);
}
return null;
}
protected static Struct getMetaData(int access,PageContext pc, ComponentImpl comp, boolean ignoreCache) throws PageException {
// Cache
Page page=MetadataUtil.getPageWhenMetaDataStillValid(pc, comp, ignoreCache);
if(page!=null && page.metaData!=null && page.metaData.get()!=null){
return page.metaData.get();
}
long creationTime=System.currentTimeMillis();
StructImpl sct=new StructImpl();
// fill udfs
metaUDFs(pc, comp, sct,access);
// meta
if(comp.properties.meta!=null)
StructUtil.copy(comp.properties.meta, sct, true);
String hint=comp.properties.hint;
String displayname=comp.properties.dspName;
if(!StringUtil.isEmpty(hint))sct.set(KeyConstants._hint,hint);
if(!StringUtil.isEmpty(displayname))sct.set(KeyConstants._displayname,displayname);
sct.set(KeyConstants._persistent,comp.properties.persistent);
sct.set(KeyConstants._hashCode,comp.hashCode());
sct.set(KeyConstants._accessors,comp.properties.accessors);
sct.set(KeyConstants._synchronized,comp.properties._synchronized);
if(comp.properties.output!=null)
sct.set(KeyConstants._output,comp.properties.output);
// extends
Struct ex=null;
if(comp.base!=null) ex=getMetaData(access,pc,comp.base,true);
if(ex!=null)sct.set(KeyConstants._extends,ex);
// implements
if(comp.absFin!=null){
Set<String> set = ListUtil.listToSet(comp.properties.implement, ",",true);
if(comp.absFin.hasInterfaces()){
Iterator<InterfaceImpl> it = comp.absFin.getInterfaceIt();
Struct imp=new StructImpl();
InterfaceImpl inter;
while(it.hasNext()) {
inter=it.next();
if(!set.contains(inter.getCallPath())) continue;
imp.setEL(KeyImpl.init(inter.getCallPath()), inter.getMetaData(pc,true));
}
sct.set(KeyConstants._implements,imp);
}
}
// PageSource
PageSource ps = comp.pageSource;
sct.set(KeyConstants._fullname,ps.getComponentName());
sct.set(KeyConstants._name,ps.getComponentName());
sct.set(KeyConstants._path,ps.getDisplayPath());
sct.set(KeyConstants._type,"component");
int dialect=comp.getPageSource().getDialect();
boolean supressWSBeforeArg=dialect!=CFMLEngine.DIALECT_CFML || pc.getConfig().getSuppressWSBeforeArg();
Class<?> skeleton = comp.getJavaAccessClass(pc,
new RefBooleanImpl(false),
((ConfigImpl)pc.getConfig()).getExecutionLogEnabled(),
false,false,
supressWSBeforeArg);
if(skeleton !=null)sct.set(KeyConstants._skeleton, skeleton);
HttpServletRequest req = pc.getHttpServletRequest();
try {
String path=ContractPath.call(pc, ps.getDisplayPath()); // MUST better impl !!!
sct.set("remoteAddress",""+new URL(req.getScheme(),req.getServerName(),req.getServerPort(),req.getContextPath()+path+"?wsdl"));
} catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);}
// Properties
if(comp.properties.properties!=null) {
ArrayImpl parr = new ArrayImpl();
Property p;
Iterator<Entry<String, Property>> pit = comp.properties.properties.entrySet().iterator();
while(pit.hasNext()){
p=pit.next().getValue();
parr.append(p.getMetaData());
}
parr.sortIt(new ArrayOfStructComparator(KeyConstants._name));
sct.set(KeyConstants._properties,parr);
}
page.metaData=new MetaDataSoftReference<Struct>(sct,creationTime);
return sct;
}
private static void metaUDFs(PageContext pc,ComponentImpl comp,Struct sct, int access) throws PageException {
ArrayImpl arr=new ArrayImpl();
//Collection.Key name;
Page page = comp._getPageSource().loadPage(pc, false);
// Page page = ((PageSourceImpl)comp._getPageSource()).getPage();
if(page!=null && page.udfs!=null){
for(int i=0;i<page.udfs.length;i++){
if(page.udfs[i].getAccess()>access) continue;
arr.append(ComponentUtil.getMetaData(pc,(UDFPropertiesBase) page.udfs[i]));
}
}
// property functions
Iterator<Entry<Key, UDF>> it = comp._udfs.entrySet().iterator();
Entry<Key, UDF> entry;
UDF udf;
while(it.hasNext()) {
entry= it.next();
udf=entry.getValue();
if(udf.getAccess()>access || !(udf instanceof UDFGSProperty)) continue;
if(comp.base!=null) {
if(udf==comp.base.getMember(access,entry.getKey(),true,true))
continue;
}
arr.append(udf.getMetaData(pc));
}
if(arr.size()!=0)sct.set(KeyConstants._functions,arr);
}
public boolean isInitalized() {
return isInit;
}
public void setInitalized(boolean isInit) {
this.isInit=isInit;;
}
/**
* sets a value to the current Component, dont to base Component
* @param key
* @param value
* @return value set
* @throws ExpressionException
*/
private synchronized Object _set(PageContext pc,Collection.Key key, Object value) throws ExpressionException {
if(value instanceof Member) {
if(value instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)((UDFPlus)value).duplicate();
//udf.isComponentMember(true);///+++
udf.setOwnerComponent(this);
if(udf.getAccess()>Component.ACCESS_PUBLIC)
udf.setAccess(Component.ACCESS_PUBLIC);
_data.put(key,udf);
_udfs.put(key,udf);
hasInjectedFunctions=true;
}
else _data.put(key,(Member)value);
}
else {
Member existing = _data.get(key);
if(loaded && !isAccessible(pc, existing!=null?existing.getAccess():dataMemberDefaultAccess))
throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+key+"]","enable [trigger data member] in admininistrator to also invoke getters and setters");
_data.put(key,new DataMember(existing!=null?existing.getAccess():dataMemberDefaultAccess,existing!=null?existing.getModifier():Member.MODIFIER_NONE,value));
}
return value;
}
/*
public void reg(Collection.Key key, UDFPlus udf) throws ApplicationException {
registerUDF(key, udf,useShadow,false);
}
public void reg(String key, UDFPlus udf) throws ApplicationException {
registerUDF(KeyImpl.init(key), udf,useShadow,false);
}*/
@Override
public void registerUDF(Collection.Key key, UDF udf) throws ApplicationException {
registerUDF(key, (UDFPlus) udf,useShadow,false);
}
@Override
public void registerUDF(Collection.Key key, UDFProperties prop) throws ApplicationException {
registerUDF(key, new UDFImpl( prop),useShadow,false);
}
/*
* @deprecated injected is not used
*/
public void registerUDF(Collection.Key key, UDFPlus udf,boolean useShadow,boolean injected) throws ApplicationException {
udf.setOwnerComponent(this);
if(insideStaticConstr) {
_static.put(key, udf);
return;
}
// Abstact UDF
if(udf.getModifier()==MODIFIER_ABSTRACT) {
// abstract methods are not allowed
if(getModifier()!=MODIFIER_ABSTRACT) {
throw new ApplicationException("the abstract function ["+key+"] is not allowed within the no abstract component ["+_getPageSource().getDisplayPath()+"]");
}
if(absFin==null)absFin=new AbstractFinal();
absFin.add(key,udf);
return; // abstract methods are not registered here
}
// Final UDF
else if(udf.getModifier()==MODIFIER_FINAL) {
if(absFin==null)absFin=new AbstractFinal();
absFin.add(key,udf);
}
_udfs.put(key,udf);
_data.put(key,udf);
if(useShadow)scope.setEL(key, udf);
}
@Override
public Object remove(Key key) throws PageException {
return _data.remove(key);
}
public Object removeEL(Collection.Key key) {
// MUST access muss beruecksichtigt werden
return _data.remove(key);
}
/*public Object set(PageContext pc, String name, Object value) throws PageException {
return set(pc, KeyImpl.init(name), value);
}*/
@Override
public Object set(PageContext pc, Collection.Key key, Object value) throws PageException {
if(pc==null)pc=ThreadLocalPageContext.get();
if(triggerDataMember(pc) && isInit) {
if(!isPrivate(pc)) {
return callSetter(pc, key, value);
}
}
return _set(pc,key,value);
}
@Override
public Object set(Collection.Key key, Object value) throws PageException {
return set(null,key,value);
}
/*public Object setEL(PageContext pc, String name, Object value) {
try {return set(pc, name, value);}
catch (PageException e) {return null;}
}*/
@Override
public Object setEL(PageContext pc, Collection.Key name, Object value) {
try {return set(pc, name, value);}
catch (PageException e) {return null;}
}
@Override
public Object setEL(Key key, Object value) {
return setEL(null, key, value);
}
@Override
public final Object put(Object key, Object value) {
// TODO find a better solution
// when a orm entity the data given by put or also written to the variables scope
if(entity) {
getComponentScope().put(key, value);
}
return super.put(key, value);
}
/*public Object get(PageContext pc, String name) throws PageException {
return get(pc, KeyImpl.init(name));
}*/
@Override
public Object get(PageContext pc, Collection.Key key) throws PageException {
Member member=getMember(pc,key,true,false);
if(member!=null) return member.getValue();
// trigger
if(triggerDataMember(pc) && !isPrivate(pc)) {
return callGetter(pc,key);
}
throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+key+"]","enable [trigger data member] in admininistrator to also invoke getters and setters");
//throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+name+"]");
}
private Object callGetter(PageContext pc,Collection.Key key) throws PageException {
Key getterName = KeyImpl.getInstance("get"+key.getLowerString());
Member member=getMember(pc,getterName,false,false);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getFunctionArguments().length==0 && udf.getReturnType()!=CFTypes.TYPE_VOID) {
return _call(pc,getterName,udf,null,ArrayUtil.OBJECT_EMPTY);
}
}
throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+key+"]");
}
private Object callGetter(PageContext pc,Collection.Key key, Object defaultValue) {
Key getterName = KeyImpl.getInstance("get"+key.getLowerString());
Member member=getMember(pc,getterName,false,false);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getFunctionArguments().length==0 && udf.getReturnType()!=CFTypes.TYPE_VOID) {
try {
return _call(pc,getterName,udf,null,ArrayUtil.OBJECT_EMPTY);
} catch (PageException e) {
return defaultValue;
}
}
}
return defaultValue;
}
private Object callSetter(PageContext pc,Collection.Key key, Object value) throws PageException {
Collection.Key setterName = KeyImpl.getInstance("set"+key.getLowerString());
Member member=getMember(pc,setterName,false,false);
if(member instanceof UDFPlus) {
UDFPlus udf = (UDFPlus)member;
if(udf.getFunctionArguments().length==1 && (udf.getReturnType()==CFTypes.TYPE_VOID) || udf.getReturnType()==CFTypes.TYPE_ANY ) {// TDOO support int return type
return _call(pc,setterName,udf,null,new Object[]{value});
}
}
return _set(pc,key,value);
}
/**
* return element that has at least given access or null
* @param access
* @param name
* @return matching value
* @throws PageException
*/
public Object get(int access, String name) throws PageException {
return get(access, KeyImpl.init(name));
}
public Object get(int access, Collection.Key key) throws PageException {
Member member=getMember(access,key,true,false);
if(member!=null) return member.getValue();
// Trigger
PageContext pc = ThreadLocalPageContext.get();
if(triggerDataMember(pc) && !isPrivate(pc)) {
return callGetter(pc,key);
}
throw new ExpressionException("Component ["+getCallName()+"] has no accessible Member with name ["+key+"]");
}
/*public Object get(PageContext pc, String name, Object defaultValue) {
return get(pc, KeyImpl.init(name), defaultValue);
}*/
@Override
public Object get(PageContext pc, Collection.Key key, Object defaultValue) {
Member member=getMember(pc,key,true,false);
if(member!=null) return member.getValue();
// trigger
if(triggerDataMember(pc) && !isPrivate(pc)) {
return callGetter(pc,key,defaultValue);
}
return defaultValue;
}
/**
* return element that has at least given access or null
* @param access
* @param name
* @return matching value
*/
protected Object get(int access, String name, Object defaultValue) {
return get(access, KeyImpl.init(name), defaultValue);
}
/**
* @param access
* @param key
* @param defaultValue
* @return
*/
public Object get(int access, Collection.Key key, Object defaultValue) {
Member member=getMember(access,key,true,false);
if(member!=null) return member.getValue();
// trigger
PageContext pc = ThreadLocalPageContext.get();
if(triggerDataMember(pc) && !isPrivate(pc)) {
return callGetter(pc,key,defaultValue);
}
return defaultValue;
}
@Override
public Object get(Collection.Key key) throws PageException {
return get(ThreadLocalPageContext.get(),key);
}
@Override
public Object get(Collection.Key key, Object defaultValue) {
return get(ThreadLocalPageContext.get(),key,defaultValue);
}
@Override
public Object call(PageContext pc, String name, Object[] args) throws PageException {
return _call(pc,KeyImpl.init(name),null,args,false);
}
public Object call(PageContext pc, Collection.Key name, Object[] args) throws PageException {
return _call(pc,name,null,args,false);
}
protected Object call(PageContext pc, int access, String name, Object[] args) throws PageException {
return _call(pc,access,KeyImpl.init(name),null,args,false);
}
public Object call(PageContext pc, int access, Collection.Key name, Object[] args) throws PageException {
return _call(pc,access,name,null,args,false);
}
@Override
public Object callWithNamedValues(PageContext pc, String name, Struct args) throws PageException {
return _call(pc,KeyImpl.init(name),args,null,false);
}
public Object callWithNamedValues(PageContext pc, Collection.Key methodName, Struct args) throws PageException {
return _call(pc,methodName,args,null,false);
}
protected Object callWithNamedValues(PageContext pc, int access, String name, Struct args) throws PageException {
return _call(pc,access,KeyImpl.init(name),args,null,false);
}
public Object callWithNamedValues(PageContext pc, int access, Collection.Key name, Struct args) throws PageException {
return _call(pc,access,name,args,null,false);
}
public boolean contains(PageContext pc,String name) {
return get(pc,KeyImpl.init(name),NullSupportHelper.NULL(pc))!=NullSupportHelper.NULL(pc);
}
/**
* @param pc
* @param key
* @return
*/
public boolean contains(PageContext pc,Key key) {
return get(pc,key,NullSupportHelper.NULL(pc))!=NullSupportHelper.NULL(pc);
}
@Override
public boolean containsKey(Key key) {
return contains(ThreadLocalPageContext.get(),key);
}
public boolean contains(int access,String name) {
return get(access,name,NullSupportHelper.NULL())!=NullSupportHelper.NULL();
}
public boolean contains(int access,Key name) {
return get(access,name,NullSupportHelper.NULL())!=NullSupportHelper.NULL();
}
@Override
public Iterator<Collection.Key> keyIterator() {
return keyIterator(getAccess(ThreadLocalPageContext.get()));
}
@Override
public Iterator<String> keysAsStringIterator() {
return keysAsStringIterator(getAccess(ThreadLocalPageContext.get()));
}
@Override
public Iterator<Entry<Key, Object>> entryIterator() {
return entryIterator(getAccess(ThreadLocalPageContext.get()));
}
@Override
public Collection.Key[] keys() {
return keys(getAccess(ThreadLocalPageContext.get()));
}
@Override
public int size() {
return size(getAccess(ThreadLocalPageContext.get()));
}
@Override
public Class<?> getJavaAccessClass(RefBoolean isNew) throws PageException {
return getJavaAccessClass(ThreadLocalPageContext.get(),isNew);
}
public Class<?> getJavaAccessClass(PageContext pc,RefBoolean isNew) throws PageException {
return getJavaAccessClass(pc,isNew, false,true,true,true,false,false);
}
@Override
public Class<?> getJavaAccessClass(PageContext pc,RefBoolean isNew,boolean writeLog, boolean takeTop, boolean create, boolean suppressWSbeforeArg) throws PageException {
isNew.setValue(false);
ComponentProperties props =(takeTop)?top.properties:properties;
if(props.javaAccessClass==null) {
props.javaAccessClass=ComponentUtil.getComponentJavaAccess(pc,this,isNew,create,writeLog,suppressWSbeforeArg,true,false);
}
return props.javaAccessClass;
}
@Override
public Class<?> getJavaAccessClass(PageContext pc,RefBoolean isNew,boolean writeLog, boolean takeTop, boolean create, boolean suppressWSbeforeArg, boolean output,boolean returnValue) throws PageException {
isNew.setValue(false);
ComponentProperties props =(takeTop)?top.properties:properties;
if(props.javaAccessClass==null) {
props.javaAccessClass=ComponentUtil.getComponentJavaAccess(pc,this,isNew,create,writeLog,suppressWSbeforeArg,output,returnValue);
}
return props.javaAccessClass;
}
public boolean isPersistent() {
return top.properties.persistent;
}
public boolean isAccessors() {
return top.properties.accessors;
}
public void setProperty(Property property) throws PageException {
top.properties.properties.put(StringUtil.toLowerCase(property.getName()),property);
if(top.properties.persistent || top.properties.accessors){
if(property.getDefault()!=null)scope.setEL(KeyImpl.init(property.getName()), property.getDefault());
PropertyFactory.createPropertyUDFs(this,property);
}
}
private void initProperties() throws PageException {
top.properties.properties=new LinkedHashMap<String,Property>();
// MappedSuperClass
if(isPersistent() && !isBasePeristent() && top.base!=null && top.base.properties.properties!=null && top.base.properties.meta!=null) {
boolean msc = Caster.toBooleanValue(top.base.properties.meta.get(KeyConstants._mappedSuperClass,Boolean.FALSE),false);
if(msc){
Property p;
Iterator<Entry<String, Property>> it = top.base.properties.properties.entrySet().iterator();
while(it.hasNext()) {
p = it.next().getValue();
if(p.isPeristent()) {
setProperty(p);
}
}
}
}
}
public Property[] getProperties(boolean onlyPeristent) {
return getProperties(onlyPeristent, false,false,false);
}
public Property[] getProperties(boolean onlyPeristent, boolean includeBaseProperties, boolean preferBaseProperties, boolean inheritedMappedSuperClassOnly) {
Map<String,Property> props=new LinkedHashMap<String,Property>();
_getProperties(top,props,onlyPeristent, includeBaseProperties, preferBaseProperties, inheritedMappedSuperClassOnly);
return props.values().toArray(new Property[props.size()]);
}
private static void _getProperties(ComponentImpl c,Map<String,Property> props,boolean onlyPeristent, boolean includeBaseProperties, boolean preferBaseProperties, boolean inheritedMappedSuperClassOnly) {
//if(c.properties.properties==null) return new Property[0];
// collect with filter
if(c.properties.properties!=null){
Property p;
Iterator<Entry<String, Property>> it = c.properties.properties.entrySet().iterator();
while(it.hasNext()) {
p = it.next().getValue();
if(!onlyPeristent || p.isPeristent()) {
if (!preferBaseProperties || !props.containsKey(p.getName().toLowerCase())) {
props.put(p.getName().toLowerCase(),p);
}
}
}
}
// MZ: Moved to the bottom to allow base properties to override inherited versions
if(includeBaseProperties && c.base!=null) {
if (!inheritedMappedSuperClassOnly || (c.base.properties.meta != null && Caster.toBooleanValue(c.base.properties.meta.get(KeyConstants._mappedSuperClass, Boolean.FALSE), false))) {
_getProperties(c.base, props, onlyPeristent, includeBaseProperties, preferBaseProperties, inheritedMappedSuperClassOnly);
}
}
}
public ComponentScope getComponentScope() {
return scope;
}
@Override
public int compareTo(boolean b) throws PageException {
return Operator.compare(castToBooleanValue(), b);
}
@Override
public int compareTo(DateTime dt) throws PageException {
return Operator.compare((Date)castToDateTime(), (Date)dt);
}
@Override
public int compareTo(double d) throws PageException {
return Operator.compare(castToDoubleValue(), d);
}
@Override
public int compareTo(String str) throws PageException {
return Operator.compare(castToString(), str);
}
public void addConstructorUDF(Key key, UDF udf) throws ApplicationException {
registerUDF(key, (UDFPlus)udf, false, true);
/*if(constructorUDFs==null)
constructorUDFs=new HashMap<Key,UDF>();
constructorUDFs.put(key, value);*/
}
// MUST more native impl
public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {
boolean pcCreated=false;
PageContext pc = ThreadLocalPageContext.get();
try{
if(pc==null){
pcCreated=true;
ConfigWeb config = (ConfigWeb) ThreadLocalPageContext.getConfig();
Pair[] parr = new Pair[0];
pc=ThreadUtil.createPageContext(config, DevNullOutputStream.DEV_NULL_OUTPUT_STREAM, "localhost", "/","", new Cookie[0], parr,null, parr, new StructImpl(),true,-1);
}
// reading fails for serialized data from Lucee version 4.1.2.002
String name = in.readUTF();
if(name.startsWith("evaluateComponent('") && name.endsWith("})")) {
readExternalOldStyle(pc, name);
return;
}
String md5 = in.readUTF();
Struct _this = Caster.toStruct(in.readObject(),null);
Struct _var = Caster.toStruct(in.readObject(),null);
try {
ComponentImpl other=(ComponentImpl)EvaluateComponent.invoke(pc, name, md5, _this,_var);
_readExternal(other);
}
catch (PageException e) {
throw ExceptionUtil.toIOException(e);
}
}
finally {
if(pcCreated)ThreadLocalPageContext.release();
}
}
private void readExternalOldStyle(PageContext pc, String str) throws IOException {
try {
ComponentImpl other=(ComponentImpl) new CFMLExpressionInterpreter(false).interpret(pc,str);
_readExternal(other);
}
catch (PageException e) {
throw ExceptionUtil.toIOException(e);
}
}
private void _readExternal(ComponentImpl other) {
this._data=other._data;
this._udfs=other._udfs;
setOwner(_udfs);
setOwner(_data);
this.afterConstructor=other.afterConstructor;
this.base=other.base;
//this.componentPage=other.componentPage;
this.pageSource=other.pageSource;
//this.constructorUDFs=other.constructorUDFs;
this.dataMemberDefaultAccess=other.dataMemberDefaultAccess;
this.absFin=other.absFin;
this.isInit=other.isInit;
this.properties=other.properties;
this.scope=other.scope;
this.top=this;
//this._triggerDataMember=other._triggerDataMember;
this.hasInjectedFunctions=other.hasInjectedFunctions;
this.isExtended=other.isExtended;
this.useShadow=other.useShadow;
this.entity=other.entity;
this._static=other._static;
}
private void setOwner(Map<Key,? extends Member> data) {
Member m;
Iterator<? extends Member> it = data.values().iterator();
while(it.hasNext()){
m=it.next();
if(m instanceof UDFPlus) {
((UDFPlus)m).setOwnerComponent(this);
}
}
}
public void writeExternal(ObjectOutput out) throws IOException {
ComponentSpecificAccess cw = new ComponentSpecificAccess(Component.ACCESS_PRIVATE,this);
Struct _this=new StructImpl();
Struct _var=new StructImpl();
// this scope (removing all UDFs)
Object member;
{
Iterator<Entry<Key, Object>> it = cw.entryIterator();
Entry<Key, Object> e;
while(it.hasNext()) {
e = it.next();
member = e.getValue();
if(member instanceof UDF)continue;
_this.setEL(e.getKey(), member);
}
}
// variables scope (removing all UDFs and key "this")
{
ComponentScope scope = getComponentScope();
Iterator<Entry<Key, Object>> it = scope.entryIterator();
Entry<Key, Object> e;
Key k;
while(it.hasNext()) {
e = it.next();
k = e.getKey();
if(KeyConstants._THIS.equalsIgnoreCase(k))continue;
member = e.getValue();
if(member instanceof UDF)continue;
_var.setEL(e.getKey(), member);
}
}
out.writeUTF(getAbsName());
out.writeUTF(ComponentUtil.md5(cw));
out.writeObject(_this);
out.writeObject(_var);
}
@Override
public Component getBaseComponent() {
return base;
}
private boolean triggerDataMember(PageContext pc) {
// dialect Lucee always triggers data members
if(pageSource.getDialect()==CFMLEngine.DIALECT_LUCEE) return true;
//if(_triggerDataMember!=null) return _triggerDataMember.booleanValue();
if(pc!=null && pc.getApplicationContext()!=null)
return pc.getApplicationContext().getTriggerComponentDataMember();
Config config = ThreadLocalPageContext.getConfig();
if(config!=null)
return config.getTriggerComponentDataMember();
return false;
}
public void setLoaded(boolean loaded) {
this.loaded=loaded;
}
public boolean hasInjectedFunctions() {
return hasInjectedFunctions;
}
@Override
public void setEntity(boolean entity) {
this.entity=entity;
}
@Override
public boolean isEntity() {
return entity;
}
@Override
public Scope staticScope() {
return _static;
}
@Override
public Interface[] getInterfaces() {
if(top.absFin==null) return EMPTY;
return top.absFin.getInterfaces();
}
@Override
public String id() {
try {
return Hash.md5(getPageSource().getDisplayPath());
}
catch (NoSuchAlgorithmException e) {
return getPageSource().getDisplayPath();
}
}
@Override
public int getType() {
return StructUtil.getType(_data);
}
}