package railo.runtime.type.scope; import java.io.Serializable; import railo.runtime.PageContext; import railo.runtime.config.ConfigServer; import railo.runtime.dump.DumpData; import railo.runtime.dump.DumpProperties; import railo.runtime.exp.ExpressionException; import railo.runtime.exp.PageException; import railo.runtime.op.Caster; import railo.runtime.type.Collection; import railo.runtime.type.Sizeable; import railo.runtime.type.Struct; public final class ClusterWrap extends ScopeSupport implements Cluster,Sizeable { private static final long serialVersionUID = -4952656252539755770L; private ClusterRemote core; private int offset; private ConfigServer configServer; public ClusterWrap(ConfigServer cs,ClusterRemote core) { this(cs,core,false); } private ClusterWrap(ConfigServer configServer,ClusterRemote core,boolean duplicate) { super(true, "cluster", Struct.TYPE_SYNC); this.configServer=configServer; if(duplicate) this.core=core.duplicate(); else this.core=core; this.core.init(configServer,this); } @Override public void init(ConfigServer configServer) { // for the custer wrap this method is not invoked, but it is part of the interface } @Override public Object get(Key key) throws PageException { return ((ClusterEntry)super.get(key)).getValue(); } @Override public Object get(Key key, Object defaultValue) { Object res = super.get(key,defaultValue); if(res instanceof ClusterEntry) return ((ClusterEntry)res).getValue(); return res; } @Override public Object remove(Key key) throws PageException { core.addEntry(new ClusterEntryImpl(key,null,offset)); return ((ClusterEntry)super.remove (key)).getValue(); } public Object removeEL(Key key) { core.addEntry(new ClusterEntryImpl(key,null,offset)); ClusterEntry entry = (ClusterEntry) super.removeEL (key); if(entry!=null) return entry.getValue(); return null; } @Override public Object setEL(Key key, Object value) { if(core.checkValue(value)) { ClusterEntry entry; core.addEntry(entry=new ClusterEntryImpl(key,(Serializable)value,offset)); super.setEL (key, entry); } return value; } public void setEntry(ClusterEntry newEntry) { ClusterEntry existingEntry=(ClusterEntry)super.get(newEntry.getKey(),null); // add if(existingEntry==null || existingEntry.getTime()<newEntry.getTime()) { if(newEntry.getValue()==null)removeEL (newEntry.getKey()); else { core.addEntry(newEntry); super.setEL (newEntry.getKey(), newEntry); } } } @Override public Object set(Key key, Object value) throws PageException { if(!core.checkValue(value)) throw new ExpressionException("object from type ["+Caster.toTypeName(value)+"] are not allowed in cluster scope" ); ClusterEntry entry; core.addEntry(entry=new ClusterEntryImpl(key,(Serializable)value,offset)); super.setEL (key, entry); return value; } @Override public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) { return super.toDumpData(pageContext, maxlevel,dp); } @Override public int getType() { return SCOPE_CLUSTER; } @Override public String getTypeAsString() { return "cluster"; } @Override public Collection duplicate(boolean deepCopy) { return new ClusterWrap(configServer,core,true); } @Override public void broadcast() { core.broadcastEntries(); } @Override public long sizeOf() { return 0; } }