Index: extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java =================================================================== --- extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java (revision 1360) +++ extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java (working copy) @@ -30,16 +30,17 @@ import javax.persistence.EntityManagerFactory; import net.jcip.annotations.ThreadSafe; import org.hibernate.ejb.Ejb3Configuration; +import org.jboss.dna.graph.connector.RepositoryConnection; /** * Utility class that owns an {@link EntityManagerFactory} instance and that provides references to {@link EntityManager} * instances while providing the ability to properly clean up all resources by closing the EntityManager and EntityManagerFactory * objects when no longer needed. *

- * This class is instantiated by the {@link JpaSource} and passed to the {@link JpaConnection} objects, which use this class to - * obtain an EntityManager. When the JpaConnection object is {@link JpaConnection#close() closed}, it returns the EntityManager to - * this object. Because this class maintains a count of the EntityManager references handed out, the last EntityManager to be - * returned will cause the EntityManagerFactory to be closed. + * This class is instantiated by the {@link JpaSource} and passed to the {@link RepositoryConnection} objects, which use this + * class to obtain an EntityManager. When the JPA connection object is {@link RepositoryConnection#close() closed}, it returns the + * EntityManager to this object. Because this class maintains a count of the EntityManager references handed out, the last + * EntityManager to be returned will cause the EntityManagerFactory to be closed. *

*

* This class does put the EntityManager implementations inside a HashMap, and therefore does expect that the EntityManager uses @@ -47,7 +48,7 @@ *

*/ @ThreadSafe -class EntityManagers { +public class EntityManagers { private final Ejb3Configuration configuration; private final Map referenceCounts = new HashMap(); Index: extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java =================================================================== --- extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java (revision 1360) +++ extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java (working copy) @@ -59,7 +59,6 @@ import org.jboss.dna.graph.connector.RepositorySource; import org.jboss.dna.graph.connector.RepositorySourceCapabilities; import org.jboss.dna.graph.connector.RepositorySourceException; -import org.jboss.dna.graph.observe.Observer; /** * The {@link RepositorySource} for the connector that stores content in a (custom) relational database. This connector uses Java @@ -75,7 +74,8 @@ */ public static class Models { public static final Model BASIC = new BasicModel(); - private static final Model[] ALL_ARRAY = new Model[] {BASIC}; + // public static final Model SIMPLE = new SimpleModel(); + private static final Model[] ALL_ARRAY = new Model[] {BASIC /*, SIMPLE */}; private static final List MODIFIABLE_MODELS = new ArrayList(Arrays.asList(ALL_ARRAY)); public static final Collection ALL = Collections.unmodifiableCollection(MODIFIABLE_MODELS); public static final Model DEFAULT = BASIC; @@ -367,6 +367,24 @@ } /** + * Returns the current cache policy + * + * @return the current cache policy + */ + public CachePolicy getCachePolicy() { + return cachePolicy; + } + + /** + * Returns the current {@code EntityManagers} reference. + * + * @return the current {@code EntityManagers} reference. + */ + public EntityManagers getEntityManagers() { + return entityManagers; + } + + /** * @return rootNodeUuid */ public String getRootNodeUuid() { @@ -374,6 +392,13 @@ } /** + * @return rootUuid + */ + public UUID getRootUuid() { + return rootUuid; + } + + /** * @param rootNodeUuid Sets rootNodeUuid to the specified value. * @throws IllegalArgumentException if the string value cannot be converted to UUID */ @@ -812,6 +837,15 @@ } /** + * Returns the current repository context for the source, as set with a call to {@link #initialize(RepositoryContext)}. + * + * @return the current repository context for the source + */ + public RepositoryContext getRepositoryContext() { + return repositoryContext; + } + + /** * {@inheritDoc} */ public Object getObjectInstance( Object obj, @@ -1000,10 +1034,8 @@ // Now, create another entity manager with the classes from the correct model and without changing the schema... entityManagers = new EntityManagers(configurator); } - Observer observer = repositoryContext != null ? repositoryContext.getObserver() : null; - return new JpaConnection(getName(), observer, cachePolicy, entityManagers, model, rootUuid, defaultWorkspace, - getPredefinedWorkspaceNames(), largeValueSizeInBytes, isCreatingWorkspacesAllowed(), - compressData, referentialIntegrityEnforced); + + return model.createConnection(this); } /** Index: extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/Model.java =================================================================== --- extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/Model.java (revision 1360) +++ extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/Model.java (working copy) @@ -24,14 +24,10 @@ package org.jboss.dna.connector.store.jpa; import java.util.Locale; -import java.util.UUID; -import javax.persistence.EntityManager; import org.hibernate.ejb.Ejb3Configuration; import org.jboss.dna.common.i18n.I18n; import org.jboss.dna.common.util.CheckArg; -import org.jboss.dna.graph.ExecutionContext; -import org.jboss.dna.graph.observe.Observer; -import org.jboss.dna.graph.request.processor.RequestProcessor; +import org.jboss.dna.graph.connector.RepositoryConnection; /** * A descriptor of a schema used by this connector. @@ -76,17 +72,7 @@ return description.text(locale); } - public abstract RequestProcessor createRequestProcessor( String sourceName, - ExecutionContext context, - Observer observer, - EntityManager entityManager, - UUID rootNodeUuid, - String nameOfDefaultWorkspace, - String[] predefinedWorkspaceNames, - long largeValueMinimumSizeInBytes, - boolean creatingWorkspacesAllowed, - boolean comparessData, - boolean enforceReferentialIntegrity ); + public abstract RepositoryConnection createConnection( JpaSource source ); /** * Configure the entity class that will be used by JPA to store information in the database. Index: extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicJpaConnection.java =================================================================== --- extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicJpaConnection.java (revision 0) +++ extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicJpaConnection.java (revision 0) @@ -0,0 +1,163 @@ +/* + * JBoss DNA (http://www.jboss.org/dna) + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. Some portions may be licensed + * to Red Hat, Inc. under one or more contributor license agreements. + * See the AUTHORS.txt file in the distribution for a full listing of + * individual contributors. + * + * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA + * is licensed to you under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * JBoss DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.dna.connector.store.jpa.model.basic; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import javax.persistence.EntityManager; +import javax.transaction.xa.XAResource; +import org.jboss.dna.connector.store.jpa.EntityManagers; +import org.jboss.dna.connector.store.jpa.JpaConnectorI18n; +import org.jboss.dna.graph.ExecutionContext; +import org.jboss.dna.graph.cache.CachePolicy; +import org.jboss.dna.graph.connector.RepositoryConnection; +import org.jboss.dna.graph.connector.RepositorySourceException; +import org.jboss.dna.graph.observe.Observer; +import org.jboss.dna.graph.request.Request; +import org.jboss.dna.graph.request.processor.RequestProcessor; + +/** + * The repository connection to JPA repository sources. + */ +class BasicJpaConnection implements RepositoryConnection { + + private final String name; + private final CachePolicy cachePolicy; + private final EntityManagers entityManagers; + private EntityManager entityManager; + private final UUID rootNodeUuid; + private final String nameOfDefaultWorkspace; + private final String[] predefinedWorkspaceNames; + private final boolean creatingWorkspacesAllowed; + private final long largeValueMinimumSizeInBytes; + private final boolean compressData; + private final boolean enforceReferentialIntegrity; + private final Observer observer; + + public BasicJpaConnection( String sourceName, + Observer observer, + CachePolicy cachePolicy, + EntityManagers entityManagers, + UUID rootNodeUuid, + String nameOfDefaultWorkspace, + String[] predefinedWorkspaceNames, + long largeValueMinimumSizeInBytes, + boolean creatingWorkspacesAllowed, + boolean compressData, + boolean enforceReferentialIntegrity ) { + assert sourceName != null; + assert entityManagers != null; + assert rootNodeUuid != null; + this.observer = observer; + this.name = sourceName; + this.cachePolicy = cachePolicy; // may be null + this.entityManagers = entityManagers; + this.entityManager = entityManagers.checkout(); + assert this.entityManagers != null; + this.rootNodeUuid = rootNodeUuid; + this.largeValueMinimumSizeInBytes = largeValueMinimumSizeInBytes; + this.compressData = compressData; + this.enforceReferentialIntegrity = enforceReferentialIntegrity; + this.nameOfDefaultWorkspace = nameOfDefaultWorkspace; + this.predefinedWorkspaceNames = predefinedWorkspaceNames != null ? predefinedWorkspaceNames : new String[] {}; + this.creatingWorkspacesAllowed = creatingWorkspacesAllowed; + } + + /** + * {@inheritDoc} + * + * @see org.jboss.dna.graph.connector.RepositoryConnection#getSourceName() + */ + public String getSourceName() { + return name; + } + + /** + * {@inheritDoc} + * + * @see org.jboss.dna.graph.connector.RepositoryConnection#getDefaultCachePolicy() + */ + public CachePolicy getDefaultCachePolicy() { + return cachePolicy; + } + + /** + * {@inheritDoc} + * + * @see org.jboss.dna.graph.connector.RepositoryConnection#getXAResource() + */ + public XAResource getXAResource() { + return null; + } + + /** + * {@inheritDoc} + * + * @see org.jboss.dna.graph.connector.RepositoryConnection#ping(long, java.util.concurrent.TimeUnit) + */ + public boolean ping( long time, + TimeUnit unit ) { + return entityManager != null ? entityManager.isOpen() : false; + } + + /** + * {@inheritDoc} + * + * @see org.jboss.dna.graph.connector.RepositoryConnection#execute(org.jboss.dna.graph.ExecutionContext, + * org.jboss.dna.graph.request.Request) + */ + public void execute( ExecutionContext context, + Request request ) throws RepositorySourceException { + if (entityManager == null) { + throw new RepositorySourceException(JpaConnectorI18n.connectionIsNoLongerOpen.text(name)); + } + + RequestProcessor proc = new BasicRequestProcessor(name, context, observer, entityManager, rootNodeUuid, + nameOfDefaultWorkspace, predefinedWorkspaceNames, + largeValueMinimumSizeInBytes, creatingWorkspacesAllowed, compressData, + enforceReferentialIntegrity); + try { + proc.process(request); + } finally { + proc.close(); + } + } + + /** + * {@inheritDoc} + * + * @see org.jboss.dna.graph.connector.RepositoryConnection#close() + */ + public void close() { + if (entityManager != null) { + // Do this only once ... + try { + entityManagers.checkin(entityManager); + } finally { + entityManager = null; + } + } + } + +} Property changes on: extensions\dna-connector-store-jpa\src\main\java\org\jboss\dna\connector\store\jpa\model\basic\BasicJpaConnection.java ___________________________________________________________________ Added: svn:keywords + Id Revision Added: svn:eol-style + LF Index: extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModel.java =================================================================== --- extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModel.java (revision 1360) +++ extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModel.java (working copy) @@ -23,21 +23,20 @@ */ package org.jboss.dna.connector.store.jpa.model.basic; -import java.util.UUID; -import javax.persistence.EntityManager; import org.hibernate.ejb.Ejb3Configuration; import org.jboss.dna.connector.store.jpa.JpaConnectorI18n; +import org.jboss.dna.connector.store.jpa.JpaSource; import org.jboss.dna.connector.store.jpa.Model; import org.jboss.dna.connector.store.jpa.model.common.ChangeLogEntity; import org.jboss.dna.connector.store.jpa.model.common.NamespaceEntity; import org.jboss.dna.connector.store.jpa.model.common.WorkspaceEntity; -import org.jboss.dna.graph.ExecutionContext; +import org.jboss.dna.graph.connector.RepositoryConnection; +import org.jboss.dna.graph.connector.RepositoryContext; import org.jboss.dna.graph.observe.Observer; import org.jboss.dna.graph.request.CopyBranchRequest; import org.jboss.dna.graph.request.DeleteBranchRequest; import org.jboss.dna.graph.request.MoveBranchRequest; import org.jboss.dna.graph.request.ReadBranchRequest; -import org.jboss.dna.graph.request.processor.RequestProcessor; /** * Database model that stores node properties as opaque records and children as transparent records. Large property values are @@ -98,29 +97,6 @@ } /** - * {@inheritDoc} - * - * @see org.jboss.dna.connector.store.jpa.Model#createRequestProcessor(String, ExecutionContext, Observer, EntityManager, - * UUID, String, String[], long, boolean, boolean, boolean) - */ - @Override - public RequestProcessor createRequestProcessor( String sourceName, - ExecutionContext context, - Observer observer, - EntityManager entityManager, - UUID rootNodeUuid, - String nameOfDefaultWorkspace, - String[] predefinedWorkspaceNames, - long largeValueMinimumSizeInBytes, - boolean creatingWorkspacesAllowed, - boolean compressData, - boolean enforceReferentialIntegrity ) { - return new BasicRequestProcessor(sourceName, context, observer, entityManager, rootNodeUuid, nameOfDefaultWorkspace, - predefinedWorkspaceNames, largeValueMinimumSizeInBytes, creatingWorkspacesAllowed, - compressData, enforceReferentialIntegrity); - } - - /** * Configure the entity class that will be used by JPA to store information in the database. * * @param configurator the Hibernate {@link Ejb3Configuration} component; never null @@ -148,4 +124,15 @@ // "read-write, RegionName"); } + @Override + public RepositoryConnection createConnection( JpaSource source ) { + RepositoryContext repositoryContext = source.getRepositoryContext(); + Observer observer = repositoryContext != null ? repositoryContext.getObserver() : null; + return new BasicJpaConnection(getName(), observer, source.getCachePolicy(), source.getEntityManagers(), + source.getRootUuid(), + source.getDefaultWorkspaceName(), source.getPredefinedWorkspaceNames(), + source.getLargeValueSizeInBytes(), source.isCreatingWorkspacesAllowed(), + source.isCompressData(), source.isReferentialIntegrityEnforced()); + } + } Index: extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java =================================================================== --- extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java (revision 1360) +++ extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java (working copy) @@ -41,7 +41,7 @@ public class JpaSourceTest { private JpaSource source; - private JpaConnection connection; + private RepositoryConnection connection; @Before public void beforeEach() throws Exception { @@ -73,7 +73,7 @@ @Test public void shouldCreateConnection() throws Exception { - connection = (JpaConnection)source.getConnection(); + connection = source.getConnection(); assertThat(connection, is(notNullValue())); } Index: extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModelTest.java =================================================================== --- extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModelTest.java (revision 1360) +++ extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModelTest.java (working copy) @@ -39,11 +39,12 @@ import org.hibernate.ejb.Ejb3Configuration; import org.jboss.dna.common.util.SecureHash; import org.jboss.dna.common.util.StringUtil; +import org.jboss.dna.connector.store.jpa.EntityManagers; import org.jboss.dna.connector.store.jpa.JpaConnectorI18n; +import org.jboss.dna.connector.store.jpa.JpaSource; import org.jboss.dna.connector.store.jpa.model.common.NamespaceEntity; -import org.jboss.dna.graph.ExecutionContext; +import org.jboss.dna.graph.connector.RepositoryConnection; import org.jboss.dna.graph.property.PropertyType; -import org.jboss.dna.graph.request.processor.RequestProcessor; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; @@ -62,7 +63,6 @@ private EntityManagerFactory factory; private EntityManager manager; private BasicModel model; - private ExecutionContext context; @BeforeClass public static void beforeAll() throws Exception { @@ -71,7 +71,6 @@ @Before public void beforeEach() throws Exception { model = new BasicModel(); - context = new ExecutionContext(); } @After @@ -122,22 +121,22 @@ } @Test - public void shouldCreateRequestProcessor() { + public void shouldCreateConnection() { EntityManager manager = mock(EntityManager.class); EntityTransaction txn = mock(EntityTransaction.class); + EntityManagers managers = mock(EntityManagers.class); + JpaSource source = mock(JpaSource.class); + stub(manager.getTransaction()).toReturn(txn); - RequestProcessor proc = model.createRequestProcessor("test source", - context, - null, - manager, - UUID.randomUUID(), - "default workspace", - new String[] {"default workspace", "workspace1"}, - 100, - true, - false, - false); - assertThat(proc, is(notNullValue())); + + stub(managers.checkout()).toReturn(manager); + + stub(source.getRootUuid()).toReturn(UUID.randomUUID()); + stub(source.getEntityManagers()).toReturn(managers); + + RepositoryConnection conn = model.createConnection(source); + + assertThat(conn, is(notNullValue())); } @Test Index: extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/ModelTest.java =================================================================== --- extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/ModelTest.java (revision 1360) +++ extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/ModelTest.java (working copy) @@ -26,13 +26,9 @@ import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertThat; -import java.util.UUID; -import javax.persistence.EntityManager; import org.hibernate.ejb.Ejb3Configuration; import org.jboss.dna.common.i18n.I18n; -import org.jboss.dna.graph.ExecutionContext; -import org.jboss.dna.graph.observe.Observer; -import org.jboss.dna.graph.request.processor.RequestProcessor; +import org.jboss.dna.graph.connector.RepositoryConnection; import org.junit.Before; import org.junit.Test; import org.mockito.MockitoAnnotations; @@ -50,7 +46,7 @@ private Model model2; private Model model3; @Mock - private RequestProcessor requestProcessor; + private RepositoryConnection connection; @Before public void beforeEach() throws Exception { @@ -104,20 +100,10 @@ public void configure( Ejb3Configuration configurator ) { } - @SuppressWarnings( "synthetic-access" ) @Override - public RequestProcessor createRequestProcessor( String sourceName, - ExecutionContext context, - Observer observer, - EntityManager entityManager, - UUID rootNodeUuid, - String nameOfDefaultWorkspace, - String[] predefinedWorkspaceNames, - long largeValueMinimumSizeInBytes, - boolean createWorkspacesAllowed, - boolean compressData, - boolean enforceReferentialIntegrity ) { - return requestProcessor; + public RepositoryConnection createConnection( JpaSource source ) { + return connection; } + } }