openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ppod...@apache.org
Subject svn commit: r619145 [3/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
Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/SliceStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/SliceStoreManager.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/SliceStoreManager.java
(added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/SliceStoreManager.java
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,113 @@
+/*
+ * 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.Connection;
+import java.sql.SQLException;
+
+import javax.sql.DataSource;
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
+import org.apache.openjpa.lib.jdbc.DelegatingDataSource;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.slice.Slice;
+import org.apache.openjpa.util.InternalException;
+
+/**
+ * A specialized JDBCStoreManager for XA-complaint DataSource.
+ * If the configured DataSource is not XA-complaint, behaves as the super 
+ * implementation.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class SliceStoreManager extends JDBCStoreManager {
+	private final Slice _slice;
+	private Boolean isXAEnabled;
+	private XAConnection xcon;
+	
+	private static final Localizer _loc = 
+		Localizer.forPackage(SliceStoreManager.class);
+	
+	/**
+	 * Construct with immutable logical name of the slice. 
+	 */
+	public SliceStoreManager(Slice slice) {
+		_slice = slice;
+	}
+	
+	/**
+	 * Gets the slice for which this receiver is working.
+	 */
+	public Slice getSlice() {
+	    return _slice;
+	}
+	
+	public String getName() {
+	    return _slice.getName();
+	}
+	
+	/**
+	 * Gets the connection via XAConnection if the datasource is XA-complaint.
+	 * Otherwise, behaves exactly as the super implementation. 
+	 */
+	@Override
+	protected RefCountConnection connectInternal() throws SQLException { 
+		if (!isXAEnabled)
+			return super.connectInternal();
+		XADataSource xds = getXADataSource();
+		xcon = xds.getXAConnection();
+		Connection con = xcon.getConnection();
+		return new RefCountConnection(con);
+	}
+	
+	/**
+	 * Gets the XAConnection if connected and XA-complaint. Otherwise null.
+	 */
+	public XAConnection getXAConnection() {
+		return xcon;
+	}
+	
+	private XADataSource getXADataSource() {
+		if (!isXAEnabled())
+			throw new InternalException(_loc.get("slice-not-xa", this));
+		return (XADataSource)getInnerDataSource();
+	}
+	
+	/**
+	 * Affirms if the configured DataSource is XA-complaint.
+	 * Can return null if the context has not been set yet.
+	 */
+	public boolean isXAEnabled() {
+		if (isXAEnabled == null) {
+			isXAEnabled = getInnerDataSource() instanceof XADataSource;
+		}
+		return isXAEnabled.booleanValue();
+	}
+	
+	private DataSource getInnerDataSource() {
+		DataSource parent = super.getDataSource();
+		DataSource real = (parent instanceof DelegatingDataSource) ?
+				((DelegatingDataSource)parent).getInnermostDelegate() 
+				: parent;
+		return real;
+	}
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/UniqueResultObjectProvider.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/UniqueResultObjectProvider.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/UniqueResultObjectProvider.java
(added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/UniqueResultObjectProvider.java
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,148 @@
+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.lib.util.Localizer;
+import org.apache.openjpa.util.InternalException;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Aggregates individual single query results from different databases.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+public class UniqueResultObjectProvider implements ResultObjectProvider {
+    private final ResultObjectProvider[] _rops;
+    private final StoreQuery _query;
+    private final QueryExpressions[] _exps;
+    private Object _single;
+    private boolean _opened;
+    
+    private static final String COUNT = "Count";
+    private static final String MAX   = "Max";
+    private static final String MIN   = "Min";
+    private static final String SUM   = "Sum";
+    
+    private static final Localizer _loc =
+        Localizer.forPackage(UniqueResultObjectProvider.class);
+    
+    public UniqueResultObjectProvider(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(_loc.get("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();
+            String op = v.getClass().getSimpleName();
+            for (ResultObjectProvider rop:_rops) {
+                rop.next();
+                Object[] row = (Object[]) rop.getResultObject();
+                if (isAggregate) {
+                    if (COUNT.equals(op)) {
+                        single[i] = count(single[i], row[i]);
+                    } else if (MAX.equals(op)) {
+                        single[i] = max(single[i], row[i]);
+                    } else if (MIN.equals(op)) {
+                        single[i] = min(single[i], row[i]);
+                    } else if (SUM.equals(op)) {
+                        single[i] = sum(single[i], row[i]);
+                    } else {
+                        throw new UnsupportedOperationException
+                            (_loc.get("aggregate-unsupported", op).toString());
+                    }
+                } else {
+                    single[i] = row[i];
+                }
+            }
+        }
+        _single = single;
+        return true;
+    }
+    
+    Object count(Object current, Object other) {
+        if (current == null)
+            return other;
+        return ((Number)current).longValue() + ((Number)other).longValue();
+    }
+    
+    Object max(Object current, Object other) {
+        if (current == null)
+            return other;
+        
+        return Math.max(((Number)current).doubleValue(), 
+                ((Number)other).doubleValue());
+    }
+    
+    Object min(Object current, Object other) {
+        if (current == null)
+            return other;
+        return Math.min(((Number)current).doubleValue(), 
+                ((Number)other).doubleValue());
+    }
+    
+    Object sum(Object current, Object other) {
+        if (current == null)
+            return other;
+        return (((Number)current).doubleValue() +
+                ((Number)other).doubleValue());
+    }
+
+
+
+    public void open() throws Exception {
+        for (ResultObjectProvider rop:_rops)
+            rop.open();
+        _opened = true;
+    }
+
+    public void reset() throws Exception {
+        _single = null;
+        for (ResultObjectProvider rop : _rops) {
+            rop.reset();
+        }
+    }
+
+    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/package.html
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/package.html?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/package.html (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/package.html Wed
Feb  6 12:26:14 2008
@@ -0,0 +1,11 @@
+<HTML>
+<BODY>
+Implements Distributed version of JDBCStoreManager and JDBCStoreQuery. 
+
+This package contains implementaions of OpenJPA interfaces using a distribution
+template pattern. Distribution template pattern for <code>T</code> is 
+defined as a type <code>T'</code>
+such that <code>T' extends T implements Iterable<T></code> i.e.<code>T'</code>

+is a special <code>T</code> that also contains many <code>T</code>.

+</BODY>
+</HTML>
\ No newline at end of file

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/package.html
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/package.html?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/package.html (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/package.html Wed Feb
 6 12:26:14 2008
@@ -0,0 +1,8 @@
+<HTML>
+<BODY>
+Extended OpenJPA Interfaces for distributed databases.
+
+This package contains interface definitions for distribution policy and
+distributed configuration.
+</BODY>
+</HTML>
\ No newline at end of file

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedNaiveTransaction.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedNaiveTransaction.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedNaiveTransaction.java
(added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedNaiveTransaction.java
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,75 @@
+package org.apache.openjpa.slice.transaction;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAResource;
+
+import org.apache.openjpa.slice.jdbc.SliceStoreManager;
+
+public class DistributedNaiveTransaction implements Transaction {
+    private Set<SliceStoreManager> _slices = new HashSet<SliceStoreManager>();
+    private Set<Synchronization> _syncs = new HashSet<Synchronization>();
+    private final TransactionManager _tm;
+    private int _status;
+    private boolean _rollbackOnly;
+
+    DistributedNaiveTransaction(TransactionManager tm) {
+        _tm = tm;
+    }
+
+    public void commit() throws HeuristicMixedException,
+            HeuristicRollbackException, RollbackException, SecurityException,
+            SystemException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean delistResource(XAResource arg0, int arg1)
+            throws IllegalStateException, SystemException {
+        return _slices.remove(arg0);
+    }
+
+    public boolean enlistResource(XAResource arg0)
+            throws IllegalStateException, RollbackException, SystemException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean enlistResource(SliceStoreManager arg0)
+            throws IllegalStateException, RollbackException, SystemException {
+        return _slices.add(arg0);
+    }
+
+    public int getStatus() throws SystemException {
+        return _status;
+    }
+
+    public void registerSynchronization(Synchronization arg0)
+            throws IllegalStateException, RollbackException, SystemException {
+        _syncs.add(arg0);
+    }
+
+    public void rollback() throws IllegalStateException, SystemException {
+        _tm.rollback();
+    }
+
+    public void setRollbackOnly() throws IllegalStateException, SystemException {
+        _rollbackOnly = true;
+    }
+    
+    public boolean isRollbackOnly() {
+        return _rollbackOnly;
+    }
+
+    Set<SliceStoreManager> getEnlistedResources() {
+        return Collections.unmodifiableSet(_slices);
+    }
+
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedTransactionManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedTransactionManager.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedTransactionManager.java
(added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedTransactionManager.java
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,191 @@
+/*
+ * 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.transaction;
+
+import static javax.transaction.xa.XAResource.TMJOIN;
+import static javax.transaction.xa.XAResource.TMNOFLAGS;
+import static javax.transaction.xa.XAResource.TMSUCCESS;
+
+import java.util.Set;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+
+import org.apache.openjpa.lib.util.Localizer;
+
+/**
+ * A simple (naive?) implementation for distributed transaction across 
+ * XA-complaint data sources. 
+ * Assumes begin() and commit() being called on the same thread.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class DistributedTransactionManager implements TransactionManager {
+    private final ThreadLocal<DistributedXATransaction> txns =
+            new ThreadLocal<DistributedXATransaction>();
+    private static final Localizer _loc =
+            Localizer.forPackage(DistributedTransactionManager.class);
+
+    public void begin() throws NotSupportedException, SystemException {
+        DistributedXATransaction txn = getTransaction(false);
+        int i = 1;
+        Set<XAResource> resources = txn.getEnlistedResources();
+        for (XAResource resource : resources) {
+            try {
+                XAResource existing = isSame(resource, resources);
+                XID branch = txn.getXID().branch(i++);
+                int flag = (existing == null) ? TMNOFLAGS : TMJOIN;
+                resource.start(branch, flag);
+            } catch (Exception e) {
+                throw new SystemException(e.toString());
+            }
+        }
+    }
+
+    public void commit() throws HeuristicMixedException,
+            HeuristicRollbackException, IllegalStateException,
+            RollbackException, SecurityException, SystemException {
+        DistributedXATransaction txn = getTransaction(true);
+        Set<XAResource> resources = txn.getEnlistedResources();
+        int branchId = 1;
+        boolean nextPhase = true;
+        for (XAResource resource : resources) {
+            XID branch = txn.getXID().branch(branchId++);
+            try {
+                resource.end(branch, TMSUCCESS);
+                resource.prepare(branch);
+            } catch (XAException e) {
+                nextPhase = false;
+            }
+        }
+
+        branchId = 1; // reset
+        if (!nextPhase) {
+            for (XAResource resource : resources) {
+                try {
+                    XID branch = txn.getXID().branch(branchId++);
+                    resource.forget(branch);
+                } catch (XAException e) {
+                    // ignore
+                }
+                throw new SystemException(_loc.get("prepare-failed")
+                        .getMessage());
+            }
+        }
+
+        branchId = 1; // reset
+        for (XAResource resource : resources) {
+            XID branch = txn.getXID().branch(branchId++);
+            try {
+                resource.commit(branch, false);
+            } catch (XAException e) {
+                throw new SystemException(e.getMessage());
+            }
+        }
+    }
+
+    public int getStatus() throws SystemException {
+        return getTransaction().getStatus();
+    }
+
+    public Transaction getTransaction() throws SystemException {
+        return getTransaction(false);
+    }
+
+    public void resume(Transaction arg0) throws IllegalStateException,
+            InvalidTransactionException, SystemException {
+        throw new UnsupportedOperationException();
+    }
+
+    public void rollback() throws IllegalStateException, SecurityException,
+            SystemException {
+        DistributedXATransaction txn = getTransaction(true);
+        Set<XAResource> slices = txn.getEnlistedResources();
+        int branchId = 1;
+        for (XAResource slice : slices) {
+            XID branch = txn.getXID().branch(branchId++);
+            try {
+                slice.end(branch, XAResource.TMFAIL);
+                slice.rollback(branch);
+            } catch (XAException e) {
+            }
+        }
+    }
+
+    public void setRollbackOnly() throws IllegalStateException, SystemException {
+        getTransaction().setRollbackOnly();
+    }
+
+    public void setTransactionTimeout(int arg0) throws SystemException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Transaction suspend() throws SystemException {
+        throw new UnsupportedOperationException();
+    }
+
+    XAResource isSame(XAResource rm, Set<XAResource> others) {
+        for (XAResource other : others)
+            try {
+                if (rm != other && other.isSameRM(rm))
+                    return other;
+            } catch (XAException e) {
+                e.printStackTrace();
+            }
+        return null;
+    }
+
+    String toString(Object o) {
+        return o.getClass().getSimpleName() + "@"
+                + Long.toHexString(System.identityHashCode(o));
+    }
+
+    /**
+     * Gets the transaction associated with the current thread. 
+     * 
+     * @param mustExist if true, a transaction must be associated with the 
+     * current thread a priori. If false, the current thread has no associated
+     * transaction, a new transaction is created with a global identifier 
+     * and associated with the current thread.
+     */
+    DistributedXATransaction getTransaction(boolean mustExist) {
+        DistributedXATransaction txn = txns.get();
+        if (txn == null) {
+            if (mustExist)
+                throw new IllegalStateException(_loc.get("no-txn-on-thread",
+                        Thread.currentThread().getName()).getMessage());
+            byte[] global =
+                    Long.toHexString(System.currentTimeMillis()).getBytes();
+            XID xid = new XID(0, global, new byte[] { 0x1 });
+            txn = new DistributedXATransaction(xid, this);
+            txns.set(txn);
+        }
+        return txn;
+    }
+
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedXATransaction.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedXATransaction.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedXATransaction.java
(added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/DistributedXATransaction.java
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,82 @@
+package org.apache.openjpa.slice.transaction;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAResource;
+
+/**
+ * Internal implementation of a Transaction with an internal global transaction
+ * identifier scheme.
+ * 
+ * @author Pinaki Poddar 
+ *
+ */
+class DistributedXATransaction implements Transaction {
+    private static ThreadLocal<Transaction> _trans = new ThreadLocal<Transaction>();
+    private Set<XAResource> _slices = new HashSet<XAResource>();
+    private Set<Synchronization> _syncs = new HashSet<Synchronization>();
+    private final TransactionManager _tm;
+    private final XID xid;
+    private int _status;
+    private boolean _rollbackOnly;
+    
+    /**
+     * Construct with 
+     * @param xid
+     * @param tm
+     */
+    DistributedXATransaction(XID xid, TransactionManager tm) {
+        this.xid = xid;
+        this._tm = tm;
+    }
+    
+    public XID getXID() {
+        return xid;
+    }
+    
+    public void commit() throws HeuristicMixedException,
+            HeuristicRollbackException, RollbackException, SecurityException,
+            SystemException {
+        _tm.commit();
+    }
+
+    public boolean delistResource(XAResource arg0, int arg1)
+            throws IllegalStateException, SystemException {
+        return _slices.remove(arg0);
+    }
+
+    public boolean enlistResource(XAResource arg0)
+            throws IllegalStateException, RollbackException, SystemException {
+        return _slices.add(arg0);
+    }
+
+    public int getStatus() throws SystemException {
+        return _status;
+    }
+
+    public void registerSynchronization(Synchronization arg0)
+            throws IllegalStateException, RollbackException, SystemException {
+        _syncs.add(arg0);
+    }
+
+    public void rollback() throws IllegalStateException, SystemException {
+        _tm.rollback();
+    }
+
+    public void setRollbackOnly() throws IllegalStateException, SystemException {
+        _rollbackOnly = true;
+    }
+    
+    Set<XAResource> getEnlistedResources() {
+        return Collections.unmodifiableSet(_slices);
+    }
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/NaiveTransactionManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/NaiveTransactionManager.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/NaiveTransactionManager.java
(added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/NaiveTransactionManager.java
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,96 @@
+package org.apache.openjpa.slice.transaction;
+
+import java.util.Set;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.slice.jdbc.SliceStoreManager;
+
+/**
+ * A fake transaction manager which runs a serial commit or rollback across
+ * the enlisted non-XA resources without any two-phase commit protocol. 
+ *  
+ * @author Pinaki Poddar 
+ *
+ */
+public class NaiveTransactionManager implements TransactionManager {
+    private final ThreadLocal<DistributedNaiveTransaction> _txns = 
+        new ThreadLocal<DistributedNaiveTransaction>();
+    private static final Localizer _loc = 
+        Localizer.forPackage(NaiveTransactionManager.class);
+
+    public void begin() throws NotSupportedException, SystemException {
+        DistributedNaiveTransaction txn = getTransaction(false);
+        Set<SliceStoreManager> slices = txn.getEnlistedResources();
+        for (SliceStoreManager slice : slices) {
+            slice.getConnection();
+            slice.begin();
+        }
+    }
+
+    public void commit() throws HeuristicMixedException,
+            HeuristicRollbackException, IllegalStateException,
+            RollbackException, SecurityException, SystemException {
+        DistributedNaiveTransaction txn = getTransaction(false);
+        Set<SliceStoreManager> slices = txn.getEnlistedResources();
+        for (SliceStoreManager slice : slices) {
+            slice.commit();
+        }
+    }
+
+    public int getStatus() throws SystemException {
+        return getTransaction().getStatus();
+    }
+
+    public Transaction getTransaction() throws SystemException {
+        return getTransaction(false);
+    }
+
+    public void resume(Transaction arg0) throws IllegalStateException,
+            InvalidTransactionException, SystemException {
+        throw new UnsupportedOperationException();
+    }
+
+    public void rollback() throws IllegalStateException, SecurityException,
+            SystemException {
+        DistributedNaiveTransaction txn = getTransaction(false);
+        Set<SliceStoreManager> slices = txn.getEnlistedResources();
+        for (SliceStoreManager slice : slices) {
+            slice.commit();
+        }
+    }
+
+    public void setRollbackOnly() throws IllegalStateException, SystemException {
+        getTransaction().setRollbackOnly();
+    }
+
+    public void setTransactionTimeout(int arg0) throws SystemException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Transaction suspend() throws SystemException {
+        throw new UnsupportedOperationException();
+    }
+    
+    DistributedNaiveTransaction getTransaction(boolean mustExist) {
+        DistributedNaiveTransaction txn = _txns.get();
+        if (txn == null) {
+            if (mustExist)
+                throw new IllegalStateException(_loc.get("no-txn-on-thread",
+                        Thread.currentThread().getName()).getMessage());
+            txn = new DistributedNaiveTransaction(this);
+            _txns.set(txn);
+        }
+        return txn;
+    }
+
+
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/XID.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/XID.java?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/XID.java
(added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/XID.java
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,83 @@
+/*
+ * 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.transaction;
+
+import javax.transaction.xa.Xid;
+
+/**
+ * Internally used Global Transaction Identifier for two-phase distributed
+ * commit protocol.
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+class XID implements Xid {
+    private final int format;
+    private final byte[] global;
+    private final byte[] branch;
+
+    public XID(int format, byte[] global, byte[] branch) {
+        super();
+        this.format = format;
+        this.global = global;
+        this.branch = branch;
+    }
+
+    public byte[] getBranchQualifier() {
+        return branch;
+    }
+
+    public int getFormatId() {
+        return format;
+    }
+
+    public byte[] getGlobalTransactionId() {
+        return global;
+    }
+
+    XID branch(Number number) {
+        return branch((number == null) ? "null" : number.toString());
+    }
+    
+    XID branch(String branch) {
+        return new XID(format, global, branch.getBytes());
+    }
+
+    public String toString() {
+        return new String(global) + ":" + new String(branch);
+    }
+
+    public boolean equals(Object other) {
+        if (other instanceof XID) {
+            XID that = (XID) other;
+            return format == that.format && equals(global, that.global)
+                    && equals(branch, that.branch);
+        }
+        return false;
+    }
+
+    boolean equals(byte[] a, byte[] b) {
+        if (a == null && b == null)
+            return true;
+        if (a == null || b == null)
+            return false;
+        return new String(a).equals(new String(b));
+    }
+
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/package.html
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/package.html?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/package.html
(added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/transaction/package.html
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,10 @@
+<HTML>
+<BODY>
+Implements TransactionManager to manage transactions across the database
+slices. This package provides two flavors of TransactionManager: one provides
+two-phase commit protocol when all underlying database slices is XA-complaint;
+while the other runs commit/rollback simply looping across all database slices
+when one or more underlying database slices is not XA-complaint and hence does 
+not guarantee atomic nature of transaction.  
+</BODY>
+</HTML> 
\ No newline at end of file

Added: openjpa/trunk/openjpa-slice/src/main/resources/META-INF/services/org.apache.openjpa.lib.conf.ProductDerivation
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/resources/META-INF/services/org.apache.openjpa.lib.conf.ProductDerivation?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/resources/META-INF/services/org.apache.openjpa.lib.conf.ProductDerivation
(added)
+++ openjpa/trunk/openjpa-slice/src/main/resources/META-INF/services/org.apache.openjpa.lib.conf.ProductDerivation
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,18 @@
+# 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.
+
+org.apache.openjpa.slice.ProductDerivation
\ No newline at end of file

Added: openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/localizer.properties?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/localizer.properties
(added)
+++ openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/jdbc/localizer.properties
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,49 @@
+slice-not-found: No slice named "{0}" can be found. Available slices are "{1}"
+slice-no-url: Slice "{0}" has no database URL. Specify a valid database URL \
+	as the value of "slice.{0}.ConnectionURL" property. ConnectionURL is the \
+	only mandatory property of a slice. If any other slice property \
+	is not specified, then the corresponding openjpa.* property value is used \
+	as default.
+slice-none-configured: No slice has been configured. Specify slice.XYZ as \
+	property name to register a slice named XYZ.
+slice-configuration: Slice "{0}" configured with "{1}"
+slice-available: Detected slices "{0}" in configuration.
+no-url: No ConnectionURL property has been specified.
+wrong-url: URL "{0}" is invalid as database URL.
+wrong-slice: Wrong slice "{0}" for "{1}"
+slice-connect: Connecting to slice "{0}" at URL "{1}"
+slice-connect-warn: Failed to connect to slice "{0}". Slice "{0}" will be \
+	ignored as configuration is set as lenient.
+slice-connect-known-warn: Failed to connect to due to "{2}. \
+	Slice "{0}" will be ignored as configuration is set as lenient.
+slice-connect-error: Failed to connect to URL "{1}"
+slice-connect-known-error: Failed to connect to URL "{1} due to {2}
+bad-policy-slice:Distribution policy "{0}" has returned invalid slice \
+	"{1}" for "{2}". The valid slices are {3}. This error may happen \
+	when one or more of the originally configured slices are unavailable \
+	and Lenient property is set to true.
+slice-xa-enabled: All slices "{0}" is XA-complaint and hence store transaction \
+	will use a two-phase commit protocol even if the persistent unit is \
+	configured for non-JTA transaction.
+slice-xa-disabled: Not all active slices "{0}" is XA-complaint and hence store \
+	transaction will not use a two-phase commit protocol. If persistent unit \
+	is configured for JTA transaction then the slices will participate in \
+	global transaction but otherwise the atomic nature of commit across all \
+	slices is not guaranteed.  
+two-phase: "{3}".{0}"(xid=[{4}]] Connection={1} XAConnection={2} 
+factory-init: Starting {0}
+config-init: Configuring Slice {0}
+no-slice-names: Slice identifiers are not listed in [slice.Names] property. \
+	The configuration will be scanned to determine slice identifiers.
+no-master-slice: No master slice has been configured explicitly in \
+	[slice.Master] property. The first slice "{0}" in the list of configured \
+	slices will be used as master. 
+resource-xa-tm-not-2pc: All slices is using XA-complaint driver but the \
+	configured "{0}" transaction manager is not capable of enlisting XA-aware \
+	resources. See slice.TransactionManager property documentation to  \
+	configure XA-aware Transaction Manager capable for two-phase commit.
+resource-not-xa-tm-2pc: One or more slices is not using XA-complaint driver \
+	but the configured "{0}" transaction manager can only enlist XA-aware \
+	resource. 
+not-open: The underlying result sets are not open.
+aggregate-unsupported: The query uses unsupported aggregate operation "{0}".  

Added: openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
(added)
+++ openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,4 @@
+bad-policy-slice:Distribution policy "{0}" has returned invalid slice \
+	"{1}" for "{2}". The valid slices are {3}. This error may happen \
+	when one or more of the originally configured slices are unavailable \
+	and Lenient property is set to true.
\ No newline at end of file

Added: openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/localizer.properties?rev=619145&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/localizer.properties
(added)
+++ openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/transaction/localizer.properties
Wed Feb  6 12:26:14 2008
@@ -0,0 +1,3 @@
+no-txn-on-thread: No transaction is associated with current thread "{0}"
+prepare-failed: one or more XA-complaint resources have failed to prepare for \
+	commit during the first phase of a two-phase commit protocol.
\ No newline at end of file

Modified: openjpa/trunk/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/pom.xml?rev=619145&r1=619144&r2=619145&view=diff
==============================================================================
--- openjpa/trunk/pom.xml (original)
+++ openjpa/trunk/pom.xml Wed Feb  6 12:26:14 2008
@@ -84,7 +84,8 @@
         <module>openjpa-lib</module>
         <module>openjpa-kernel</module>
         <module>openjpa-jdbc</module>
-        <module>openjpa-xmlstore</module>
+        <module>openjpa-xmlstore</module>
+        <module>openjpa-slice</module>
         <module>openjpa-all</module>
         <module>openjpa-project</module>
         <module>openjpa-integration</module>
@@ -100,7 +101,8 @@
                 <module>openjpa-persistence</module>
                 <module>openjpa-persistence-jdbc</module>
                 <module>openjpa-kernel-5</module>
-                <module>openjpa-jdbc-5</module>
+                <module>openjpa-jdbc-5</module>
+                <module>openjpa-slice</module>
                 <module>openjpa-examples</module>
             </modules>
         </profile>



Mime
View raw message