openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ppod...@apache.org
Subject svn commit: r619145 [1/3] - in /openjpa/trunk: ./ openjpa-project/src/doc/manual/ openjpa-slice/ openjpa-slice/src/ openjpa-slice/src/main/ openjpa-slice/src/main/java/ openjpa-slice/src/main/java/org/ openjpa-slice/src/main/java/org/apache/ openjpa-sl...
Date Wed, 06 Feb 2008 20:26:17 GMT
Author: ppoddar
Date: Wed Feb  6 12:26:14 2008
New Revision: 619145

URL: http://svn.apache.org/viewvc?rev=619145&view=rev
Log:
Adding new (source code + pom.xml + doc) for Slice 

Added:
    openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_slice.xml
    openjpa/trunk/openjpa-slice/
    openjpa/trunk/openjpa-slice/pom.xml
    openjpa/trunk/openjpa-slice/src/
    openjpa/trunk/openjpa-slice/src/main/
    openjpa/trunk/openjpa-slice/src/main/java/
    openjpa/trunk/openjpa-slice/src/main/java/org/
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ExecutorServiceValue.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/Slice.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceVersion.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/AggregateResultObjectProvider.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedPreparedStatement.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedResultSet.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStatement.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedTemplate.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/SliceStoreManager.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/UniqueResultObjectProvider.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/package.html
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/package.html
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedNaiveTransaction.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedTransactionManager.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedXATransaction.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/NaiveTransactionManager.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/XID.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/package.html
    openjpa/trunk/openjpa-slice/src/main/resources/
    openjpa/trunk/openjpa-slice/src/main/resources/META-INF/
    openjpa/trunk/openjpa-slice/src/main/resources/META-INF/services/
    openjpa/trunk/openjpa-slice/src/main/resources/META-INF/services/org.apache.openjpa.lib.conf.ProductDerivation
    openjpa/trunk/openjpa-slice/src/main/resources/org/
    openjpa/trunk/openjpa-slice/src/main/resources/org/apache/
    openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/
    openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/
    openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/
    openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/localizer.properties
    openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
    openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/
    openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/localizer.properties
Modified:
    openjpa/trunk/openjpa-project/src/doc/manual/manual.xml
    openjpa/trunk/pom.xml

Modified: openjpa/trunk/openjpa-project/src/doc/manual/manual.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/manual.xml?rev=619145&r1=619144&r2=619145&view=diff
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/manual.xml (original)
+++ openjpa/trunk/openjpa-project/src/doc/manual/manual.xml Wed Feb  6 12:26:14 2008
@@ -46,7 +46,8 @@
     <!ENTITY ref_guide_deploy.xml SYSTEM "ref_guide_deploy.xml">
     <!ENTITY ref_guide_runtime.xml SYSTEM "ref_guide_runtime.xml">
     <!ENTITY ref_guide_caching.xml SYSTEM "ref_guide_caching.xml">
-    <!ENTITY ref_guide_remote.xml SYSTEM "ref_guide_remote.xml">
+    <!ENTITY ref_guide_remote.xml SYSTEM "ref_guide_remote.xml">
+    <!ENTITY ref_guide_slice.xml SYSTEM "ref_guide_slice.xml">
     <!ENTITY ref_guide_integration.xml SYSTEM "ref_guide_integration.xml">
     <!ENTITY ref_guide_optimization.xml SYSTEM "ref_guide_optimization.xml">
     <!ENTITY samples_guide.xml SYSTEM "samples_guide.xml">
@@ -100,7 +101,8 @@
         &ref_guide_deploy.xml;
         &ref_guide_runtime.xml;
         &ref_guide_caching.xml;
-        &ref_guide_remote.xml;
+        &ref_guide_remote.xml;
+        &ref_guide_slice.xml;
         &ref_guide_integration.xml;
         &ref_guide_optimization.xml;
     </part>

Added: openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_slice.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_slice.xml?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_slice.xml (added)
+++ openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_slice.xml Wed Feb  6 12:26:14 2008
@@ -0,0 +1,498 @@
+<?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.   
+-->
+<chapter id="ref_guide_slice">
+  <title>
+    Distributed Persistence
+  </title>
+  <para>
+  The standard JPA runtime environment works with a <emphasis>single</emphasis>
+  database instance. OpenJPA can be extended via plug-in to work with 
+  multiple databases within the same transaction without any change to the 
+  existing application. This capability of OpenJPA for distributed 
+  database environment is called <emphasis>Slice</emphasis> and is explained in 
+  the following sections.
+  </para>
+  
+  <section id="slice_overview">
+    <title>Overview</title>
+    <para>
+    Enterprise applications are increasingly deployed for distributed database
+    environments. The reasons for distributed, often horizontally-partitioned 
+    database environment can be to counter massive data growth, to 
+    support multiple external clients on a hosted platform or many other 
+    practical scenarios that can benefit from data partitioning.
+    </para>
+    
+    <para>
+    Any JPA-based user application has to address serious technical and conceptual
+    challenges to directly interact with a set of physical databases
+    within a single transaction. 
+    Slice encapsulates the complexity of distributed database environment 
+    via the abstraction of <emphasis>virtual</emphasis> database which internally 
+    manages multiple physical databases. We refer each physical database instance 
+    as <emphasis>slice</emphasis>. 
+    <emphasis>Virtualization</emphasis> of distributed databases 
+    makes OpenJPA object management kernel and 
+    the user application to work in the same way as in the case of a single physical 
+    database.
+    </para>
+  </section>
+  
+    <section id="Features and Limitations">
+       <title>Salient Features</title>
+         <section><title>Transparency</title>
+            <para>
+              The existing application or the persistent domain model requires 
+              <emphasis>no change</emphasis> to upgrade from a single database 
+              to a distributed database environment. 
+            </para>
+         </section>
+         
+         <section><title>Custom Distribution Policy</title>
+            <para>
+             User application decides how the newly persistent instances be 
+             distributed across the database slices. The data
+             distribution policy across the slices may be based on the attribute 
+             of the data itself. For example, all Customer whose first name begins with
+             character 'A' to 'M' will be stored in one slice while names
+             beginning with 'N' to 'Z' will be stored in another slice. 
+             <para>
+             This custom data distribution policy is specified by implementing  
+             <classname>org.apache.openjpa.slice.DistributionPolicy</classname>
+             interface by the user application.
+             </para>
+          
+             <para> 
+             Slice tracks the original database for existing instances. When
+             an application issues a query, the resultant instances can be loaded 
+             from different slices. This tracking is important as subsequent
+             update to any of these instances is committed to the appropriate 
+             original database slice. 
+            </para>
+            <para>
+            <warning>Currently, there is no provision for migrating an 
+            existing instance from one slice to another.
+            </warning>
+            </para>
+         </section>
+         
+         <section><title>Heterogeneous Database</title>
+            <para> 
+              Each slice can be configured independently with its own JDBC 
+              driver and other connection parameters. Hence the target database 
+              environment can constitute of heterogeneous databases. 
+            </para>
+        </section>
+        
+        <section><title>Parallel Execution</title>
+            <para> 
+              All database operations such as query, commit or flush operates
+              in parallel across the database slices. The execution threading
+              policy is configurable. 
+            </para>
+         </section>
+         
+         <section><title>Distributed Query</title>
+            <para>
+            The queries are executed across all slices and the results are
+            merged into a single list. The query result that includes 
+            <code>ORDER BY</code> clause are sorted correctly by merging 
+            results from each individual slice. 
+            </para>
+            The queries that specify an aggregate projection such as 
+            <code>COUNT()</code>, <code>MAX()</code>, <code>MIN()</code> 
+            and <code>SUM()</code>
+            are correctly evaluated <emphasis>only if</emphasis> they 
+            return a single result.
+            <para>
+            </para>
+            <para>
+            <warning>
+            The aggregate operation <code>AVG()</code> is not supported.
+            </warning>
+            </para>
+         </section>
+         
+         <section><title>Distributed Transaction</title>
+            <para> 
+            The database slices participate in a global transaction provided
+            each slice is configured with a XA-complaint JDBC driver, even
+            when the persistence unit is configured for <code>RESOURCE_LOCAL</code>
+            transaction.
+            </para>
+            <para>
+            <warning>
+            If any of the configured slices is not XA-complaint <emphasis>and</emphasis> 
+            the persistence unit is configured for <code>RESOURCE_LOCAL</code>
+            transaction then each slice is committed without any two-phase
+            commit protocol. If commit on any slice fails, then atomic nature of
+            the transaction is not ensured.
+            </warning>
+            </para>
+          </section>
+   
+    
+    
+        
+         <section id="collocation_constraint"><title>Collocation Constraint</title>
+            <para> 
+            No relationship can exist across database slices. In O-R mapping parlance,
+            this condition translates to the limitation that the closure of an object graph must be 
+            <emphasis>collocated</emphasis> in the same database.
+            For example, consider a domain model where Person relates to Adress.
+            Person X refers to Address A while Person Y refers to Address B. 
+            Collocation Constraint means that <emphasis>both</emphasis> X and A 
+            must be stored in the same
+            database slice. Similarly Y and B must be stored in a single slice.
+            </para>
+            <para>
+            Slice, however, helps to maintain collocation constraint automatically.
+            The instances in the closure set of any newly persistent instance 
+            reachable via cascaded relationship is stored in the same slice.
+            The user-defined distribution policy requires to supply the slice 
+            for the root instance only.
+            </para>
+         </section>
+    </section>
+  
+  <section id="slice_configuration">
+    <title>Usage</title>
+    <para>
+     Slice is activated via the following property settings:
+    </para>
+    <section>
+      <title>How to activate Slice Runtime?</title>
+      <para>
+       The basic configuration property is 
+       <programlisting> 
+        <![CDATA[ <property name="openjpa.BrokerFactory" value="slice"/>]]>
+       </programlisting> 
+       This critical configuration activates a specialized factory class aliased
+       as <code>slice</code> to create object management kernel that
+       can work against multiple databases.  
+      </para>
+    </section> 
+    
+    <section>
+      <title>How to configure each database slice?</title>
+      <para>
+      Each database slice is identified by a logical name unique within a
+      persistent unit. The list of the slices is specified by <code>slice.Names</code> property.
+      For example, specify three slices named <code>"One"</code>, 
+      <code>"Two"</code> and <code>"Three"</code> as follows:
+      <programlisting>
+      <![CDATA[ <property name="slice.Names" value="One, Two, Three"/>]]>
+      </programlisting>
+      </para>
+      <para>
+      This property is not mandatory. If this property is not specified then
+      the configuration is scanned for logical slice names. Any property
+      of the form <code>slice.XYZ.abc</code> will register a slice with logical
+      name <code>"XYZ"</code>.
+      </para>
+      <para>
+      The order of the names can be significant if no <code>slice.Master</code>
+      property is specified. 
+      </para>
+      
+      <para>
+       Each database slice can be configured independently. For example, the
+       following configuration will register two slices with logical name 
+       <code>One</code> and <code>Two</code>.
+       <programlisting> 
+        <![CDATA[<property name="slice.One.ConnectionURL" value="jdbc:mysql:localhost//slice1"/>
+        <property name="slice.Two.ConnectionURL" value="jdbc:mysql:localhost//slice2"/>]]>
+       </programlisting> 
+      </para>
+      
+      <para>
+       Any OpenJPA specific property can be configured per slice basis. 
+       For example, the following configuration will use two different JDBC 
+       drivers for slice <code>One</code> and <code>Two</code>.
+       <programlisting> 
+        <![CDATA[<property name="slice.One.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
+        <property name="slice.Two.ConnectionDriverName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>]]>
+       </programlisting> 
+      </para>
+      
+      <para>
+        Any property if unspecified for a particular slice will be defaulted by
+        corresponding OpenJPA property. For example, consider following three slices
+        <programlisting> 
+         <![CDATA[<property name="slice.One.ConnectionURL"          value="jdbc:mysql:localhost//slice1"/>
+         <property name="slice.Two.ConnectionURL"          value="jdbc:mysql:localhost//slice2"/>
+         <property name="slice.Three.ConnectionURL"        value="jdbc:oracle:localhost//slice3"/>
+
+         <property name="openjpa.ConnectionDriverName"     value="com.mysql.jdbc.Driver"/>
+         <property name="slice.Three.ConnectionDriverName" value="oracle.jdbc.Driver"/>]]>
+        </programlisting> 
+        In this example, <code>Three</code> will use slice-specific
+        <code>oracle.jdbc.Driver</code> driver while slice
+        <code>One</code> and <code>Two</code> will use
+        the driver <code>com.mysql.jdbc.Driver</code> as 
+        specified by <code>openjpa.ConnectionDriverName</code> 
+        property value.
+      </para>
+    </section>
+     
+    <section id="distribution_policy">
+       <title>Implement DistributionPolicy interface</title>
+       <para>
+        Slice needs to determine which slice will persist a new instance. 
+        The application can only decide this policy (for example, 
+        all PurchaseOrders before April 30 goes to slice <code>One</code>,
+        all the rest goes to slice <code>Two</code>). This is why
+        the application has to implement 
+        <code>org.apache.openjpa.slice.DistributionPolicy</code> and
+        specify the implementation class in configuration
+        <programlisting> 
+         <![CDATA[ <property name="slice.DistributionPolicy" value="com.acme.foo.MyOptimialDistributionPolicy"/>]]>
+        </programlisting>
+       </para>
+       
+       <para>
+        The interface <code>org.apache.openjpa.slice.DistributionPolicy</code>
+        is simple with a single method. The complete listing of the
+        documented interface follows:
+       <programlisting> 
+       <![CDATA[ 
+public interface DistributionPolicy {
+    /**
+     * Gets the name of the slice where a given instance will be stored.
+     *  
+     * @param pc The newly persistent or to-be-merged object. 
+     * @param slices name of the configured slices.
+     * @param context persistence context managing the given instance.
+     * 
+     * @return identifier of the slice. This name must match one of the
+     * configured slice names. 
+     * @see DistributedConfiguration#getSliceNames()
+     */
+    String distribute(Object pc, List<String> slices, Object context);
+}
+]]>
+       </programlisting>
+        </para>
+        
+        <para>
+        While implementing a distribution policy the most important thing to
+        remember is <link linkend="collocation_constraint">collocation constraint</link>.
+        Because Slice can not establish or query any cross-database relationship, all the
+        related instances must be stored in the same database slice. 
+ 
+        Slice can determine the closure of a root object by traversal of 
+        cascaded relationships. Hence user-defined policy has to only decide the
+        database for the root instance that is the explicit argument to 
+        <code>EntityManager.persist()</code> call.
+        Slice will ensure that all other related instances that gets persisted by cascade
+        is assigned to the same database slice as that of the root instance.
+        However, the user-defined distribution policy must return the
+        same slice identifier for the instances that are logically related but
+        not cascaded for persist. 
+        </para>
+    </section>
+    
+    <section>
+    </section>
+  </section>
+  
+  <title>Configuration Properties</title>
+    <para>
+    The properties to configure Slice can be classified in two broad groups.
+The <emphasis>global</emphasis> properties apply to all the slices, for example,
+the thread pool used to execute the queries in parallel or the transaction 
+manager used to coordinate transaction across multiple slices. 
+The <emphasis>per-slice</emphasis> properties apply to individual slice, for example,
+the JDBC connection URL of a slice.
+   </para>
+   
+   <section>
+     <title>Global Properties</title>
+     
+     <section>
+        <title>slice.DistributionPolicy</title>
+        <para>
+         This <emphasis>mandatory</emphasis> plug-in property determines how newly
+         persistent instances are distributed across individual slices. 
+         The value of this property is a fully-qualified class name that implements
+         <ulink url="../javadoc/org/apache/openjpa/slice/DistributionPolicy.html">
+         <classname>org.apache.openjpa.slice.DistributionPolicy</classname>
+         </ulink> interface.
+        </para>
+     </section>
+     
+     <section><title>slice.Lenient</title>
+      <para>
+        This boolean plug-in property controls the behavior when one or more slice 
+        can not be connected or unavailable for some other reasons.
+        If <code>true</code>, the unreachable slices are ignored. If 
+        <code>false</code> then any unreachable slice will raise an exception
+        during startup.
+        </para>
+        <para>
+        By default this value is set to <code>false</code> i.e. all configured
+        slices must be available.
+        </para> 
+     </section>
+
+     <section>
+      <title>slice.Master</title>
+      <para>
+       This plug-in property can be used to identify the name of the master slice. 
+       Master slice is used when a primary key is to be generated from a database sequence. 
+       </para>
+       <para>
+        By default the master slice is the first slice in the list of configured slice names. 
+       </para>
+       <para>
+              <warning>
+              Currently, there is no provision to use sequence from 
+              multiple database slices.
+              </warning>
+       </para>
+     </section>
+    
+     <section>
+        <title>slice.Names</title>
+        <para>
+         This plug-in property can be used to register the logical slice names.
+         The value of this property is comma-separated list of slice names. 
+         The ordering of the names in this list is 
+         <emphasis>significant</emphasis> because 
+         <link linkend="distribution_policy">DistributionPolicy</link> receives 
+         the input argument of the slice names in the same order.
+        </para>
+        <para>
+        If logical slice names are not registered explicitly via this property,
+        then all logical slice names available in the persistence unit are 
+        registered. The ordering of the slice names in this case is alphabetical.  
+        </para>
+        <para>
+        If logical slice names are registered explicitly via this property, then
+        any logical slice that is available in the persistence unit but excluded
+        from this list is ignored. 
+        </para>
+     </section>
+    
+     <section>
+        <title>slice.ThreadingPolicy</title>
+        <para>
+        This plug-in property determines the nature of thread pool being used 
+        for database operations such as query or flush on individual slices. 
+        The value of the property is a 
+        fully-qualified class name that implements 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html">
+        <classname>java.util.concurrent.ExecutorService</classname>
+        </ulink> interface.  
+        Two pre-defined pools can be chosen via their aliases namely 
+        <code>fixed</code> or <code>cached</code>.
+        </para>
+        <para>
+        The pre-defined alias <code>cached</code> activates a 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool()">cached thread pool</ulink>. 
+        A cached thread pool creates new threads as needed, but will reuse 
+        previously constructed threads when they are available. This pool 
+        is suitable in scenarios that execute many short-lived asynchronous tasks.
+        The way Slice uses the thread pool to execute database operations is 
+        akin to such scenario and hence <code>cached</code> is the default 
+        value for this plug-in property.  
+        </para>
+        <para>
+        The <code>fixed</code> alias activates a 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int)">fixed thread pool</ulink>.
+        The fixed thread pool can be further parameterized with 
+        <code>CorePoolSize</code>, <code>MaximumPoolSize</code>, 
+        <code>KeepAliveTime</code> and <code>RejectedExecutionHandler</code>. 
+        The meaning of these parameters are described in 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html">JavaDoc</ulink>.
+        The users can exercise finer control on thread pool behavior via these
+        parameters.
+        By default, the core pool size is <code>10</code>, maximum pool size is
+        also <code>10</code>, keep alive time is <code>60</code> seconds and 
+        rejected execution is 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.AbortPolicy.html">aborted</ulink>.
+        </para>
+        <para>
+        Both of the pre-defined aliases can be parameterized with a fully-qualified
+        class name that implements 
+        <ulink url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadFactory.html">
+        <classname>java.util.concurrent.ThreadFactory</classname>
+        </ulink> interface.
+        </para>
+     </section>
+      
+     <section>
+      <title>slice.TransactionPolicy</title>
+      <para>
+      This plug-in property determines the policy for transaction commit 
+      across multiple slices. The value of this property is a fully-qualified 
+      class name that implements 
+      <ulink url="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/transaction/TransactionManager.html">
+      <classname>javax.transaction.TransactionManager</classname> 
+      </ulink> interface. 
+      </para>
+      <para>
+      Three pre-defined policies can be chosen
+      by their aliases namely <code>default</code>,
+      <code>xa</code> and <code>jndi</code>. 
+      </para>
+      <para>
+      The <code>default</code> policy employs 
+      a Transaction Manager that commits or rolls back transaction on individual
+      slices <emphasis>without</emphasis> a two-phase commit protocol. 
+      It does <emphasis>not</emphasis>
+      guarantee atomic nature of transaction across all the slices because if
+      one or more slice fails to commit, there is no way to rollback the transaction
+      on other slices that committed successfully.
+      </para>
+      <para>
+      The <code>xa</code> policy employs a Transaction Manager that that commits 
+      or rolls back transaction on individual
+      slices using a two-phase commit protocol. The prerequisite to use this scheme
+      is, of course, that all the slices must be configured to use
+      XA-complaint JDBC driver. 
+      </para>
+      <para>
+      The <code>jndi</code> policy employs a Transaction Manager by looking up the
+      JNDI context. The prerequisite to use this transaction
+      manager is, of course, that all the slices must be configured to use
+      XA-complaint JDBC driver. 
+      <warning>This JNDI based policy is not available currently.</warning>
+      </para>
+    </section>
+   </section>
+   
+   <section>
+     <title>Per-Slice Properties</title>
+     <para>
+     Any OpenJPA property can be configured for each individual slice. The property name
+     is of the form <code>slice.[Logical slice name].[OpenJPA Property Name]</code>.
+     For example, <code>slice.One.ConnectionURL</code> where <code>One</code>
+     is the logical slice name and <code>ConnectionURL</code> is a OpenJPA property
+     name. 
+     </para>
+     <para>
+     If a property is not configured for a specific slice, then the value for
+     the property equals to the corresponding <code>openjpa.*</code> property.
+     </para>
+   </section>
+  
+</chapter>
+  
\ No newline at end of file

Added: openjpa/trunk/openjpa-slice/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/pom.xml?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/pom.xml (added)
+++ openjpa/trunk/openjpa-slice/pom.xml Wed Feb  6 12:26:14 2008
@@ -0,0 +1,61 @@
+<?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/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.openjpa</groupId>
+    <artifactId>openjpa-slice</artifactId>
+    <packaging>jar</packaging>
+    <name>OpenJPA Slice</name>
+    <description>OpenJPA Slice</description>
+    <url>http://openjpa.apache.org</url>
+    <parent>
+        <groupId>org.apache.openjpa</groupId>
+        <artifactId>openjpa-parent</artifactId>
+        <version>1.1.0-SNAPSHOT</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.openjpa</groupId>
+            <artifactId>openjpa-kernel</artifactId>
+            <version>${pom.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.openjpa</groupId>
+            <artifactId>openjpa-jdbc</artifactId>
+            <version>${pom.version}</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,82 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice;
+
+import org.apache.openjpa.kernel.BrokerImpl;
+import org.apache.openjpa.kernel.OpCallbacks;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * A specialized Broker to associate slice identifiers with the StateManagers as
+ * they are persisted in a cascade. This intervention helps the user to define
+ * distribution policy only for root instances i.e. the instances that are
+ * explicit argument to persist() call. The cascaded instances are assigned the
+ * same slice to honor collocation constraint.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+@SuppressWarnings("serial")
+public class DistributedBrokerImpl extends BrokerImpl {
+	private transient String slice;
+
+	private static final Localizer _loc =
+			Localizer.forPackage(DistributedBrokerImpl.class);
+
+	/**
+	 * Assigns slice identifier to the resultant StateManager as initialized by
+	 * the super class implementation. The slice identifier is decided by
+	 * {@link DistributionPolicy} for given <code>pc</code> if it is a root
+	 * instance i.e. the argument of the user application's persist() call. The
+	 * cascaded instances are detected by non-empty status of the current
+	 * operating set. The slice is assigned only if a StateManager has never
+	 * been assigned before.
+	 */
+	public OpenJPAStateManager persist(Object pc, Object id, boolean explicit,
+			OpCallbacks call) {
+		OpenJPAStateManager sm = getStateManager(pc);
+		if (getOperatingSet().isEmpty()
+				&& (sm == null || sm.getImplData() == null)) {
+			slice = getSlice(pc);
+		}
+		sm = super.persist(pc, id, explicit, call);
+		if (sm.getImplData() == null)
+			sm.setImplData(slice, true);
+
+		return sm;
+	}
+
+	/**
+	 * Gets the slice by the user-defined distribution policy.
+	 */
+	String getSlice(Object pc) {
+		DistributedConfiguration conf =
+				(DistributedConfiguration) getConfiguration();
+		String slice =
+				(conf.getDistributionPolicyInstance().distribute(pc, conf
+						.getActiveSliceNames(), this));
+		if (!conf.getActiveSliceNames().contains(slice))
+			throw new UserException(_loc.get("bad-policy-slice", new Object[] {
+					conf.getDistributionPolicyInstance().getClass().getName(),
+					slice, pc, conf.getActiveSliceNames() }));
+		return slice;
+	}
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,78 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.List;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+
+/**
+ * A configuration for multiple data stores, each referred as <em>slice</em>.
+ * This configuration allows each underlying slice be configured with its
+ * own specific configuration properties such as JDBC Driver or connection
+ * user/password etc. <br>
+ * This configuration also extends by adding a {@link DistributionPolicy 
+ * DistributionPolicy} that governs how new instances be distributed
+ * among the slices.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public interface DistributedConfiguration extends OpenJPAConfiguration {
+	/**
+	 * Gets the active slice identifiers. This list is determined by the
+	 * configuration properties either by explicit listing in 
+	 * <code>slice.Names</code> property or by scanning <code>slice.*.*</code>
+	 * properties.
+	 * <br> 
+	 * The ordering of the slice identifiers is determined when they are
+	 * specified explicitly in <code>slice.Names</code> property or 
+	 * ordered alphabetically when found by scanning the properties.
+	 * <br>
+	 * This list always returns the identifiers that are <em>active</em>, slices
+	 * that can not be connected to are not included in this list.
+	 */
+	List<String> getActiveSliceNames();
+	
+	/**
+	 * Gets the available slice identifiers irrespective of their status.
+	 * @return
+	 */
+    List<String> getAvailableSliceNames();
+
+	
+	/**
+	 * Gets the slices of given status.
+	 * @param statuses list of status flags. If null, returns all slices 
+	 * irrespective of status;
+	 */
+	List<Slice> getSlices(Slice.Status...statuses);
+	
+	/**
+	 * Gets the Slice for a given name.
+	 * Exception is raised if the given slice is not configured.
+	 */
+	Slice getSlice(String sliceName);
+	
+	/**
+	 * Gets the policy that governs how new instances will be distributed across
+	 * the available slices.
+	 */
+	DistributionPolicy getDistributionPolicyInstance();
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,46 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.List;
+
+
+/**
+ * Policy to select one of the physical databases referred as <em>slice</em>
+ * in which a given persistent instance will be stored.
+ *  
+ * @author Pinaki Poddar 
+ *
+ */
+public interface DistributionPolicy {
+	/**
+	 * Gets the name of the slice where a given instance will be stored.
+	 *  
+	 * @param pc The newly persistent or to-be-merged object. 
+	 * @param slices list of names of the configured slices. The ordering of 
+	 * the list is either explicit (by the <code>slice.Names</code> property)
+	 * or implicit i.e. alphabetic if <code>slice.Names</code> is unspecified.  
+	 * @param context generic persistence context managing the given instance.
+	 * 
+	 * @return identifier of the slice. This name must match one of the
+	 * configured slice names. 
+	 * @see DistributedConfiguration#getActiveSliceNames()
+	 */
+	String distribute(Object pc, List<String> slices, Object context);
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ExecutorServiceValue.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ExecutorServiceValue.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ExecutorServiceValue.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ExecutorServiceValue.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,112 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.openjpa.event.RemoteCommitEventManager;
+import org.apache.openjpa.event.RemoteCommitProvider;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.conf.PluginValue;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Value type used to represent a {@link ExecutorService}.
+ * This value controls the thread pool parameters. The thread pool is used
+ * to execute the queries.
+ * 
+ * @author Pinaki Poddar
+ * @nojavadoc
+ */
+
+public class ExecutorServiceValue extends PluginValue {
+    private static List<String> known =
+            Arrays.asList(new String[] { "cached", "fixed" });
+
+    private static Localizer _loc =
+            Localizer.forPackage(ExecutorServiceValue.class);
+
+    public ExecutorServiceValue() {
+        super("ThreadingPolicy", true);
+        setDefault("cached");
+    }
+
+    public void setProperties(String props) {
+        super.setProperties(props);
+    }
+
+    /**
+     * Configures a cached or fixed thread pool.
+     */
+    @Override
+    public Object instantiate(Class type, Configuration conf, boolean fatal) {
+        Object obj = null;
+        int defaultSize = 10;
+        String cls = getClassName();
+        if (!known.contains(cls))
+            cls = "cached";
+
+        Options opts = Configurations.parseProperties(getProperties());
+
+        ThreadFactory factory = null;
+        if (opts.containsKey("ThreadFactory")) {
+            String fName = opts.getProperty("ThreadFactory");
+            try {
+                factory = (ThreadFactory) Class.forName(fName).newInstance();
+                Configurations.configureInstance(factory, conf, opts,
+                        getProperty());
+            } catch (Throwable t) {
+                throw new UserException(_loc.get("bad-thread-factory", fName), t);
+            } finally {
+                opts.removeProperty("ThreadFactory");
+            }
+        } else {
+            factory = Executors.defaultThreadFactory();
+        }
+        if ("cached".equals(cls)) {
+            obj = Executors.newCachedThreadPool(factory);
+        } else if ("fixed".equals(cls)) {
+            long keepAliveTime = 60L;
+            if (opts.containsKey("KeepAliveTime")) {
+                keepAliveTime = opts.getLongProperty("KeepAliveTime");
+                opts.removeLongProperty("KeepAliveTime");
+            }
+            obj = new ThreadPoolExecutor(defaultSize, defaultSize,
+                            keepAliveTime, TimeUnit.SECONDS,
+                            new PriorityBlockingQueue<Runnable>(), factory);
+
+            Configurations.configureInstance(obj, conf, opts, getProperty());
+        }
+        set(obj, true);
+        return obj;
+    }
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,50 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.Map;
+
+import org.apache.openjpa.conf.OpenJPAProductDerivation;
+import org.apache.openjpa.lib.conf.AbstractProductDerivation;
+import org.apache.openjpa.slice.jdbc.DistributedJDBCBrokerFactory;
+
+/**
+ * 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;
+	}
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/Slice.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/Slice.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/Slice.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/Slice.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,98 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+
+/**
+ * Represents a database slice of immutable logical name.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class Slice implements Comparable<Slice> {
+    public enum Status {
+        NOT_INITIALIZED, 
+        ACTIVE, 
+        INACTIVE, // configured but not available
+        EXCLUDED  // configured but not used
+    }; 
+    
+    private final String name;
+    private transient final OpenJPAConfiguration conf;
+    private transient Status status;
+    
+    /**
+     * Supply the logical name and configuration.
+     */
+    public Slice(String name, OpenJPAConfiguration conf) {
+        this.name = name;
+        this.conf = conf;
+        this.status = Status.NOT_INITIALIZED;
+    }
+    
+    /**
+     * Gets the immutable logical name.
+     */
+    public String getName() {
+        return name;
+    }
+    
+    public OpenJPAConfiguration getConfiguration() {
+        return conf;
+    }
+    
+    public Status getStatus() {
+        return status;
+    }
+    
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+    
+    public boolean isActive() {
+        return status == Status.ACTIVE;
+    }
+    
+    public String toString() {
+        return name;
+    }
+    
+    public int compareTo(Slice other) {
+        return name.compareTo(other.name);
+    }
+    
+    /**
+     * Equals by name.
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) return true;
+        if (other == null) return false;
+        if (other instanceof Slice) {
+            return name.equals(((Slice)other).getName());
+        }
+        return false;
+    }
+    
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,50 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.kernel.StateManagerImpl;
+import org.apache.openjpa.util.ImplHelper;
+
+/**
+ * A helper to determine the slice identifier of an instance.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class SlicePersistence {
+	/**
+	 * Get the slice identifier for the given instance if it is a managed
+	 * instance and has been assigned to a slice.
+	 * 
+	 * @return name of the slice, if any. null otherwise.
+	 */
+	public static String getSlice(Object obj) {
+		if (obj == null)
+			return null;
+		PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, null);
+		if (pc == null)
+			return null;
+		StateManagerImpl sm = (StateManagerImpl)pc.pcGetStateManager();
+		if (sm == null)
+			return null;
+		Object slice = sm.getImplData();
+		return (slice instanceof String) ? (String)slice : null;
+	}
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceVersion.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceVersion.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceVersion.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceVersion.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,55 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice;
+
+import java.io.InputStream;
+import java.util.Properties;
+
+public class SliceVersion  {
+    public static final String VERSION;
+    public static final String REVISION;
+    
+    static {
+        Properties revisionProps = new Properties();
+        try {
+            InputStream in = SliceVersion.class.getResourceAsStream
+                ("/META-INF/org.apache.openjpa.slice.revision.properties");
+            if (in != null) {
+                try {
+                    revisionProps.load(in);
+                } finally {
+                    in.close();
+                }
+            }
+        } catch (Exception e) {
+        }
+
+        VERSION = revisionProps.getProperty("slice.version", "0.0.0");
+        REVISION = revisionProps.getProperty("revision.number");
+    }
+    
+    public static void main(String[] args) {
+        System.out.println(new SliceVersion());
+    }
+    
+    public String toString() {
+        return "Slice Version " + VERSION + " [revision "+REVISION+"]";
+    }
+
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/AggregateResultObjectProvider.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/AggregateResultObjectProvider.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/AggregateResultObjectProvider.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/AggregateResultObjectProvider.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,120 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
+import org.apache.openjpa.kernel.exps.Value;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.util.InternalException;
+
+public class AggregateResultObjectProvider implements ResultObjectProvider {
+    private final ResultObjectProvider[] _rops;
+    private final StoreQuery _query;
+    private final QueryExpressions[] _exps;
+    private Object _single;
+    private boolean _opened;
+
+    public AggregateResultObjectProvider(ResultObjectProvider[] rops, 
+            StoreQuery q, QueryExpressions[] exps) {
+        _rops = rops;
+        _query = q;
+        _exps = exps;
+    }
+    
+    public boolean absolute(int pos) throws Exception {
+        return false;
+    }
+
+    public void close() throws Exception {
+        _opened = false;
+        for (ResultObjectProvider rop:_rops)
+            rop.close();
+    }
+
+    public Object getResultObject() throws Exception {
+        if (!_opened)
+            throw new InternalException(this + " not-open");
+        return _single;
+    }
+
+    public void handleCheckedException(Exception e) {
+        _rops[0].handleCheckedException(e);
+    }
+
+    public boolean next() throws Exception {
+        if (!_opened) {
+            open();
+        }
+            
+        if (_single != null)
+            return false;
+        
+        Value[] values = _exps[0].projections;
+        Object[] single = new Object[values.length]; 
+        for (int i=0; i<values.length; i++) {
+            Value v = values[i];
+            boolean isAggregate = v.isAggregate();
+            int op = decideOperationType(v);
+            for (ResultObjectProvider rop:_rops) {
+                rop.next();
+                Object[] row = (Object[]) rop.getResultObject();
+                switch (op) {
+                case 2: single[i] = count(single[i],row[i]);
+                break;
+                default : single[i] = row[i];
+                }
+            } 
+        }
+        
+        _single = single;
+        return true;
+    }
+    
+    int decideOperationType(Value v) {
+        String cls = v.getClass().getName();
+        if (cls.equals("org.apache.openjpa.jdbc.kernel.exps.Sum"))
+            return 1;
+        if (cls.equals("org.apache.openjpa.jdbc.kernel.exps.Count"))
+            return 2;
+        return 0;
+    }
+    long count(Object current, Object other) {
+        if (current == null)
+            return (Long) other;
+        return (Long)current + (Long)other;
+    }
+
+    public void open() throws Exception {
+        for (ResultObjectProvider rop:_rops)
+            rop.open();
+        _opened = true;
+    }
+
+    public void reset() throws Exception {
+    }
+
+    public int size() throws Exception {
+        return 1;
+    }
+
+    public boolean supportsRandomAccess() {
+         return false;
+    }
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedConnection.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,263 @@
+/*
+ * 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.    
+ */
+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
+ * 
+ */
+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: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,102 @@
+/*
+ * 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.    
+ */
+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 javax.sql.XADataSource;
+
+import org.apache.openjpa.lib.jdbc.DecoratingDataSource;
+
+/**
+ * A virtual datasource that contains many physical datasources.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+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));
+		real = dataSources;
+		master = dataSources.get(0);
+	}
+	
+	Connection getConnection(DataSource ds) throws SQLException {
+		if (ds instanceof DecoratingDataSource)
+			return getConnection(((DecoratingDataSource)ds).getInnermostDelegate());
+		if (ds instanceof XADataSource)
+			return ((XADataSource)ds).getXAConnection().getConnection();
+		return ds.getConnection();
+	}
+	
+	Connection getConnection(DataSource ds, String user, String pwd) throws SQLException {
+		if (ds instanceof DecoratingDataSource)
+			return getConnection(((DecoratingDataSource)ds).getInnermostDelegate(), user, pwd);
+		if (ds instanceof XADataSource)
+			return ((XADataSource)ds).getXAConnection(user, pwd).getConnection();
+		return ds.getConnection(user, pwd);
+	}
+
+	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: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,107 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.util.Map;
+
+import org.apache.openjpa.conf.OpenJPAVersion;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+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;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.slice.SliceVersion;
+
+/**
+ * A factory for distributed JDBC datastores.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+@SuppressWarnings("serial")
+public class DistributedJDBCBrokerFactory extends JDBCBrokerFactory {
+	private static final Localizer _loc = 
+	    Localizer.forPackage(DistributedJDBCBrokerFactory.class);
+	/**
+	 * Factory method for constructing a factory from properties. Invoked from
+	 * {@link Bootstrap#newBrokerFactory}.
+	 */
+	public static DistributedJDBCBrokerFactory newInstance(
+			ConfigurationProvider cp) {
+		DistributedJDBCConfigurationImpl conf =
+				new DistributedJDBCConfigurationImpl(cp);
+		cp.setInto(conf);
+		return new DistributedJDBCBrokerFactory(conf);
+	}
+
+	/**
+	 * Factory method for obtaining a possibly-pooled factory from properties.
+	 * Invoked from {@link Bootstrap#getBrokerFactory}.
+	 */
+	public static JDBCBrokerFactory getInstance(ConfigurationProvider cp) {
+	    Map properties = cp.getProperties();
+	    Object key = toPoolKey(properties);
+		DistributedJDBCBrokerFactory factory =
+				(DistributedJDBCBrokerFactory) getPooledFactoryForKey(key);
+		if (factory != null)
+			return factory;
+
+		factory = newInstance(cp);
+		pool(key, factory);
+		return factory;
+	}
+
+	/**
+	 * Factory method for constructing a factory from a configuration.
+	 */
+	public static synchronized JDBCBrokerFactory getInstance(
+			JDBCConfiguration conf) {
+	    Map properties = conf.toProperties(false);
+	    Object key = toPoolKey(properties);
+		DistributedJDBCBrokerFactory factory =
+				(DistributedJDBCBrokerFactory) getPooledFactoryForKey(key);
+		if (factory != null)
+			return factory;
+
+		factory = new DistributedJDBCBrokerFactory(
+		        (DistributedJDBCConfiguration) conf);
+		pool(key, factory);
+		return factory;
+	}
+
+	public DistributedJDBCBrokerFactory(DistributedJDBCConfiguration conf) {
+		super(conf);
+	}
+	
+	@Override
+	public DistributedJDBCConfiguration getConfiguration() {
+	    return (DistributedJDBCConfiguration)super.getConfiguration();
+	}
+
+	@Override
+	protected StoreManager newStoreManager() {
+		return new DistributedStoreManager(getConfiguration());
+	}
+	
+    @Override
+    protected Object getFactoryInitializationBanner() {
+        return _loc.get("factory-init", new SliceVersion());
+    }
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfiguration.java Wed Feb  6 12:26:14 2008
@@ -0,0 +1,63 @@
+/*
+ * 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.    
+ */
+package org.apache.openjpa.slice.jdbc;
+
+import java.util.concurrent.ExecutorService;
+
+import javax.transaction.TransactionManager;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.slice.DistributedConfiguration;
+import org.apache.openjpa.slice.Slice;
+
+/**
+ * A distributed configuration that is a ordered collection of 
+ * JDBCConfigurations.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public interface DistributedJDBCConfiguration extends JDBCConfiguration, 
+	DistributedConfiguration {
+    /**
+     * Gets the master slice.
+     */
+    Slice getMaster();
+    
+    /**
+     * Gets the TransactionManager instance being used.
+     */
+    TransactionManager getTransactionManagerInstance();
+    
+    /**
+     * Gets the alias for TransactionManager being used.
+     */
+    String getTransactionManager();
+    
+    /**
+     * Gets the alias for ExecutorService being used.
+     */
+    
+    String getExecutorService();
+    
+    /**
+     * Gets the ExecutorService being used.
+     */
+    ExecutorService getExecutorServiceInstance();
+}



Mime
View raw message