Author: bcarothers
Date: 2009-11-27 12:22:54 -0500 (Fri, 27 Nov 2009)
New Revision: 1366
Added:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicJpaConnection.java
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/Model.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModel.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/ModelTest.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModelTest.java
Log:
DNA-546
Committed patch (DNA-546_jpa_connector_refactor.patch) that refactors the existing JPA
connector framework to more readily support the new model that I'm working on.
The patch removes the relationship between the model and the request processor and adds a
relationship between the model and its connection. To work within the MapRepository
framework, I had to be able to pass a reference to the MapRepository into the
MapRequestProcessor. This ruled out using the existing JpaConnection. The cleanest way to
isolate the reusable pieces of the code seemed to be to rename JpaConnection to
BasicJpaConnection, move it into model.basic, and then replace
Model.createRequestProcessor(...) with Model.createConnection(JpaSource). This required a
few changes to class visibility (but not constructor visibility) and the addition of some
accessors to JpaSource.
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java 2009-11-27
16:52:16 UTC (rev 1365)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java 2009-11-27
17:22:54 UTC (rev 1366)
@@ -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.
* <p>
- * 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.
* </p>
* <p>
* This class does put the EntityManager implementations inside a HashMap, and therefore
does expect that the EntityManager uses
@@ -47,7 +48,7 @@
* </p>
*/
@ThreadSafe
-class EntityManagers {
+public class EntityManagers {
private final Ejb3Configuration configuration;
private final Map<EntityManager, AtomicInteger> referenceCounts = new
HashMap<EntityManager, AtomicInteger>();
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java 2009-11-27
16:52:16 UTC (rev 1365)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java 2009-11-27
17:22:54 UTC (rev 1366)
@@ -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<Model> MODIFIABLE_MODELS = new
ArrayList<Model>(Arrays.asList(ALL_ARRAY));
public static final Collection<Model> 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);
}
/**
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/Model.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/Model.java 2009-11-27
16:52:16 UTC (rev 1365)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/Model.java 2009-11-27
17:22:54 UTC (rev 1366)
@@ -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.
Added:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicJpaConnection.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicJpaConnection.java
(rev 0)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicJpaConnection.java 2009-11-27
17:22:54 UTC (rev 1366)
@@ -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:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicJpaConnection.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModel.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModel.java 2009-11-27
16:52:16 UTC (rev 1365)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModel.java 2009-11-27
17:22:54 UTC (rev 1366)
@@ -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());
+ }
+
}
Modified:
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/ModelTest.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/ModelTest.java 2009-11-27
16:52:16 UTC (rev 1365)
+++
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/ModelTest.java 2009-11-27
17:22:54 UTC (rev 1366)
@@ -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;
}
+
}
}
Modified:
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModelTest.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModelTest.java 2009-11-27
16:52:16 UTC (rev 1365)
+++
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/model/basic/BasicModelTest.java 2009-11-27
17:22:54 UTC (rev 1366)
@@ -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