You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2013/09/12 14:52:52 UTC
git commit: ISIS-528: handle domain objects new'ed up rather than
through newTransientInstance()
Updated Branches:
refs/heads/master f52e9d941 -> edfc5f5f7
ISIS-528: handle domain objects new'ed up rather than through newTransientInstance()
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/edfc5f5f
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/edfc5f5f
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/edfc5f5f
Branch: refs/heads/master
Commit: edfc5f5f70dbc0b742a2c01ca1b9d6dc73a87725
Parents: f52e9d9
Author: Dan Haywood <da...@apache.org>
Authored: Thu Sep 12 13:52:27 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Thu Sep 12 13:52:27 2013 +0100
----------------------------------------------------------------------
.../isis/applib/AbstractContainedObject.java | 63 +++++++++--
.../isis/applib/DomainObjectContainer.java | 109 ++++++++++++++++---
.../container/DomainObjectContainerDefault.java | 22 +++-
3 files changed, 166 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/edfc5f5f/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java b/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
index d5307cd..c6dbea2 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
@@ -37,7 +37,39 @@ import org.apache.isis.applib.security.UserMemento;
*/
public abstract class AbstractContainedObject {
- // {{ factory methods
+ /**
+ * Create a new instance of the specified class, but do not persist it.
+ *
+ * <p>
+ * It is recommended that the object be initially instantiated using
+ * this method, though the framework will also handle the case when
+ * the object is simply <i>new()</i>ed up. The benefits of using
+ * {@link #newTransientInstance(Class)} are:
+ * <ul>
+ * <li>any services will be injected into the object immediately
+ * (otherwise they will not be injected until the framework
+ * becomes aware of the object, typically when it is
+ * {@link #persist(Object) persist}ed</li>
+ * <li>the default value for any properties (usually as specified by
+ * <tt>default<i>Xxx</i>()</tt> supporting methods) will not be
+ * used</li>
+ * <li>the <tt>created()</tt> callback will not be called.
+ * </ul>
+ *
+ * <p>
+ * The corollary is: if your code never uses <tt>default<i>Xxx</i>()</tt>
+ * supporting methods or the <tt>created()</tt> callback, then you can
+ * alternatively just <i>new()</i> up the object rather than call this
+ * method.
+
+ * <p>
+ * If the type is annotated with {@link Aggregated}, then as per
+ * {@link #newAggregatedInstance(Object, Class)}. Otherwise will be an
+ * aggregate root.
+ *
+ * @see #newPersistentInstance(Class)
+ * @see #newAggregatedInstance(Object, Class)
+ */
@Hidden
protected <T> T newTransientInstance(final Class<T> ofType) {
return getContainer().newTransientInstance(ofType);
@@ -257,7 +289,8 @@ public abstract class AbstractContainedObject {
// //////////////////////////////////////
/**
- * Whether the provided object is persistent.
+ * Determines if the specified object is persistent (that it is stored
+ * permanently outside of the virtual machine).
*/
@Hidden
protected boolean isPersistent(final Object domainObject) {
@@ -265,12 +298,20 @@ public abstract class AbstractContainedObject {
}
/**
- * Save provided object to the persistent object store.
+ * Persist the specified transient object.
*
* <p>
- * If the object {@link #isPersistent(Object) is persistent} already, then
- * will throw an exception.
+ * It is recommended that the object be initially instantiated using
+ * {@link #newTransientInstance(Class)}. However, the framework will also
+ * handle the case when the object is simply <i>new()</i>ed up. See
+ * {@link #newTransientInstance(Class)} for more information.
*
+ * <p>
+ * Throws an exception if object is already persistent, or if the object
+ * is not yet known to the framework.
+ *
+ * @see #newTransientInstance(Class)
+ * @see #isPersistent(Object)
* @see #persistIfNotAlready(Object)
*/
@Hidden
@@ -280,10 +321,16 @@ public abstract class AbstractContainedObject {
}
/**
- * Saves the object, but only if not already {@link #isPersistent()
- * persistent}.
+ * Persist the specified object (or do nothing if already persistent).
*
- * @see #isPersistent()
+ * <p>
+ * It is recommended that the object be initially instantiated using
+ * {@link #newTransientInstance(Class)}. However, the framework will also
+ * handle the case when the object is simply <i>new()</i>ed up. See
+ * {@link #newTransientInstance(Class)} for more information.
+ *
+ * @see #newTransientInstance(Class)
+ * @see #isPersistent(Object)
* @see #persist(Object)
*/
@Hidden
http://git-wip-us.apache.org/repos/asf/isis/blob/edfc5f5f/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java b/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
index afe968e..0c06b7f 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
@@ -29,8 +29,9 @@ import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.security.UserMemento;
/**
- * Represents a container that the domain objects work within. It provides
- * access to the persistence mechanism and user interface.
+ * A domain service that acts as a framework's container for managing the
+ * domain objects, and which provides functionality to those domain objects
+ * in order that they might interact or have knowledge of with the "outside world".
*/
public interface DomainObjectContainer {
@@ -38,6 +39,10 @@ public interface DomainObjectContainer {
// titleOf
// ////////////////////////////////////////////////////////////////
+ /**
+ * Return the title of the object, as rendered in the UI by the
+ * Isis viewers.
+ */
String titleOf(Object domainObject);
// ////////////////////////////////////////////////////////////////
@@ -50,7 +55,14 @@ public interface DomainObjectContainer {
* <p>
* This forces the lazy loading mechanism to load the object if it is not
* already loaded.
+ *
+ * <p>
+ * This method has been deprecated because lazy loading is now typically performed
+ * by the framework, rather than by application code.
+ *
+ * @deprecated
*/
+ @Deprecated
void resolve(Object domainObject);
/**
@@ -60,13 +72,27 @@ public interface DomainObjectContainer {
* <p>
* This forces the lazy loading mechanism to load the object if it is not
* already loaded.
+ *
+ * <p>
+ * This method has been deprecated because lazy loading is now typically performed
+ * by the framework, rather than by application code.
+ *
+ * @deprecated
*/
+ @Deprecated
void resolve(Object domainObject, Object field);
/**
* Flags that the specified object's state has changed and its changes need
* to be saved.
+ *
+ * <p>
+ * This method has been deprecated because object dirtying is now typically performed
+ * by the framework, rather than by application code.
+ *
+ * @deprecated
*/
+ @Deprecated
void objectChanged(Object domainObject);
// ////////////////////////////////////////////////////////////////
@@ -103,7 +129,29 @@ public interface DomainObjectContainer {
/**
* Create a new instance of the specified class, but do not persist it.
- *
+ *
+ * <p>
+ * It is recommended that the object be initially instantiated using
+ * this method, though the framework will also handle the case when
+ * the object is simply <i>new()</i>ed up. The benefits of using
+ * {@link #newTransientInstance(Class)} are:
+ * <ul>
+ * <li>any services will be injected into the object immediately
+ * (otherwise they will not be injected until the framework
+ * becomes aware of the object, typically when it is
+ * {@link #persist(Object) persist}ed</li>
+ * <li>the default value for any properties (usually as specified by
+ * <tt>default<i>Xxx</i>()</tt> supporting methods) will not be
+ * used</li>
+ * <li>the <tt>created()</tt> callback will not be called.
+ * </ul>
+ *
+ * <p>
+ * The corollary is: if your code never uses <tt>default<i>Xxx</i>()</tt>
+ * supporting methods or the <tt>created()</tt> callback, then you can
+ * alternatively just <i>new()</i> up the object rather than call this
+ * method.
+
* <p>
* If the type is annotated with {@link Aggregated}, then as per
* {@link #newAggregatedInstance(Object, Class)}. Otherwise will be an
@@ -117,19 +165,41 @@ public interface DomainObjectContainer {
/**
* Create a new instance that will be persisted as part of the specified
* parent (ie will be a part of a larger aggregate).
+ *
+ * <p>
+ * <b>Note:</b> not every objectstore implementation supports the concept
+ * of aggregated instances.
*/
<T> T newAggregatedInstance(Object parent, Class<T> ofType);
/**
* Returns a new instance of the specified class that will have been
* persisted.
+ *
+ * <p>
+ * This method has been deprecated because in almost all cases the
+ * workflow is to {@link #newTransientInstance(Class)}, populate the object
+ * (eg with the arguments to an action) and then to
+ * {@link #persist(Object) persist) the object. It is exceptionally rare for
+ * an object to be created, and with no further data required - be in a state
+ * to be persisted immediately.
+ *
+ * @deprecated
*/
+ @Deprecated
<T> T newPersistentInstance(final Class<T> ofType);
/**
- * Returns a new instance of the specified class that has the sane persisted
- * state as the specified object.
+ * Returns a new instance of the specified class that has the same persisted
+ * state (either transient or persisted) as the provided object.
+ *
+ * <p>
+ * This method has been deprecated because it is a rare use case, causing
+ * unnecessary interface bloat for very little gain.
+ *
+ * @deprecated
*/
+ @Deprecated
<T> T newInstance(final Class<T> ofType, final Object object);
// ////////////////////////////////////////////////////////////////
@@ -166,22 +236,34 @@ public interface DomainObjectContainer {
boolean isPersistent(Object domainObject);
/**
- * Make the specified transient object persistent.
+ * Persist the specified transient object.
+ *
+ * <p>
+ * It is recommended that the object be initially instantiated using
+ * {@link #newTransientInstance(Class)}. However, the framework will also
+ * handle the case when the object is simply <i>new()</i>ed up. See
+ * {@link #newTransientInstance(Class)} for more information.
*
* <p>
- * Throws an exception if object is already persistent.
+ * Throws an exception if object is already persistent, or if the object
+ * is not yet known to the framework.
*
+ * @see #newTransientInstance(Class)
* @see #isPersistent(Object)
* @see #persistIfNotAlready(Object)
*/
- void persist(Object transientDomainObject);
+ void persist(Object domainObject);
/**
- * Make the specified object persistent if not already.
+ * Persist the specified object (or do nothing if already persistent).
*
* <p>
- * Does nothing otherwise.
- *
+ * It is recommended that the object be initially instantiated using
+ * {@link #newTransientInstance(Class)}. However, the framework will also
+ * handle the case when the object is simply <i>new()</i>ed up. See
+ * {@link #newTransientInstance(Class)} for more information.
+ *
+ * @see #newTransientInstance(Class)
* @see #isPersistent(Object)
* @see #persist(Object)
*/
@@ -262,9 +344,6 @@ public interface DomainObjectContainer {
/**
* Get the details about the current user.
- *
- * @uml.property name="user"
- * @uml.associationEnd
*/
UserMemento getUser();
@@ -437,6 +516,8 @@ public interface DomainObjectContainer {
*/
<T> T firstMatch(Query<T> query);
+ // //////////////////////////////////////
+
/**
* Find the only instance of the specified type (including subtypes) that
* has the specified title.
http://git-wip-us.apache.org/repos/asf/isis/blob/edfc5f5f/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
index 52dbf7b..6b3f1ee 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
@@ -132,7 +132,7 @@ public class DomainObjectContainerDefault implements DomainObjectContainer, Que
}
/**
- * Returns a new instance of the specified class that has the sane persisted
+ * Returns a new instance of the specified class that has the same persisted
* state as the specified object.
*/
@Override
@@ -236,19 +236,29 @@ public class DomainObjectContainerDefault implements DomainObjectContainer, Que
return adapter.representsPersistent();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public void persist(final Object transientObject) {
- final ObjectAdapter adapter = getAdapterManager().getAdapterFor(transientObject);
- // TODO check aggregation is supported
+ public void persist(final Object domainObject) {
+ final ObjectAdapter adapter = getAdapterManager().adapterFor(domainObject);
+
+ if(adapter == null) {
+ throw new PersistFailedException("Object not known to framework; instantiate using newTransientInstance(...) rather than simply new'ing up.");
+ }
if (adapter.isParented()) {
+ // TODO check aggregation is supported
return;
}
- if (isPersistent(transientObject)) {
- throw new PersistFailedException("Object already persistent: " + adapter);
+ if (isPersistent(domainObject)) {
+ throw new PersistFailedException("Object already persistent; OID=" + adapter.getOid());
}
getObjectPersistor().makePersistent(adapter);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void persistIfNotAlready(final Object object) {
if (isPersistent(object)) {