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 2015/10/09 19:00:32 UTC
[2/3] isis git commit: ISIS-1211: no-arg versions of domain events,
to reduce boilerplate.
ISIS-1211: no-arg versions of domain events, to reduce boilerplate.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/c5aeadd2
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/c5aeadd2
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/c5aeadd2
Branch: refs/heads/master
Commit: c5aeadd2bdb982971bd6e21f31cfad96cc93f290
Parents: 6ad9088
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Fri Oct 9 17:33:51 2015 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Fri Oct 9 17:33:51 2015 +0100
----------------------------------------------------------------------
.../apache/isis/applib/IsisApplibModule.java | 36 +++++++++++--
.../services/eventbus/AbstractDomainEvent.java | 37 ++++++++++++-
.../eventbus/AbstractInteractionEvent.java | 5 ++
.../services/eventbus/ActionDomainEvent.java | 32 ++++++++++-
.../eventbus/CollectionDomainEvent.java | 19 +++++++
.../services/eventbus/PropertyDomainEvent.java | 19 +++++++
.../metamodel/facets/DomainEventHelper.java | 56 ++++++++++++++++++++
.../java/domainapp/dom/simple/SimpleObject.java | 48 +++++------------
8 files changed, 210 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/c5aeadd2/core/applib/src/main/java/org/apache/isis/applib/IsisApplibModule.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/IsisApplibModule.java b/core/applib/src/main/java/org/apache/isis/applib/IsisApplibModule.java
index fa728f9..6209d50 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/IsisApplibModule.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/IsisApplibModule.java
@@ -25,34 +25,62 @@ public final class IsisApplibModule {
private IsisApplibModule(){}
public abstract static class ActionDomainEvent<S> extends org.apache.isis.applib.services.eventbus.ActionDomainEvent<S> {
+ public ActionDomainEvent() {}
+
+ /**
+ * @deprecated - use the {@link #ActionDomainEvent() no-arg constructor} instead to avoid boilerplate.
+ */
+ @Deprecated
public ActionDomainEvent(final S source, final Identifier identifier) {
super(source, identifier);
}
-
+ /**
+ * @deprecated - use the {@link #ActionDomainEvent() no-arg constructor} instead to avoid boilerplate.
+ */
+ @Deprecated
public ActionDomainEvent(final S source, final Identifier identifier, final Object... arguments) {
super(source, identifier, arguments);
}
-
+ /**
+ * @deprecated - use the {@link #ActionDomainEvent() no-arg constructor} instead to avoid boilerplate.
+ */
+ @Deprecated
public ActionDomainEvent(final S source, final Identifier identifier, final List<Object> arguments) {
super(source, identifier, arguments);
}
}
public abstract static class CollectionDomainEvent<S,T> extends org.apache.isis.applib.services.eventbus.CollectionDomainEvent<S,T> {
+ public CollectionDomainEvent() { }
+ /**
+ * @deprecated - use the {@link #CollectionDomainEvent() no-arg constructor} instead to avoid boilerplate.
+ */
+ @Deprecated
public CollectionDomainEvent(final S source, final Identifier identifier, final Of of) {
super(source, identifier, of);
}
-
+ /**
+ * @deprecated - use the {@link #CollectionDomainEvent() no-arg constructor} instead to avoid boilerplate.
+ */
+ @Deprecated
public CollectionDomainEvent(final S source, final Identifier identifier, final Of of, final T value) {
super(source, identifier, of, value);
}
}
public abstract static class PropertyDomainEvent<S,T> extends org.apache.isis.applib.services.eventbus.PropertyDomainEvent<S,T> {
+ public PropertyDomainEvent() { }
+ /**
+ * @deprecated - use the {@link #PropertyDomainEvent() no-arg constructor} instead to avoid boilerplate.
+ */
+ @Deprecated
public PropertyDomainEvent(final S source, final Identifier identifier) {
super(source, identifier);
}
-
+ /**
+ * @deprecated - use the {@link #PropertyDomainEvent() no-arg constructor} instead to avoid boilerplate.
+ */
+ @Deprecated
public PropertyDomainEvent(final S source, final Identifier identifier, final T oldValue, final T newValue) {
super(source, identifier, oldValue, newValue);
}
http://git-wip-us.apache.org/repos/asf/isis/blob/c5aeadd2/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractDomainEvent.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractDomainEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractDomainEvent.java
index 1e74584..cab9149 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractDomainEvent.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractDomainEvent.java
@@ -18,6 +18,7 @@
*/
package org.apache.isis.applib.services.eventbus;
+import java.util.EventObject;
import java.util.Map;
import com.google.common.collect.Maps;
import org.apache.isis.applib.Identifier;
@@ -29,13 +30,28 @@ public abstract class AbstractDomainEvent<S> extends java.util.EventObject {
private static final long serialVersionUID = 1L;
+ /**
+ * If used then the framework will set state via (non-API) setters.
+ *
+ * <p>
+ * Because the {@link EventObject} superclass prohibits a null source, a dummy value is temporarily used.
+ * </p>
+ */
+ public AbstractDomainEvent() {
+ this(null, null);
+ }
+
public AbstractDomainEvent(
final S source,
final Identifier identifier) {
- super(source);
+ super(sourceElseDummy(source));
this.identifier = identifier;
}
+ private static Object sourceElseDummy(final Object source) {
+ return source != null ? source : new Object();
+ }
+
//region > Phase
public enum Phase {
@@ -94,13 +110,30 @@ public abstract class AbstractDomainEvent<S> extends java.util.EventObject {
public S getSource() {
return (S)source;
}
+
+ /**
+ * Not API, set by the framework if the no-arg constructor is used.
+ */
+ public void setSource(S source) {
+ this.source = source;
+ }
//endregion
//region > identifier
- private final Identifier identifier;
+ /**
+ * If the no-arg constructor is used, then the framework will populate this field reflectively.
+ */
+ private Identifier identifier;
public Identifier getIdentifier() {
return identifier;
}
+
+ /**
+ * Not API, set by the framework if the no-arg constructor is used.
+ */
+ public void setIdentifier(final Identifier identifier) {
+ this.identifier = identifier;
+ }
//endregion
//region > hide, isHidden
http://git-wip-us.apache.org/repos/asf/isis/blob/c5aeadd2/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractInteractionEvent.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractInteractionEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractInteractionEvent.java
index 8762844..8e14186 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractInteractionEvent.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/AbstractInteractionEvent.java
@@ -27,6 +27,11 @@ import org.apache.isis.applib.Identifier;
@Deprecated
public abstract class AbstractInteractionEvent<S> extends AbstractDomainEvent<S> {
+ /**
+ * If used then the framework will set state via (non-API) setters.
+ */
+ public AbstractInteractionEvent() {}
+
public AbstractInteractionEvent(
final S source,
final Identifier identifier) {
http://git-wip-us.apache.org/repos/asf/isis/blob/c5aeadd2/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ActionDomainEvent.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ActionDomainEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ActionDomainEvent.java
index 895e3a5..17d6f7c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ActionDomainEvent.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ActionDomainEvent.java
@@ -46,19 +46,49 @@ public abstract class ActionDomainEvent<S> extends AbstractInteractionEvent<S> {
//endregion
//region > constructors
+
+ /**
+ * If used then the framework will set state via (non-API) setters.
+ *
+ * <p>
+ * Recommended because it reduces the amount of boilerplate in the domain object classes.
+ * </p>
+ */
+ public ActionDomainEvent() {
+ }
+
+ /**
+ * @deprecated - the {@link #ActionDomainEvent() no-arg constructor} is recommended instead, to reduce boilerplate.
+ */
+ @Deprecated
public ActionDomainEvent(
final S source,
final Identifier identifier) {
super(source, identifier);
}
+ /**
+ * @deprecated - the {@link #ActionDomainEvent() no-arg constructor} is recommended instead, to reduce boilerplate.
+ */
+ @Deprecated
public ActionDomainEvent(
final S source,
final Identifier identifier,
final Object... arguments) {
- this(source, identifier, arguments != null? Arrays.asList(arguments): Collections.emptyList());
+ this(source, identifier,
+ asList(arguments));
}
+ private static List<Object> asList(final Object[] arguments) {
+ return arguments != null
+ ? Arrays.asList(arguments)
+ : Collections.emptyList();
+ }
+
+ /**
+ * @deprecated - the {@link #ActionDomainEvent() no-arg constructor} is recommended instead, to reduce boilerplate.
+ */
+ @Deprecated
public ActionDomainEvent(
final S source,
final Identifier identifier,
http://git-wip-us.apache.org/repos/asf/isis/blob/c5aeadd2/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/CollectionDomainEvent.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/CollectionDomainEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/CollectionDomainEvent.java
index 9b6d567..c91daa7 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/CollectionDomainEvent.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/CollectionDomainEvent.java
@@ -43,6 +43,21 @@ public abstract class CollectionDomainEvent<S,T> extends AbstractInteractionEven
//endregion
//region > constructors
+
+ /**
+ * If used then the framework will set state via (non-API) setters.
+ *
+ * <p>
+ * Recommended because it reduces the amount of boilerplate in the domain object classes.
+ * </p>
+ */
+ public CollectionDomainEvent() {
+ }
+
+ /**
+ * @deprecated - the {@link #CollectionDomainEvent() no-arg constructor} is recommended instead, to reduce boilerplate.
+ */
+ @Deprecated
public CollectionDomainEvent(
final S source,
final Identifier identifier,
@@ -51,6 +66,10 @@ public abstract class CollectionDomainEvent<S,T> extends AbstractInteractionEven
this.of = of;
}
+ /**
+ * @deprecated - the {@link #CollectionDomainEvent() no-arg constructor} is recommended instead, to reduce boilerplate.
+ */
+ @Deprecated
public CollectionDomainEvent(
final S source,
final Identifier identifier,
http://git-wip-us.apache.org/repos/asf/isis/blob/c5aeadd2/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/PropertyDomainEvent.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/PropertyDomainEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/PropertyDomainEvent.java
index 76a2883..b641276 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/PropertyDomainEvent.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/PropertyDomainEvent.java
@@ -39,12 +39,31 @@ public abstract class PropertyDomainEvent<S,T> extends AbstractInteractionEvent<
//endregion
//region > constructors
+
+ /**
+ * If used then the framework will set state via (non-API) setters.
+ *
+ * <p>
+ * Recommended because it reduces the amount of boilerplate in the domain object classes.
+ * </p>
+ */
+ public PropertyDomainEvent() {
+ }
+
+ /**
+ * @deprecated - the {@link #PropertyDomainEvent() no-arg constructor} is recommended instead, to reduce boilerplate.
+ */
+ @Deprecated
public PropertyDomainEvent(
final S source,
final Identifier identifier) {
super(source, identifier);
}
+ /**
+ * @deprecated - the {@link #PropertyDomainEvent() no-arg constructor} is recommended instead, to reduce boilerplate.
+ */
+ @Deprecated
public PropertyDomainEvent(
final S source,
final Identifier identifier,
http://git-wip-us.apache.org/repos/asf/isis/blob/c5aeadd2/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
index 2744478..c5729f7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/DomainEventHelper.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -135,7 +136,24 @@ public class DomainEventHelper {
final Identifier identifier,
final S source,
final Object... arguments) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+
final Constructor<?>[] constructors = type.getConstructors();
+
+ // no-arg constructor
+ for (final Constructor<?> constructor : constructors) {
+ final Class<?>[] parameterTypes = constructor.getParameterTypes();
+ if(parameterTypes.length == 0) {
+ final Object event = constructor.newInstance();
+ final ActionDomainEvent<S> ade = (ActionDomainEvent<S>) event;
+
+ ade.setSource(source);
+ ade.setIdentifier(identifier);
+ ade.setArguments(asList(arguments));
+ return ade;
+ }
+ }
+
+
for (final Constructor<?> constructor : constructors) {
final Class<?>[] parameterTypes = constructor.getParameterTypes();
if(parameterTypes.length != 3) {
@@ -155,6 +173,13 @@ public class DomainEventHelper {
}
throw new NoSuchMethodException(type.getName()+".<init>(? super " + source.getClass().getName() + ", " + Identifier.class.getName() + ", [Ljava.lang.Object;)");
}
+
+ // same as in ActionDomainEvent's constructor.
+ private static List<Object> asList(final Object[] arguments) {
+ return arguments != null
+ ? Arrays.asList(arguments)
+ : Collections.emptyList();
+ }
//endregion
//region > postEventForProperty, newPropertyInteraction
@@ -209,6 +234,22 @@ public class DomainEventHelper {
final T newValue) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
final Constructor<?>[] constructors = type.getConstructors();
+
+ // no-arg constructor
+ for (final Constructor<?> constructor : constructors) {
+ final Class<?>[] parameterTypes = constructor.getParameterTypes();
+ if(parameterTypes.length == 0) {
+ final Object event = constructor.newInstance();
+ final PropertyDomainEvent<S, T> pde = (PropertyDomainEvent<S, T>) event;
+ pde.setSource(source);
+ pde.setIdentifier(identifier);
+ pde.setOldValue(oldValue);
+ pde.setNewValue(newValue);
+ return pde;
+ }
+ }
+
+ // else
for (final Constructor<?> constructor : constructors) {
final Class<?>[] parameterTypes = constructor.getParameterTypes();
if(parameterTypes.length != 4) {
@@ -282,6 +323,21 @@ public class DomainEventHelper {
final Constructor<?>[] constructors = type.getConstructors();
+ // no-arg constructor
+ for (final Constructor<?> constructor : constructors) {
+ final Class<?>[] parameterTypes = constructor.getParameterTypes();
+ if(parameterTypes.length ==0) {
+ final Object event = constructor.newInstance();
+ final CollectionDomainEvent<S, T> cde = (CollectionDomainEvent<S, T>) event;
+
+ cde.setSource(source);
+ cde.setIdentifier(identifier);
+ cde.setOf(of);
+ cde.setValue(value);
+ return cde;
+ }
+ }
+
// search for constructor accepting source, identifier, type, value
for (final Constructor<?> constructor : constructors) {
final Class<?>[] parameterTypes = constructor.getParameterTypes();
http://git-wip-us.apache.org/repos/asf/isis/blob/c5aeadd2/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java b/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java
index 07844c5..b5b8500 100644
--- a/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java
+++ b/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.java
@@ -23,7 +23,7 @@ import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.VersionStrategy;
import org.apache.isis.applib.DomainObjectContainer;
-import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.IsisApplibModule;
import org.apache.isis.applib.annotation.Action;
import org.apache.isis.applib.annotation.BookmarkPolicy;
import org.apache.isis.applib.annotation.DomainObject;
@@ -32,7 +32,6 @@ import org.apache.isis.applib.annotation.Editing;
import org.apache.isis.applib.annotation.Parameter;
import org.apache.isis.applib.annotation.ParameterLayout;
import org.apache.isis.applib.annotation.Property;
-import org.apache.isis.applib.annotation.Title;
import org.apache.isis.applib.services.eventbus.ActionDomainEvent;
import org.apache.isis.applib.services.i18n.TranslatableString;
import org.apache.isis.applib.util.ObjectContracts;
@@ -68,86 +67,65 @@ import org.apache.isis.applib.util.ObjectContracts;
)
public class SimpleObject implements Comparable<SimpleObject> {
+ public static final int NAME_LENGTH = 40;
- //region > identificatiom
public TranslatableString title() {
return TranslatableString.tr("Object: {name}", "name", getName());
}
- //endregion
- //region > name (property)
- private String name;
-
- @javax.jdo.annotations.Column(allowsNull="false", length = 40)
- @Title(sequence="1")
+ public static class NameDomainEvent extends IsisApplibModule.PropertyDomainEvent<SimpleObject,String> {}
+ @javax.jdo.annotations.Column(
+ allowsNull="false",
+ length = NAME_LENGTH
+ )
@Property(
editing = Editing.DISABLED
)
+ private String name;
public String getName() {
return name;
}
-
public void setName(final String name) {
this.name = name;
}
- // endregion
-
- //region > updateName (action)
-
- public static class UpdateNameDomainEvent extends ActionDomainEvent<SimpleObject> {
- public UpdateNameDomainEvent(final SimpleObject source, final Identifier identifier, final Object... arguments) {
- super(source, identifier, arguments);
- }
- }
+ public static class UpdateNameDomainEvent extends ActionDomainEvent<SimpleObject> {}
@Action(
domainEvent = UpdateNameDomainEvent.class
)
public SimpleObject updateName(
- @Parameter(maxLength = 40)
+ @Parameter(maxLength = NAME_LENGTH)
@ParameterLayout(named = "New name")
final String name) {
setName(name);
return this;
}
-
public String default0UpdateName() {
return getName();
}
-
public TranslatableString validateUpdateName(final String name) {
return name.contains("!")? TranslatableString.tr("Exclamation mark is not allowed"): null;
}
- //endregion
- //region > version (derived property)
-// public Long getVersionSequence() {
-// return (Long) JDOHelper.getVersion(this);
-// }
+ /**
+ * version (derived property)
+ */
public java.sql.Timestamp getVersionSequence() {
return (java.sql.Timestamp) JDOHelper.getVersion(this);
}
- //endregion
- //region > compareTo
@Override
public int compareTo(final SimpleObject other) {
return ObjectContracts.compare(this, other, "name");
}
- //endregion
-
- //region > injected services
@javax.inject.Inject
@SuppressWarnings("unused")
private DomainObjectContainer container;
- //endregion
-
-
}