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 2016/04/19 22:48:10 UTC
[2/3] isis git commit: ISIS-1291: memento xsd schemas + utils;
new command memento DTO for Command#memento, updated background
service, background execution; new PublisherService
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/applib/src/main/java/org/apache/isis/schema/utils/CommonDtoUtils.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/schema/utils/CommonDtoUtils.java b/core/applib/src/main/java/org/apache/isis/schema/utils/CommonDtoUtils.java
new file mode 100644
index 0000000..41f102f
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/schema/utils/CommonDtoUtils.java
@@ -0,0 +1,183 @@
+/*
+ * 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.isis.schema.utils;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import javax.annotation.Nullable;
+
+import com.google.common.base.Function;
+import com.google.common.base.Strings;
+
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.joda.time.LocalDateTime;
+import org.joda.time.LocalTime;
+
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.schema.cmd.v1.ParamDto;
+import org.apache.isis.schema.common.v1.OidDto;
+import org.apache.isis.schema.common.v1.ValueDto;
+import org.apache.isis.schema.common.v1.ValueType;
+import org.apache.isis.schema.utils.jaxbadapters.JodaDateTimeXMLGregorianCalendarAdapter;
+import org.apache.isis.schema.utils.jaxbadapters.JodaLocalDateTimeXMLGregorianCalendarAdapter;
+import org.apache.isis.schema.utils.jaxbadapters.JodaLocalDateXMLGregorianCalendarAdapter;
+import org.apache.isis.schema.utils.jaxbadapters.JodaLocalTimeXMLGregorianCalendarAdapter;
+
+public final class CommonDtoUtils {
+
+ public static final Function<OidDto, String> OID_DTO_2_STR = new Function<OidDto, String>() {
+ @Nullable @Override
+ public String apply(final OidDto oidDto) {
+ final Bookmark bookmark = Bookmark.from(oidDto);
+ return bookmark.toString();
+ }
+ };
+
+ public static final Function<ParamDto, String> PARAM_DTO_TO_NAME = new Function<ParamDto, String>() {
+ @Override public String apply(final ParamDto paramDto) {
+ return paramDto.getParameterName();
+ }
+ };
+ public static final Function<ParamDto, ValueType> PARAM_DTO_TO_TYPE = new Function<ParamDto, ValueType>() {
+ @Override public ValueType apply(final ParamDto paramDto) {
+ return paramDto.getParameterType();
+ }
+ };
+
+ public static boolean setValue(
+ final ValueDto valueDto,
+ final Class<?> type,
+ final Object val) {
+ if(type == String.class) {
+ final String argValue = (String) val;
+ valueDto.setString(argValue);
+ } else
+ if(type == byte.class || type == Byte.class) {
+ final Byte argValue = (Byte) val;
+ valueDto.setByte(argValue);
+ } else
+ if(type == short.class || type == Short.class) {
+ final Short argValue = (Short) val;
+ valueDto.setShort(argValue);
+ }else
+ if(type == int.class || type == Integer.class) {
+ final Integer argValue = (Integer) val;
+ valueDto.setInt(argValue);
+ }else
+ if(type == long.class || type == Long.class) {
+ final Long argValue = (Long) val;
+ valueDto.setLong(argValue);
+ }else
+ if(type == char.class || type == Character.class) {
+ final Character argValue = (Character) val;
+ valueDto.setChar("" + argValue);
+ }else
+ if(type == boolean.class || type == Boolean.class) {
+ final Boolean argValue = (Boolean) val;
+ valueDto.setBoolean(argValue);
+ }else
+ if(type == float.class || type == Float.class) {
+ final Float argValue = (Float) val;
+ valueDto.setFloat(argValue);
+ }else
+ if(type == double.class || type == Double.class) {
+ final Double argValue = (Double) val;
+ valueDto.setDouble(argValue);
+ }else
+ if(type == BigInteger.class) {
+ final BigInteger argValue = (BigInteger) val;
+ valueDto.setBigInteger(argValue);
+ }else
+ if(type == BigDecimal.class) {
+ final BigDecimal argValue = (BigDecimal) val;
+ valueDto.setBigDecimal(argValue);
+ }else
+ if(type == DateTime.class) {
+ final DateTime argValue = (DateTime) val;
+ valueDto.setDateTime(JodaDateTimeXMLGregorianCalendarAdapter.print(argValue));
+ }else
+ if(type == LocalDateTime.class) {
+ final LocalDateTime argValue = (LocalDateTime) val;
+ valueDto.setLocalDateTime(JodaLocalDateTimeXMLGregorianCalendarAdapter.print(argValue));
+ }else
+ if(type == LocalDate.class) {
+ final LocalDate argValue = (LocalDate) val;
+ valueDto.setLocalDate(JodaLocalDateXMLGregorianCalendarAdapter.print(argValue));
+ }else
+ if(type == LocalTime.class) {
+ final LocalTime argValue = (LocalTime) val;
+ valueDto.setLocalTime(JodaLocalTimeXMLGregorianCalendarAdapter.print(argValue));
+ }else
+ {
+ // none of the supported value types
+ return false;
+ }
+ return true;
+ }
+
+ public static <T> T getValue(
+ final ValueDto valueDto,
+ final ValueType valueType) {
+ switch(valueType) {
+ case STRING:
+ return (T) valueDto.getString();
+ case BYTE:
+ return (T) valueDto.getByte();
+ case SHORT:
+ return (T) valueDto.getShort();
+ case INT:
+ return (T) valueDto.getInt();
+ case LONG:
+ return (T) valueDto.getLong();
+ case FLOAT:
+ return (T) valueDto.getFloat();
+ case DOUBLE:
+ return (T) valueDto.getDouble();
+ case BOOLEAN:
+ return (T) valueDto.isBoolean();
+ case CHAR:
+ final String aChar = valueDto.getChar();
+ if(Strings.isNullOrEmpty(aChar)) { return null; }
+ return (T) (Object)aChar.charAt(0);
+ case BIG_DECIMAL:
+ return (T) valueDto.getBigDecimal();
+ case BIG_INTEGER:
+ return (T) valueDto.getBigInteger();
+ case JODA_DATE_TIME:
+ return (T) JodaDateTimeXMLGregorianCalendarAdapter.parse(valueDto.getDateTime());
+ case JODA_LOCAL_DATE:
+ return (T) JodaLocalDateXMLGregorianCalendarAdapter.parse(valueDto.getLocalDate());
+ case JODA_LOCAL_DATE_TIME:
+ return (T) JodaLocalDateTimeXMLGregorianCalendarAdapter.parse(valueDto.getLocalDateTime());
+ case JODA_LOCAL_TIME:
+ return (T) JodaLocalTimeXMLGregorianCalendarAdapter.parse(valueDto.getLocalTime());
+ case REFERENCE:
+ return (T) valueDto.getReference();
+ }
+ throw new IllegalStateException("Value type was not recognised (possible bug)");
+ }
+
+ public static OidDto asOidDto(final Bookmark reference) {
+ return reference != null ? reference.toOidDto() : null;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java
----------------------------------------------------------------------
diff --git a/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java b/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java
index bc8a44d..5be8a88 100644
--- a/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java
+++ b/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java
@@ -30,7 +30,7 @@ import org.joda.time.LocalTime;
import org.junit.Test;
import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.schema.aim.v1.ActionInvocationMementoDto;
+import org.apache.isis.schema.aim.v2.ActionInvocationMementoDto;
import org.apache.isis.schema.common.v1.OidDto;
import org.apache.isis.schema.common.v1.ValueType;
@@ -45,63 +45,60 @@ public class Roundtrip {
public void happyCase() throws Exception {
// given
- final ActionInvocationMementoDto aim = ActionInvocationMementoDtoUtils.newDto();
-
- ActionInvocationMementoDtoUtils.setMetadata(
- aim,
+ final ActionInvocationMementoDto aim = ActionInvocationMementoDtoUtils.newDto(
UUID.randomUUID(),
1,
- new java.sql.Timestamp(new java.util.Date().getTime()),
- "com.mycompany.myapp.Customer", "placeOrder", "com.mycompany.myapp.Customer#placeOrder",
- "CUS", "12345", "John Customer", "freddyUser");
+ "com.mycompany.myapp.Customer#placeOrder",
+ new Bookmark("CUS", "12345"), "John Customer", "freddyUser",
+ new java.sql.Timestamp(new java.util.Date().getTime()));
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aString", String.class, "Fred");
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullString", String.class, (String) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aString", String.class, "Fred", null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullString", String.class, (String) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aByte", Byte.class, (Byte) (byte) 123);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullByte", Byte.class, (Byte) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aByte", Byte.class, (Byte) (byte) 123, null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullByte", Byte.class, (Byte) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aShort", Short.class, (Short) (short) 32123);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullShort", Short.class, (Short) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aShort", Short.class, (Short) (short) 32123, null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullShort", Short.class, (Short) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "anInt", Integer.class, 123454321);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullInt", Integer.class, (Integer) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "anInt", Integer.class, 123454321, null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullInt", Integer.class, (Integer) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aLong", Long.class, 1234567654321L);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullLong", Long.class, (Long) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aLong", Long.class, 1234567654321L, null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullLong", Long.class, (Long) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aFloat", Float.class, 12345.6789F);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullFloat", Float.class, (Float) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aFloat", Float.class, 12345.6789F, null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullFloat", Float.class, (Float) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aDouble", Double.class, 12345678.90123);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullDouble", Double.class, (Double) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aDouble", Double.class, 12345678.90123, null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullDouble", Double.class, (Double) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aBoolean", Boolean.class, true);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullBoolean", Boolean.class, (Boolean) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aBoolean", Boolean.class, true, null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullBoolean", Boolean.class, (Boolean) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aChar", Character.class, 'x');
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullChar", Character.class, (Character) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aChar", Character.class, 'x', null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullChar", Character.class, (Character) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aBigInteger", java.math.BigInteger.class, new java.math.BigInteger("12345678901234567890"));
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullBigInteger", java.math.BigInteger.class, (java.math.BigInteger) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aBigInteger", java.math.BigInteger.class, new java.math.BigInteger("12345678901234567890"), null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullBigInteger", java.math.BigInteger.class, (java.math.BigInteger) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aBigDecimal", java.math.BigDecimal.class, new java.math.BigDecimal("12345678901234567890"));
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullBigDecimal", java.math.BigDecimal.class, (java.math.BigDecimal) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aBigDecimal", java.math.BigDecimal.class, new java.math.BigDecimal("12345678901234567890"), null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullBigDecimal", java.math.BigDecimal.class, (java.math.BigDecimal) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aJodaDateTime", org.joda.time.DateTime.class, new org.joda.time.DateTime(2015, 5, 23, 9, 54, 1));
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullJodaDateTime", org.joda.time.DateTime.class, (org.joda.time.DateTime) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aJodaDateTime", org.joda.time.DateTime.class, new org.joda.time.DateTime(2015, 5, 23, 9, 54, 1), null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullJodaDateTime", org.joda.time.DateTime.class, (org.joda.time.DateTime) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aJodaLocalDate", org.joda.time.LocalDate.class, new org.joda.time.LocalDate(2015, 5, 23));
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullJodaLocalDate", org.joda.time.LocalDate.class, (org.joda.time.LocalDate) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aJodaLocalDate", org.joda.time.LocalDate.class, new org.joda.time.LocalDate(2015, 5, 23), null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullJodaLocalDate", org.joda.time.LocalDate.class, (org.joda.time.LocalDate) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aJodaLocalDateTime", org.joda.time.LocalDateTime.class, new org.joda.time.LocalDateTime(2015, 5, 23, 9, 54, 1));
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullJodaLocalDateTime", org.joda.time.LocalDateTime.class, (org.joda.time.LocalDateTime) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aJodaLocalDateTime", org.joda.time.LocalDateTime.class, new org.joda.time.LocalDateTime(2015, 5, 23, 9, 54, 1), null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullJodaLocalDateTime", org.joda.time.LocalDateTime.class, (org.joda.time.LocalDateTime) null, null);
- ActionInvocationMementoDtoUtils.addArgValue(aim, "aJodaLocalTime", org.joda.time.LocalTime.class, new org.joda.time.LocalTime(9, 54, 1));
- ActionInvocationMementoDtoUtils.addArgValue(aim, "nullJodaLocalTime", org.joda.time.LocalTime.class, (org.joda.time.LocalTime) null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aJodaLocalTime", org.joda.time.LocalTime.class, new org.joda.time.LocalTime(9, 54, 1), null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullJodaLocalTime", org.joda.time.LocalTime.class, (org.joda.time.LocalTime) null, null);
- ActionInvocationMementoDtoUtils.addArgReference(aim, "aReference", new Bookmark("ORD", "12345"));
- ActionInvocationMementoDtoUtils.addArgReference(aim, "nullReference", null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "aReference", null, new Bookmark("ORD", "12345"), null);
+ ActionInvocationMementoDtoUtils.addParamArg(aim, "nullReference", null, null, null);
// when
@@ -115,9 +112,9 @@ public class Roundtrip {
// then
- assertThat(recreated.getMetadata().getActionIdentifier(), Matchers.is(aim.getMetadata().getActionIdentifier()));
- assertThat(recreated.getMetadata().getTarget().getObjectType(), Matchers.is(aim.getMetadata().getTarget().getObjectType()));
- assertThat(recreated.getMetadata().getTarget().getObjectIdentifier(), Matchers.is(aim.getMetadata().getTarget().getObjectIdentifier()));
+ assertThat(recreated.getInvocation().getAction().getActionIdentifier(), Matchers.is(aim.getInvocation().getAction().getActionIdentifier()));
+ assertThat(recreated.getInvocation().getTarget().getObjectType(), Matchers.is(aim.getInvocation().getTarget().getObjectType()));
+ assertThat(recreated.getInvocation().getTarget().getObjectIdentifier(), Matchers.is(aim.getInvocation().getTarget().getObjectIdentifier()));
int param = 0;
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java
index ae26640..a2535ec 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java
@@ -27,6 +27,7 @@ import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
+import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.core.metamodel.adapter.oid.Oid.State;
import org.apache.isis.core.metamodel.adapter.version.Version;
import org.apache.isis.core.metamodel.spec.ObjectSpecId;
@@ -82,11 +83,14 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
public class OidMarshaller {
//region > public constants
- public static final String VIEWMODEL_INDICATOR = "*";
+ public static final String VIEWMODEL_INDICATOR =
+ Bookmark.ObjectState.VIEW_MODEL.getCode(); // "*"
//endregion
//region > private constants
- private static final String TRANSIENT_INDICATOR = "!";
+ private static final String TRANSIENT_INDICATOR =
+ Bookmark.ObjectState.TRANSIENT.getCode() ; // "!"
+
private static final String SEPARATOR = ":";
private static final String SEPARATOR_NESTING = "~";
private static final String SEPARATOR_COLLECTION = "$";
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
index 790ff8c..6199504 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
@@ -42,10 +42,11 @@ import org.apache.isis.applib.services.background.ActionInvocationMemento;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.command.CommandContext;
-import org.apache.isis.applib.services.command.CommandMementoService;
+import org.apache.isis.core.metamodel.services.command.CommandMementoService;
import org.apache.isis.applib.services.command.spi.CommandService;
import org.apache.isis.applib.services.eventbus.AbstractDomainEvent;
import org.apache.isis.applib.services.eventbus.ActionDomainEvent;
+import org.apache.isis.applib.services.jaxb.JaxbService;
import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
@@ -75,6 +76,8 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.specloader.ReflectiveActionException;
import org.apache.isis.core.metamodel.transactions.TransactionState;
import org.apache.isis.core.metamodel.transactions.TransactionStateProvider;
+import org.apache.isis.schema.cmd.v1.CommandMementoDto;
+import org.apache.isis.schema.utils.CommandMementoDtoUtils;
public abstract class ActionInvocationFacetForDomainEventAbstract
extends ActionInvocationFacetAbstract
@@ -193,7 +196,7 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
final ObjectAdapter[] arguments,
final InteractionInitiatedBy interactionInitiatedBy) {
- final CommandContext commandContext = getServicesInjector().lookupService(CommandContext.class);
+ final CommandContext commandContext = getCommandContext();
final Command command = commandContext != null ? commandContext.getCommand() : null;
// ... post the executing event
@@ -281,10 +284,8 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
final ObjectAdapter targetAdapter,
final ObjectAdapter[] arguments) {
-
try {
-
final Object[] executionParameters = new Object[arguments.length];
for (int i = 0; i < arguments.length; i++) {
executionParameters[i] = unwrap(arguments[i]);
@@ -294,7 +295,7 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
final BulkFacet bulkFacet = getFacetHolder().getFacet(BulkFacet.class);
if (bulkFacet != null) {
- final ActionInvocationContext actionInvocationContext = getServicesInjector().lookupService(ActionInvocationContext.class);
+ final ActionInvocationContext actionInvocationContext = getActionInvocationContext();
if (actionInvocationContext != null &&
actionInvocationContext.getInvokedOn() == null) {
@@ -302,7 +303,7 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
actionInvocationContext.setDomainObjects(Collections.singletonList(targetPojo));
}
- final Bulk.InteractionContext bulkInteractionContext = getServicesInjector().lookupService(Bulk.InteractionContext.class);
+ final Bulk.InteractionContext bulkInteractionContext = getBulkInteractionContext();
if (bulkInteractionContext != null &&
bulkInteractionContext.getInvokedAs() == null) {
@@ -326,7 +327,7 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
command.setTarget(targetBookmark);
}
- if("(edit)".equals(command.getMemberIdentifier())) {
+ if(Command.ACTION_IDENTIFIER_FOR_EDIT.equals(command.getMemberIdentifier())) {
// special case for edit properties
} else {
@@ -339,18 +340,34 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
if(command.getMemento() == null) {
// similarly, guard here to deal with subsequent contributed/mixin actions.
- final CommandMementoService commandMementoService = getServicesInjector().lookupService(CommandMementoService.class);
- if(commandMementoService != null) {
- final Object targetObject = unwrap(targetAdapter);
- final Object[] args = CommandUtil.objectsFor(arguments);
- final ActionInvocationMemento aim = commandMementoService.asActionInvocationMemento(method, targetObject, args);
+ final CommandMementoService commandMementoService = getCommandMementoService();
+
+ final Object targetObject = unwrap(targetAdapter);
+ final Object[] args = CommandUtil.objectsFor(arguments);
+
+ final CommandMementoDto dto = commandMementoService.asCommandMemento(
+ Collections.singletonList(targetAdapter),
+ owningAction, arguments);
+ if(dto != null) {
+ // the default implementation will always return a dto. The guard is to allow
+ // for the default implementation to be replaced with a version that returns null
+ // allowing a fallback to the original API (using ActionInvocationMemento rather than
+ // CommandMementoDto).
+ final String mementoXml = CommandMementoDtoUtils.toXml(dto);
+ command.setMemento(mementoXml);
+ } else {
+
+ // fallback to old behaviour
+ ActionInvocationMemento aim = commandMementoService
+ .asActionInvocationMemento(method, targetObject, args);
if(aim != null) {
command.setMemento(aim.asMementoString());
+
} else {
+ String actionIdentifier = owningAction.getIdentifier().toClassAndNameIdentityString();
throw new IsisException(
- "Unable to build memento for action " +
- owningAction.getIdentifier().toClassAndNameIdentityString());
+ "Unable to build memento for action " + actionIdentifier);
}
}
}
@@ -375,7 +392,7 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
command.getExecuteIn() == org.apache.isis.applib.annotation.Command.ExecuteIn.BACKGROUND) {
// persist command so can be this command can be in the 'background'
- final CommandService commandService = getServicesInjector().lookupService(CommandService.class);
+ final CommandService commandService = getCommandService();
if(commandService.persistIfPossible(command)) {
// force persistence, then return the command itself.
final ObjectAdapter resultAdapter = getAdapterManager().adapterFor(command);
@@ -399,9 +416,8 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
Object result;
if(cacheable) {
- final QueryResultsCache queryResultsCache = getServicesInjector().lookupService(QueryResultsCache.class);
- final Object[] targetPojoPlusExecutionParameters = ArrayExtensions
- .appendT(executionParameters, targetPojo);
+ final QueryResultsCache queryResultsCache = getQueryResultsCache();
+ final Object[] targetPojoPlusExecutionParameters = ArrayExtensions.appendT(executionParameters, targetPojo);
result = queryResultsCache.execute(new Callable<Object>() {
@Override
public Object call() throws Exception {
@@ -494,8 +510,6 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
}
}
-
-
private static Object unwrap(final ObjectAdapter adapter) {
return adapter == null ? null : adapter.getObject();
}
@@ -506,10 +520,44 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
}
+
+ // /////////////////////////////////////////////////////////
+ // Dependencies (looked up)
+ // /////////////////////////////////////////////////////////
+
+ private CommandContext getCommandContext() {
+ return lookupService(CommandContext.class);
+ }
+
+ private QueryResultsCache getQueryResultsCache() {
+ return lookupService(QueryResultsCache.class);
+ }
+
+ private CommandService getCommandService() {
+ return lookupService(CommandService.class);
+ }
+
+ private CommandMementoService getCommandMementoService() {
+ return lookupService(CommandMementoService.class);
+ }
+
+ private Bulk.InteractionContext getBulkInteractionContext() {
+ return lookupService(Bulk.InteractionContext.class);
+ }
+
+ private ActionInvocationContext getActionInvocationContext() {
+ return lookupService(ActionInvocationContext.class);
+ }
+
+ private <T> T lookupService(final Class<T> serviceClass) {
+ return getServicesInjector().lookupService(serviceClass);
+ }
+
// /////////////////////////////////////////////////////////
// Dependencies (from constructor)
// /////////////////////////////////////////////////////////
+
private AdapterManager getAdapterManager() {
return adapterManager;
}
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
index 2230d38..9339274 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
@@ -74,8 +74,8 @@ public class PropertySetterFacetViaModifyMethod extends PropertySetterFacetAbstr
command.setTarget(CommandUtil.bookmarkFor(targetAdapter));
command.setTargetClass(CommandUtil.targetClassNameFor(targetAdapter));
- command.setTargetAction(Command.TARGET_ACTION_FOR_EDIT);
- command.setMemberIdentifier(Command.TARGET_ACTION_FOR_EDIT);
+ command.setTargetAction(Command.ACTION_IDENTIFIER_FOR_EDIT);
+ command.setMemberIdentifier(Command.ACTION_IDENTIFIER_FOR_EDIT);
command.setExecuteIn(org.apache.isis.applib.annotation.Command.ExecuteIn.FOREGROUND);
command.setPersistence(org.apache.isis.applib.annotation.Command.Persistence.IF_HINTED);
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandMementoService.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandMementoService.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandMementoService.java
new file mode 100644
index 0000000..acbec29
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandMementoService.java
@@ -0,0 +1,53 @@
+/**
+ * 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.isis.core.metamodel.services.command;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.background.ActionInvocationMemento;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.schema.cmd.v1.CommandMementoDto;
+
+/**
+ * Used to create mementos of a command, such that it can be persisted and then executed either immediately (ie invoke
+ * in the foreground) or deferred (ie invoke in the background at some later time).
+ */
+public interface CommandMementoService {
+
+ /**
+ * Note that this method (more precisely, {@link ActionInvocationMemento}) does <i>not</i> support mixins.
+ *
+ * @deprecated - use {@link #asCommandMemento(List, ObjectAction, ObjectAdapter[])} instead.
+ */
+ @Deprecated
+ @Programmatic
+ ActionInvocationMemento asActionInvocationMemento(Method m, Object domainObject, Object[] args);
+
+ /**
+ * The default implementation returns a non-null value. If a custom implementation returns <tt>null</tt>, then
+ * the framework will fall back to using the deprecated {@link #asActionInvocationMemento(Method, Object, Object[])}.
+ */
+ @Programmatic
+ CommandMementoDto asCommandMemento(
+ final List<ObjectAdapter> targetAdapters,
+ final ObjectAction objectAction,
+ final ObjectAdapter[] argAdapters);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
index 09f1b2a..79c2ab8 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
@@ -18,7 +18,9 @@ package org.apache.isis.core.runtime.services.background;
import java.util.List;
+import com.google.common.base.Function;
import com.google.common.base.Throwables;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.apache.isis.applib.clock.Clock;
@@ -28,6 +30,7 @@ import org.apache.isis.applib.services.bookmark.BookmarkService;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.command.Command.Executor;
import org.apache.isis.applib.services.command.CommandContext;
+import org.apache.isis.applib.services.jaxb.JaxbService;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -40,6 +43,11 @@ import org.apache.isis.core.runtime.sessiontemplate.AbstractIsisSessionTemplate;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
import org.apache.isis.core.runtime.system.transaction.TransactionalClosure;
+import org.apache.isis.schema.cmd.v1.ActionDto;
+import org.apache.isis.schema.cmd.v1.CommandMementoDto;
+import org.apache.isis.schema.cmd.v1.ParamDto;
+import org.apache.isis.schema.common.v1.OidDto;
+import org.apache.isis.schema.utils.CommandMementoDtoUtils;
/**
* Intended to be used as a base class for executing queued up {@link Command background action}s.
@@ -89,42 +97,101 @@ public abstract class BackgroundCommandExecution extends AbstractIsisSessionTemp
transactionManager.executeWithinTransaction(new TransactionalClosure() {
@Override
public void execute() {
+
commandContext.setCommand(command);
- try {
+ final String memento = command.getMemento();
+ final boolean legacy = memento.startsWith("<memento");
+ try {
command.setStartedAt(Clock.getTimeAsJavaSqlTimestamp());
command.setExecutor(Executor.BACKGROUND);
- final String memento = command.getMemento();
- final ActionInvocationMemento aim = new ActionInvocationMemento(mementoService, memento);
+ if(legacy) {
- final String actionId = aim.getActionId();
+ final ActionInvocationMemento aim = new ActionInvocationMemento(mementoService, memento);
- final Bookmark targetBookmark = aim.getTarget();
- final Object targetObject = bookmarkService.lookup(targetBookmark);
+ final String actionId = aim.getActionId();
- final ObjectAdapter targetAdapter = adapterFor(targetObject);
- final ObjectSpecification specification = targetAdapter.getSpecification();
+ final Bookmark targetBookmark = aim.getTarget();
+ final Object targetObject = bookmarkService.lookup(targetBookmark);
- final ObjectAction objectAction = findAction(specification, actionId);
- if(objectAction == null) {
- throw new Exception("Unknown action '" + actionId + "'");
- }
+ final ObjectAdapter targetAdapter = adapterFor(targetObject);
+ final ObjectSpecification specification = targetAdapter.getSpecification();
+
+ final ObjectAction objectAction = findAction(specification, actionId);
+ if(objectAction == null) {
+ throw new Exception("Unknown action '" + actionId + "'");
+ }
+
+ final ObjectAdapter[] argAdapters = argAdaptersFor(aim);
+ final ObjectAdapter resultAdapter = objectAction.execute(
+ targetAdapter, argAdapters, InteractionInitiatedBy.FRAMEWORK);
+ if(resultAdapter != null) {
+ Bookmark resultBookmark = CommandUtil.bookmarkFor(resultAdapter);
+ command.setResult(resultBookmark);
+ }
+
+ } else {
- final ObjectAdapter[] argAdapters = argAdaptersFor(aim);
- final ObjectAdapter resultAdapter = objectAction.execute(
- targetAdapter, argAdapters, InteractionInitiatedBy.FRAMEWORK);
- if(resultAdapter != null) {
- Bookmark resultBookmark = CommandUtil.bookmarkFor(resultAdapter);
- command.setResult(resultBookmark);
+ final CommandMementoDto dto = jaxbService.fromXml(CommandMementoDto.class, memento);
+ final ActionDto actionDto = dto.getAction();
+ final String actionId = actionDto.getActionIdentifier();
+
+ final List<OidDto> targetOidDtos = dto.getTargets();
+ for (OidDto targetOidDto : targetOidDtos) {
+
+ final Bookmark bookmark = Bookmark.from(targetOidDto);
+ final Object targetObject = bookmarkService.lookup(bookmark);
+
+ final ObjectAdapter targetAdapter = adapterFor(targetObject);
+ final String mixinFqClassName = actionDto.getMixinFqClassName();
+
+ final ObjectAction objectAction =
+ findObjectAction(mixinFqClassName, targetAdapter, actionId);
+
+ final ObjectAdapter[] argAdapters = argAdaptersFor(dto);
+ objectAction.execute(
+ targetAdapter, argAdapters, InteractionInitiatedBy.FRAMEWORK);
+
+ // no longer capture the result, because there may be many
+ // (should be done by auditing/profiling instead).
+ }
}
} catch (Exception e) {
- command.setException(Throwables.getStackTraceAsString(e));
+ if(legacy) {
+ command.setException(Throwables.getStackTraceAsString(e));
+ } else {
+ // no longer capture any exceptions, could be bulk action.
+ // (should be done by auditing/profiling instead).
+ }
} finally {
+ // decided to keep this, even though really this
+ // should be the responsibility of auditing/profiling
command.setCompletedAt(Clock.getTimeAsJavaSqlTimestamp());
}
}
+
+ private ObjectAction findObjectAction(
+ final String mixinFqClassName,
+ final ObjectAdapter targetAdapter,
+ final String actionId) throws Exception {
+
+ final ObjectAction objectAction;
+ if(mixinFqClassName != null) {
+ final ObjectSpecification mixinSpec = getSpecificationLoader()
+ .loadSpecification(mixinFqClassName);
+ objectAction = mixinSpec.getObjectAction(actionId);
+ } else {
+ final ObjectSpecification specification = targetAdapter.getSpecification();
+
+ objectAction = findAction(specification, actionId);
+ }
+ if(objectAction == null) {
+ throw new Exception("Unknown action '" + actionId + "'");
+ }
+ return objectAction;
+ }
});
}
@@ -163,12 +230,30 @@ public abstract class BackgroundCommandExecution extends AbstractIsisSessionTemp
}
}
-
+ private ObjectAdapter[] argAdaptersFor(final CommandMementoDto dto) {
+ final List<ParamDto> params = dto.getAction().getParameters();
+ final List<ObjectAdapter> args = Lists.newArrayList(
+ Iterables.transform(params, new Function<ParamDto, ObjectAdapter>() {
+ @Override
+ public ObjectAdapter apply(final ParamDto paramDto) {
+ final Object arg = CommandMementoDtoUtils.paramArgOf(paramDto);
+ return adapterFor(arg);
+ }
+ })
+ );
+ return args.toArray(new ObjectAdapter[]{});
+ }
+
+
+
// //////////////////////////////////////
@javax.inject.Inject
private BookmarkService bookmarkService;
@javax.inject.Inject
+ private JaxbService jaxbService;
+
+ @javax.inject.Inject
private CommandContext commandContext;
}
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
index f00ff3d..0c2badc 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
@@ -17,17 +17,19 @@
package org.apache.isis.core.runtime.services.background;
import java.lang.reflect.Method;
+import java.util.Collections;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.services.background.ActionInvocationMemento;
import org.apache.isis.applib.services.background.BackgroundCommandService;
+import org.apache.isis.applib.services.background.BackgroundCommandService2;
import org.apache.isis.applib.services.background.BackgroundService;
import org.apache.isis.applib.services.bookmark.BookmarkService;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.command.CommandContext;
-import org.apache.isis.applib.services.command.CommandMementoService;
+import org.apache.isis.core.metamodel.services.command.CommandMementoService;
import org.apache.isis.core.commons.ensure.Ensure;
import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.commons.lang.ArrayExtensions;
@@ -42,6 +44,7 @@ import org.apache.isis.core.metamodel.specloader.classsubstitutor.JavassistEnhan
import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.schema.cmd.v1.CommandMementoDto;
import javassist.util.proxy.MethodFilter;
import javassist.util.proxy.MethodHandler;
@@ -164,15 +167,34 @@ public class BackgroundServiceDefault implements BackgroundService {
final String targetClassName = CommandUtil.targetClassNameFor(targetAdapter);
final String targetActionName = CommandUtil.targetActionNameFor(action);
- final String targetArgs = CommandUtil.argDescriptionFor(action, adaptersFor(args));
+ final ObjectAdapter[] argAdapters = adaptersFor(args);
+ final String targetArgs = CommandUtil.argDescriptionFor(action, argAdapters);
final Command command = commandContext.getCommand();
+ if(backgroundCommandService instanceof BackgroundCommandService2) {
+ final BackgroundCommandService2 backgroundCommandService2 =
+ (BackgroundCommandService2) backgroundCommandService;
+
+ final CommandMementoDto dto = commandMementoService
+ .asCommandMemento(Collections.singletonList(targetAdapter), action, argAdapters);
+
+ if(dto != null) {
+ // the default implementation returns a non-null value. This guard is to allow a different
+ // implementation to be configured that returns null, thereby falling through to the
+ // original behaviour (of using ActionInvocationMemento instead of CommandMementoDto).
+ backgroundCommandService2.schedule(dto, command, targetClassName, targetActionName, targetArgs);
+
+ return null;
+ }
+ }
+
+ // fallback
final ActionInvocationMemento aim = commandMementoService
.asActionInvocationMemento(proxyMethod, domainObject, args);
backgroundCommandService.schedule(aim, command, targetClassName, targetActionName, targetArgs);
-
+
return null;
}
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandMementoServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandMementoServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandMementoServiceDefault.java
index 5b6399f..1f09abb 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandMementoServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandMementoServiceDefault.java
@@ -17,7 +17,6 @@
package org.apache.isis.core.runtime.services.command;
import java.lang.reflect.Method;
-import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -33,24 +32,22 @@ import org.apache.isis.applib.services.background.ActionInvocationMemento;
import org.apache.isis.applib.services.background.BackgroundCommandService;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.bookmark.BookmarkService;
-import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.CommandMementoService;
-import org.apache.isis.applib.services.publish.EventMetadata;
-import org.apache.isis.core.commons.ensure.Ensure;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
+import org.apache.isis.core.metamodel.services.command.CommandMementoService;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.schema.aim.v1.ActionInvocationMementoDto;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
+import org.apache.isis.schema.cmd.v1.ActionDto;
+import org.apache.isis.schema.cmd.v1.CommandMementoDto;
+import org.apache.isis.schema.utils.CommandMementoDtoUtils;
/**
* Depends on an implementation of {@link BackgroundCommandService} to
@@ -103,9 +100,13 @@ public class CommandMementoServiceDefault implements CommandMementoService {
// //////////////////////////////////////
+ @Deprecated
@Programmatic
@Override
- public ActionInvocationMemento asActionInvocationMemento(Method method, Object domainObject, Object[] args) {
+ public ActionInvocationMemento asActionInvocationMemento(
+ final Method method,
+ final Object domainObject,
+ final Object[] args) {
final ObjectSpecificationDefault targetObjSpec = getJavaSpecificationOfOwningClass(method);
final ObjectMember member = targetObjSpec.getMember(method);
@@ -137,47 +138,51 @@ public class CommandMementoServiceDefault implements CommandMementoService {
return aim;
}
+ @Override
+ public CommandMementoDto asCommandMemento(
+ final List<ObjectAdapter> targetAdapters,
+ final ObjectAction objectAction,
+ final ObjectAdapter[] argAdapters) {
+
+ final CommandMementoDto dto = new CommandMementoDto();
+ dto.setMajorVersion("1");
+ dto.setMinorVersion("0");
+
+ for (ObjectAdapter targetAdapter : targetAdapters) {
+ final RootOid rootOid = (RootOid) targetAdapter.getOid();
+ final Bookmark bookmark = rootOid.asBookmark();
+ dto.getTargets().add(bookmark.toOidDto());
+ }
- /**
- * Not API
- */
- ActionInvocationMemento newActionInvocationMemento(String mementoStr) {
- return new ActionInvocationMemento(mementoService, mementoStr);
- }
+ final ActionDto actionDto = new ActionDto();
+ dto.setAction(actionDto);
- // //////////////////////////////////////
+ final String actionIdentifier = CommandUtil.actionIdentifierFor(objectAction);
+ actionDto.setActionIdentifier(actionIdentifier);
- @Override
- public EventMetadata newEventMetadata(
- final Command command,
- final String currentUser, final Timestamp timestamp, final String sequenceName) {
-
- if(command.getTargetAction().equals(Command.TARGET_ACTION_FOR_EDIT)) {
- throw new IllegalArgumentException(String.format(
- "EventMetadata can only be created for commands that represent actions, not property edits; object: %s, member: %s",
- command.getTarget(), command.getMemberIdentifier()));
+ List<ObjectActionParameter> actionParameters = objectAction.getParameters();
+ for (int paramNum = 0; paramNum < actionParameters.size(); paramNum++) {
+ final ObjectActionParameter actionParameter = actionParameters.get(paramNum);
+ final String parameterName = actionParameter.getName();
+ final Class<?> paramType = actionParameter.getSpecification().getCorrespondingClass();
+ ObjectAdapter argAdapter = argAdapters[paramNum];
+ final Object arg = argAdapter != null? argAdapter.getObject(): null;
+ CommandMementoDtoUtils.addParamArg(actionDto.getParameters(), parameterName, paramType, arg, bookmarkService);
}
+ actionDto.setMixinFqClassName(null);
- throw new RuntimeException("not yet implemented");
- }
-
- @Override
- public ActionInvocationMementoDto asActionInvocationMementoDto(
- final EventMetadata metadata) {
- throw new RuntimeException("not yet implemented");
+ dto.setTransactionId(UUID.randomUUID().toString());
+ return dto;
}
// //////////////////////////////////////
+
@javax.inject.Inject
private BookmarkService bookmarkService;
- private void ensureDependenciesInjected() {
- Ensure.ensureThatState(this.bookmarkService, is(not(nullValue())), "BookmarkService domain service must be configured");
- }
-
// //////////////////////////////////////
protected SpecificationLoaderSpi getSpecificationLoader() {
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/runtime/src/main/java/org/apache/isis/core/runtime/sessiontemplate/AbstractIsisSessionTemplate.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/sessiontemplate/AbstractIsisSessionTemplate.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/sessiontemplate/AbstractIsisSessionTemplate.java
index 5a18234..fa7b036 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/sessiontemplate/AbstractIsisSessionTemplate.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/sessiontemplate/AbstractIsisSessionTemplate.java
@@ -20,6 +20,7 @@ import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
import org.apache.isis.core.runtime.system.session.IsisSession;
@@ -101,5 +102,8 @@ public abstract class AbstractIsisSessionTemplate {
return getPersistenceSession();
}
+ protected SpecificationLoader getSpecificationLoader() {
+ return IsisContext.getSpecificationLoader();
+ }
}
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0-binding.xml
----------------------------------------------------------------------
diff --git a/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0-binding.xml b/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0-binding.xml
index a5c8e82..c8cf1ed 100644
--- a/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0-binding.xml
+++ b/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0-binding.xml
@@ -26,7 +26,7 @@
we don't include the minor version, because the
generated Java class will be backwards compatible
-->
- <jaxb:package name="org.apache.isis.schema.aim.v1"/>
+ <jaxb:package name="org.apache.isis.schema.aim.v2"/>
</jaxb:schemaBindings>
</jaxb:bindings>
<!-- since aim-2.0.xsd does an xs:import of common-1.0.xsd, we need to specify common's package bindings -->
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0.xsd
----------------------------------------------------------------------
diff --git a/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0.xsd b/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0.xsd
index be7f442..ce1bfed 100644
--- a/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0.xsd
+++ b/core/schema/src/main/resources/org/apache/isis/schema/aim/aim-2.0.xsd
@@ -37,15 +37,15 @@
<xs:complexType name="actionInvocationMementoDto">
<xs:sequence>
- <xs:element name="majorVersion" type="xs:string" minOccurs="0" maxOccurs="1" default="1">
+ <xs:element name="majorVersion" type="xs:string" minOccurs="0" maxOccurs="1" default="2">
<xs:annotation>
- <xs:documentation>The major version of the schema that an XML instance was created using. This element is optional for backward compatibility, but will be populated for any v1.1+ instances of this schema. If missing, assume '0'.
+ <xs:documentation>The major version of the schema that an XML instance was created using.
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="minorVersion" type="xs:string" minOccurs="0" maxOccurs="1" default="1">
+ <xs:element name="minorVersion" type="xs:string" minOccurs="0" maxOccurs="1" default="0">
<xs:annotation>
- <xs:documentation>Introduced in v1.1. The minor version of the schema that an XML instance was created using. This element is optional for backward compatibility, but will be populated for any v1.1+ instances of this schema. If missing, assume '0'.
+ <xs:documentation>The minor version of the schema that an XML instance was created using.
</xs:documentation>
</xs:annotation>
</xs:element>
@@ -56,9 +56,9 @@
</xs:annotation>
</xs:element>
<xs:element name="invocation" type="actionInvocationDto"/>
- <xs:element name="subActions" type="actionInvocationDto" minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="subInvocations" type="actionInvocationDto" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
- <xs:documentation>Introduced in v1.1. Capture sub-actions (if-any) invoked from this action, for example using the WrapperFactory service. These therefore define a graph/call-stack of actions. Note that the subactions will redundantly also specify their majorVersion and minorVersion (the alternative would have required restructuring in such a way as to break backward compatibility).
+ <xs:documentation>Capture invocations of any other actions invoked from this action, using the WrapperFactory service. These therefore define a graph/call-stack of actions. Note that the subactions will redundantly also specify their majorVersion and minorVersion (the alternative would have required restructuring in such a way as to break backward compatibility).
</xs:documentation>
</xs:annotation>
</xs:element>
@@ -67,28 +67,32 @@
<xs:complexType name="actionInvocationDto">
<xs:sequence>
- <xs:element name="sequence" type="xs:int">
+ <xs:element name="id" type="xs:string">
<xs:annotation>
- <xs:documentation>The combination of ['transactionId', 'sequence'] is guaranteed to be unique.
+ <xs:documentation>Unique identifier for this action invocation in the format "transactionId.sequence".
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="specification" type="cmd:specificationDto"/>
- <xs:element name="user" type="xs:string">
+ <xs:element name="sequence" type="xs:int">
<xs:annotation>
- <xs:documentation>The name of the user that invoked this action. Note that this isn't necessarily the user that initiated the original command; the SudoService may be being used to temporarily switch the effective user.
+ <xs:documentation>Action invocation within this transaction/command.
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="timestampStart" type="xs:dateTime">
+ <xs:element name="target" type="common:oidDto" minOccurs="1" maxOccurs="1">
<xs:annotation>
- <xs:documentation>The point in time that this action was invoked. See also 'timestampComplete'.
+ <xs:documentation>For regular actions, represents the entity or view model upon which the action is to be invoked. For mixin actions, is the object being mixed-into (the constructor arg to the mixin). For contributed actions, is the domain service (the contributee object will be one of the action arguments within the payload). Mixin actions can be determined by the presence of the 'mixinFqClassName' element.
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="timestampComplete" type="xs:dateTime" minOccurs="0" maxOccurs="1">
+ <xs:element name="action" type="cmd:actionDto">
<xs:annotation>
- <xs:documentation>Introduced in v1.1. The point in time that this action completed. The duration that the action took is the difference between 'timestamp' and 'timestampComplete'. This element is optional for backward compatibility, but will be populated for any v1.1 instances of this schema.
+ <xs:documentation>The action and arguments to be invoked on the target object.</xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="user" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>The name of the user that invoked this action. Note that this isn't necessarily the user that initiated the original command; the SudoService may be being used to temporarily switch the effective user.
</xs:documentation>
</xs:annotation>
</xs:element>
@@ -98,6 +102,12 @@
</xs:documentation>
</xs:annotation>
</xs:element>
+ <xs:element name="timings" type="common:periodDto">
+ <xs:annotation>
+ <xs:documentation>Captures the time taken to invoke the action.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
<xs:choice>
<xs:element name="returned" type="returnDto" minOccurs="0" maxOccurs="1">
<xs:annotation>
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/schema/src/main/resources/org/apache/isis/schema/cmd/cmd-1.0.xsd
----------------------------------------------------------------------
diff --git a/core/schema/src/main/resources/org/apache/isis/schema/cmd/cmd-1.0.xsd b/core/schema/src/main/resources/org/apache/isis/schema/cmd/cmd-1.0.xsd
index 60add44..75b9479 100644
--- a/core/schema/src/main/resources/org/apache/isis/schema/cmd/cmd-1.0.xsd
+++ b/core/schema/src/main/resources/org/apache/isis/schema/cmd/cmd-1.0.xsd
@@ -52,7 +52,17 @@
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="specification" type="specificationDto"/>
+ <xs:element name="targets" type="common:oidDto" minOccurs="1" maxOccurs="unbounded">
+ <xs:annotation>
+ <xs:documentation>For regular actions, represents the entity/entities or view model(s) upon which the action is to be invoked. For mixin actions, is the object(s) being mixed-into (the constructor arg to the mixin). For contributed actions, is the domain service (the contributee object will be one of the action arguments within the payload). Note that this means that bulk contributed actions cannot be reified as a memento (for this use case, implement as a mixin action instead). Mixin actions can be determined by the presence of the 'mixinFqClassName' element.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="action" type="actionDto">
+ <xs:annotation>
+ <xs:documentation>The action and arguments to be invoked on the target object(s).</xs:documentation>
+ </xs:annotation>
+ </xs:element>
<xs:element name="user" type="xs:string">
<xs:annotation>
<xs:documentation>The name of the user that initiated/created this command.
@@ -62,18 +72,12 @@
</xs:sequence>
</xs:complexType>
- <xs:complexType name="specificationDto">
+ <xs:complexType name="actionDto">
<xs:annotation>
- <xs:documentation>Captures the information required to be able to invoke an action on an object(s). In particular, identifies the the target object(s), the action to be invoked, whether that action is a mixin, and also the arguments for the parameters of said action.
+ <xs:documentation>Captures the information required to be able to invoke an action on the target(s). In particular, identifies the action to be invoked, whether that action is a mixin, and also the arguments for the parameters of said action. Note that the targets are not part of this structure so that it can be reused between cmd and aim schemas (the former of which can relate to multiple targets, the latter always to a single target).
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="target" type="common:oidDto" minOccurs="1" maxOccurs="unbounded">
- <xs:annotation>
- <xs:documentation>For regular actions, represents the entity/entities or view model(s) upon which the action is to be invoked. For mixin actions, is the object(s) being mixed-into (the constructor arg to the mixin). For contributed actions, is the domain service (the contributee object will be one of the action arguments within the payload). Note that tis means that bulk contributed actions cannot be reified as a memento (for this use case, implement as a mixin action instead). Mixin actions can be determined by the presence of the 'mixinFqClassName' element.
- </xs:documentation>
- </xs:annotation>
- </xs:element>
<xs:element name="mixinFqClassName" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Populated only for mixin actions, is the fully qualified class name of the mixin type.
@@ -86,14 +90,9 @@
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="parameters">
- <xs:complexType>
- <xs:sequence maxOccurs="unbounded">
- <xs:element name="param" type="paramDto"/>
- </xs:sequence>
- <xs:attribute name="num" use="required" type="xs:int"/>
- </xs:complexType>
- </xs:element>
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="parameters" type="paramDto"/>
+ </xs:sequence>
</xs:sequence>
</xs:complexType>
@@ -103,7 +102,11 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="value" type="common:valueDto"/>
+ <xs:element name="argument" type="common:valueDto">
+ <xs:annotation>
+ <xs:documentation>The argument value of this parameter.</xs:documentation>
+ </xs:annotation>
+ </xs:element>
</xs:sequence>
<xs:attribute name="parameterName" use="required" type="xs:string"/>
<xs:attribute name="parameterType" use="required" type="common:valueType"/>
http://git-wip-us.apache.org/repos/asf/isis/blob/0264ec60/core/schema/src/main/resources/org/apache/isis/schema/common/common-1.0.xsd
----------------------------------------------------------------------
diff --git a/core/schema/src/main/resources/org/apache/isis/schema/common/common-1.0.xsd b/core/schema/src/main/resources/org/apache/isis/schema/common/common-1.0.xsd
index 4bc5fa9..fe2ac8f 100644
--- a/core/schema/src/main/resources/org/apache/isis/schema/common/common-1.0.xsd
+++ b/core/schema/src/main/resources/org/apache/isis/schema/common/common-1.0.xsd
@@ -94,5 +94,26 @@
</xs:restriction>
</xs:simpleType>
+ <xs:complexType name="periodDto">
+ <xs:annotation>
+ <xs:documentation>Captures a period of time, eg for capturing metrics/timings.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="start" type="xs:dateTime">
+ <xs:annotation>
+ <xs:documentation>The point in time that this period of time started.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="complete" type="xs:dateTime" minOccurs="0" maxOccurs="1">
+ <xs:annotation>
+ <xs:documentation>The point in time that this period of time completed. The duration is the difference between 'start' and 'complete'.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
</xs:schema>