You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by pp...@apache.org on 2007/12/18 23:08:01 UTC

svn commit: r605340 [1/2] - in /labs/fluid/slice: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/openjpa/ src/main/java/org/apache/openjpa/slice/ src/main/java/org/apache/openjpa/slice/jdbc/ src/t...

Author: ppoddar
Date: Tue Dec 18 14:07:57 2007
New Revision: 605340

URL: http://svn.apache.org/viewvc?rev=605340&view=rev
Log:
Checkin Slice codebase

Added:
    labs/fluid/slice/pom.xml
    labs/fluid/slice/src/
    labs/fluid/slice/src/main/
    labs/fluid/slice/src/main/java/
    labs/fluid/slice/src/main/java/org/
    labs/fluid/slice/src/main/java/org/apache/
    labs/fluid/slice/src/main/java/org/apache/openjpa/
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RandomDistributionPolicy.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RoundRobinDistributionPolicy.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
    labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedTemplate.java
    labs/fluid/slice/src/test/
    labs/fluid/slice/src/test/java/
    labs/fluid/slice/src/test/java/domain/
    labs/fluid/slice/src/test/java/domain/Address.java
    labs/fluid/slice/src/test/java/domain/PObject.java
    labs/fluid/slice/src/test/java/domain/Person.java
    labs/fluid/slice/src/test/java/org/
    labs/fluid/slice/src/test/java/org/apache/
    labs/fluid/slice/src/test/java/org/apache/openjpa/
    labs/fluid/slice/src/test/java/org/apache/openjpa/distributed/
    labs/fluid/slice/src/test/java/org/apache/openjpa/distributed/OddEvenDistributionPolicy.java
    labs/fluid/slice/src/test/java/org/apache/openjpa/distributed/TestConfiguration.java
    labs/fluid/slice/src/test/java/org/apache/openjpa/distributed/UserDistributionPolicy.java

Added: labs/fluid/slice/pom.xml
URL: http://svn.apache.org/viewvc/labs/fluid/slice/pom.xml?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/pom.xml (added)
+++ labs/fluid/slice/pom.xml Tue Dec 18 14:07:57 2007
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you 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.   
+-->
+<project 
+  xmlns="http://maven.apache.org/POM/4.0.0" 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
+                      http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.openjpa</groupId>
+  <artifactId>openjpa-slice</artifactId>
+  <packaging>jar</packaging>
+  <version>0.1.0-SNAPSHOT</version>
+  <name>Slice</name>
+  <description>Distributed Persistence Service using OpenJPA</description>
+  <url>http://people.apache.org/~ppoddar/slice/site/index.html</url>
+  <inceptionYear>2007</inceptionYear>
+   <developers>
+         <developer>
+            <name>Pinaki Poddar</name>
+            <id>ppoddar</id>
+            <organization>BEA Systems, Inc.</organization>
+            <email>ppoddar@bea.com</email>
+        </developer>
+  	</developers>
+    <contributors>
+  	</contributors>
+  	
+ 
+  	<scm>
+        <connection>scm:svn:http://${scm.dir}</connection>
+        <developerConnection>scm:svn:https://${scm.dir}</developerConnection>
+        <url>https://${scm.dir}</url>
+  	</scm>
+  	
+    <organization>
+        <name>Apache Software Labs</name>
+        <url>http://labs.apache.org</url>
+    </organization>
+  
+  
+  <properties>
+        <scm.dir>svn.apache.org/repos/asf/labs/fluid/slice</scm.dir>
+        <javadoc.output.dir>src/site/resources</javadoc.output.dir>
+        <maven.sdocbook.src.dir>src/site/docbook</maven.sdocbook.src.dir>
+  </properties>
+  
+  <repositories>
+        <repository>
+            <id>central</id>
+            <name>Maven Repository Switchboard</name>
+            <url>http://www.ibiblio.org/maven2</url>
+        </repository>
+        <repository>
+            <id>maven-central</id>
+            <name>Maven Plugin Repository</name>
+            <url>http://repo1.maven.org</url>
+        </repository>
+        <repository>
+            <id>apache-snapshots</id>
+            <url>http://people.apache.org/repo/m2-snapshot-repository</url>
+        </repository>
+        <repository>
+            <id>apache-incubator</id>
+            <url>http://people.apache.org/repo/m2-incubating-repository</url>
+        </repository>
+        <repository>
+            <id>serp-rep</id>
+            <url>http://serp.sourceforge.net/m2repo</url>
+        </repository>
+  </repositories>
+    
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.openjpa</groupId>
+      <artifactId>openjpa</artifactId>
+      <version>1.1.0-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    
+    <dependency>
+       <groupId>org.apache.openjpa</groupId>
+       <artifactId>openjpa-lib</artifactId>
+       <version>1.1.0-SNAPSHOT</version>
+       <scope>compile</scope>
+    </dependency>
+    
+    <dependency>
+      <groupId>net.sourceforge.serp</groupId>
+  	  <artifactId>serp</artifactId>
+  	  <version>1.13.0</version>
+  	  <scope>compile</scope>
+    </dependency>
+        
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>5.0.4</version>
+      <scope>test</scope>
+    </dependency>
+    
+    <dependency>
+      <groupId>commons-collections</groupId>
+      <artifactId>commons-collections</artifactId>
+      <version>3.2</version>
+      <scope>test</scope>
+    </dependency>       
+    
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    
+  </dependencies>
+  
+  
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                    <fork>true</fork>
+                </configuration>
+            </plugin>
+            
+            <plugin>
+        		<groupId>org.apache.maven.plugins</groupId>
+        		<artifactId>maven-surefire-plugin</artifactId>
+        		<configuration>
+          			<forkMode>pertest</forkMode>
+          			<disableXmlReport>true</disableXmlReport>
+          			<trimStackTrace>true</trimStackTrace>
+        		</configuration>
+      		</plugin>
+<!--      		
+      		<plugin>
+      			<groupId>org.apache.maven.plugins</groupId>
+      			<artifactId>maven-javadoc-plugin</artifactId>
+      			<version>2.2</version>
+				<configuration>
+                   <outputDirectory>${javadoc.output.dir}</outputDirectory>
+                   <reportOutputDirectory>${javadoc.output.dir}</reportOutputDirectory>
+                   <additionalparam>${javadoc.additionalparam}</additionalparam>
+                   <aggregate>true</aggregate>
+                   <verbose>false</verbose>
+                   <noqualifier>all</noqualifier>
+                   <maxmemory>512m</maxmemory>
+                   <links>
+                      <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
+                      <link>http://java.sun.com/javaee/5/docs/api</link>
+                      <link>http://openjpa.apache.org/docs/latest/javadoc/</link>
+                      <link>http://jakarta.apache.org/commons/collections/api-release</link>
+                    </links>
+                </configuration>  
+                <executions>
+                  <execution>
+                     <goals>
+                       <goal>javadoc</goal>
+                       <goal>test-javadoc</goal>
+                     </goals>
+                   </execution>
+                 </executions>    			
+      		</plugin>
+-->      		
+            <plugin>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>test-compile</phase>
+                        <configuration>
+                    		<fork>true</fork>
+                            <tasks>
+                                <path id="cp">
+                                    <pathelement path="${basedir}/test/resources"/>
+                                    <path refid="maven.test.classpath"/>
+                                    <path refid="maven.compile.classpath"/>
+                                    <path refid="maven.dependency.classpath"/>
+                                </path>
+                                <taskdef name="openjpac" classname=
+                                    "org.apache.openjpa.ant.PCEnhancerTask">
+                                    <classpath refid="cp"/>
+                                </taskdef>
+                                <fileset id="enhance.path.ref"
+                                    dir="${project.build.testOutputDirectory}">
+                                    <include name="**/*.class"/>
+                                </fileset>
+                                <!-- Generate POJO source files from META-INF/*.xsd -->
+                                <mkdir dir="${generated.src}"/>
+                                <echo message="Compiling generated Java source"/>
+                                <javac srcdir="${generated.src}" 
+                                	executable="${env.JAVA_HOME}/bin/javac.exe"
+                                	fork="true"
+                                	destdir="${project.build.testOutputDirectory}">
+                                    <classpath refid="cp"/>
+                                </javac>
+                                <echo message="Enhancing Entities"/>
+                                <java classname="org.apache.openjpa.enhance.PCEnhancer">
+                                    <classpath refid="cp"/>
+                                    <arg value="-properties"/>
+                                    <arg value="META-INF/persistence.xml"/>
+                                </java>
+                            </tasks>
+                        </configuration>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            
+        </plugins>
+    </build>  
+    
+    
+    <profiles>    
+        <profile>
+            <!--                        
+                Javadoc profile. Docs can be built by running:
+                    mvn process-classes -Dtest=false -Pjavadoc-profile
+            -->  
+            <id>javadoc-profile</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-javadoc-plugin</artifactId>
+                        <version>2.2</version>
+                        <executions>
+                            <execution>
+                                <phase>process-classes</phase>
+                                <goals><goal>javadoc</goal></goals>
+                                <configuration>
+                                    <outputDirectory>${javadoc.output.dir}</outputDirectory>
+                                    <reportOutputDirectory>${javadoc.output.dir}</reportOutputDirectory>
+                                    <additionalparam>
+                                        ${javadoc.additionalparam}
+                                    </additionalparam>
+                                    <aggregate>true</aggregate>
+                                    <verbose>false</verbose>
+                                    <noqualifier>all</noqualifier>
+                                    <!-- <linksource>true</linksource> -->
+                                    <maxmemory>512m</maxmemory>
+                                    <links>
+                                        <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
+                                        <link>http://java.sun.com/javaee/5/docs/api</link>
+                                        <link>http://jakarta.apache.org/commons/collections/api-release</link>
+                                    </links>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+            <activation>
+                <property>
+                    <name>builddocs</name>
+                    <value>true</value>
+                </property>
+            </activation>
+        </profile>
+     </profiles>
+     
+     <distributionManagement>
+  	<!-- use the following if you're not using a snapshot version. -->
+  		<!-- repository>
+    		<id>repo</id>
+    			<name>Repository Name</name>
+    			<url>scp://host/path/to/repo</url>
+  		</repository -->
+  		<!-- use the following if you ARE using a snapshot version. -->
+  		<snapshotRepository>
+    		<id>fluid.snapshot.repo</id>
+    		<name>Fluid Snapshot Repository</name>
+    		<url>scp://svn.apache.org/repos/asf/labs/fluid</url>
+  		</snapshotRepository>
+     	<site>
+      		<id>fluid.website</id>
+         		<!-- Set to the deployment URL on your own server. -->
+         	<url>scp://people.apache.org/home/ppoddar/public_html/fluid/site/</url>
+      	</site>
+	</distributionManagement>
+     
+     <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+                  <reportSets>
+                     <reportSet>
+                        <reports>
+                           <report>dependencies</report>
+                           <report>project-team</report>
+                           <report>mailing-list</report>
+                           <report>scm</report>
+                        </reports>
+                     </reportSet>
+                  </reportSets>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,22 @@
+package org.apache.openjpa.slice;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+
+/**
+ * A configuration for multiple datastores.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public interface DistributedConfiguration extends OpenJPAConfiguration {
+	/**
+	 * Gets the connection URLs in the same order as specified in the 
+	 * configuration.
+	 */
+	String[] getConnectionURLs();
+
+	/**
+	 * Gets the policy that distributes the instances.
+	 */
+	DistributionPolicy getDistributionPolicyInstance();
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,20 @@
+package org.apache.openjpa.slice;
+
+
+/**
+ * Decide in which datastore a new persistent instance should reside.
+ *  
+ * @author Pinaki Poddar 
+ *
+ */
+public interface DistributionPolicy {
+	/**
+	 * 
+	 * @param pc The persistent object 
+	 * @param stores the list of Connection URLs in the same order as specified 
+	 * in the configuration.
+	 * 
+	 * @return an index in the given list.
+	 */
+	int distribute(Object pc, String[] urls);
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,43 @@
+package org.apache.openjpa.slice;
+
+import java.security.AccessController;
+import java.util.Map;
+
+import org.apache.openjpa.conf.OpenJPAProductDerivation;
+import org.apache.openjpa.lib.conf.AbstractProductDerivation;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
+import org.apache.openjpa.slice.jdbc.DistributedJDBCBrokerFactory;
+import org.apache.openjpa.slice.jdbc.DistributedJDBCConfigurationImpl;
+
+/**
+ * Derives configuration for Slice.
+ * Introduces a specialized BrokerFactory aliased as <code>slice</code>.
+ * All Slice specific configuration is prefixed as <code>slice.XXX</code>
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class ProductDerivation extends AbstractProductDerivation implements
+		OpenJPAProductDerivation {
+
+	@SuppressWarnings("unchecked")
+	public void putBrokerFactoryAliases(Map m) {
+		m.put("slice", DistributedJDBCBrokerFactory.class.getName());
+	}
+
+	public String getConfigurationPrefix() {
+		return "slice";
+	}
+
+	public int getType() {
+		return TYPE_FEATURE;
+	}
+
+	@SuppressWarnings("unchecked")
+	public void validate() throws Exception {
+		AccessController.doPrivileged(J2DoPrivHelper
+				.getClassLoaderAction(DistributedJDBCBrokerFactory.class));
+	}
+
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RandomDistributionPolicy.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RandomDistributionPolicy.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RandomDistributionPolicy.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RandomDistributionPolicy.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,16 @@
+package org.apache.openjpa.slice;
+
+import java.util.Random;
+
+/**
+ * A policy to distribute the instances randomly in the given databases.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class RandomDistributionPolicy implements DistributionPolicy {
+	static Random rng = new Random(System.currentTimeMillis());
+	public int distribute(Object pc, String[] stores) {
+		return rng.nextInt(stores.length);
+	}
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RoundRobinDistributionPolicy.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RoundRobinDistributionPolicy.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RoundRobinDistributionPolicy.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/RoundRobinDistributionPolicy.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,10 @@
+package org.apache.openjpa.slice;
+
+
+public class RoundRobinDistributionPolicy implements DistributionPolicy {
+	private static int index = 0;
+	public int distribute(Object pc, String[] urls) {
+		return index++%urls.length;
+	}
+
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,245 @@
+package org.apache.openjpa.slice.jdbc;
+
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A virtual connection that contains multiple physical connections.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class DistributedConnection implements Connection {
+	private final List<Connection> real;
+	private final Connection master;
+
+	public DistributedConnection(List<Connection> connections) {
+		if (connections == null || connections.isEmpty())
+			throw new NullPointerException();
+		real = connections;
+		master = connections.get(0);
+	}
+	
+	public boolean contains(Connection c) {
+		return real.contains(c);
+	}
+
+	public void clearWarnings() throws SQLException {
+		for (Connection c : real)
+			c.clearWarnings();
+	}
+
+	public void close() throws SQLException {
+		for (Connection c : real)
+			c.close();
+	}
+
+	public void commit() throws SQLException {
+		for (Connection c : real)
+			c.commit();
+	}
+
+	public Statement createStatement() throws SQLException {
+		DistributedStatement ret = new DistributedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.createStatement());
+		}
+		return ret;
+	}
+
+	public Statement createStatement(int arg0, int arg1) throws SQLException {
+		DistributedStatement ret = new DistributedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.createStatement(arg0, arg1));
+		}
+		return ret;
+	}
+
+	public Statement createStatement(int arg0, int arg1, int arg2)
+			throws SQLException {
+		DistributedStatement ret = new DistributedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.createStatement(arg0, arg1, arg2));
+		}
+		return ret;
+	}
+
+	public boolean getAutoCommit() throws SQLException {
+		return master.getAutoCommit();
+	}
+
+	public String getCatalog() throws SQLException {
+		return master.getCatalog();
+	}
+
+	public int getHoldability() throws SQLException {
+		return master.getHoldability();
+	}
+
+	public DatabaseMetaData getMetaData() throws SQLException {
+		return master.getMetaData();
+	}
+
+	public int getTransactionIsolation() throws SQLException {
+		return master.getTransactionIsolation();
+	}
+
+	public Map<String, Class<?>> getTypeMap() throws SQLException {
+		return master.getTypeMap();
+	}
+
+	public SQLWarning getWarnings() throws SQLException {
+		return master.getWarnings();
+	}
+
+	public boolean isClosed() throws SQLException {
+		boolean ret = false;
+		for (Connection c : real) {
+			ret &= c.isClosed();
+		}
+		return ret;
+	}
+
+	public boolean isReadOnly() throws SQLException {
+		boolean ret = false;
+		for (Connection c : real) {
+			ret &= c.isReadOnly();
+		}
+		return ret;
+	}
+
+	public String nativeSQL(String arg0) throws SQLException {
+		return master.nativeSQL(arg0);
+	}
+
+	public CallableStatement prepareCall(String arg0) throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public CallableStatement prepareCall(String arg0, int arg1, int arg2)
+			throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public CallableStatement prepareCall(String arg0, int arg1, int arg2,
+			int arg3) throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public PreparedStatement prepareStatement(String arg0) throws SQLException {
+		// TODO: Big hack
+		if (arg0.startsWith("SELECT SEQUENCE_VALUE FROM OPENJPA_SEQUENCE_TABLE"))
+			return master.prepareStatement(arg0);
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, int arg1)
+			throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, int[] arg1)
+			throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, String[] arg1)
+			throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, int arg1, int arg2)
+			throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1, arg2));
+		}
+		return ret;
+	}
+
+	public PreparedStatement prepareStatement(String arg0, int arg1, int arg2,
+			int arg3) throws SQLException {
+		DistributedPreparedStatement ret = new DistributedPreparedStatement(this);
+		for (Connection c : real) {
+			ret.add(c.prepareStatement(arg0, arg1, arg2));
+		}
+		return ret;
+	}
+
+	public void releaseSavepoint(Savepoint arg0) throws SQLException {
+		for (Connection c : real)
+			c.releaseSavepoint(arg0);
+	}
+
+	public void rollback() throws SQLException {
+		for (Connection c : real)
+			c.rollback();
+	}
+
+	public void rollback(Savepoint arg0) throws SQLException {
+		for (Connection c : real)
+			c.rollback(arg0);
+	}
+
+	public void setAutoCommit(boolean arg0) throws SQLException {
+		for (Connection c : real)
+			c.setAutoCommit(arg0);
+	}
+
+	public void setCatalog(String arg0) throws SQLException {
+		for (Connection c : real)
+			c.setCatalog(arg0);
+	}
+
+	public void setHoldability(int arg0) throws SQLException {
+		for (Connection c : real)
+			c.setHoldability(arg0);
+	}
+
+	public void setReadOnly(boolean arg0) throws SQLException {
+		for (Connection c : real)
+			c.setReadOnly(arg0);
+	}
+
+	public Savepoint setSavepoint() throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public Savepoint setSavepoint(String arg0) throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void setTransactionIsolation(int arg0) throws SQLException {
+		for (Connection c : real)
+			c.setTransactionIsolation(arg0);
+	}
+
+	public void setTypeMap(Map<String, Class<?>> arg0) throws SQLException {
+		for (Connection c : real)
+			c.setTypeMap(arg0);
+	}
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,63 @@
+package org.apache.openjpa.slice.jdbc;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.sql.DataSource;
+
+import org.apache.openjpa.lib.jdbc.DecoratingDataSource;
+
+public class DistributedDataSource extends DecoratingDataSource implements
+		Iterable<DataSource> {
+	private List<DataSource> real = new ArrayList<DataSource>();
+	private DataSource master;
+	
+	public DistributedDataSource(List<DataSource> dataSources) {
+		super(dataSources.get(0));
+		if (dataSources == null || dataSources.isEmpty())
+			throw new NullPointerException();
+		real = dataSources;
+		master = dataSources.get(0);
+	}
+
+	public Iterator<DataSource> iterator() {
+		return real.iterator();
+	}
+
+	public Connection getConnection() throws SQLException {
+		List<Connection> c = new ArrayList<Connection>();
+		for (DataSource ds : real)
+			c.add(ds.getConnection());
+		return new DistributedConnection(c);
+	}
+
+	public Connection getConnection(String username, String password)
+			throws SQLException {
+		List<Connection> c = new ArrayList<Connection>();
+		for (DataSource ds : real)
+			c.add(ds.getConnection(username, password));
+		return new DistributedConnection(c);
+	}
+
+	public PrintWriter getLogWriter() throws SQLException {
+		return master.getLogWriter();
+	}
+
+	public int getLoginTimeout() throws SQLException {
+		return master.getLoginTimeout();
+	}
+
+	public void setLogWriter(PrintWriter out) throws SQLException {
+		for (DataSource ds:real)
+			ds.setLogWriter(out);
+	}
+
+	public void setLoginTimeout(int seconds) throws SQLException {
+		for (DataSource ds:real)
+			ds.setLoginTimeout(seconds);
+	}
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,38 @@
+package org.apache.openjpa.slice.jdbc;
+
+import org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory;
+import org.apache.openjpa.kernel.Bootstrap;
+import org.apache.openjpa.kernel.StoreManager;
+import org.apache.openjpa.lib.conf.ConfigurationProvider;
+
+/**
+ * A factory for distributed JDBC datastores.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class DistributedJDBCBrokerFactory extends JDBCBrokerFactory {
+	private DistributedJDBCConfiguration conf;
+
+    /**
+     * Factory method for constructing a factory from properties. Invoked from
+     * {@link Bootstrap#newBrokerFactory}.
+     */
+    public static DistributedJDBCBrokerFactory newInstance(ConfigurationProvider cp) {
+    	DistributedJDBCConfigurationImpl conf = 
+    		new DistributedJDBCConfigurationImpl();
+    	cp.setInto(conf);
+        return new DistributedJDBCBrokerFactory(conf);
+    }
+
+    public DistributedJDBCBrokerFactory(DistributedJDBCConfiguration conf) {
+        super(conf);
+        this.conf = conf;
+   }
+    
+	@Override
+	protected StoreManager newStoreManager() {
+        return new DistributedStoreManager(conf);
+    }
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,16 @@
+package org.apache.openjpa.slice.jdbc;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.slice.DistributedConfiguration;
+
+/**
+ * A distributed configuration that is a ordered collection of 
+ * JDBCConfigurations.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public interface DistributedJDBCConfiguration extends JDBCConfiguration, 
+	Iterable<JDBCConfiguration>, DistributedConfiguration {
+
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,120 @@
+package org.apache.openjpa.slice.jdbc;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.sql.DataSource;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
+import org.apache.openjpa.jdbc.schema.DataSourceFactory;
+import org.apache.openjpa.kernel.BrokerImpl;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.conf.PluginValue;
+import org.apache.openjpa.lib.jdbc.DecoratingDataSource;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.slice.DistributionPolicy;
+import org.apache.openjpa.slice.RandomDistributionPolicy;
+import org.apache.openjpa.slice.RoundRobinDistributionPolicy;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Implements a distributed configuration of JDBCStoreManagers.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class DistributedJDBCConfigurationImpl extends JDBCConfigurationImpl 
+	implements DistributedJDBCConfiguration {
+	
+	private final List<JDBCConfiguration> children = 
+		new ArrayList<JDBCConfiguration>();
+	private String[] urls;
+	private DecoratingDataSource dataSource;
+	public PluginValue distributionPolicyPlugin;
+	public DistributionPolicy distributionPolicy;
+	
+	private static Localizer _loc = 
+		Localizer.forPackage(DistributedJDBCConfigurationImpl.class);
+	
+	public DistributedJDBCConfigurationImpl() {
+		super(true, false);
+		distributionPolicyPlugin = addPlugin("DistributionPolicy", true);
+		distributionPolicyPlugin.setDynamic(true);
+		String[] aliases = new String[] {
+				"random", RandomDistributionPolicy.class.getName(),
+				"round-robin", RoundRobinDistributionPolicy.class.getName()};
+		
+		distributionPolicyPlugin.setAliases(aliases);
+		distributionPolicyPlugin.setDefault(aliases[0]);
+		distributionPolicyPlugin.setString(aliases[0]);
+	}
+	
+	public Iterator<JDBCConfiguration> iterator() {
+		return children.iterator();
+	}
+	
+	/**
+	 * Gets the URLs of all the underlying physical datastores.
+	 */
+	public String[] getConnectionURLs() {
+		if (urls == null) {
+		    urls = getURLs();
+		    Map parent = toProperties(true);
+		    Configurations.removeProperty("DistributionPolicy", parent);
+		    for (String url:urls) {
+		    	JDBCConfigurationImpl child = new JDBCConfigurationImpl();
+		    	child.fromProperties(parent);
+		    	child.setConnectionURL(url);
+		    	child.setBrokerFactory(BrokerImpl.class.getName());
+		    	children.add(child);
+		    }
+		}
+		return urls;
+	}
+	
+	public DistributionPolicy getDistributionPolicyInstance() {
+		if (distributionPolicy == null) {
+			Object val = distributionPolicyPlugin.instantiate(
+					DistributionPolicy.class, this, true);
+			distributionPolicy = (DistributionPolicy)val;
+		}
+		return distributionPolicy;
+	}
+	
+	public void setDistributionPolicyInstance(String val) {
+		distributionPolicyPlugin.set(val);
+	}
+
+	
+    public Object getConnectionFactory() {
+        if (dataSource == null) {
+        	getConnectionURLs();
+            DistributedDataSource ds = createDistributedDataStore();
+            dataSource = DataSourceFactory.installDBDictionary
+                (getDBDictionaryInstance(), ds, this, false);
+        }
+        return dataSource;
+    }
+    
+    private DistributedDataSource createDistributedDataStore() {
+    	List<DataSource> dataSources = new ArrayList<DataSource>();
+    	for (JDBCConfiguration conf:children)
+    		dataSources.add(DataSourceFactory.newDataSource(conf, false));
+    	return new DistributedDataSource(dataSources);
+    }
+
+    private String[] getURLs() {
+    	StringTokenizer tokenizer = new StringTokenizer(getConnectionURL(),"|");
+    	String[] tokens = new String[tokenizer.countTokens()];
+	    if (tokens.length == 0)
+	    	throw new UserException(_loc.get("wrong-url", getConnectionURL()));
+    	for (int i=0; i<tokens.length; i++) {
+    		tokens[i] = tokenizer.nextToken();
+    	}
+    	return tokens;
+    }
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,407 @@
+package org.apache.openjpa.slice.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+
+public class DistributedPreparedStatement extends DistributedTemplate<PreparedStatement>
+		implements PreparedStatement {
+
+	DistributedPreparedStatement(DistributedConnection c) {
+		super(c);
+	}
+
+	public void clearParameters() throws SQLException {
+		for (PreparedStatement s : this)
+			s.clearParameters();
+	}
+
+	public boolean execute() throws SQLException {
+		boolean ret = true;
+		for (PreparedStatement s : this)
+			ret = s.execute() & ret;
+		return ret;
+	}
+
+	public ResultSet executeQuery() throws SQLException {
+		DistributedResultSet mrs = new DistributedResultSet();
+		for (PreparedStatement t : this)
+			mrs.add(t.executeQuery());
+		return mrs;
+	}
+
+	public int executeUpdate() throws SQLException {
+		int ret = 0;
+		for (PreparedStatement t : this)
+			ret += t.executeUpdate();
+		return ret;
+	}
+
+	public ResultSetMetaData getMetaData() throws SQLException {
+		return master.getMetaData();
+	}
+
+	public ParameterMetaData getParameterMetaData() throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void setArray(int i, Array x) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setArray(i, x);
+	}
+
+	public void setAsciiStream(int arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		for (PreparedStatement t : this)
+			t.setAsciiStream(arg0, arg1, arg2);
+	}
+
+	public void setBigDecimal(int arg0, BigDecimal arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBigDecimal(arg0, arg1);
+	}
+
+	public void setBinaryStream(int arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBinaryStream(arg0, arg1, arg2);
+	}
+
+	public void setBlob(int arg0, Blob arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBlob(arg0, arg1);
+	}
+
+	public void setBoolean(int arg0, boolean arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBoolean(arg0, arg1);
+	}
+
+	public void setByte(int arg0, byte arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setByte(arg0, arg1);
+	}
+
+	public void setBytes(int arg0, byte[] arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setBytes(arg0, arg1);
+	}
+
+	public void setCharacterStream(int arg0, Reader arg1, int arg2)
+			throws SQLException {
+		for (PreparedStatement t : this)
+			t.setCharacterStream(arg0, arg1, arg2);
+	}
+
+	public void setClob(int arg0, Clob arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setClob(arg0, arg1);
+	}
+
+	public void setDate(int arg0, Date arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setDate(arg0, arg1);
+	}
+
+	public void setDate(int arg0, Date arg1, Calendar arg2) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setDate(arg0, arg1, arg2);
+	}
+
+	public void setDouble(int arg0, double arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setDouble(arg0, arg1);
+	}
+
+	public void setFloat(int arg0, float arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setFloat(arg0, arg1);
+	}
+
+	public void setInt(int arg0, int arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setInt(arg0, arg1);
+	}
+
+	public void setLong(int arg0, long arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setLong(arg0, arg1);
+	}
+
+	public void setNull(int arg0, int arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setNull(arg0, arg1);
+	}
+
+	public void setNull(int arg0, int arg1, String arg2) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setNull(arg0, arg1, arg2);
+	}
+
+	public void setObject(int arg0, Object arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setObject(arg0, arg1);
+	}
+
+	public void setObject(int arg0, Object arg1, int arg2) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setObject(arg0, arg1, arg2);
+	}
+
+	public void setObject(int arg0, Object arg1, int arg2, int arg3)
+			throws SQLException {
+		for (PreparedStatement t : this)
+			t.setObject(arg0, arg1, arg2, arg3);
+	}
+
+	public void setRef(int arg0, Ref arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setRef(arg0, arg1);
+	}
+
+	public void setShort(int arg0, short arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setShort(arg0, arg1);
+	}
+
+	public void setString(int arg0, String arg1) throws SQLException {
+		for (PreparedStatement t : this)
+			t.setString(arg0, arg1);
+	}
+
+	 public void setTime(int arg0, Time arg1) throws SQLException {
+			for (PreparedStatement t : this)
+				t.setTime(arg0, arg1);
+	 }
+	
+	 public void setTime(int arg0, Time arg1, Calendar arg2) throws
+	 SQLException {
+			for (PreparedStatement t : this)
+				t.setTime(arg0, arg1, arg2);
+	 }
+	
+	 public void setTimestamp(int arg0, Timestamp arg1) throws SQLException {
+			for (PreparedStatement t : this)
+				t.setTimestamp(arg0, arg1);
+	 }
+	
+	 public void setTimestamp(int arg0, Timestamp arg1, Calendar arg2)
+	 throws SQLException {
+			for (PreparedStatement t : this)
+				t.setTimestamp(arg0, arg1, arg2);
+	 }
+	
+	 public void setURL(int arg0, URL arg1) throws SQLException {
+			for (PreparedStatement t : this)
+				t.setURL(arg0, arg1);
+	 }
+	
+	 public void setUnicodeStream(int arg0, InputStream arg1, int arg2)
+	 throws SQLException {
+			for (PreparedStatement t : this)
+				t.setUnicodeStream(arg0, arg1, arg2);
+	 }
+	
+	 public void addBatch() throws SQLException {
+				for (PreparedStatement t:this)
+					t.addBatch();
+	 }
+	
+	// public void cancel() throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public void clearBatch() throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public void clearWarnings() throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public void close() throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public boolean execute(String arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	// return false;
+	// }
+	//
+	// public boolean execute(String arg0, int arg1) throws SQLException {
+	// // TODO Auto-generated method stub
+	// return false;
+	// }
+	//
+	// public boolean execute(String arg0, int[] arg1) throws SQLException {
+	// // TODO Auto-generated method stub
+	// return false;
+	// }
+	//
+	// public boolean execute(String arg0, String[] arg1) throws SQLException {
+	// // TODO Auto-generated method stub
+	// return false;
+	// }
+	//
+	// public int[] executeBatch() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return null;
+	// }
+	//
+	// public ResultSet executeQuery(String arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	// return null;
+	// }
+	//
+	// public int executeUpdate(String arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public int executeUpdate(String arg0, int arg1) throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public int executeUpdate(String arg0, int[] arg1) throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public int executeUpdate(String arg0, String[] arg1) throws SQLException
+	// {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public Connection getConnection() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return null;
+	// }
+	//
+	// public int getFetchDirection() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public int getFetchSize() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public ResultSet getGeneratedKeys() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return null;
+	// }
+	//
+	// public int getMaxFieldSize() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public int getMaxRows() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public boolean getMoreResults() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return false;
+	// }
+	//
+	// public boolean getMoreResults(int arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	// return false;
+	// }
+	//
+	// public int getQueryTimeout() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public ResultSet getResultSet() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return null;
+	// }
+	//
+	// public int getResultSetConcurrency() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public int getResultSetHoldability() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public int getResultSetType() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public int getUpdateCount() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return 0;
+	// }
+	//
+	// public SQLWarning getWarnings() throws SQLException {
+	// // TODO Auto-generated method stub
+	// return null;
+	// }
+	//
+	// public void setCursorName(String arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public void setEscapeProcessing(boolean arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public void setFetchDirection(int arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public void setFetchSize(int arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public void setMaxFieldSize(int arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public void setMaxRows(int arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+	//
+	// public void setQueryTimeout(int arg0) throws SQLException {
+	// // TODO Auto-generated method stub
+	//
+	// }
+
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,745 @@
+package org.apache.openjpa.slice.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.LinkedList;
+import java.util.Map;
+
+/**
+ * A chain of ResultSet.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class DistributedResultSet implements ResultSet {
+	LinkedList<ResultSet> comps = new LinkedList<ResultSet>();
+	ResultSet current;
+	int cursor = -1;
+	
+	/**
+	 * Adds the ResultSet only if it has rows.
+	 */
+	public void add(ResultSet rs) {
+		try {
+			if (rs.first())
+				comps.add(rs);
+		} catch (SQLException e) {
+			// ignore
+		}
+	}
+	
+	public boolean absolute(int arg0) throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void afterLast() throws SQLException {
+		current = null;
+		cursor  = comps.size();
+	}
+
+	public void beforeFirst() throws SQLException {
+		current = null;
+		cursor  = -1;
+	}
+
+	public void cancelRowUpdates() throws SQLException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void clearWarnings() throws SQLException {
+		for (ResultSet rs:comps)
+			rs.clearWarnings();
+	}
+
+	public void close() throws SQLException {
+		for (ResultSet rs:comps)
+			rs.close();
+	}
+
+	public void deleteRow() throws SQLException {
+		current.deleteRow();
+	}
+
+	public int findColumn(String arg0) throws SQLException {
+		return 0;
+	}
+
+	public boolean first() throws SQLException {
+		if (comps.isEmpty()) return false;
+		cursor = 0;
+		current = comps.get(0);
+		return true;
+	}
+
+	public Array getArray(int arg0) throws SQLException {
+		return current.getArray(arg0);
+	}
+
+	public Array getArray(String arg0) throws SQLException {
+		return current.getArray(arg0);
+	}
+
+	public InputStream getAsciiStream(int arg0) throws SQLException {
+		return current.getAsciiStream(arg0);
+	}
+
+	public InputStream getAsciiStream(String arg0) throws SQLException {
+		return current.getAsciiStream(arg0);
+	}
+
+	public BigDecimal getBigDecimal(int arg0) throws SQLException {
+		return current.getBigDecimal(arg0);
+	}
+
+	public BigDecimal getBigDecimal(String arg0) throws SQLException {
+		return current.getBigDecimal(arg0);
+	}
+
+	public BigDecimal getBigDecimal(int arg0, int arg1) throws SQLException {
+		return current.getBigDecimal(arg0, arg1);
+	}
+
+	public BigDecimal getBigDecimal(String arg0, int arg1) throws SQLException {
+		return current.getBigDecimal(arg0, arg1);
+	}
+
+	public InputStream getBinaryStream(int arg0) throws SQLException {
+		return current.getBinaryStream(arg0);
+	}
+
+	public InputStream getBinaryStream(String arg0) throws SQLException {
+		return current.getBinaryStream(arg0);
+	}
+
+	public Blob getBlob(int arg0) throws SQLException {
+		return current.getBlob(arg0);
+	}
+
+	public Blob getBlob(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public boolean getBoolean(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public boolean getBoolean(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public byte getByte(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public byte getByte(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public byte[] getBytes(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public byte[] getBytes(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Reader getCharacterStream(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Reader getCharacterStream(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Clob getClob(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Clob getClob(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public int getConcurrency() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public String getCursorName() throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Date getDate(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Date getDate(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Date getDate(int arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Date getDate(String arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public double getDouble(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public double getDouble(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public int getFetchDirection() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public int getFetchSize() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public float getFloat(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public float getFloat(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public int getInt(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public int getInt(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public long getLong(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public long getLong(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public ResultSetMetaData getMetaData() throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getObject(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getObject(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getObject(int arg0, Map<String, Class<?>> arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getObject(String arg0, Map<String, Class<?>> arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Ref getRef(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Ref getRef(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public int getRow() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public short getShort(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public short getShort(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public Statement getStatement() throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public String getString(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public String getString(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Time getTime(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Time getTime(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Time getTime(int arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Time getTime(String arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Timestamp getTimestamp(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Timestamp getTimestamp(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Timestamp getTimestamp(int arg0, Calendar arg1) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Timestamp getTimestamp(String arg0, Calendar arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public int getType() throws SQLException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public URL getURL(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public URL getURL(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public InputStream getUnicodeStream(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public InputStream getUnicodeStream(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public SQLWarning getWarnings() throws SQLException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void insertRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public boolean isAfterLast() throws SQLException {
+		return current == null && cursor >= comps.size();
+	}
+
+	public boolean isBeforeFirst() throws SQLException {
+		return current == null && cursor<0;
+	}
+
+	public boolean isFirst() throws SQLException {
+		return current != null && current.isFirst() && cursor==0;
+	}
+
+	public boolean isLast() throws SQLException {
+		return current != null && current.isLast() && cursor==comps.size()-1;
+	}
+
+	public boolean last() throws SQLException {
+		if (comps.isEmpty()) return false;
+		cursor = comps.size()-1;
+		return false;
+	}
+
+	public void moveToCurrentRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void moveToInsertRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public boolean next() throws SQLException {
+		if (current == null) {
+			current = comps.get(0);
+			cursor = 0;
+		}
+		if (current.next())
+			return true;
+		cursor++;
+		if (cursor<comps.size())
+			current = comps.get(cursor);
+		return cursor<comps.size();
+	}
+
+	public boolean previous() throws SQLException {
+		return current.previous();
+	}
+
+	public void refreshRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public boolean relative(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public boolean rowDeleted() throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public boolean rowInserted() throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public boolean rowUpdated() throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public void setFetchDirection(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void setFetchSize(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateArray(int arg0, Array arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateArray(String arg0, Array arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateAsciiStream(int arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateAsciiStream(String arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBigDecimal(int arg0, BigDecimal arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBigDecimal(String arg0, BigDecimal arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBinaryStream(int arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBinaryStream(String arg0, InputStream arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBlob(int arg0, Blob arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBlob(String arg0, Blob arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBoolean(int arg0, boolean arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBoolean(String arg0, boolean arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateByte(int arg0, byte arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateByte(String arg0, byte arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBytes(int arg0, byte[] arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateBytes(String arg0, byte[] arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateCharacterStream(int arg0, Reader arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateCharacterStream(String arg0, Reader arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateClob(int arg0, Clob arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateClob(String arg0, Clob arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateDate(int arg0, Date arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateDate(String arg0, Date arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateDouble(int arg0, double arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateDouble(String arg0, double arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateFloat(int arg0, float arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateFloat(String arg0, float arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateInt(int arg0, int arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateInt(String arg0, int arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateLong(int arg0, long arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateLong(String arg0, long arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateNull(int arg0) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateNull(String arg0) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateObject(int arg0, Object arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateObject(String arg0, Object arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateObject(int arg0, Object arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateObject(String arg0, Object arg1, int arg2)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateRef(int arg0, Ref arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateRef(String arg0, Ref arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateRow() throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateShort(int arg0, short arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateShort(String arg0, short arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateString(int arg0, String arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateString(String arg0, String arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateTime(int arg0, Time arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateTime(String arg0, Time arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateTimestamp(int arg0, Timestamp arg1) throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void updateTimestamp(String arg0, Timestamp arg1)
+			throws SQLException {
+		// TODO Auto-generated method stub
+
+	}
+
+	public boolean wasNull() throws SQLException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,225 @@
+package org.apache.openjpa.slice.jdbc;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DistributedStatement extends DistributedTemplate<Statement>  {
+	public DistributedStatement(DistributedConnection c) {
+		super(c);
+	}
+	
+//	public void add(Statement s) {
+//		try {
+//			if (!con.contains(s.getConnection()))
+//				throw new IllegalArgumentException(s + " has different connection");
+//			stmts.add(s);
+//		} catch (SQLException e) {
+//			e.printStackTrace();
+//		}
+//	}
+//	
+//	public void addBatch(String sql) throws SQLException {
+//		for (Statement s:stmts)
+//			s.addBatch(sql);
+//	}
+//
+//	public void cancel() throws SQLException {
+//		for (Statement s:stmts)
+//			s.cancel();
+//	}
+//
+//	public void clearBatch() throws SQLException {
+//		for (Statement s:stmts)
+//			s.clearBatch();
+//	}
+//
+//	public void clearWarnings() throws SQLException {
+//		for (Statement s:stmts)
+//			s.clearWarnings();
+//	}
+//
+//	public void close() throws SQLException {
+//		for (Statement s:stmts)
+//			s.close();
+//	}
+//
+//	public boolean execute(String arg0) throws SQLException {
+//		boolean ret = true;
+//		for (Statement s:stmts)
+//			ret = s.execute(arg0) & ret;
+//		return ret;
+//	}
+//
+//	public boolean execute(String arg0, int arg1) throws SQLException {
+//		boolean ret = true;
+//		for (Statement s:stmts)
+//			ret = s.execute(arg0, arg1) & ret;
+//		return ret;
+//	}
+//
+//	public boolean execute(String arg0, int[] arg1) throws SQLException {
+//		boolean ret = true;
+//		for (Statement s:stmts)
+//			ret = s.execute(arg0, arg1) & ret;
+//		return ret;
+//	}
+//
+//	public boolean execute(String arg0, String[] arg1) throws SQLException {
+//		boolean ret = true;
+//		for (Statement s:stmts)
+//			ret = s.execute(arg0, arg1) & ret;
+//		return ret;
+//	}
+//
+//	public int[] executeBatch() throws SQLException {
+//		int[] ret = new int[0];
+//		for (Statement s:stmts) {
+//			int[] tmp = s.executeBatch();
+//			ret = new int[ret.length + tmp.length];
+//			System.arraycopy(tmp, 0, ret, ret.length-tmp.length, tmp.length);
+//		}
+//		return ret;
+//	}
+//
+//	public ResultSet executeQuery(String arg0) throws SQLException {
+//		MultiResultSet rs = new MultiResultSet();
+//		for (Statement s:stmts)
+//			rs.add(s.executeQuery(arg0));
+//		return rs;
+//	}
+//
+//	public int executeUpdate(String arg0) throws SQLException {
+//		int ret = 0;
+//		for (Statement s:stmts)
+//			ret += s.executeUpdate(arg0);
+//		return ret;
+//	}
+//
+//	public int executeUpdate(String arg0, int arg1) throws SQLException {
+//		int ret = 0;
+//		for (Statement s:stmts)
+//			ret += s.executeUpdate(arg0, arg1);
+//		return ret;
+//	}
+//
+//	public int executeUpdate(String arg0, int[] arg1) throws SQLException {
+//		int ret = 0;
+//		for (Statement s:stmts)
+//			ret += s.executeUpdate(arg0, arg1);
+//		return ret;
+//	}
+//
+//	public int executeUpdate(String arg0, String[] arg1) throws SQLException {
+//		int ret = 0;
+//		for (Statement s:stmts)
+//			ret += s.executeUpdate(arg0, arg1);
+//		return ret;
+//	}
+//
+//	public Connection getConnection() throws SQLException {
+//		return con;
+//	}
+//
+//	public int getFetchDirection() throws SQLException {
+//		
+//		return 0;
+//	}
+//
+//	public int getFetchSize() throws SQLException {
+//		return stmts.get(0).getFetchSize();
+//	}
+//
+//	public ResultSet getGeneratedKeys() throws SQLException {
+//		throw new UnsupportedOperationException();
+//	}
+//
+//	public int getMaxFieldSize() throws SQLException {
+//		return stmts.get(0).getMaxFieldSize();
+//	}
+//
+//	public int getMaxRows() throws SQLException {
+//		return stmts.get(0).getMaxRows();
+//	}
+//
+//	public boolean getMoreResults() throws SQLException {
+//		// TODO Auto-generated method stub
+//		return false;
+//	}
+//
+//	public boolean getMoreResults(int arg0) throws SQLException {
+//		// TODO Auto-generated method stub
+//		return false;
+//	}
+//
+//	public int getQueryTimeout() throws SQLException {
+//		return stmts.get(0).getQueryTimeout();
+//	}
+//
+//	public ResultSet getResultSet() throws SQLException {
+//		MultiResultSet rs = new MultiResultSet();
+//		for (Statement s:stmts)
+//			rs.add(s.getResultSet());
+//		return rs;
+//	}
+//
+//	public int getResultSetConcurrency() throws SQLException {
+//		return stmts.get(0).getResultSetConcurrency();
+//	}
+//
+//	public int getResultSetHoldability() throws SQLException {
+//		return stmts.get(0).getResultSetHoldability();
+//	}
+//
+//	public int getResultSetType() throws SQLException {
+//		return stmts.get(0).getResultSetType();
+//	}
+//
+//	public int getUpdateCount() throws SQLException {
+//		return stmts.get(0).getUpdateCount();
+//	}
+//
+//	public SQLWarning getWarnings() throws SQLException {
+//		// TODO Auto-generated method stub
+//		return null;
+//	}
+//
+//	public void setCursorName(String name) throws SQLException {
+//		for (Statement s:stmts)
+//			s.setCursorName(name);
+//	}
+//
+//	public void setEscapeProcessing(boolean flag) throws SQLException {
+//		for (Statement s:stmts)
+//			s.setEscapeProcessing(flag);
+//	}
+//
+//	public void setFetchDirection(int dir) throws SQLException {
+//		for (Statement s:stmts)
+//			s.setFetchDirection(dir);
+//	}
+//
+//	public void setFetchSize(int size) throws SQLException {
+//		for (Statement s:stmts)
+//			s.setFetchSize(size);
+//	}
+//
+//	public void setMaxFieldSize(int size) throws SQLException {
+//		for (Statement s:stmts)
+//			s.setMaxFieldSize(size);
+//	}
+//
+//	public void setMaxRows(int n) throws SQLException {
+//		for (Statement s:stmts)
+//			s.setMaxFieldSize(n);
+//	}
+//	
+//	public void setQueryTimeout(int n) throws SQLException {
+//		for (Statement s:stmts)
+//			s.setMaxFieldSize(n);
+//	}
+}

Added: labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
URL: http://svn.apache.org/viewvc/labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java?rev=605340&view=auto
==============================================================================
--- labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java (added)
+++ labs/fluid/slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java Tue Dec 18 14:07:57 2007
@@ -0,0 +1,330 @@
+package org.apache.openjpa.slice.jdbc;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.kernel.ConnectionInfo;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.ResultSetResult;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.kernel.QueryLanguages;
+import org.apache.openjpa.kernel.Seq;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.kernel.StoreManager;
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.kernel.exps.ExpressionParser;
+import org.apache.openjpa.lib.rop.MergedResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.slice.DistributionPolicy;
+import org.apache.openjpa.util.InternalException;
+
+/**
+ * A Store manager for multiple physical databases.
+ * 
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class DistributedStoreManager extends JDBCStoreManager {
+	private final JDBCStoreManager[] _children;
+	private final JDBCStoreManager _master;
+	private final DistributedJDBCConfiguration _conf;
+	private final Integer[] _storeIds;
+	private static final Localizer _loc = 
+		Localizer.forPackage(DistributedStoreManager.class);
+
+	/**
+	 * Constructs a set of child StoreManagers each connected to a physical
+	 * DataSource.
+	 * 
+	 * The supplied configuration carries multiple URL for underlying physical
+	 * slices. The first slice is referred as <em>master</em> and is used to
+	 * get Sequence based entity identifiers.
+	 */
+	public DistributedStoreManager(DistributedJDBCConfiguration conf) {
+		_conf = conf;
+		_children = new JDBCStoreManager[conf.getConnectionURLs().length];
+		_storeIds = new Integer[_children.length];
+		for (int i = 0; i < _children.length; i++) {
+			JDBCStoreManager child = new JDBCStoreManager();
+			_children[i] = child;
+			_storeIds[i] = i;
+		}
+		_master = _children[0];
+	}
+
+	public DistributedJDBCConfiguration getConfiguration() {
+		return _conf;
+	}
+
+	/**
+	 * Decides the index of the StoreManager by first looking at the
+	 * implementation data. If not found then {@link DistributionPolicy
+	 * DistributionPolicy} determines the target store for new instances and
+	 * additional connection info is used to estimate for the existing
+	 * instances.
+	 */
+	protected int getSliceIndex(OpenJPAStateManager sm, Object info) {
+		boolean hasIndex = hasSliceIndex(sm);
+		if (hasIndex)
+			return (Integer) sm.getImplData();
+		if (sm.isNew()) {
+			return assignSliceIndex(sm);
+		} else {
+			int i = estimateSliceIndex(sm, info);
+			if (i < 0)
+				return assignSliceIndex(sm);
+			else
+				return i;
+		}
+	}
+
+	private boolean hasSliceIndex(OpenJPAStateManager sm) {
+		Object index = sm.getImplData();
+		return index != null;
+	}
+
+	private int assignSliceIndex(OpenJPAStateManager sm) {
+		PersistenceCapable pc = sm.getPersistenceCapable();
+		int newi = _conf.getDistributionPolicyInstance().distribute(pc,
+				_conf.getConnectionURLs());
+		sm.setImplData(_storeIds[newi], true);
+		return newi;
+	}
+
+	/**
+	 * The additional edata is used, if possible, to find the StoreManager
+	 * managing the given StateManager. If the additional data is unavailable
+	 * then return a negative value.
+	 * 
+	 */
+	private int estimateSliceIndex(OpenJPAStateManager sm, Object edata) {
+		if (edata == null || !(edata instanceof ConnectionInfo))
+			return -1;
+
+		Result result = ((ConnectionInfo) edata).result;
+		if (result instanceof ResultSetResult) {
+			JDBCStore store = ((ResultSetResult) result).getStore();
+			for (int i = 0; i < _children.length; i++) {
+				if (_children[i] == store) {
+					sm.setImplData(_storeIds[i], true);
+					return i;
+				}
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * Selects a child StoreManager where the given instance resides.
+	 */
+	private StoreManager selectStore(OpenJPAStateManager sm, Object edata) {
+		int i = getSliceIndex(sm, edata);
+		if (i >= 0 && i < _children.length)
+			return _children[i];
+		throw new InternalException(_loc.get("wrong-slice", i, sm));
+	}
+
+	public boolean assignField(OpenJPAStateManager sm, int field,
+			boolean preFlush) {
+		return selectStore(sm, null).assignField(sm, field, preFlush);
+	}
+
+	public boolean assignObjectId(OpenJPAStateManager sm, boolean preFlush) {
+		return _master.assignObjectId(sm, preFlush);
+	}
+
+	public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
+			PCState toState) {
+		_master.beforeStateChange(sm, fromState, toState);
+	}
+
+	public void begin() {
+		for (StoreManager child : _children)
+			child.begin();
+	}
+
+	public void beginOptimistic() {
+		for (StoreManager child : _children)
+			child.beginOptimistic();
+	}
+
+	public boolean cancelAll() {
+		boolean ret = true;
+		for (StoreManager child : _children)
+			ret = child.cancelAll() & ret;
+		return ret;
+	}
+
+	public void close() {
+		for (StoreManager child : _children)
+			child.close();
+	}
+
+	public void commit() {
+		for (StoreManager child : _children)
+			child.commit();
+	}
+
+	public int compareVersion(OpenJPAStateManager sm, Object v1, Object v2) {
+		return selectStore(sm, null).compareVersion(sm, v1, v2);
+	}
+
+	public Object copyDataStoreId(Object oid, ClassMetaData meta) {
+		return _master.copyDataStoreId(oid, meta);
+	}
+
+	public ResultObjectProvider executeExtent(ClassMetaData meta,
+			boolean subclasses, FetchConfiguration fetch) {
+		ResultObjectProvider[] tmp = new ResultObjectProvider[_children.length];
+		int i = 0;
+		for (StoreManager child : _children) {
+			tmp[i++] = child.executeExtent(meta, subclasses, fetch);
+		}
+		return new MergedResultObjectProvider(tmp);
+	}
+
+	public boolean exists(OpenJPAStateManager sm, Object edata) {
+		for (int i=0; i<_children.length; i++) {
+			if (_children[i].exists(sm, edata)) {
+				sm.setImplData(_storeIds[i], true);
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Flush the given StateManagers after binning them to respective physical
+	 * slices.
+	 */
+	@SuppressWarnings("unchecked")
+	public Collection flush(Collection sms) {
+		Collection exceptions = new ArrayList();
+		for (int i = 0; i < _children.length; i++) {
+			Collection subset = new ArrayList();
+			for (Object x : sms) {
+				OpenJPAStateManager sm = (OpenJPAStateManager) x;
+				if (getSliceIndex(sm, null) == i)
+					subset.add(sm);
+			}
+			exceptions.addAll(_children[i].flush(subset));
+			subset.clear();
+		}
+		return exceptions;
+	}
+
+	public Object getClientConnection() {
+		throw new UnsupportedOperationException();
+	}
+
+	public Seq getDataStoreIdSequence(ClassMetaData forClass) {
+		return _master.getDataStoreIdSequence(forClass);
+	}
+
+	public Class getDataStoreIdType(ClassMetaData meta) {
+		return _master.getDataStoreIdType(meta);
+	}
+
+	public Class getManagedType(Object oid) {
+		return _master.getManagedType(oid);
+	}
+
+	public Seq getValueSequence(FieldMetaData forField) {
+		return _master.getValueSequence(forField);
+	}
+
+	public boolean initialize(OpenJPAStateManager sm, PCState state,
+			FetchConfiguration fetch, Object edata) {
+		if (edata instanceof ConnectionInfo) {
+			int slice = getSliceIndex(sm, (ConnectionInfo) edata);
+			if (slice >= 0)
+				return _children[slice].initialize(sm, state, fetch, edata);
+		}
+		// not a part of Query result load. Look into the slices till found
+		for (int i = 0; i < _children.length; i++) {
+			if (_children[i].initialize(sm, state, fetch, edata)) {
+				sm.setImplData(_storeIds[i], true);
+				return true;
+			}
+		}
+		return false;
+
+	}
+
+	public boolean load(OpenJPAStateManager sm, BitSet fields,
+			FetchConfiguration fetch, int lockLevel, Object edata) {
+		return selectStore(sm, edata).load(sm, fields, fetch, lockLevel, edata);
+	}
+
+	public Collection loadAll(Collection sms, PCState state, int load,
+			FetchConfiguration fetch, Object edata) {
+		throw new UnsupportedOperationException();
+	}
+
+	public Object newDataStoreId(Object oidVal, ClassMetaData meta) {
+		return _master.newDataStoreId(oidVal, meta);
+	}
+
+	public FetchConfiguration newFetchConfiguration() {
+		return _master.newFetchConfiguration();
+	}
+
+	/**
+	 * Construct a distributed query to be executed against all the slices.
+	 */
+	public StoreQuery newQuery(String language) {
+		ExpressionParser parser = QueryLanguages.parserForLanguage(language);
+		DistributedStoreQuery ret = new DistributedStoreQuery(this, parser);
+		for (JDBCStoreManager child : _children) {
+			ret.add(child.newQuery(language));
+		}
+		return ret;
+	}
+
+	public void releaseConnection() {
+		for (StoreManager child : _children)
+			child.releaseConnection();
+
+	}
+
+	public void retainConnection() {
+		for (StoreManager child : _children)
+			child.retainConnection();
+	}
+
+	public void rollback() {
+		for (StoreManager child : _children)
+			child.rollback();
+	}
+
+	public void rollbackOptimistic() {
+		for (StoreManager child : _children)
+			child.rollbackOptimistic();
+	}
+
+	/**
+	 * Sets the context for this receiver and all its underlying slices.
+	 */
+	public void setContext(StoreContext ctx) {
+		super.setContext(ctx);
+		Iterator<JDBCConfiguration> confs = _conf.iterator();
+		for (JDBCStoreManager child : _children)
+			child.setContext(ctx, confs.next());
+	}
+
+	public boolean syncVersion(OpenJPAStateManager sm, Object edata) {
+		return selectStore(sm, edata).syncVersion(sm, edata);
+	}
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org