incubator-wadi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdud...@apache.org
Subject svn commit: r356933 [13/35] - in /incubator/wadi/trunk: ./ etc/ modules/ modules/assembly/ modules/assembly/src/ modules/assembly/src/bin/ modules/assembly/src/conf/ modules/assembly/src/main/ modules/assembly/src/main/assembly/ modules/core/ modules/c...
Date Wed, 14 Dec 2005 23:36:16 GMT
Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleContextualiserStack.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleContextualiserStack.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleContextualiserStack.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleContextualiserStack.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,186 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+//Thoughts -
+
+//invalidation is tricky - stuff invalidated on disc needs may need to be unmarshalled so that the correct listeners may be notified...
+
+//we need a JDBC passivation store
+
+//can we even store an invalidated session without breaking listener model - consider...
+
+import java.io.File;
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.Collapser;
+import org.codehaus.wadi.ContextPool;
+import org.codehaus.wadi.Contextualiser;
+import org.codehaus.wadi.ContextualiserConfig;
+import org.codehaus.wadi.Emoter;
+import org.codehaus.wadi.Evictable;
+import org.codehaus.wadi.Evicter;
+import org.codehaus.wadi.Immoter;
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.InvocationException;
+import org.codehaus.wadi.Motable;
+import org.codehaus.wadi.PoolableInvocationWrapperPool;
+import org.codehaus.wadi.Relocater;
+import org.codehaus.wadi.Streamer;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
+import EDU.oswego.cs.dl.util.concurrent.Sync;
+
+public class SimpleContextualiserStack implements Contextualiser {
+	
+	protected final Log _log = LogFactory.getLog(getClass());
+	
+	protected final Streamer _streamer;
+	protected final Collapser _collapser;
+	
+	protected final DummyContextualiser _dummy;
+	
+	protected final DataSource _databaseDataSource;
+	protected final String _databaseTable;
+	protected Evicter _databaseEvicter;
+	protected final SharedStoreContextualiser _database;
+	
+	protected final Relocater _clusterRelocater;
+	protected final ClusterContextualiser _cluster;
+	
+	protected final Pattern _statelessMethods;
+	protected final boolean _statelessMethodFlag;
+	protected final Pattern _statelessURIs;
+	protected final boolean _statelessURIFlag;
+	protected final StatelessContextualiser _stateless;
+	
+	protected final File _discDirectory;
+	protected final Evicter _discEvicter;
+	protected final Map _discMap;
+	protected final ExclusiveStoreContextualiser _disc;
+	
+	protected final SerialContextualiser _serial;
+	
+	protected final ContextPool _memoryPool;
+	protected final PoolableInvocationWrapperPool _requestPool;
+	protected final Evicter _memoryEvicter;
+	protected final Map _memoryMap;
+	protected final MemoryContextualiser _memory;
+	
+	public SimpleContextualiserStack(Map sessionMap, ContextPool pool, DataSource dataSource, Relocater relocater) throws Exception {
+		super();
+		_streamer=new SimpleStreamer();
+		_collapser=new DebugCollapser();
+		//_collapser=new HashingCollapser(1000, 6000);
+		
+		_dummy=new DummyContextualiser();
+		_databaseDataSource=dataSource;
+		_databaseTable="WADI";
+		//DatabaseMotable.init(_databaseDataSource, _databaseTable);
+		_database=new SharedStoreContextualiser(_dummy, _collapser, true, new DatabaseStore("test", _databaseDataSource, _databaseTable, false, false, false));
+		InetAddress localhost=InetAddress.getLocalHost();
+		System.out.println("LOCALHOST: "+localhost);
+		_clusterRelocater=relocater;
+		_cluster=new ClusterContextualiser(_database, _collapser, _clusterRelocater);
+		
+		_statelessMethods=Pattern.compile("GET|POST", Pattern.CASE_INSENSITIVE);
+		_statelessMethodFlag=true;
+		_statelessURIs=Pattern.compile(".*\\.(JPG|JPEG|GIF|PNG|ICO|HTML|HTM)(|;jsessionid=.*)", Pattern.CASE_INSENSITIVE);
+		_statelessURIFlag=false;
+		_stateless=new StatelessContextualiser(_cluster, _statelessMethods, _statelessMethodFlag, _statelessURIs, _statelessURIFlag);
+		
+		File dir=new File(new File(System.getProperty("java.io.tmpdir")), "sessions");
+		dir.delete();
+		dir.mkdir();
+		_discDirectory=dir;
+		// TODO - consider eviction on disc, indexing by ttl would be efficient enough...
+		_discEvicter=new NeverEvicter(20, true); // sessions never pass below this point, unless the node is shutdown
+		_discMap=new ConcurrentHashMap();
+		_disc=new ExclusiveStoreContextualiser(_stateless, _collapser, true, _discEvicter, _discMap, _streamer, _discDirectory);
+		
+		
+		_memoryPool=pool;
+		_memoryEvicter=new AbsoluteEvicter(10, true, 10); // if a session is inactive for 10 secs, it moves to disc
+		_memoryMap=sessionMap;
+		_serial=new SerialContextualiser(_disc, _collapser, _memoryMap);
+		_requestPool=new DummyStatefulHttpServletRequestWrapperPool(); // TODO - use a ThreadLocal based Pool
+		_memory=new MemoryContextualiser(_serial, _memoryEvicter, _memoryMap, _streamer, _memoryPool, _requestPool);
+		
+		// ready to rock !
+	}
+	
+	public boolean contextualise(InvocationContext invocationContext, String id, Immoter immoter, Sync motionLock, boolean exclusiveOnly) throws InvocationException {
+		return _memory.contextualise(invocationContext, id, immoter, motionLock, exclusiveOnly);
+	}
+	
+	public Evicter getEvicter() {
+		return _memory.getEvicter();
+	}
+	
+	public boolean isExclusive() {
+		return _memory.isExclusive();
+	}
+	
+	public Immoter getDemoter(String name, Motable motable) {
+		return _memory.getDemoter(name, motable);
+	}
+	
+	public Immoter getSharedDemoter() {
+		return _memory.getSharedDemoter();
+	}
+	
+	public void init(ContextualiserConfig config) {
+		_memory.init(config);
+	}
+	
+	public void start() throws Exception {
+		_memory.start();
+	}
+	
+	public void stop() throws Exception {
+		_memory.stop();
+	}
+	
+	public void destroy() {
+		_memory.destroy();
+	}
+	
+	public void promoteToExclusive(Immoter immoter){_memory.promoteToExclusive(immoter);}
+	public void load(Emoter emoter, Immoter immoter) {_memory.load(emoter, immoter);}
+	
+	public void setLastAccessedTime(Evictable evictable, long oldTime, long newTime){_memory.setLastAccessedTime(evictable, oldTime, newTime);}
+	public void setMaxInactiveInterval(Evictable evictable, int oldInterval, int newInterval) {_memory.setMaxInactiveInterval(evictable, oldInterval, newInterval);}
+	
+	public Contextualiser getTop() {return _memory;}
+	
+	public void findRelevantSessionNames(int numPartitions, Collection[] resultSet) {
+		_log.info("findRelevantSessionNames");
+		_memory.findRelevantSessionNames(numPartitions, resultSet);
+	}
+	
+	public int getLocalSessionCount() {
+		return _memory.getLocalSessionCount();
+	}
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleEvictable.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleEvictable.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleEvictable.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleEvictable.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,89 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+
+import org.codehaus.wadi.Evictable;
+
+/**
+ * A very Simple impementation of Evictable
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.2 $
+ */
+
+public abstract class SimpleEvictable implements Evictable, Serializable {
+
+    public void init(long creationTime, long lastAccessedTime, int maxInactiveInterval) {
+        _creationTime=creationTime;
+        _lastAccessedTime=lastAccessedTime;
+        _maxInactiveInterval=maxInactiveInterval;
+    }
+    
+    public void destroy() throws Exception {
+        _creationTime=0;
+        _lastAccessedTime=0;
+        _maxInactiveInterval=0;
+    }
+    
+    public void copy(Evictable evictable) throws Exception {
+        _creationTime=evictable.getCreationTime();
+        _lastAccessedTime=evictable.getLastAccessedTime();
+        _maxInactiveInterval=evictable.getMaxInactiveInterval();
+    }
+    
+    public void mote(Evictable recipient) throws Exception {
+    	recipient.copy(this);
+    	destroy();
+    }
+     
+    public void readContent(ObjectInput oi) throws IOException, ClassNotFoundException {
+        _creationTime=oi.readLong();
+        _lastAccessedTime=oi.readLong();
+        _maxInactiveInterval=oi.readInt();
+    }
+    
+    public void writeContent(ObjectOutput oo) throws IOException {
+        oo.writeLong(_creationTime);
+        oo.writeLong(_lastAccessedTime);
+        oo.writeInt(_maxInactiveInterval);
+    }
+    
+    protected long _creationTime;
+	public long getCreationTime() {return _creationTime;}
+
+	protected long _lastAccessedTime;
+	public long getLastAccessedTime(){return _lastAccessedTime;}
+	public void setLastAccessedTime(long lastAccessedTime){_lastAccessedTime=lastAccessedTime;}
+
+	protected int _maxInactiveInterval;
+	public int  getMaxInactiveInterval(){return _maxInactiveInterval;}
+	public void setMaxInactiveInterval(int maxInactiveInterval){_maxInactiveInterval=maxInactiveInterval;}
+    
+    public boolean isNew(){return _lastAccessedTime==_creationTime;} // assumes lastAccessedTime is only updated once per request...
+    
+	public boolean checkTimeframe(long time) {return !(_creationTime>time || _lastAccessedTime>time);}
+	
+	public long getTimeToLive(long time) {return _maxInactiveInterval<0?Long.MAX_VALUE:(_maxInactiveInterval*1000)-(time-_lastAccessedTime);}
+
+	public boolean getTimedOut(long time) {return getTimeToLive(time)<=0;}
+	
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleLog.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleLog.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleLog.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleLog.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.codehaus.wadi.impl;
+
+/**
+ * This class is NOT for production use. It is useful for debugging
+ * race conditions.
+ *
+ * @author <a href="mailto:jules@coredevelopers.net"></a>
+ * @version $Revision: 1.1 $
+ */
+public class
+  SimpleLog
+  extends org.apache.commons.logging.impl.SimpleLog
+{
+  public SimpleLog(String name){super(name);}
+
+  protected void
+    log(int type, Object message, Throwable t)
+  {
+    synchronized (System.err)	// yeugh !
+    {
+      System.err.print("{"+Thread.currentThread().getName()+"} "); // yeugh !
+      super.log(type, message, t);
+    }
+  }
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleMotable.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleMotable.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleMotable.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleMotable.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,65 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+
+import org.codehaus.wadi.Motable;
+
+/**
+ * A very Simple implementation of Motable, with the Bytes field represented as a byte[]
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.2 $
+ */
+
+public class SimpleMotable extends AbstractMotable implements Serializable {
+
+	protected byte[] _bytes;
+	public byte[] getBodyAsByteArray() {return _bytes;}
+	public void setBodyAsByteArray(byte[] bytes){_bytes=bytes;}
+    
+    public ByteBuffer getBodyAsByteBuffer() throws Exception {throw new UnsupportedOperationException();}
+    public void setBodyAsByteBuffer(ByteBuffer body) throws Exception {throw new UnsupportedOperationException();}
+
+    public boolean equals(Object object) {
+        if (this==object)
+            return true;
+        if (!(object instanceof Motable))
+            return false;
+        try {
+            Motable motable = (Motable) object;
+            byte[] bytes=motable.getBodyAsByteArray();
+            int l=_bytes.length;
+            if (l!=bytes.length)
+                return false;
+            else {
+                for (int i=0; i<l; i++)
+                    if (_bytes[i]!=bytes[i])
+                        return false;
+                return true;
+            }
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            return false;
+        }
+    }
+}
+
+

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimplePartitionMapper.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimplePartitionMapper.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimplePartitionMapper.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimplePartitionMapper.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,35 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import org.codehaus.wadi.gridstate.PartitionMapper;
+
+public class SimplePartitionMapper implements PartitionMapper {
+
+	protected final int _numPartitions;
+	
+	public SimplePartitionMapper(int numPartitions) {
+		super();
+		_numPartitions=numPartitions;
+		// TODO Auto-generated constructor stub
+	}
+
+	public int map(Object key) {
+		return Math.abs(key.hashCode()%_numPartitions);
+	}
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleSessionPool.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleSessionPool.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleSessionPool.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleSessionPool.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,52 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Session;
+import org.codehaus.wadi.SessionConfig;
+import org.codehaus.wadi.SessionFactory;
+import org.codehaus.wadi.SessionPool;
+
+public class SimpleSessionPool implements SessionPool {
+
+    protected final SessionFactory _factory;
+    protected SessionConfig _config;
+    
+    public SimpleSessionPool(SessionFactory factory) {
+        super();
+        _factory=factory;
+    }
+    
+    public void init(SessionConfig config) {
+        assert _config==null : "already initialised";
+        _config=config;
+    }
+    
+    public void destroy() {
+        assert _config!=null : "not yet initialised";
+        _config=null;
+    }
+    
+    public Session take() {
+        return _factory.create(_config);
+    }
+
+    public void put(Session session) {
+        // just drop the session - truly pool later
+    }
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleStreamer.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleStreamer.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleStreamer.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleStreamer.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,65 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.codehaus.wadi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+
+import org.codehaus.wadi.Streamer;
+import org.codehaus.wadi.StreamerConfig;
+
+/**
+ * Don't do anything extra, just connect streams up directly.
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.3 $
+ */
+public class SimpleStreamer implements Streamer {
+    
+	protected StreamerConfig _config;
+	
+	public SimpleStreamer() {
+		// empty
+	}
+	
+	public void init(StreamerConfig config) {
+		_config=config;
+	}
+	
+	public ObjectInput getInputStream(InputStream is) throws IOException {
+        return new ObjectInputStream(is, _config.getClassLoader());
+    }
+    
+    public ObjectOutput getOutputStream(OutputStream os) throws IOException {
+        return new ObjectOutputStream(os);
+    }
+    
+    public String getSuffix() {
+        return "ser";
+    }
+    
+    public String getSuffixWithDot() {
+        return ".ser";
+    }
+    
+}
+

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleValuePool.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleValuePool.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleValuePool.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SimpleValuePool.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,45 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Value;
+import org.codehaus.wadi.ValueConfig;
+import org.codehaus.wadi.ValueFactory;
+import org.codehaus.wadi.ValuePool;
+
+/**
+ * TODO - JavaDoc this type
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class SimpleValuePool implements ValuePool {
+    
+    protected final ValueFactory _factory;
+    
+    public SimpleValuePool(ValueFactory factory) {_factory=factory;}
+
+    public Value take(ValueConfig config) {
+        return _factory.create(config);
+    }
+
+    public void put(Value attribute) {
+        // just drop the Attribute - no pooling...
+    }
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SleepingReplicater.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SleepingReplicater.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SleepingReplicater.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SleepingReplicater.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,57 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Replicater;
+
+public class SleepingReplicater implements Replicater {
+
+	protected final long _delay;
+
+	public SleepingReplicater(long delay) {
+		_delay=delay;
+	}
+
+	public boolean getReusingStore() {
+		return false;
+	}
+
+	public void create(Object tmp) {
+		try {
+			Thread.sleep(_delay);
+		} catch (InterruptedException e) {
+			// do nothing
+		}
+	}
+
+	public void update(Object tmp) {
+		try {
+			Thread.sleep(_delay);
+		} catch (InterruptedException e) {
+			// do nothing
+		}
+	}
+
+	public void destroy(Object tmp) {
+		try {
+			Thread.sleep(_delay);
+		} catch (InterruptedException e) {
+			// do nothing
+		}
+	}
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SleepingReplicaterFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SleepingReplicaterFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SleepingReplicaterFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SleepingReplicaterFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,25 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+public class SleepingReplicaterFactory extends StatelessReplicaterFactory {
+
+	public SleepingReplicaterFactory(long delay) {
+		super(new SleepingReplicater(delay));
+	}
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SpringManagerFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SpringManagerFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SpringManagerFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/SpringManagerFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,87 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.SessionFactory;
+import org.codehaus.wadi.SessionWrapperFactory;
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.InputStreamResource;
+
+public class SpringManagerFactory {
+  protected final static Log _log = LogFactory
+      .getLog(SpringManagerFactory.class);
+  protected final InputStream _descriptor;
+  protected final String _beanName;
+  protected final SessionFactory _sessionFactory;
+  protected final SessionWrapperFactory _sessionWrapperFactory;
+
+  public SpringManagerFactory(InputStream descriptor, String beanName,
+      SessionFactory sessionFactory, SessionWrapperFactory sessionWrapperFactory) {
+    _descriptor = descriptor;
+    _beanName = beanName;
+    _sessionFactory = sessionFactory;
+    _sessionWrapperFactory = sessionWrapperFactory;
+  }
+
+  public StandardManager create() throws FileNotFoundException {
+    return create(_descriptor, _beanName, _sessionFactory,
+        _sessionWrapperFactory);
+  }
+
+  public static StandardManager create(InputStream descriptor, String beanName,
+      SessionFactory sessionFactory, SessionWrapperFactory sessionWrapperFactory)
+      throws FileNotFoundException {
+    DefaultListableBeanFactory dlbf = new DefaultListableBeanFactory();
+    String wadiPropsName = System.getProperty("wadi.properties");
+    FileSystemResource props = null;
+    if ((wadiPropsName != null) && (!"".equals(wadiPropsName.trim()))) {
+      props = new FileSystemResource(new File(wadiPropsName.trim()));
+    }
+    PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
+    if ((props != null) && props.exists())
+      cfg.setLocation(props);
+    else
+      _log.info("properties file " + wadiPropsName + " does not exist");
+    _log.info("java.io.tmpdir=" + System.getProperty("java.io.tmpdir"));
+    new XmlBeanDefinitionReader(dlbf)
+        .loadBeanDefinitions(new InputStreamResource(descriptor));
+    cfg
+        .setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_FALLBACK);
+    cfg.postProcessBeanFactory(dlbf);
+    dlbf.registerSingleton("SessionFactory", sessionFactory);
+    dlbf.registerSingleton("SessionWrapperFactory", sessionWrapperFactory);
+    // dlbf.getBean("exporter");
+    // dlbf.getBean("serverConnector");
+    dlbf.preInstantiateSingletons();
+    StandardManager manager = (StandardManager) dlbf.getBean(beanName);
+    if (manager == null)
+      if (_log.isErrorEnabled())
+        _log.error("could not find WADI Manager bean: " + beanName);
+      else if (_log.isInfoEnabled())
+        _log.info("loaded bean: " + beanName + " from WADI descriptor: "
+            + descriptor);
+    return manager;
+  }
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardAttributes.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardAttributes.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardAttributes.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardAttributes.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,81 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.codehaus.wadi.Attributes;
+import org.codehaus.wadi.AttributesConfig;
+import org.codehaus.wadi.Value;
+import org.codehaus.wadi.ValueConfig;
+
+public class StandardAttributes implements Attributes, ValueConfig {
+
+    protected final Map _map;
+    protected final AttributesConfig _config;
+    
+    public StandardAttributes(AttributesConfig config, Map map) {
+        super();
+        _map=map; // could be inherited ?
+        _config=config;
+    }
+
+    public Object get(Object key) {
+        Value a=(Value)_map.get(key);
+        if (a==null){
+            return null;
+        } else {
+            return a.getValue();
+        }
+    }
+
+    public Object remove(Object key) {
+        Value a=(Value)_map.remove(key);
+        if (a==null) {
+            return null;
+        } else {
+            Object tmp=a.getValue();
+            a.setValue(null);
+            _config.getValuePool().put(a);
+            return tmp;
+        }
+    }
+
+    public Object put(Object key, Object newValue) {
+        Value in=_config.getValuePool().take(this);
+        in.setValue(newValue);
+        Value out=(Value)_map.put(key, in);
+        if (out==null) {
+            return null;
+        } else {
+            Object tmp=out.getValue();
+            out.setValue(null);
+            _config.getValuePool().put(out);
+            return tmp;
+        }
+    }
+
+    public int size() {return _map.size();}
+    public Set keySet() {return _map.keySet();}
+
+    public void clear() {
+        // should we null-out all Attributes - TODO
+        _map.clear();
+    }
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardAttributesFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardAttributesFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardAttributesFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardAttributesFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,31 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import java.util.HashMap;
+
+import org.codehaus.wadi.Attributes;
+import org.codehaus.wadi.AttributesConfig;
+import org.codehaus.wadi.AttributesFactory;
+
+public class StandardAttributesFactory implements AttributesFactory {
+
+    public Attributes create(AttributesConfig config) {
+        return new StandardAttributes(config, new HashMap());
+    }
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardHttpProxy.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardHttpProxy.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardHttpProxy.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardHttpProxy.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,334 @@
+/**
+*
+* Copyright 2003-2005 Core Developers Network Ltd.
+*
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*/
+//this started life as org.mortbay.servlet.ProxyServlet. I copied the
+//whole thing to use as a starting point - Thanks Greg !
+
+// ========================================================================
+// $Id: StandardHttpProxy.java,v 1.4 2005/12/05 11:43:32 jules Exp $
+// Copyright 2004-2004 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================================================================
+
+package org.codehaus.wadi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.ProtocolException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.IrrecoverableException;
+import org.codehaus.wadi.ProxyingException;
+import org.codehaus.wadi.RecoverableException;
+
+// My choice of proxy - still suboptimal - servlet spec imposes a very clumsy API
+// for copying the headers out of the HttpServletRequest (a proprietary solution
+// would be faster), but at least the Cookie headers can be copied straight across
+// (see CommonsHttpProxy where they cannot...).
+
+// This does not yet support e.g. WebDav methods like PROPFIND etc...
+
+/**
+ * HttpProxy implementation based on java.net.HttpURLConnection
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @author <a href="mailto:gregw@mortbay.com">Greg Wilkins</a>
+ * @version $Revision: 1.4 $
+ */
+public class StandardHttpProxy extends AbstractHttpProxy {
+	
+	protected static final Log _log=LogFactory.getLog(StandardHttpProxy.class);
+	
+	public StandardHttpProxy(String sessionPathParamKey) {
+		super(sessionPathParamKey);
+	}
+	
+	protected void doProxy(InetSocketAddress location, WebInvocationContext context) throws ProxyingException {
+		HttpServletRequest req = context.getHreq();
+		HttpServletResponse res = context.getHres();
+		
+		String uri=getRequestURI(req);
+		String qs=req.getQueryString();
+		if (qs!=null) {
+			uri=new StringBuffer(uri).append("?").append(qs).toString();
+		}
+		
+		URL url=null;
+		try {
+			url=new URL("http", location.getAddress().getHostAddress(), location.getPort(), uri);
+			if (_log.isTraceEnabled()) _log.trace("proxying to: "+url);
+		} catch (MalformedURLException e) {
+			if (_log.isWarnEnabled()) _log.warn("bad proxy url: "+url, e);
+			throw new IrrecoverableException("bad proxy url", e);
+		}
+		
+		long startTime=System.currentTimeMillis();
+		
+		HttpURLConnection huc=null;
+		String m=req.getMethod();
+		try {
+			huc=(HttpURLConnection)url.openConnection(); // IOException
+			huc.setRequestMethod(m); // ProtocolException
+		} catch (ProtocolException e) {
+			if (_log.isWarnEnabled()) _log.warn("unsupported http method: "+m, e);
+			throw new IrrecoverableException("unsupported HTTP method: "+m, e);
+		} catch (IOException e) {
+			if (_log.isWarnEnabled()) _log.warn("proxy IO problem", e);
+			throw new RecoverableException("could not open proxy connection", e);
+		}
+		
+		huc.setAllowUserInteraction(false);
+		huc.setInstanceFollowRedirects(false);
+		
+		// check connection header
+		// TODO - this might need some more time: see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+		String connectionHdr = req.getHeader("Connection"); // TODO - what if there are multiple values ?
+		if (connectionHdr != null) {
+			connectionHdr = connectionHdr.toLowerCase();
+			if (connectionHdr.equals("keep-alive")|| connectionHdr.equals("close"))
+				connectionHdr = null; // TODO  ??
+		}
+		
+		// copy headers - inefficient, but we are constrained by servlet API
+		{
+			for (Enumeration e=req.getHeaderNames(); e.hasMoreElements();) {
+				String hdr = (String) e.nextElement();
+				String lhdr = hdr.toLowerCase();
+				
+				if (_DontProxyHeaders.contains(lhdr))
+					continue;
+				if (connectionHdr != null && connectionHdr.indexOf(lhdr) >= 0) // what is going on here ?
+					continue;
+				// HTTP/1.1 proxies MUST parse the Connection header field before a message is forwarded and, for each connection-token in this field, remove any header field(s) from the message with the same name as the connection-token. Connection options are signaled by the presence of a connection-token in the Connection header field, not by any corresponding additional header field(s), since the additional header field may not be sent if there are no parameters associated with that connection option
+				if (_WADI_IsSecure.equals(hdr)) // don't worry about case - we should be the only one messing with this header...
+					continue; // strip this out - we may be being spoofed
+				
+				for (Enumeration f=req.getHeaders(hdr); f.hasMoreElements();) {
+					String val=(String)f.nextElement();
+					if (val!=null) {
+						huc.addRequestProperty(hdr, val);
+					}
+				}
+			}
+		}
+		
+		// content ?
+		boolean hasContent=false;
+		{
+			int contentLength=0;
+			String tmp=huc.getRequestProperty("Content-Length");
+			if (tmp!=null) {
+				try {
+					contentLength=Integer.parseInt(tmp);
+				} catch (NumberFormatException ignore) {
+					// ignore
+				}
+			}
+			
+			if (contentLength>0)
+				hasContent=true;
+			else
+				hasContent=(huc.getRequestProperty("Content-Type")!=null);
+		}
+		
+		// proxy
+		{
+			huc.addRequestProperty("Via", "1.1 "+req.getLocalName()+":"+req.getLocalPort()+" \"WADI\""); // TODO - should we be giving out personal details ?
+			huc.addRequestProperty("X-Forwarded-For", req.getRemoteAddr()); // adds last link in request chain...
+			// String tmp=uc.getRequestProperty("Max-Forwards"); // TODO - do we really need to bother with this ?
+		}
+		
+		// cache-control
+		{
+			String cacheControl=huc.getRequestProperty("Cache-Control");
+			if (cacheControl!=null && (cacheControl.indexOf("no-cache")>=0 || cacheControl.indexOf("no-store")>=0))
+				huc.setUseCaches(false);
+		}
+		
+		// confidentiality
+		{
+			if (req.isSecure()) {
+				huc.addRequestProperty(_WADI_IsSecure, req.getLocalAddr().toString());
+			}
+			
+			// at the other end, if this header is present we must :
+			
+			// wrap the request so that req.isSecure()=true, before processing...
+			// mask the header - so it is never seen by the app.
+			
+			// the code for the other end should live in this class.
+			
+			// this code should also confirm that it not being spoofed by confirming that req.getRemoteAddress() is a cluster member...
+		}
+		// customize Connection
+		huc.setDoInput(true);
+		
+		// client->server
+		int client2ServerTotal=0;
+		{
+			if (hasContent) {
+				huc.setDoOutput(true);
+				
+				OutputStream toServer=null;
+				try {
+					InputStream fromClient=req.getInputStream(); // IOException
+					toServer=huc.getOutputStream(); // IOException
+					client2ServerTotal=copy(fromClient, toServer, 8192);
+				} catch (IOException e) {
+					new IrrecoverableException("problem proxying client request to server", e);
+				} finally {
+					if (toServer!=null) {
+						try {
+							toServer.close(); // IOException
+						} catch (IOException e) {
+							_log.warn("problem closing server request stream", e);
+						}
+					}
+				}
+			}
+		}
+		
+		// Connect
+		try {
+			huc.connect(); // IOException
+		} catch (IOException e) {
+			if (_log.isWarnEnabled()) _log.warn("proxy connection problem: "+url, e);
+			throw new RecoverableException("could not connect to proxy target", e);
+		}
+		
+		InputStream fromServer=null;
+		
+		// handler status codes etc.
+		int code=0;
+		if (huc==null) {
+			try {
+				fromServer = huc.getInputStream(); // IOException
+			} catch (IOException e) {
+				if (_log.isWarnEnabled()) _log.warn("proxying problem", e);
+				throw new IrrecoverableException("problem acquiring client output", e);
+			}
+		} else {
+			code=502;
+			//			String message="Bad Gateway: could not read server response code or message";
+			try {
+				code=huc.getResponseCode(); // IOException
+				//				message=huc.getResponseMessage(); // IOException
+			} catch (IOException e) {
+				if (_log.isWarnEnabled()) _log.warn("proxying problem", e);
+				throw new IrrecoverableException("problem acquiring http server response code/message", e);
+			} finally {
+				//				res.setStatus(code, message); - deprecated
+				res.setStatus(code);
+			}
+			
+			if (code<400) {
+				// 1XX:continue, 2XX:successful, 3XX:multiple-choices...
+				try {
+					fromServer=huc.getInputStream(); // IOException
+				} catch (IOException e) {
+					if (_log.isWarnEnabled()) _log.warn("proxying problem", e);
+					throw new IrrecoverableException("problem acquiring http client output", e);
+				}
+			} else {
+				// 4XX:client, 5XX:server error...
+				fromServer = huc.getErrorStream(); // why does this not throw IOException ?
+				// TODO - do we need to use sendError()?
+			}
+		}
+		
+		// clear response defaults.
+		res.setHeader("Date", null);
+		res.setHeader("Server", null);
+		
+		// set response headers
+		if (false) {
+			int h = 0;
+			String hdr = huc.getHeaderFieldKey(h);
+			String val = huc.getHeaderField(h);
+			while (hdr != null || val != null) {
+				String lhdr = (hdr != null) ? hdr.toLowerCase() : null;
+				if (hdr != null && val != null && !_DontProxyHeaders.contains(lhdr))
+					res.addHeader(hdr, val);
+				
+				// if (_log.isDebugEnabled()) _log.debug("res " + hdr + ": " + val);
+				
+				h++;
+				hdr = huc.getHeaderFieldKey(h);
+				val = huc.getHeaderField(h);
+			}
+		} else {
+			// TODO - is it a bug in Jetty that I have to start my loop at 1 ? or that key[0]==null ?
+			// Try this inside Tomcat...
+			String key;
+			for (int i=1; (key=huc.getHeaderFieldKey(i))!=null; i++) {
+				key=key.toLowerCase();
+				String val=huc.getHeaderField(i);
+				if (val!=null && !_DontProxyHeaders.contains(key)) {
+					res.addHeader(key, val);
+				}
+			}
+		}
+		
+		// do we need another Via header in the response...
+		
+		// server->client
+		int server2ClientTotal=0;
+		{
+			if (fromServer!=null) {
+				try {
+					OutputStream toClient=res.getOutputStream();// IOException
+					server2ClientTotal+=copy(fromServer, toClient, 8192);// IOException
+				} catch (IOException e) {
+					if (_log.isWarnEnabled()) _log.warn("proxying problem", e);
+					throw new IrrecoverableException("problem proxying server response back to client", e);
+				} finally {
+					try {
+						fromServer.close();
+					} catch (IOException e) {
+						// well - we did our best...
+						_log.warn("problem closing server response stream", e);
+					}
+				}
+			}
+		}
+		
+		huc.disconnect();
+		
+		long endTime=System.currentTimeMillis();
+		long elapsed=endTime-startTime;
+		if (_log.isDebugEnabled()) _log.debug("in:"+client2ServerTotal+", out:"+server2ClientTotal+", status:"+code+", time:"+elapsed+", url:"+url);
+	}
+	
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardManager.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardManager.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardManager.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardManager.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,308 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Timer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.AttributesFactory;
+import org.codehaus.wadi.Contextualiser;
+import org.codehaus.wadi.ContextualiserConfig;
+import org.codehaus.wadi.Evictable;
+import org.codehaus.wadi.Immoter;
+import org.codehaus.wadi.Lifecycle;
+import org.codehaus.wadi.ManagerConfig;
+import org.codehaus.wadi.Motable;
+import org.codehaus.wadi.Router;
+import org.codehaus.wadi.RouterConfig;
+import org.codehaus.wadi.Session;
+import org.codehaus.wadi.SessionConfig;
+import org.codehaus.wadi.SessionIdFactory;
+import org.codehaus.wadi.SessionPool;
+import org.codehaus.wadi.SessionWrapperFactory;
+import org.codehaus.wadi.ValuePool;
+import org.codehaus.wadi.WADIHttpSession;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
+
+/**
+ * TODO - JavaDoc this type
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.12 $
+ */
+
+public class StandardManager implements Lifecycle, SessionConfig, ContextualiserConfig, RouterConfig {
+	
+	protected final Log _log = LogFactory.getLog(getClass());
+	
+	protected final SessionPool _sessionPool;
+	protected final AttributesFactory _attributesFactory;
+	protected final ValuePool _valuePool;
+	protected final SessionWrapperFactory _sessionWrapperFactory;
+	protected final SessionIdFactory _sessionIdFactory;
+	protected final Contextualiser _contextualiser;
+	protected final Map _map;
+	protected final Timer _timer;
+	protected final Router _router;
+	protected final boolean _errorIfSessionNotAcquired;
+	protected final SynchronizedBoolean _acceptingSessions=new SynchronizedBoolean(true);
+	
+	protected HttpSessionListener[] _sessionListeners;
+	protected HttpSessionAttributeListener[] _attributeListeners;
+	
+	public StandardManager(SessionPool sessionPool, AttributesFactory attributesFactory, ValuePool valuePool, SessionWrapperFactory sessionWrapperFactory, SessionIdFactory sessionIdFactory, Contextualiser contextualiser, Map map, Router router, boolean errorIfSessionNotAcquired) {
+		_sessionPool=sessionPool;
+		_attributesFactory=attributesFactory;
+		_valuePool=valuePool;
+		_sessionWrapperFactory=sessionWrapperFactory;
+		_sessionIdFactory=sessionIdFactory;
+		_contextualiser=contextualiser;
+		_map=map; // TODO - can we get this from Contextualiser
+		_timer=new Timer();
+		_router=router;
+		_errorIfSessionNotAcquired=errorIfSessionNotAcquired;
+	}
+	
+	protected ManagerConfig _config;
+	
+	public void init(ManagerConfig config) {
+		if (_sessionListeners==null)
+			_sessionListeners=new HttpSessionListener[]{};
+		if (_attributeListeners==null)
+			_attributeListeners=new HttpSessionAttributeListener[]{};
+		
+		_config=config;
+		_sessionPool.init(this);
+		_contextualiser.init(this);
+		_router.init(this);
+	}
+	
+	protected boolean _started;
+	
+	public boolean isStarted() {
+		return _started;
+	}
+	
+	public void start() throws Exception {
+		_log.info("starting");
+		
+		_contextualiser.promoteToExclusive(null);
+		_contextualiser.start();
+		ServletContext context=getServletContext();
+		if (context==null) {
+			_log.warn("null ServletContext");
+		} else {
+			context.setAttribute(StandardManager.class.getName(), this); // TODO - security risk ?
+		}
+		_started=true;
+	}
+	
+	public void aboutToStop() throws Exception {
+		// do nothing
+	}
+	
+	public void stop() throws Exception {
+		_started=false;
+		_acceptingSessions.set(false);
+		// if we are clustered, partitions must be evacuated before sessions - hack
+		aboutToStop();
+		_contextualiser.stop();
+		_log.info("stopped"); // although this sometimes does not appear, it IS called...
+	}
+	
+	protected void notifySessionCreation(Session session) {
+		WADIHttpSession httpSession = ensureTypeAndCast(session);
+		int l=_sessionListeners.length;
+		HttpSessionEvent hse=httpSession.getHttpSessionEvent();
+		for (int i=0; i<l; i++)
+			_sessionListeners[i].sessionCreated(hse);
+	}
+	
+	protected void notifySessionDestruction(Session session) {
+		WADIHttpSession httpSession = ensureTypeAndCast(session);
+		int l=_sessionListeners.length;
+		HttpSessionEvent hse=httpSession.getHttpSessionEvent();
+		for (int i=0; i<l; i++)
+			_sessionListeners[i].sessionDestroyed(hse); // actually - about-to-be-destroyed - hasn't happened yet - see SRV.15.1.14.1
+	}
+	
+	private WADIHttpSession ensureTypeAndCast(Session session) {
+		if (false == session instanceof WADIHttpSession) {
+			throw new IllegalArgumentException(WADIHttpSession.class +
+			" instance is expected.");
+		}
+		WADIHttpSession httpSession = (WADIHttpSession) session;
+		return httpSession;
+	}
+	
+	public void destroy() {
+		_router.destroy();
+		_contextualiser.destroy();
+		_sessionPool.destroy();
+	}
+	
+	protected boolean validateSessionName(String name) {
+		return true;
+	}
+	
+	public Session create() {
+		String name=null;
+		do {
+			name=_sessionIdFactory.create(); // TODO - API on this class is wrong...
+		} while (!validateSessionName(name));
+		
+		Session session=_sessionPool.take();
+		long time=System.currentTimeMillis();
+		session.init(time, time, _maxInactiveInterval, name);
+		_map.put(name, session);
+		notifySessionInsertion(name);
+		notifySessionCreation(session);
+		// TODO - somehow notify Evicter
+		// _contextualiser.getEvicter().insert(session);
+		if (_log.isDebugEnabled()) _log.debug("creation: "+name);
+		return session;
+	}
+	
+	public void destroy(Session session) {
+		for (Iterator i=new ArrayList(session.getAttributeNameSet()).iterator(); i.hasNext();) // ALLOC ?
+			session.removeAttribute((String)i.next()); // TODO - very inefficient
+		// _contextualiser.getEvicter().remove(session);
+		// TODO - somehow notify Evicter
+		String name=session.getName();
+		notifySessionDeletion(name);
+		notifySessionDestruction(session);
+		_map.remove(name);
+		try {
+			session.destroy();
+		} catch (Exception e) {
+			_log.warn("unexpected problem destroying session", e);
+		}
+		_sessionPool.put(session);
+		if (_log.isDebugEnabled()) _log.debug("destruction: "+name);
+	}
+	
+	//----------------------------------------
+	// Listeners
+	
+	public HttpSessionListener[] getSessionListeners() {
+		return _sessionListeners;
+	}
+	
+	public void setSessionListeners(HttpSessionListener[] sessionListeners) {
+		_sessionListeners=sessionListeners;
+	}
+	
+	public HttpSessionAttributeListener[] getAttributeListeners() {
+		return _attributeListeners;
+	}
+	
+	public void setAttributelisteners(HttpSessionAttributeListener[] attributeListeners) {
+		_attributeListeners=attributeListeners;
+	}
+	
+	// Context stuff
+	public ServletContext getServletContext() {return _config.getServletContext();}
+	
+	public AttributesFactory getAttributesFactory() {return _attributesFactory;}
+	public ValuePool getValuePool() {return _valuePool;}
+	
+	public StandardManager getManager(){return this;}
+	
+	// this should really be abstract, but is useful for testing - TODO
+	
+	public SessionWrapperFactory getSessionWrapperFactory() {return _sessionWrapperFactory;}
+	
+	public SessionIdFactory getSessionIdFactory() {return _sessionIdFactory;}
+	
+	protected int _maxInactiveInterval=30*60; // 30 mins
+	public int getMaxInactiveInterval(){return _maxInactiveInterval;}
+	public void setMaxInactiveInterval(int interval){_maxInactiveInterval=interval;}
+	
+	// integrate with Filter instance
+	protected Filter _filter;
+	
+	public void setFilter(Filter filter) {
+		_filter=filter;
+		_config.callback(this);
+	}
+	
+	public boolean getDistributable(){return false;}
+	
+	public Contextualiser getContextualiser() {return _contextualiser;}
+	
+	public void setLastAccessedTime(Evictable evictable, long oldTime, long newTime) {_contextualiser.setLastAccessedTime(evictable, oldTime, newTime);}
+	public void setMaxInactiveInterval(Evictable evictable, int oldInterval, int newInterval) {_contextualiser.setMaxInactiveInterval(evictable, oldInterval, newInterval);}
+	
+	public void expire(Motable motable) {
+		destroy((Session)motable);
+	}
+	
+	public Immoter getEvictionImmoter() {
+		return ((AbstractExclusiveContextualiser)_contextualiser).getImmoter();
+	} // HACK - FIXME
+	
+	public Timer getTimer() {return _timer;}
+	
+	public SessionPool getSessionPool() {return _sessionPool;}
+	
+	public Router getRouter() {return _router;}
+	
+	// Container integration... - override if a particular Container can do better... 
+	
+	public int getHttpPort(){return Integer.parseInt(System.getProperty("http.port"));} // TODO - temporary hack...
+	
+	public String getSessionCookieName()  {return "JSESSIONID";}
+	
+	public String getSessionCookiePath(HttpServletRequest req){return req.getContextPath();}
+	
+	public String getSessionCookieDomain(){return null;}
+	
+	public String getSessionUrlParamName(){return "jsessionid";}
+	
+	public boolean getErrorIfSessionNotAcquired() {return _errorIfSessionNotAcquired;}
+	
+	protected SynchronizedInt _errorCounter=new SynchronizedInt(0);
+	
+	public void incrementErrorCounter() {_errorCounter.increment();}
+	
+	public int getErrorCount() {return _errorCounter.get();}
+	
+	public SynchronizedBoolean getAcceptingSessions() {return _acceptingSessions;}
+	
+	public void notifySessionInsertion(String name) {
+	}
+	
+	public void notifySessionDeletion(String name) {
+	}
+	
+	// called on new host...
+	public void notifySessionRelocation(String name) {
+	}
+	
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSession.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSession.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSession.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSession.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,212 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Set;
+
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionEvent;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.Attributes;
+import org.codehaus.wadi.AttributesConfig;
+import org.codehaus.wadi.SessionConfig;
+import org.codehaus.wadi.ValuePool;
+import org.codehaus.wadi.WADIHttpSession;
+
+/**
+ * Our internal representation of any Web Session
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.4 $
+ */
+
+public class StandardSession extends AbstractContext implements WADIHttpSession, AttributesConfig {
+	
+	protected final static Log _log = LogFactory.getLog(StandardSession.class);
+	protected final SessionConfig _config;
+	protected final Attributes _attributes;
+	protected final HttpSession _wrapper;
+	protected final HttpSessionEvent _httpSessionEvent;
+	
+	public StandardSession(SessionConfig config) {
+		super();
+		_config=config;
+		_attributes=_config.getAttributesFactory().create(this);
+		_wrapper=_config.getSessionWrapperFactory().create(this);
+		_httpSessionEvent=new HttpSessionEvent(_wrapper);
+		
+		// TODO - resolve different APIs used by Factories and Pools...
+	}
+	
+	public void destroy() throws Exception {
+		super.destroy();
+		_attributes.clear();
+		// NYI - other fields...
+	}
+	
+	public byte[] getBodyAsByteArray() throws Exception {
+		throw new NotSerializableException();
+	}
+	
+	public void setBodyAsByteArray(byte[] bytes) throws IOException, ClassNotFoundException {
+		throw new NotSerializableException();
+	}
+	
+	// public access to the contents of this session should all be directed via wrapper
+	public HttpSession getWrapper() {
+		return _wrapper;
+	}
+	
+	// cached events...
+	public HttpSessionEvent getHttpSessionEvent() {
+		return _httpSessionEvent;
+	}
+	
+	//public String getRealId() {return null;} // TODO - lose this method...
+	
+	// useful constants...
+	protected static final String[]    _emptyStringArray =new String[0];
+	protected static final Enumeration _emptyEnumeration =Collections.enumeration(Collections.EMPTY_LIST);
+	
+	// Attributes...
+	
+	// Setters
+	
+	public Object getAttribute(String name) {
+		if (null==name)
+			throw new IllegalArgumentException("HttpSession attribute names must be non-null (see SRV.15.1.7.1)");
+		
+		return _attributes.get(name);
+	}
+	
+	public Set getAttributeNameSet() {
+		return _attributes.keySet();
+	}
+	
+	public Enumeration getAttributeNameEnumeration() {
+		return _attributes.size()==0?_emptyEnumeration:Collections.enumeration(_attributes.keySet());
+	}
+	
+	public String[] getAttributeNameStringArray() {
+		return _attributes.size()==0?_emptyStringArray:(String[])_attributes.keySet().toArray(new String[_attributes.size()]);
+	}
+	
+	protected void notifyBindingListeners(String name, Object oldValue, Object newValue) {
+		if (null!=oldValue && oldValue instanceof HttpSessionBindingListener)
+			((HttpSessionBindingListener)oldValue).valueUnbound(new HttpSessionBindingEvent(_wrapper, name, oldValue));
+		if (newValue instanceof HttpSessionBindingListener)
+			((HttpSessionBindingListener)newValue).valueBound(new HttpSessionBindingEvent(_wrapper, name, newValue));
+	}
+	
+	protected void notifyAttributeListeners(String name, Object oldValue, Object newValue) {
+		boolean replaced=(oldValue!=null);
+		HttpSessionAttributeListener[] listeners=_config.getAttributeListeners();
+		
+		int l=listeners.length;
+		if (l>0) {
+			if (replaced) { // only test once, instead of inside the loop - results in duplicate code...
+				HttpSessionBindingEvent hsbe=new HttpSessionBindingEvent(_wrapper, name, oldValue);
+				for (int i=0; i<l; i++)
+					listeners[i].attributeReplaced(hsbe);
+			} else {
+				HttpSessionBindingEvent hsbe=new HttpSessionBindingEvent(_wrapper, name, newValue);
+				for (int i=0; i<l; i++)
+					listeners[i].attributeAdded(hsbe);
+			}
+		}
+	}
+	
+	public Object setAttribute(String name, Object newValue) {
+		if (null==name)
+			throw new IllegalArgumentException("HttpSession attribute names must be non-null (see SRV.15.1.7.1)");
+		
+		Object oldValue=_attributes.put(name, newValue);
+		
+		notifyBindingListeners(name, oldValue, newValue);
+		notifyAttributeListeners(name, oldValue, newValue);
+		
+		return oldValue;
+	}
+	
+	void notifyAttributeListeners(String name, Object oldValue) {
+		if (null!=oldValue) {
+			HttpSessionAttributeListener[] listeners=_config.getAttributeListeners();
+			int l=listeners.length;
+			if (l>0) {
+				HttpSessionBindingEvent hsbe=new HttpSessionBindingEvent(_wrapper, name, oldValue);
+				for (int i=0; i<l; i++)
+					listeners[i].attributeRemoved(hsbe);
+			}
+		}
+	}
+	
+	void notifyBindingListeners(String name, Object oldValue) {
+		if (null!=oldValue && oldValue instanceof HttpSessionBindingListener) {
+			((HttpSessionBindingListener)oldValue).valueUnbound(new HttpSessionBindingEvent(_wrapper, name, oldValue));
+		}
+	}
+	
+	public Object removeAttribute(String name) {
+		if (null==name)
+			throw new IllegalArgumentException("HttpSession attribute names must be non-null (see SRV.15.1.7.1)");
+		// we could remove the Map if num entries fell back to '0' -
+		// but we would probably be creating more work than saving
+		// memory..
+		Object oldValue=_attributes.remove(name);
+		
+		notifyBindingListeners(name, oldValue);
+		notifyAttributeListeners(name, oldValue);
+		
+		return oldValue;
+	}
+	
+	public SessionConfig getConfig() {
+		return _config;
+	}
+	
+	// AttributesConfig
+	
+	public ValuePool getValuePool(){
+		return _config.getValuePool();
+	}
+	
+	public void setLastAccessedTime(long newLastAccessedTime) {
+		long oldLastAccessedTime=_lastAccessedTime;
+		super.setLastAccessedTime(newLastAccessedTime);
+		_config.setLastAccessedTime(this, oldLastAccessedTime, newLastAccessedTime);
+	}
+	
+	public void setMaxInactiveInterval(int newMaxInactiveInterval) {
+		int oldMaxInactiveInterval=_maxInactiveInterval;
+		super.setMaxInactiveInterval(newMaxInactiveInterval);
+		_config.setMaxInactiveInterval(this, oldMaxInactiveInterval, newMaxInactiveInterval);
+	}
+	
+	public String getId() {
+		return _config.getRouter().augment(_name);
+	} // TODO - How can we cache this ?
+	
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSessionFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSessionFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSessionFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSessionFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,28 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Session;
+import org.codehaus.wadi.SessionConfig;
+import org.codehaus.wadi.SessionFactory;
+
+public class StandardSessionFactory implements SessionFactory {
+
+    public Session create(SessionConfig config) {
+        return new StandardSession(config);
+    }
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSessionWrapperFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSessionWrapperFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSessionWrapperFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardSessionWrapperFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,30 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import javax.servlet.http.HttpSession;
+
+import org.codehaus.wadi.Session;
+import org.codehaus.wadi.SessionWrapperFactory;
+
+public class StandardSessionWrapperFactory implements SessionWrapperFactory {
+
+    public HttpSession create(Session session) {
+    	return new SessionWrapper(session);
+    }
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardValue.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardValue.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardValue.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardValue.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,49 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Value;
+import org.codehaus.wadi.ValueConfig;
+
+/**
+ * A simple slot for holding and Attribute's value
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.2 $
+ */
+
+public class StandardValue implements Value {
+    
+    protected final ValueConfig _config;
+    
+    public StandardValue(ValueConfig config) {
+    	_config=config;
+    }
+    
+    protected Object _value;
+    
+    public Object getValue() {
+        return _value;
+    }
+    
+    public Object setValue(Object newValue) {
+        Object oldValue=_value;
+        _value=newValue;
+        return oldValue;
+    }	
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardValueFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardValueFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardValueFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StandardValueFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,40 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Value;
+import org.codehaus.wadi.ValueConfig;
+import org.codehaus.wadi.ValueFactory;
+
+/**
+ * TODO - JavaDoc this type
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class StandardValueFactory implements ValueFactory {
+
+    public StandardValueFactory() {
+        super();
+    }
+
+    public Value create(ValueConfig config) {
+        return new StandardValue(config);
+    }
+
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatefulHttpServletRequestWrapper.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatefulHttpServletRequestWrapper.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatefulHttpServletRequestWrapper.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatefulHttpServletRequestWrapper.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,63 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
+
+import org.codehaus.wadi.Context;
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.PoolableHttpServletRequestWrapper;
+import org.codehaus.wadi.WADIHttpSession;
+
+public class StatefulHttpServletRequestWrapper extends HttpServletRequestWrapper implements PoolableHttpServletRequestWrapper {
+	
+	protected static final HttpServletRequest _dummy=new DummyHttpServletRequest();
+	protected HttpSession _session; // I want to maintain a Session - but it's hard to get hold of it upon creation... - do we really need it ?
+	
+	
+	public StatefulHttpServletRequestWrapper() {
+		super(_dummy);
+	}
+	
+	public void init(InvocationContext invocationContext, Context context) {
+		HttpServletRequest request = ((WebInvocationContext) invocationContext).getHreq();
+		setRequest(request);
+		_session=context==null?null:((WADIHttpSession)context).getWrapper();
+	}
+	
+	public void destroy() {
+		setRequest(_dummy);
+		_session=null;
+	}
+	
+	// Session related method interceptions...
+	
+	public HttpSession getSession(){return getSession(true);}
+	
+	public HttpSession getSession(boolean create) {
+		// TODO - I'm assuming single threaded access to request objects...
+		// so no synchronization ?
+		
+		if (null==_session)
+			return (_session=((HttpServletRequest)getRequest()).getSession(create));
+		else
+			return _session;
+	}
+	
+}
\ No newline at end of file

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessContextualiser.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessContextualiser.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessContextualiser.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessContextualiser.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,135 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.wadi.Contextualiser;
+import org.codehaus.wadi.Immoter;
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.InvocationException;
+import org.codehaus.wadi.PoolableHttpServletRequestWrapper;
+
+import EDU.oswego.cs.dl.util.concurrent.Sync;
+
+//N.B.
+//Ultimately this should support pluggable and combinable 'Tests' - i.e. URIPatternTest
+//MethodPatternTest & AndTest...
+
+/**
+ * A Contextualiser that will intercept requests that can be shown to be stateless
+ * and run them in a generic stateless Context immediately, without the overhead of
+ * locating the (possibly remote) relevant Context.
+ *
+ * Logically, this Contextualiser should sit at the top of the stack, preventing
+ * unecessary cycles being spent locating state that will not actually be consumed
+ * by the incoming request. Actually, taking into account the expense of performing
+ * this check, vs. the expense of checking locally for the session, or locating a
+ * remote session, the sensible place to deploy this Contextualiser may be at the
+ * boundary between local and remote Contextualisers.
+ *
+ * If you are caching static content agressively you may not need this Contextualiser.
+ *
+ * @author <a href="mailto:jules@coredevelopers.net">Jules Gosnell</a>
+ * @version $Revision: 1.5 $
+ */
+public class StatelessContextualiser extends AbstractDelegatingContextualiser {
+
+	protected final Pattern _methods; // =Pattern.compile("GET|POST", Pattern.CASE_INSENSITIVE); // TODO - |HEAD|PUT|DELETE ?
+	protected final boolean _methodFlag; //true
+	protected final Pattern _uris; //=Pattern.compile(".*\\.(JPG|JPEG|GIF|PNG|ICO|HTML|HTM)", Pattern.CASE_INSENSITIVE); // TODO - CSS, ...?
+	protected final boolean _uriFlag; // false
+	protected final Log _lockLog=LogFactory.getLog("org.codehaus.wadi.LOCKS");
+
+	/**
+	 * @param next - The next Contextualiser in the stack
+	 * @param methods - Pattern used to match HTTP method names (null will match nothing)
+	 * @param methodFlag - Does this Pattern match stateful (true) or stateless (false) HTTP methods
+	 * @param uris - Pattern used to match URIs (null will match nothing)
+	 * @param uriFlag - Does this Pattern match stateful (true) or stateless (false) URIs
+	 */
+	public StatelessContextualiser(Contextualiser next, Pattern methods, boolean methodFlag, Pattern uris, boolean uriFlag) {
+		super(next);
+		_methods=methods;
+		_methodFlag=methodFlag;
+		_uris=uris;
+		_uriFlag=uriFlag;
+	}
+
+	public ThreadLocal _wrapper=new ThreadLocal(){
+		protected synchronized Object initialValue() {
+			return new StatelessHttpServletRequestWrapper();
+		}
+	};
+
+	public boolean contextualise(InvocationContext invocationContext, String id, Immoter immoter, Sync invocationLock, boolean exclusiveOnly) throws InvocationException {
+		WebInvocationContext context = (WebInvocationContext) invocationContext;
+		HttpServletRequest hreq = context.getHreq();
+		if (hreq==null || isStateful(hreq)) {
+			// we cannot optimise...
+			return _next.contextualise(invocationContext, id, immoter, invocationLock, exclusiveOnly);
+		} else {
+			// we know that we can run the request locally...
+			if (invocationLock!=null) {
+				Utils.release("Invocation", id, invocationLock);
+			}
+			// wrap the request so that session is inaccessible and process here...
+			PoolableHttpServletRequestWrapper wrapper=(PoolableHttpServletRequestWrapper)_wrapper.get();
+			wrapper.init(invocationContext, null);
+			try {
+				invocationContext.invoke(wrapper);
+			} finally {
+				wrapper.destroy();
+			}
+			return true;
+		}
+	}
+
+	/**
+	 * We know request is stateful - if, either Pattern matches
+	 * stateFULL requests AND match succeeded, or Pattern matches
+	 * stateLESS requests AND matched failed
+	 *
+	 * @param hreq
+	 * @return - whether, or not, the request must be assumed stateful
+	 */
+	public boolean isStateful(HttpServletRequest hreq) {
+		// TODO - should the order of matching be configurable ?
+		boolean matched;
+
+		// can we prove it is stateless ? - try first test...
+		if (_methods!=null) {
+			matched=(_methods.matcher(hreq.getMethod()).matches());
+			if (matched!=_methodFlag)
+				return false;
+		}
+
+		// could still be stateful - try second test...
+		if (_uris!=null) {
+			matched=(_uris.matcher(hreq.getRequestURI()).matches());
+			if (matched!=_uriFlag)
+				return false;
+		}
+
+		// we cannot eliminate the possibility that the request is stateful...
+		return true;
+	}
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessHttpServletRequestWrapper.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessHttpServletRequestWrapper.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessHttpServletRequestWrapper.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessHttpServletRequestWrapper.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,52 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
+
+import org.codehaus.wadi.Context;
+import org.codehaus.wadi.InvocationContext;
+import org.codehaus.wadi.PoolableHttpServletRequestWrapper;
+
+public class StatelessHttpServletRequestWrapper extends HttpServletRequestWrapper implements PoolableHttpServletRequestWrapper {
+	
+	protected static final HttpServletRequest DUMMY = new DummyHttpServletRequest();
+	
+	public StatelessHttpServletRequestWrapper() {
+		super(DUMMY);
+	}
+	
+	public StatelessHttpServletRequestWrapper(HttpServletRequest request) {super(request);}
+	
+	// These methods should never be called while contextualising a stateless request...
+	public HttpSession getSession(){return getSession(true);}
+	public HttpSession getSession(boolean create){throw new UnsupportedOperationException();}
+	
+	// TODO - consider session cookie related methods as well..
+	
+	public void init(InvocationContext invocationContext, Context context) {
+		HttpServletRequest request = ((WebInvocationContext) invocationContext).getHreq();
+		setRequest(request);
+	}
+	
+	public void destroy() {
+		setRequest(DUMMY);
+	}
+	
+}

Added: incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessReplicaterFactory.java
URL: http://svn.apache.org/viewcvs/incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessReplicaterFactory.java?rev=356933&view=auto
==============================================================================
--- incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessReplicaterFactory.java (added)
+++ incubator/wadi/trunk/modules/core/src/main/java/org/codehaus/wadi/impl/StatelessReplicaterFactory.java Wed Dec 14 15:32:56 2005
@@ -0,0 +1,34 @@
+/**
+ *
+ * Copyright 2003-2005 Core Developers Network Ltd.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.codehaus.wadi.impl;
+
+import org.codehaus.wadi.Replicater;
+import org.codehaus.wadi.ReplicaterFactory;
+
+public class StatelessReplicaterFactory implements ReplicaterFactory {
+
+	protected Replicater _replicater;
+
+	public StatelessReplicaterFactory(Replicater replicater) {
+		_replicater=replicater;
+	}
+
+	public Replicater create() {
+		return _replicater;
+	}
+
+}



Mime
View raw message