001    package railo.runtime.type.scope;
002    
003    import java.io.Serializable;
004    
005    import railo.commons.lang.SizeOf;
006    import railo.runtime.PageContext;
007    import railo.runtime.config.ConfigServer;
008    import railo.runtime.dump.DumpData;
009    import railo.runtime.dump.DumpProperties;
010    import railo.runtime.exp.ExpressionException;
011    import railo.runtime.exp.PageException;
012    import railo.runtime.op.Caster;
013    import railo.runtime.type.Collection;
014    import railo.runtime.type.KeyImpl;
015    import railo.runtime.type.Sizeable;
016    import railo.runtime.type.Struct;
017    
018    public final class ClusterWrap extends ScopeSupport implements Cluster,Sizeable {
019    
020            private ClusterRemote core;
021            private int offset;
022            private ConfigServer configServer;
023    
024            public ClusterWrap(ConfigServer cs,ClusterRemote core) {
025                    this(cs,core,false);
026            }
027            
028            private ClusterWrap(ConfigServer configServer,ClusterRemote core,boolean duplicate) {
029                    super(true, "cluster", Struct.TYPE_SYNC);
030                    this.configServer=configServer;
031                    if(duplicate) this.core=core.duplicate();
032                    else this.core=core;
033                    this.core.init(configServer,this);
034            }
035            
036            public void init(ConfigServer configServer) {
037                    // for the custer wrap this method is not invoked, but it is part of the interface
038            }
039    
040            /**
041             * @see railo.runtime.type.StructImpl#remove(java.lang.String)
042             */
043            public Object remove(String key) throws PageException {
044                    return remove(KeyImpl.init(key));
045            }
046    
047            
048            
049            /**
050             * @see railo.runtime.type.StructImpl#get(railo.runtime.type.Collection.Key)
051             */
052            public Object get(Key key) throws PageException {
053                    return ((ClusterEntry)super.get(key)).getValue();
054            }
055    
056            /**
057             * @see railo.runtime.type.StructImpl#get(railo.runtime.type.Collection.Key, java.lang.Object)
058             */
059            public Object get(Key key, Object defaultValue) {
060                    Object res = super.get(key,defaultValue);
061                    if(res instanceof ClusterEntry) return  ((ClusterEntry)res).getValue();
062                    return res;
063            }
064            
065            /**
066             * @see railo.runtime.type.StructImpl#remove(railo.runtime.type.Collection.Key)
067             */
068            public Object remove(Key key) throws PageException {
069                    core.addEntry(new ClusterEntryImpl(key,null,offset));
070                    return ((ClusterEntry)super.remove (key)).getValue();
071                    
072            }
073    
074            public Object removeEL(Key key) {
075                    core.addEntry(new ClusterEntryImpl(key,null,offset));
076                    ClusterEntry entry = (ClusterEntry) super.removeEL (key);
077                    if(entry!=null) return entry.getValue();
078                    return null;
079            }
080    
081            /**
082             * @see railo.runtime.type.StructImpl#setEL(railo.runtime.type.Collection.Key, java.lang.Object)
083             */
084            public Object setEL(Key key, Object value) {
085                    if(core.checkValue(value)) {
086                            ClusterEntry entry;
087                            core.addEntry(entry=new ClusterEntryImpl(key,(Serializable)value,offset));
088                            super.setEL (key, entry);
089                    }
090                    return value;
091            }
092    
093            public void setEntry(ClusterEntry newEntry) {
094                    ClusterEntry existingEntry=(ClusterEntry)super.get(newEntry.getKey(),null);
095                    // add
096                    if(existingEntry==null || existingEntry.getTime()<newEntry.getTime()) {
097                            if(newEntry.getValue()==null)removeEL (newEntry.getKey());
098                            else {
099                                    core.addEntry(newEntry);
100                                    super.setEL (newEntry.getKey(), newEntry);
101                            }
102                    }
103            }
104            
105            /**
106             * @see railo.runtime.type.StructImpl#set(railo.runtime.type.Collection.Key, java.lang.Object)
107             */
108            public Object set(Key key, Object value) throws PageException {
109                    if(!core.checkValue(value))
110                            throw new ExpressionException("object from type ["+Caster.toTypeName(value)+"] are not allowed in cluster scope" );
111                    ClusterEntry entry;
112                    core.addEntry(entry=new ClusterEntryImpl(key,(Serializable)value,offset));
113                    super.setEL (key, entry);
114                    return value;
115            }
116            
117            /**
118             *
119             * @see railo.runtime.type.scope.ScopeSupport#toDumpData(railo.runtime.PageContext, int)
120             */
121            public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
122                    return super.toDumpData(pageContext, maxlevel,dp);
123            }
124    
125            /**
126             *
127             * @see railo.runtime.type.scope.ScopeSupport#getType()
128             */
129            public int getType() {
130                    return SCOPE_CLUSTER;
131            } 
132    
133            /**
134             *
135             * @see railo.runtime.type.scope.ScopeSupport#getTypeAsString()
136             */
137            public String getTypeAsString() {
138                    return "cluster";
139            }
140            
141            /**
142             * @see railo.runtime.type.StructImpl#duplicate(boolean)
143             */
144            public Collection duplicate(boolean deepCopy) {
145                    return new ClusterWrap(configServer,core,true);
146            }
147    
148            /**
149             * @see railo.runtime.type.scope.Cluster#broadcast()
150             */
151            public void broadcast() {
152                    core.broadcastEntries();
153            }
154    
155            /**
156             * @see railo.runtime.type.Sizeable#sizeOf()
157             */
158            public long sizeOf() {
159                    return SizeOf.size(getMap());
160            }
161    }