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/05/26 16:30:16 UTC
[1/2] isis git commit: ISIS-1414: removing
'numberOfPropertiesModified' from ixn.xsd and MetricsService;
this is xactn-scoped information, not request-scoped. Also introduced
WithTransactionScoped as a means to indicate which of the request-scoped mem
Repository: isis
Updated Branches:
refs/heads/master 0d327212a -> ad9cec42c
ISIS-1414: removing 'numberOfPropertiesModified' from ixn.xsd and MetricsService; this is xactn-scoped information, not request-scoped. Also introduced WithTransactionScoped as a means to indicate which of the request-scoped members are really transaction-scoped.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/ad9cec42
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/ad9cec42
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/ad9cec42
Branch: refs/heads/master
Commit: ad9cec42cb3828f2f9c4d43c62bd787ccff94d81
Parents: 21b27fe
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu May 26 17:25:46 2016 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu May 26 17:26:54 2016 +0100
----------------------------------------------------------------------
.../main/asciidoc/guides/_rgcms_schema-ixn.adoc | 7 +--
.../src/main/asciidoc/schema/ixn/ixn-1.0.xsd | 6 ---
.../src/main/asciidoc/schema/ixn/ixn.xsd | 6 ---
core/applib/pom.xml | 4 +-
.../isis/applib/services/iactn/Interaction.java | 20 +++------
.../applib/services/metrics/MetricsService.java | 13 ------
.../schema/utils/MemberExecutionDtoUtils.java | 8 ----
core/pom.xml | 5 ---
.../changes/ChangedObjectsServiceInternal.java | 45 ++++++++++----------
.../services/metrics/MetricsServiceDefault.java | 18 +++++---
.../PublishingServiceInternalDefault.java | 2 +-
.../system/transaction/IsisTransaction.java | 9 +++-
.../transaction/WithTransactionScope.java | 27 ++++++++++++
.../service/support/TimestampService.java | 8 ++--
.../org/apache/isis/schema/ixn/ixn-1.0.xsd | 6 ---
15 files changed, 81 insertions(+), 103 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/adocs/documentation/src/main/asciidoc/guides/_rgcms_schema-ixn.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_schema-ixn.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_schema-ixn.adoc
index 6acacd0..6aa0e94 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_schema-ixn.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_schema-ixn.adoc
@@ -187,8 +187,6 @@ The schema also defines a small number of supporting types:
<xs:sequence>
<xs:element name="loaded" type="com:differenceDto"/>
<xs:element name="dirtied" type="com:differenceDto"/>
- <xs:element name="propertiesModified"
- type="com:differenceDto"/>
</xs:sequence>
</xs:complexType>
@@ -203,9 +201,8 @@ The schema also defines a small number of supporting types:
----
<1> the `metricsDto` captures the time to perform an execution, and also the differences in various object counts.
<2> the `objectCountsDto` complex type is the set of before/after differences, one for each execution; the framework
-tracks number of objects loaded (read from) the database, the number of objects dirtied (will need to be saved back
-to the database), and the number of properties across all objects that changed. Together these metrics give an idea of
-the "size" of this particular execution.
+tracks number of objects loaded (read from) the database and the number of objects dirtied (will need to be saved back
+to the database). Together these metrics give an idea of the "size" of this particular execution.
<3> the `exceptionDto` complex type defines a structure for capturing the stack trace of any exception that might occur
in the course of invoking an action or editing a property.
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/adocs/documentation/src/main/asciidoc/schema/ixn/ixn-1.0.xsd
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/schema/ixn/ixn-1.0.xsd b/adocs/documentation/src/main/asciidoc/schema/ixn/ixn-1.0.xsd
index 3527234..77a733e 100644
--- a/adocs/documentation/src/main/asciidoc/schema/ixn/ixn-1.0.xsd
+++ b/adocs/documentation/src/main/asciidoc/schema/ixn/ixn-1.0.xsd
@@ -197,12 +197,6 @@
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="propertiesModified" type="com:differenceDto">
- <xs:annotation>
- <xs:documentation>The number of individual properties of objects that were modified (each such change would correspond to a separate call to AuditingService if configured).
- </xs:documentation>
- </xs:annotation>
- </xs:element>
</xs:sequence>
</xs:complexType>
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/adocs/documentation/src/main/asciidoc/schema/ixn/ixn.xsd
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/schema/ixn/ixn.xsd b/adocs/documentation/src/main/asciidoc/schema/ixn/ixn.xsd
index 3527234..77a733e 100644
--- a/adocs/documentation/src/main/asciidoc/schema/ixn/ixn.xsd
+++ b/adocs/documentation/src/main/asciidoc/schema/ixn/ixn.xsd
@@ -197,12 +197,6 @@
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="propertiesModified" type="com:differenceDto">
- <xs:annotation>
- <xs:documentation>The number of individual properties of objects that were modified (each such change would correspond to a separate call to AuditingService if configured).
- </xs:documentation>
- </xs:annotation>
- </xs:element>
</xs:sequence>
</xs:complexType>
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/applib/pom.xml
----------------------------------------------------------------------
diff --git a/core/applib/pom.xml b/core/applib/pom.xml
index a38461c..27c2239 100644
--- a/core/applib/pom.xml
+++ b/core/applib/pom.xml
@@ -102,8 +102,8 @@
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
- <groupId>javax.transaction</groupId>
- <artifactId>transaction-api</artifactId>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jta_1.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java b/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
index dbf7083..5a70c18 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
@@ -549,8 +549,7 @@ public class Interaction implements HasTransactionId {
final Execution<?, ?> execution,
final Timestamp timestamp,
final int numberObjectsLoaded,
- final int numberObjectsDirtied,
- final int numberObjectPropertiesModified) {
+ final int numberObjectsDirtied) {
execution.startedAt = timestamp;
@@ -562,7 +561,6 @@ public class Interaction implements HasTransactionId {
final ObjectCountsDto objectCountsDto = objectCountsFor(metricsDto);
numberObjectsLoadedFor(objectCountsDto).setBefore(numberObjectsLoaded);
numberObjectsDirtiedFor(objectCountsDto).setBefore(numberObjectsDirtied);
- numberObjectPropertiesModifiedFor(objectCountsDto).setBefore(numberObjectPropertiesModified);
}
},
@@ -571,8 +569,7 @@ public class Interaction implements HasTransactionId {
final Execution<?, ?> execution,
final Timestamp timestamp,
final int numberObjectsLoaded,
- final int numberObjectsDirtied,
- final int numberObjectPropertiesModified) {
+ final int numberObjectsDirtied) {
execution.completedAt = timestamp;
@@ -584,16 +581,11 @@ public class Interaction implements HasTransactionId {
final ObjectCountsDto objectCountsDto = objectCountsFor(metricsDto);
numberObjectsLoadedFor(objectCountsDto).setAfter(numberObjectsLoaded);
numberObjectsDirtiedFor(objectCountsDto).setAfter(numberObjectsDirtied);
- numberObjectPropertiesModifiedFor(objectCountsDto).setAfter(numberObjectPropertiesModified);
-
}
};
//region > helpers
- private static DifferenceDto numberObjectPropertiesModifiedFor(final ObjectCountsDto objectCountsDto) {
- return MemberExecutionDtoUtils.numberObjectPropertiesModifiedFor(objectCountsDto);
- }
private static DifferenceDto numberObjectsDirtiedFor(final ObjectCountsDto objectCountsDto) {
return MemberExecutionDtoUtils.numberObjectsDirtiedFor(objectCountsDto);
@@ -617,20 +609,18 @@ public class Interaction implements HasTransactionId {
//endregion
abstract void syncMetrics(
- final Execution<?,?> teExecution,
+ final Execution<?, ?> teExecution,
final Timestamp timestamp,
final int numberObjectsLoaded,
- final int numberObjectsDirtied,
- final int numberObjectPropertiesModified);
+ final int numberObjectsDirtied);
}
private void syncMetrics(final When when, final Timestamp timestamp) {
final MetricsService metricsService = interaction.metricsService;
final int numberObjectsLoaded = metricsService.numberObjectsLoaded();
final int numberObjectsDirtied = metricsService.numberObjectsDirtied();
- final int numberObjectPropertiesModified = metricsService.numberObjectPropertiesModified();
- when.syncMetrics(this, timestamp, numberObjectsLoaded, numberObjectsDirtied, numberObjectPropertiesModified);
+ when.syncMetrics(this, timestamp, numberObjectsLoaded, numberObjectsDirtied);
}
//endregion
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/applib/src/main/java/org/apache/isis/applib/services/metrics/MetricsService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/metrics/MetricsService.java b/core/applib/src/main/java/org/apache/isis/applib/services/metrics/MetricsService.java
index 4404418..2460d23 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/metrics/MetricsService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/metrics/MetricsService.java
@@ -61,19 +61,6 @@ public interface MetricsService {
@Programmatic
int numberObjectsDirtied();
- /**
- * The number of individual properties of objects that were modified; a good measure of the amount of work being done in the interaction.
- *
- * <p>
- * Related to {@link #numberObjectsDirtied()}, corresponds to the number of times that {@link org.apache.isis.applib.services.audit.AuditingService3#audit(UUID, String, Bookmark, String, String, String, String, String, Timestamp)} would be called if the transaction were to complete.
- * </p>
- *
- * <p>
- * Is captured within {@link MemberExecutionDto#getMetrics()} (accessible from {@link InteractionContext#getInteraction()}).
- * </p>
- */
- @Programmatic
- int numberObjectPropertiesModified();
}
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/applib/src/main/java/org/apache/isis/schema/utils/MemberExecutionDtoUtils.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/schema/utils/MemberExecutionDtoUtils.java b/core/applib/src/main/java/org/apache/isis/schema/utils/MemberExecutionDtoUtils.java
index f1309f5..121ea92 100644
--- a/core/applib/src/main/java/org/apache/isis/schema/utils/MemberExecutionDtoUtils.java
+++ b/core/applib/src/main/java/org/apache/isis/schema/utils/MemberExecutionDtoUtils.java
@@ -110,12 +110,4 @@ public final class MemberExecutionDtoUtils {
}
return differenceDto;
}
- public static DifferenceDto numberObjectPropertiesModifiedFor(final ObjectCountsDto objectCountsDto) {
- DifferenceDto differenceDto = objectCountsDto.getPropertiesModified();
- if(differenceDto == null) {
- differenceDto = new DifferenceDto();
- objectCountsDto.setPropertiesModified(differenceDto);
- }
- return differenceDto;
- }
}
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 611c6bb..6564bf4 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -1891,11 +1891,6 @@ ${license.additional-notes}
<artifactId>validation-api</artifactId>
<version>${validation-api.version}</version>
</dependency>
- <dependency>
- <groupId>javax.transaction</groupId>
- <artifactId>transaction-api</artifactId>
- <version>${transaction-api.version}</version>
- </dependency>
<!-- DataNucleus -->
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
index 8001b6b..f450729 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
@@ -25,7 +25,6 @@ import java.util.Set;
import javax.enterprise.context.RequestScoped;
import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -38,10 +37,11 @@ import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
+import org.apache.isis.core.runtime.system.transaction.WithTransactionScope;
@DomainService(nature = NatureOfService.DOMAIN)
@RequestScoped
-public class ChangedObjectsServiceInternal {
+public class ChangedObjectsServiceInternal implements WithTransactionScope {
/**
* Used for auditing: this contains the pre- values of every property of every object enlisted.
@@ -209,19 +209,9 @@ public class ChangedObjectsServiceInternal {
return previous == null;
}
-
- @Programmatic
- public boolean hasChangedAdapters() {
- final Set<Map.Entry<AdapterAndProperty, PreAndPostValues>> changedObjectProperties = getChangedObjectProperties();
-
- final Set<ObjectAdapter> changedAdapters = Sets.newHashSet(
- Iterables.transform(
- changedObjectProperties,
- AdapterAndProperty.Functions.GET_ADAPTER)
- );
- return !changedAdapters.isEmpty();
- }
-
+ /**
+ * Intended to be called at the end of the transaction. Use {@link #resetForNextTransaction()} once fully read.
+ */
@Programmatic
public Set<Map.Entry<AdapterAndProperty, PreAndPostValues>> getChangedObjectProperties() {
return changedObjectProperties != null
@@ -257,12 +247,6 @@ public class ChangedObjectsServiceInternal {
Sets.filter(processedObjectProperties1.entrySet(), PreAndPostValues.Predicates.CHANGED));
}
- @Programmatic
- public void clearChangedObjectProperties() {
- enlistedObjectProperties.clear();
- changedObjectProperties = null;
- }
-
private static final Predicate<ObjectAdapter> IS_TRANSACTION_ID = new Predicate<ObjectAdapter>() {
@Override
public boolean apply(ObjectAdapter input) {
@@ -285,9 +269,26 @@ public class ChangedObjectsServiceInternal {
return changeKindByEnlistedAdapter.size();
}
+ /**
+ * Must be called only after {@link #getChangedObjectProperties()} has been called at least once.
+ */
@Programmatic
public int numberObjectPropertiesModified() {
- return enlistedObjectProperties.size();
+ if(changedObjectProperties == null) {
+ throw new IllegalStateException("getChangedObjectProperties() has not yet been called");
+ }
+ return changedObjectProperties.size();
+ }
+
+ /**
+ * Intended to be called at the end of a transaction. (This service really ought to be considered
+ * a transaction-scoped service; since that isn't yet supported by the framework, we have to manually reset).
+ */
+ @Override
+ @Programmatic
+ public void resetForNextTransaction() {
+ enlistedObjectProperties.clear();
+ changedObjectProperties = null;
}
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/runtime/src/main/java/org/apache/isis/core/runtime/services/metrics/MetricsServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/metrics/MetricsServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/metrics/MetricsServiceDefault.java
index f06c81d..604e097 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/metrics/MetricsServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/metrics/MetricsServiceDefault.java
@@ -31,10 +31,11 @@ import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.services.metrics.MetricsService;
import org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal;
+import org.apache.isis.core.runtime.system.transaction.WithTransactionScope;
@RequestScoped
@DomainService(nature = NatureOfService.DOMAIN)
-public class MetricsServiceDefault implements MetricsService, InstanceLifecycleListener, LoadLifecycleListener {
+public class MetricsServiceDefault implements MetricsService, InstanceLifecycleListener, LoadLifecycleListener, WithTransactionScope {
private AtomicInteger numberLoaded = new AtomicInteger(0);
@@ -48,20 +49,23 @@ public class MetricsServiceDefault implements MetricsService, InstanceLifecycleL
return changedObjectsServiceInternal.numberObjectsDirtied();
}
- @Override
- public int numberObjectPropertiesModified() {
- return changedObjectsServiceInternal.numberObjectPropertiesModified();
- }
-
@Programmatic
@Override
public void postLoad(final InstanceLifecycleEvent event) {
numberLoaded.incrementAndGet();
}
+ /**
+ * Intended to be called at the end of a transaction. (This service really ought to be considered
+ * a transaction-scoped service; since that isn't yet supported by the framework, we have to manually reset).
+ */
+ @Programmatic
+ @Override
+ public void resetForNextTransaction() {
+ numberLoaded.set(0);
+ }
@Inject
ChangedObjectsServiceInternal changedObjectsServiceInternal;
-
}
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publish/PublishingServiceInternalDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publish/PublishingServiceInternalDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publish/PublishingServiceInternalDefault.java
index 3d570b8..c063506 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publish/PublishingServiceInternalDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publish/PublishingServiceInternalDefault.java
@@ -183,7 +183,7 @@ public class PublishingServiceInternalDefault implements PublishingServiceIntern
}
final int numberLoaded = metricsService.numberObjectsLoaded();
- final int numberObjectPropertiesModified = metricsService.numberObjectPropertiesModified();
+ final int numberObjectPropertiesModified = changedObjectsServiceInternal.numberObjectPropertiesModified();
final PublishedObjects publishedObjects = newPublishedObjects(numberLoaded, numberObjectPropertiesModified,
changeKindByPublishedAdapter);
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
index 98535f7..c79977b 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
@@ -27,6 +27,7 @@ import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.isis.applib.services.metrics.MetricsService;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.authentication.MessageBroker;
import org.apache.isis.core.commons.components.TransactionScopedComponent;
@@ -172,6 +173,7 @@ public class IsisTransaction implements TransactionScopedComponent {
private final PublishingServiceInternal publishingServiceInternal;
private final AuditingServiceInternal auditingServiceInternal;
private final ChangedObjectsServiceInternal changedObjectsServiceInternal;
+ private final MetricsService metricsService;
private final UUID transactionId;
@@ -194,7 +196,7 @@ public class IsisTransaction implements TransactionScopedComponent {
this.publishingServiceInternal = lookupService(PublishingServiceInternal.class);
this.auditingServiceInternal = lookupService(AuditingServiceInternal.class);
this.changedObjectsServiceInternal = lookupService(ChangedObjectsServiceInternal.class);
-
+ this.metricsService = lookupService(MetricsService.class);
this.transactionId = transactionId;
@@ -411,7 +413,10 @@ public class IsisTransaction implements TransactionScopedComponent {
setAbortCause(new IsisTransactionManagerException(ex));
throw ex;
} finally {
- changedObjectsServiceInternal.clearChangedObjectProperties();
+ changedObjectsServiceInternal.resetForNextTransaction();
+ if(metricsService instanceof WithTransactionScope) {
+ ((WithTransactionScope) metricsService).resetForNextTransaction();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/WithTransactionScope.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/WithTransactionScope.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/WithTransactionScope.java
new file mode 100644
index 0000000..c0b156a
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/WithTransactionScope.java
@@ -0,0 +1,27 @@
+/*
+ * 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.runtime.system.transaction;
+
+/**
+ * Hacky workaround since we don't currently support @TransactionScoped.
+ */
+public interface WithTransactionScope {
+ void resetForNextTransaction();
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/TimestampService.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/TimestampService.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/TimestampService.java
index fb18cfe..b270f39 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/TimestampService.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/TimestampService.java
@@ -22,7 +22,6 @@ import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.jdo.listener.InstanceLifecycleEvent;
-import org.apache.isis.applib.DomainObjectContainer;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.annotation.Programmatic;
@@ -30,6 +29,7 @@ import org.apache.isis.applib.services.clock.ClockService;
import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
import org.apache.isis.applib.services.timestamp.HoldsUpdatedAt;
import org.apache.isis.applib.services.timestamp.HoldsUpdatedBy;
+import org.apache.isis.applib.services.user.UserService;
@RequestScoped
@DomainService(
@@ -54,11 +54,9 @@ public class TimestampService implements
final Object pi = event.getPersistentInstance();
if(pi instanceof org.datanucleus.enhancement.Persistable) {
- boolean isPersistent =
- ((org.datanucleus.enhancement.Persistable)pi).dnIsPersistent();
if(pi instanceof HoldsUpdatedBy) {
- ((HoldsUpdatedBy)pi).setUpdatedBy(container.getUser().getName());
+ ((HoldsUpdatedBy)pi).setUpdatedBy(userService.getUser().getName());
}
if(pi instanceof HoldsUpdatedAt) {
((HoldsUpdatedAt)pi).setUpdatedAt(clockService.nowAsJavaSqlTimestamp());
@@ -72,7 +70,7 @@ public class TimestampService implements
}
@Inject
- DomainObjectContainer container;
+ UserService userService;
@Inject
ClockService clockService;
http://git-wip-us.apache.org/repos/asf/isis/blob/ad9cec42/core/schema/src/main/resources/org/apache/isis/schema/ixn/ixn-1.0.xsd
----------------------------------------------------------------------
diff --git a/core/schema/src/main/resources/org/apache/isis/schema/ixn/ixn-1.0.xsd b/core/schema/src/main/resources/org/apache/isis/schema/ixn/ixn-1.0.xsd
index 359eca0..53afb2d 100644
--- a/core/schema/src/main/resources/org/apache/isis/schema/ixn/ixn-1.0.xsd
+++ b/core/schema/src/main/resources/org/apache/isis/schema/ixn/ixn-1.0.xsd
@@ -197,12 +197,6 @@
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="propertiesModified" type="com:differenceDto">
- <xs:annotation>
- <xs:documentation>The number of individual properties of objects that were modified (each such change would correspond to a separate call to AuditingService if configured).
- </xs:documentation>
- </xs:annotation>
- </xs:element>
</xs:sequence>
</xs:complexType>
[2/2] isis git commit: ISIS-1414: moving the @RequestScoped
initialization/close stuff out of IsisTransactionManager and IsisTransaction,
and into PersistenceSession.
Posted by da...@apache.org.
ISIS-1414: moving the @RequestScoped initialization/close stuff out of IsisTransactionManager and IsisTransaction, and into PersistenceSession.
Also:
- CommandService#startTransaction is no longer called.
- remove unused code/hashmap in PersistenceSession
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/21b27fe4
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/21b27fe4
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/21b27fe4
Branch: refs/heads/master
Commit: 21b27fe49790adc78a3fe7804ff4feba7790bbed
Parents: 0d32721
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu May 26 16:22:19 2016 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu May 26 17:26:54 2016 +0100
----------------------------------------------------------------------
.../guides/_rgsvc_spi_CommandService.adoc | 2 +-
core/applib/pom.xml | 4 +
.../services/command/spi/CommandService.java | 2 +
core/pom.xml | 6 +
.../runtime/services/ServiceInstantiator.java | 36 +--
.../changes/ChangedObjectsServiceInternal.java | 1 +
.../system/persistence/PersistenceSession.java | 271 ++++++++++++++-----
.../system/transaction/IsisTransaction.java | 225 +++++----------
.../transaction/IsisTransactionManager.java | 134 ++-------
9 files changed, 312 insertions(+), 369 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/21b27fe4/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc
index ee3885b..a795586 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc
@@ -56,7 +56,7 @@ public interface CommandService {
<1> Instantiate the appropriate instance of the `Command` (as defined by the
xref:rgsvc.adoc#_rgsvc_api_CommandContext[`CommandContext`] service). Its members will be populated automatically by
the framework.
-<2> (as of `1.13.0-SNAPSHOT`) is deprecated: the framework automatically populates the ``Command``'s `timestamp`,
+<2> (as of `1.13.0-SNAPSHOT`) is *NO LONGER CALLED* and is deprecated: the framework automatically populates the ``Command``'s `timestamp`,
`user` and `transactionId` fields, so there is no need for the service implementation to initialize any of these. In
particular, the ``Command`` will already have been initialized with the provided `transactionId` argument.
<3> Set the hint that the `Command` should be persisted if possible (when completed, see below).
http://git-wip-us.apache.org/repos/asf/isis/blob/21b27fe4/core/applib/pom.xml
----------------------------------------------------------------------
diff --git a/core/applib/pom.xml b/core/applib/pom.xml
index 4cb78cd..a38461c 100644
--- a/core/applib/pom.xml
+++ b/core/applib/pom.xml
@@ -102,6 +102,10 @@
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>transaction-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jcdi_1.0_spec</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/isis/blob/21b27fe4/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java b/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java
index da7434e..5d018de 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java
@@ -34,6 +34,8 @@ public interface CommandService {
Command create();
/**
+ * DEPRECATED - this method is no longer called by the framework.
+ *
* @deprecated - the framework automatically populates the {@link Command}'s {@link Command#getTimestamp()}, {@link Command#getUser()} and {@link Command#getTransactionId()}, so there is no need for the service implementation to initialize any of these. In particular, the {@link Command} will already have been initialized with the provided <tt>transactionId</tt> argument.
*/
@Deprecated
http://git-wip-us.apache.org/repos/asf/isis/blob/21b27fe4/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 6770b0d..611c6bb 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -175,6 +175,7 @@
<geronimo-jcdi_1.0_spec.version>1.0</geronimo-jcdi_1.0_spec.version>
<validation-api.version>1.1.0.Final</validation-api.version>
+ <transaction-api.version>1.2</transaction-api.version>
<javax-mail.version>1.4.7</javax-mail.version>
@@ -1890,6 +1891,11 @@ ${license.additional-notes}
<artifactId>validation-api</artifactId>
<version>${validation-api.version}</version>
</dependency>
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>transaction-api</artifactId>
+ <version>${transaction-api.version}</version>
+ </dependency>
<!-- DataNucleus -->
http://git-wip-us.apache.org/repos/asf/isis/blob/21b27fe4/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java
index 27ee048..bda20bd 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServiceInstantiator.java
@@ -19,22 +19,21 @@
package org.apache.isis.core.runtime.services;
-import javassist.util.proxy.MethodFilter;
-import javassist.util.proxy.MethodHandler;
-import javassist.util.proxy.ProxyFactory;
-import javassist.util.proxy.ProxyObject;
-
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
+
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.RequestScoped;
+
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.commons.factory.InstanceCreationClassException;
@@ -44,6 +43,11 @@ import org.apache.isis.core.commons.lang.MethodExtensions;
import org.apache.isis.core.metamodel.services.ServicesInjector;
import org.apache.isis.core.metamodel.specloader.classsubstitutor.JavassistEnhanced;
+import javassist.util.proxy.MethodFilter;
+import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.ProxyFactory;
+import javassist.util.proxy.ProxyObject;
+
/**
* Instantiates the service, taking into account whether the service is annotated with
* {@link RequestScoped} or not.
@@ -75,13 +79,6 @@ public final class ServiceInstantiator {
// //////////////////////////////////////
- private boolean ignoreFailures;
- public void setIgnoreFailures(boolean ignoreFailures) {
- this.ignoreFailures = ignoreFailures;
- }
-
- // //////////////////////////////////////
-
/**
* initially null, but checked before first use that has been set (through {@link #setConfiguration(org.apache.isis.core.commons.config.IsisConfiguration)}).
@@ -116,9 +113,6 @@ public final class ServiceInstantiator {
//return Thread.currentThread().getContextClassLoader().loadClass(className);
return Class.forName(className);
} catch (final ClassNotFoundException ex) {
- if(ignoreFailures) {
- return null;
- }
throw new InitialisationException(String.format("Cannot find class '%s' for service", className));
}
}
@@ -219,21 +213,17 @@ public final class ServiceInstantiator {
} else {
T service = serviceByThread.get();
if(service == null) {
- // ignore; this could potentially happen during an application-level init (PersistenceSessionFactory#init)
- // it has also happened in past when enabling debugging, though the
- // new hashCode(), equals() and toString() checks above should mitigate.
- return null;
+ // shouldn't happen...
+ throw new IllegalStateException("No service of type " + cls + " is available on this ");
}
- final Object proxiedReturn = proxyMethod.invoke(service, args);
+ final Object proxiedReturn = proxyMethod.invoke(service, args);
return proxiedReturn;
}
}
});
return newInstance;
- } catch (final InstantiationException e) {
- throw new IsisException(e);
- } catch (final IllegalAccessException e) {
+ } catch (final InstantiationException | IllegalAccessException e) {
throw new IsisException(e);
}
}
http://git-wip-us.apache.org/repos/asf/isis/blob/21b27fe4/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
index fd5b618..8001b6b 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
@@ -260,6 +260,7 @@ public class ChangedObjectsServiceInternal {
@Programmatic
public void clearChangedObjectProperties() {
enlistedObjectProperties.clear();
+ changedObjectProperties = null;
}
private static final Predicate<ObjectAdapter> IS_TRANSACTION_ID = new Predicate<ObjectAdapter>() {
http://git-wip-us.apache.org/repos/asf/isis/blob/21b27fe4/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
index f2eecbd..9cdd8cb 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
@@ -20,6 +20,7 @@ package org.apache.isis.core.runtime.system.persistence;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
+import java.sql.Timestamp;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
@@ -29,6 +30,7 @@ import javax.jdo.FetchGroup;
import javax.jdo.FetchPlan;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.listener.InstanceLifecycleListener;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -38,15 +40,26 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.isis.applib.RecoverableException;
+import org.apache.isis.applib.annotation.Bulk;
import org.apache.isis.applib.profiles.Localization;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.bookmark.BookmarkService2;
+import org.apache.isis.applib.services.clock.ClockService;
import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.Command2;
+import org.apache.isis.applib.services.command.Command3;
+import org.apache.isis.applib.services.command.CommandContext;
+import org.apache.isis.applib.services.command.spi.CommandService;
import org.apache.isis.applib.services.eventbus.AbstractLifecycleEvent;
import org.apache.isis.applib.services.eventbus.EventBusService;
import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2;
+import org.apache.isis.applib.services.factory.FactoryService;
+import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.InteractionContext;
+import org.apache.isis.applib.services.metrics.MetricsService;
+import org.apache.isis.applib.services.user.UserService;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.components.SessionScopedComponent;
import org.apache.isis.core.commons.config.IsisConfiguration;
@@ -112,8 +125,8 @@ import org.apache.isis.core.runtime.persistence.objectstore.transaction.Transact
import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindAllInstances;
import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindUsingApplibQueryDefault;
import org.apache.isis.core.runtime.runner.opts.OptionHandlerFixtureAbstract;
+import org.apache.isis.core.runtime.services.RequestScopedService;
import org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal;
-import org.apache.isis.core.runtime.services.metrics.MetricsServiceDefault;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.persistence.adaptermanager.OidAdapterHashMap;
import org.apache.isis.core.runtime.system.persistence.adaptermanager.PojoAdapterHashMap;
@@ -176,6 +189,20 @@ public class PersistenceSession implements
private final AuthenticationSession authenticationSession;
private final ServicesInjector servicesInjector;
+
+ private final CommandContext commandContext;
+ private final CommandService commandService;
+
+ private final InteractionContext interactionContext;
+ private final EventBusService eventBusService ;
+ private final ChangedObjectsServiceInternal changedObjectsServiceInternal;
+ private final FactoryService factoryService;
+ private final MetricsService metricsService;
+ private final ClockService clockService;
+ private final UserService userService;
+ private final Bulk.InteractionContext bulkInteractionContext;
+
+
/**
* Used to create the {@link #persistenceManager} when {@link #open()}ed.
*/
@@ -196,7 +223,6 @@ public class PersistenceSession implements
*/
private final Map<Class<?>, PersistenceQueryProcessor<?>> persistenceQueryProcessorByClass = Maps.newHashMap();
- private final Map<ObjectSpecId, RootOid> registeredServices = Maps.newHashMap();
private final boolean concurrencyCheckingGloballyEnabled;
@@ -217,21 +243,32 @@ public class PersistenceSession implements
LOG.debug("creating " + this);
}
+ this.servicesInjector = servicesInjector;
+ this.jdoPersistenceManagerFactory = jdoPersistenceManagerFactory;
+ this.fixturesInstalledFlag = fixturesInstalledFlag;
+
// injected
this.configuration = configuration;
this.specificationLoader = specificationLoader;
this.authenticationSession = authenticationSession;
- this.fixturesInstalledFlag = fixturesInstalledFlag;
- this.servicesInjector = servicesInjector;
- this.jdoPersistenceManagerFactory = jdoPersistenceManagerFactory;
+ this.commandContext = lookupService(CommandContext.class);
+ this.commandService = lookupService(CommandService.class);
+ this.interactionContext = lookupService(InteractionContext.class);
+ this.eventBusService = lookupService(EventBusService.class);
+ this.changedObjectsServiceInternal = lookupService(ChangedObjectsServiceInternal.class);
+ this.metricsService = lookupService(MetricsService.class);
+ this.factoryService = lookupService(FactoryService.class);
+ this.clockService = lookupService(ClockService.class);
+ this.userService = lookupService(UserService.class);
+ this.bulkInteractionContext = lookupService(Bulk.InteractionContext.class);
// sub-components
final AdapterManager adapterManager = this;
this.persistenceQueryFactory = new PersistenceQueryFactory(adapterManager, specificationLoader);
this.transactionManager = new IsisTransactionManager(this, servicesInjector);
- setState(State.NOT_INITIALIZED);
+ this.state = State.NOT_INITIALIZED;
final boolean concurrencyCheckingGloballyDisabled =
configuration.getBoolean("isis.persistor.disableConcurrencyChecking", false);
@@ -285,39 +322,86 @@ public class PersistenceSession implements
new PersistenceQueryFindUsingApplibQueryProcessor(this));
initServices();
+ startRequestOnRequestScopedServices();
+
+ if(metricsService instanceof InstanceLifecycleListener) {
+ final InstanceLifecycleListener metricsService = (InstanceLifecycleListener) this.metricsService;
+ persistenceManager.addInstanceLifecycleListener(metricsService, (Class[]) null);
+ }
+
+
+ final Command command = createCommand();
+ final UUID transactionId = UUID.randomUUID();
+ final Interaction interaction = factoryService.instantiate(Interaction.class);
+
+ final Timestamp timestamp = clockService.nowAsJavaSqlTimestamp();
+ final String userName = userService.getUser().getName();
+
+ command.setTimestamp(timestamp);
+ command.setUser(userName);
+ command.setTransactionId(transactionId);
+
+ interaction.setTransactionId(transactionId);
- final MetricsServiceDefault metricsServiceDefault = servicesInjector.lookupService(MetricsServiceDefault.class);
- persistenceManager.addInstanceLifecycleListener(metricsServiceDefault, (Class[])null);
+ commandContext.setCommand(command);
+ interactionContext.setInteraction(interaction);
- setState(State.OPEN);
+ Bulk.InteractionContext.current.set(bulkInteractionContext);
+
+ this.state = State.OPEN;
}
+
+ private void startRequestOnRequestScopedServices() {
+
+ final List<Object> registeredServices = servicesInjector.getRegisteredServices();
+
+ // tell the proxy of all request-scoped services to instantiate the underlying
+ // services, store onto the thread-local and inject into them...
+ for (final Object service : registeredServices) {
+ if(service instanceof RequestScopedService) {
+ ((RequestScopedService)service).__isis_startRequest(servicesInjector);
+ }
+ }
+ // ... and invoke all @PostConstruct
+ for (final Object service : registeredServices) {
+ if(service instanceof RequestScopedService) {
+ ((RequestScopedService)service).__isis_postConstruct();
+ }
+ }
+ }
+
/**
- * Creates {@link ObjectAdapter adapters} for the service list.
+ * Creates {@link ObjectAdapter adapters} for the service list, ensuring that these are mapped correctly,
+ * and have the same OIDs as in any previous sessions.
*/
private void initServices() {
final List<Object> registeredServices = servicesInjector.getRegisteredServices();
+
for (final Object service : registeredServices) {
final ObjectSpecification serviceSpecification =
specificationLoader.loadSpecification(service.getClass());
serviceSpecification.markAsService();
- final RootOid existingOid = getOidForService(serviceSpecification);
- final ObjectAdapter serviceAdapter =
- existingOid == null
- ? adapterFor(service)
- : mapRecreatedPojo(existingOid, service);
- if (serviceAdapter.getOid().isTransient()) {
- remapAsPersistent(serviceAdapter, null);
- }
- if (existingOid == null) {
- final RootOid persistentOid = (RootOid) serviceAdapter.getOid();
- this.registeredServices.put(persistentOid.getObjectSpecId(), persistentOid);
- }
+ final ObjectAdapter serviceAdapter = adapterFor(service);
+ remapAsPersistentIfRequired(serviceAdapter);
}
}
+ private void remapAsPersistentIfRequired(final ObjectAdapter serviceAdapter) {
+ if (serviceAdapter.getOid().isTransient()) {
+ remapAsPersistent(serviceAdapter, null);
+ }
+ }
+
+ private Command createCommand() {
+ final Command command = commandService.create();
+
+ servicesInjector.injectServicesInto(command);
+ return command;
+ }
+
//endregion
//region > close
@@ -335,11 +419,18 @@ public class PersistenceSession implements
*/
public void close() {
- if (getState() == State.CLOSED) {
+ if (state == State.CLOSED) {
// nothing to do
return;
}
+ completeCommandFromInteractionAndClearDomainEvents();
+ transactionManager.flushTransaction();
+
+ Bulk.InteractionContext.current.set(null);
+
+ endRequestOnRequestScopeServices();
+
try {
final IsisTransaction currentTransaction = transactionManager.getTransaction();
if (currentTransaction != null && !currentTransaction.getState().isComplete()) {
@@ -361,8 +452,6 @@ public class PersistenceSession implements
LOG.error(
"close: failed to close JDO persistenceManager; continuing to avoid memory leakage");
}
- // TODO: REVIEW ... ??? this is a guess: don't set to null, because we need for -> transactionManager -> transaction -> messageBroker
- // persistenceManager = null;
try {
oidAdapterMap.close();
@@ -378,9 +467,66 @@ public class PersistenceSession implements
LOG.error("close: pojoAdapterMap#close() failed; continuing to avoid memory leakage");
}
- setState(State.CLOSED);
+ this.state = State.CLOSED;
+ }
+
+ private void endRequestOnRequestScopeServices() {
+ // tell the proxy of all request-scoped services to invoke @PreDestroy
+ // (if any) on all underlying services stored on their thread-locals...
+ for (final Object service : servicesInjector.getRegisteredServices()) {
+ if(service instanceof RequestScopedService) {
+ ((RequestScopedService)service).__isis_preDestroy();
+ }
+ }
+
+ // ... and then remove those underlying services from the thread-local
+ for (final Object service : servicesInjector.getRegisteredServices()) {
+ if(service instanceof RequestScopedService) {
+ ((RequestScopedService)service).__isis_endRequest();
+ }
+ }
+ }
+
+ private void completeCommandFromInteractionAndClearDomainEvents() {
+
+ final Command command = commandContext.getCommand();
+ final Interaction interaction = interactionContext.getInteraction();
+
+ if(command.getStartedAt() != null && command.getCompletedAt() == null) {
+ // the guard is in case we're here as the result of a redirect following a previous exception;just ignore.
+
+
+ // copy over from the most recent (which will be the top-level) interaction
+ Interaction.Execution priorExecution = interaction.getPriorExecution();
+ final Timestamp completedAt = priorExecution.getCompletedAt();
+ command.setCompletedAt(completedAt);
+ }
+
+ // ensureCommandsPersistedIfDirtyXactn
+
+ // ensure that any changed objects means that the command should be persisted
+ if(command.getMemberIdentifier() != null) {
+ if(metricsService.numberObjectsDirtied() > 0) {
+ command.setPersistHint(true);
+ }
+ }
+
+
+ commandService.complete(command);
+
+ if(command instanceof Command3) {
+ final Command3 command3 = (Command3) command;
+ command3.flushActionDomainEvents();
+ } else
+ if(command instanceof Command2) {
+ final Command2 command2 = (Command2) command;
+ command2.flushActionInteractionEvents();
+ }
+
+ interaction.clear();
}
+
//endregion
//region > QuerySubmitter impl, findInstancesInTransaction
@@ -484,16 +630,8 @@ public class PersistenceSession implements
private State state;
- private State getState() {
- return state;
- }
-
- private void setState(final State state) {
- this.state = state;
- }
-
protected void ensureNotOpened() {
- if (getState() != State.NOT_INITIALIZED) {
+ if (state != State.NOT_INITIALIZED) {
throw new IllegalStateException("Persistence session has already been initialized");
}
}
@@ -510,7 +648,6 @@ public class PersistenceSession implements
}
-
//endregion
//region > createTransientInstance, createViewModelInstance
@@ -657,31 +794,15 @@ public class PersistenceSession implements
final List<Object> services = servicesInjector.getRegisteredServices();
final List<ObjectAdapter> serviceAdapters = Lists.newArrayList();
for (final Object servicePojo : services) {
- serviceAdapters.add(getService(servicePojo));
+ ObjectAdapter serviceAdapter = getAdapterFor(servicePojo);
+ if(serviceAdapter == null) {
+ throw new IllegalStateException("ObjectAdapter for service " + servicePojo + " does not exist?!?");
+ }
+ serviceAdapters.add(serviceAdapter);
}
return serviceAdapters;
}
- private ObjectAdapter getService(final Object servicePojo) {
- final ObjectSpecification serviceSpecification =
- specificationLoader.loadSpecification(servicePojo.getClass());
- final RootOid oid = getOidForService(serviceSpecification);
- final ObjectAdapter serviceAdapter = mapRecreatedPojo(oid, servicePojo);
-
- return serviceAdapter;
- }
-
- /**
- * Returns the OID for the adapted service. This allows a service object to
- * be given the same OID that it had when it was created in a different
- * session.
- */
- private RootOid getOidForService(final ObjectSpecification serviceSpec) {
- final ObjectSpecId serviceSpecId = serviceSpec.getSpecId();
- final RootOid oid = this.registeredServices.get(serviceSpecId);
- return oid;
- }
-
//endregion
//region > helper: postEvent
@@ -699,7 +820,6 @@ public class PersistenceSession implements
}
void postEvent(final AbstractLifecycleEvent<Object> event, final Object pojo) {
- final EventBusService eventBusService = getServicesInjector().lookupService(EventBusService.class);
event.setSource(pojo);
eventBusService.post(event);
}
@@ -851,7 +971,8 @@ public class PersistenceSession implements
result = persistenceManager.getObjectById(cls, jdoObjectId);
} catch (final RuntimeException e) {
- final List<ExceptionRecognizer> exceptionRecognizers = getServicesInjector().lookupServices(ExceptionRecognizer.class);
+ Class<ExceptionRecognizer> serviceClass = ExceptionRecognizer.class;
+ final List<ExceptionRecognizer> exceptionRecognizers = lookupServices(serviceClass);
for (ExceptionRecognizer exceptionRecognizer : exceptionRecognizers) {
if(exceptionRecognizer instanceof ExceptionRecognizer2) {
final ExceptionRecognizer2 recognizer = (ExceptionRecognizer2) exceptionRecognizer;
@@ -1967,9 +2088,6 @@ public class PersistenceSession implements
public void enlistDeletingAndInvokeIsisRemovingCallbackFacet(final Persistable pojo) {
ObjectAdapter adapter = adapterFor(pojo);
- final ChangedObjectsServiceInternal changedObjectsServiceInternal =
- getServicesInjector().lookupService(ChangedObjectsServiceInternal.class);
-
changedObjectsServiceInternal.enlistDeleting(adapter);
CallbackFacet.Util.callCallback(adapter, RemovingCallbackFacet.class);
@@ -2159,10 +2277,6 @@ public class PersistenceSession implements
CallbackFacet.Util.callCallback(adapter, PersistedCallbackFacet.class);
postLifecycleEventIfRequired(adapter, PersistedLifecycleEventFacet.class);
-
- final ChangedObjectsServiceInternal changedObjectsServiceInternal =
- getServicesInjector().lookupService(ChangedObjectsServiceInternal.class);
-
changedObjectsServiceInternal.enlistCreated(adapter);
} else {
@@ -2207,10 +2321,6 @@ public class PersistenceSession implements
CallbackFacet.Util.callCallback(adapter, UpdatingCallbackFacet.class);
postLifecycleEventIfRequired(adapter, UpdatingLifecycleEventFacet.class);
-
- final ChangedObjectsServiceInternal changedObjectsServiceInternal =
- getServicesInjector().lookupService(ChangedObjectsServiceInternal.class);
-
changedObjectsServiceInternal.enlistUpdating(adapter);
ensureRootObject(pojo);
@@ -2275,6 +2385,25 @@ public class PersistenceSession implements
//endregion
+ //region > helpers: lookupService, lookupServices
+
+ private <T> T lookupService(Class<T> serviceType) {
+ T service = lookupServiceIfAny(serviceType);
+ if(service == null) {
+ throw new IllegalStateException("Could not locate service of type '" + serviceType + "'");
+ }
+ return service;
+ }
+
+ private <T> T lookupServiceIfAny(final Class<T> serviceType) {
+ return servicesInjector.lookupService(serviceType);
+ }
+
+ private <T> List<T> lookupServices(final Class<T> serviceClass) {
+ return servicesInjector.lookupServices(serviceClass);
+ }
+ //endregion
+
//region > toString
@Override
@@ -2285,6 +2414,8 @@ public class PersistenceSession implements
//endregion
+
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/21b27fe4/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
index 516bcb6..98535f7 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
@@ -19,7 +19,6 @@
package org.apache.isis.core.runtime.system.transaction;
-import java.sql.Timestamp;
import java.util.List;
import java.util.UUID;
@@ -28,15 +27,6 @@ import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.isis.applib.annotation.Bulk;
-import org.apache.isis.applib.services.actinvoc.ActionInvocationContext;
-import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.Command2;
-import org.apache.isis.applib.services.command.Command3;
-import org.apache.isis.applib.services.command.CommandContext;
-import org.apache.isis.applib.services.command.spi.CommandService;
-import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.applib.services.iactn.InteractionContext;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.authentication.MessageBroker;
import org.apache.isis.core.commons.components.TransactionScopedComponent;
@@ -137,14 +127,6 @@ public class IsisTransaction implements TransactionScopedComponent {
/**
- * Whether it is valid to {@link IsisTransaction#flush() flush} this
- * {@link IsisTransaction transaction}.
- */
- public boolean canFlush() {
- return this == IN_PROGRESS;
- }
-
- /**
* Whether it is valid to {@link IsisTransaction#commit() commit} this
* {@link IsisTransaction transaction}.
*/
@@ -177,32 +159,24 @@ public class IsisTransaction implements TransactionScopedComponent {
}
}
-
private static final Logger LOG = LoggerFactory.getLogger(IsisTransaction.class);
+ //region > constructor, fields
+
private final List<PersistenceCommand> persistenceCommands = Lists.newArrayList();
private final IsisTransactionManager transactionManager;
private final MessageBroker messageBroker;
private final ServicesInjector servicesInjector;
- private final CommandContext commandContext;
- private final CommandService commandService;
-
- private final InteractionContext interactionContext;
private final PublishingServiceInternal publishingServiceInternal;
private final AuditingServiceInternal auditingServiceInternal;
private final ChangedObjectsServiceInternal changedObjectsServiceInternal;
-
private final UUID transactionId;
- private State state;
private IsisException abortCause;
-
-
-
public IsisTransaction(
final IsisTransactionManager transactionManager,
final MessageBroker messageBroker,
@@ -217,11 +191,6 @@ public class IsisTransaction implements TransactionScopedComponent {
this.messageBroker = messageBroker;
this.servicesInjector = servicesInjector;
- this.commandContext = lookupService(CommandContext.class);
- this.commandService = lookupService(CommandService.class);
-
- this.interactionContext = lookupService(InteractionContext.class);
-
this.publishingServiceInternal = lookupService(PublishingServiceInternal.class);
this.auditingServiceInternal = lookupService(AuditingServiceInternal.class);
this.changedObjectsServiceInternal = lookupService(ChangedObjectsServiceInternal.class);
@@ -236,19 +205,19 @@ public class IsisTransaction implements TransactionScopedComponent {
}
}
+ //endregion
- // ////////////////////////////////////////////////////////////////
- // GUID
- // ////////////////////////////////////////////////////////////////
+ //region > transactionId
public final UUID getTransactionId() {
return transactionId;
}
-
-
- // ////////////////////////////////////////////////////////////////
- // State
- // ////////////////////////////////////////////////////////////////
+
+ //endregion
+
+ //region > state
+
+ private State state;
public State getState() {
return state;
@@ -258,10 +227,10 @@ public class IsisTransaction implements TransactionScopedComponent {
this.state = state;
}
-
- // //////////////////////////////////////////////////////////
- // Commands
- // //////////////////////////////////////////////////////////
+ //endregion
+
+ //region > commands
+
/**
* Add the non-null command to the list of commands to execute at the end of
@@ -298,11 +267,41 @@ public class IsisTransaction implements TransactionScopedComponent {
persistenceCommands.add(command);
}
+ private boolean alreadyHasCommand(final Class<?> commandClass, final ObjectAdapter onObject) {
+ return getCommand(commandClass, onObject) != null;
+ }
+
+ private boolean alreadyHasCreate(final ObjectAdapter onObject) {
+ return alreadyHasCommand(CreateObjectCommand.class, onObject);
+ }
+
+ private boolean alreadyHasDestroy(final ObjectAdapter onObject) {
+ return alreadyHasCommand(DestroyObjectCommand.class, onObject);
+ }
+
+ private PersistenceCommand getCommand(final Class<?> commandClass, final ObjectAdapter onObject) {
+ for (final PersistenceCommand command : persistenceCommands) {
+ if (command.onAdapter().equals(onObject)) {
+ if (commandClass.isAssignableFrom(command.getClass())) {
+ return command;
+ }
+ }
+ }
+ return null;
+ }
+
+ private void removeCommand(final Class<?> commandClass, final ObjectAdapter onObject) {
+ final PersistenceCommand toDelete = getCommand(commandClass, onObject);
+ persistenceCommands.remove(toDelete);
+ }
+ private void removeCreate(final ObjectAdapter onObject) {
+ removeCommand(CreateObjectCommand.class, onObject);
+ }
- // ////////////////////////////////////////////////////////////////
- // flush
- // ////////////////////////////////////////////////////////////////
+ //endregion
+
+ //region > flush
public synchronized final void flush() {
@@ -382,10 +381,9 @@ public class IsisTransaction implements TransactionScopedComponent {
}
+ //endregion
- // ////////////////////////////////////////////////////////////////
- // preCommit, commit
- // ////////////////////////////////////////////////////////////////
+ //region > preCommit, commit
synchronized void preCommit() {
ensureThatState(getState().canCommit(), is(true), "state is: " + getState());
@@ -403,68 +401,20 @@ public class IsisTransaction implements TransactionScopedComponent {
}
try {
- // ensureCommandsPersistedIfDirtyXactn
- final Command command = commandContext.getCommand();
-
- // ensure that any changed objects means that the command should be persisted
- final boolean hasChangedAdapters = changedObjectsServiceInternal.hasChangedAdapters();
- if(hasChangedAdapters && command.getMemberIdentifier() != null) {
- command.setPersistHint(true);
- }
-
auditingServiceInternal.audit();
publishingServiceInternal.publishObjects();
doFlush();
- final ActionInvocationContext actionInvocationContext = lookupService(ActionInvocationContext.class);
- if(actionInvocationContext != null) {
- Bulk.InteractionContext.current.set(null);
- }
-
- completeCommandAndInteractionAndClearDomainEvents();
- doFlush();
-
} catch (final RuntimeException ex) {
setAbortCause(new IsisTransactionManagerException(ex));
- completeCommandAndInteractionAndClearDomainEvents();
throw ex;
} finally {
changedObjectsServiceInternal.clearChangedObjectProperties();
}
}
- private void completeCommandAndInteractionAndClearDomainEvents() {
-
- final Command command = commandContext.getCommand();
- final Interaction interaction = interactionContext.getInteraction();
-
- if(command.getStartedAt() != null && command.getCompletedAt() == null) {
- // the guard is in case we're here as the result of a redirect following a previous exception;just ignore.
-
- // copy over from the most recent interaction
- Interaction.Execution priorExecution = interaction.getPriorExecution();
- final Timestamp completedAt = priorExecution.getCompletedAt();
- command.setCompletedAt(completedAt);
- }
-
- commandService.complete(command);
-
- if(command instanceof Command3) {
- final Command3 command3 = (Command3) command;
- command3.flushActionDomainEvents();
- } else
- if(command instanceof Command2) {
- final Command2 command2 = (Command2) command;
- command2.flushActionInteractionEvents();
- }
-
- interaction.clear();
- }
-
-
- // ////////////////////////////////////////////////////////////////
public synchronized void commit() {
ensureThatState(getState().canCommit(), is(true), "state is: " + getState());
@@ -485,12 +435,14 @@ public class IsisTransaction implements TransactionScopedComponent {
}
-
- // ////////////////////////////////////////////////////////////////
- // markAsAborted
- // ////////////////////////////////////////////////////////////////
+ //endregion
- public synchronized final void markAsAborted() {
+ //region > abortCause, markAsAborted
+
+ /**
+ * internal API called by IsisTransactionManager only
+ */
+ synchronized final void markAsAborted() {
ensureThatState(getState().canAbort(), is(true), "state is: " + getState());
if (LOG.isInfoEnabled()) {
LOG.info("abort transaction " + this);
@@ -499,12 +451,6 @@ public class IsisTransaction implements TransactionScopedComponent {
setState(State.ABORTED);
}
-
-
- /////////////////////////////////////////////////////////////////////////
- // handle exceptions on load, flush or commit
- /////////////////////////////////////////////////////////////////////////
-
/**
* Indicate that the transaction must be aborted, and that there is
@@ -532,63 +478,25 @@ public class IsisTransaction implements TransactionScopedComponent {
abortCause = null;
}
-
- // //////////////////////////////////////////////////////////
- // Helpers
- // //////////////////////////////////////////////////////////
- private boolean alreadyHasCommand(final Class<?> commandClass, final ObjectAdapter onObject) {
- return getCommand(commandClass, onObject) != null;
- }
+ //endregion
- private boolean alreadyHasCreate(final ObjectAdapter onObject) {
- return alreadyHasCommand(CreateObjectCommand.class, onObject);
- }
-
- private boolean alreadyHasDestroy(final ObjectAdapter onObject) {
- return alreadyHasCommand(DestroyObjectCommand.class, onObject);
- }
-
- private PersistenceCommand getCommand(final Class<?> commandClass, final ObjectAdapter onObject) {
- for (final PersistenceCommand command : persistenceCommands) {
- if (command.onAdapter().equals(onObject)) {
- if (commandClass.isAssignableFrom(command.getClass())) {
- return command;
- }
- }
- }
- return null;
- }
-
- private void removeCommand(final Class<?> commandClass, final ObjectAdapter onObject) {
- final PersistenceCommand toDelete = getCommand(commandClass, onObject);
- persistenceCommands.remove(toDelete);
- }
-
- private void removeCreate(final ObjectAdapter onObject) {
- removeCommand(CreateObjectCommand.class, onObject);
- }
-
- // ////////////////////////////////////////////////////////////////
- // toString
- // ////////////////////////////////////////////////////////////////
+ //region > toString
@Override
public String toString() {
return appendTo(new ToString(this)).toString();
}
- protected ToString appendTo(final ToString str) {
+ private ToString appendTo(final ToString str) {
str.append("state", state);
str.append("commands", persistenceCommands.size());
return str;
}
+ //endregion
- // ////////////////////////////////////////////////////////////////
- // Depenendencies (from constructor)
- // ////////////////////////////////////////////////////////////////
-
+ //region > getMessageBroker
/**
* The {@link org.apache.isis.core.commons.authentication.MessageBroker} for this transaction.
@@ -602,11 +510,9 @@ public class IsisTransaction implements TransactionScopedComponent {
return messageBroker;
}
+ //endregion
- ////////////////////////////////////////////////////////////////////////
- // Dependencies (lookup)
- ////////////////////////////////////////////////////////////////////////
-
+ //region > helpers: lookupService etc
private <T> T lookupService(Class<T> serviceType) {
T service = lookupServiceIfAny(serviceType);
if(service == null) {
@@ -618,4 +524,9 @@ public class IsisTransaction implements TransactionScopedComponent {
private <T> T lookupServiceIfAny(final Class<T> serviceType) {
return servicesInjector.lookupService(serviceType);
}
+
+ //endregion
+
}
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/21b27fe4/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java
index deb0072..6589cb0 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java
@@ -19,22 +19,16 @@
package org.apache.isis.core.runtime.system.transaction;
-import java.sql.Timestamp;
-import java.util.List;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.isis.applib.annotation.Bulk;
-import org.apache.isis.applib.services.clock.ClockService;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.command.CommandContext;
import org.apache.isis.applib.services.command.spi.CommandService;
-import org.apache.isis.applib.services.factory.FactoryService;
import org.apache.isis.applib.services.iactn.Interaction;
import org.apache.isis.applib.services.iactn.InteractionContext;
-import org.apache.isis.applib.services.user.UserService;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.authentication.MessageBroker;
import org.apache.isis.core.commons.components.SessionScopedComponent;
@@ -42,7 +36,6 @@ import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
import org.apache.isis.core.metamodel.services.ServicesInjector;
import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommand;
-import org.apache.isis.core.runtime.services.RequestScopedService;
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;
@@ -68,15 +61,9 @@ public class IsisTransactionManager implements SessionScopedComponent {
private final ServicesInjector servicesInjector;
- private final FactoryService factoryService;
private final CommandContext commandContext;
- private final CommandService commandService;
-
private final InteractionContext interactionContext;
- private final ClockService clockService;
- private final UserService userService;
-
// ////////////////////////////////////////////////////////////////
// constructor
@@ -89,14 +76,8 @@ public class IsisTransactionManager implements SessionScopedComponent {
this.persistenceSession = persistenceSession;
this.servicesInjector = servicesInjector;
- this.factoryService = lookupService(FactoryService.class);
this.commandContext = lookupService(CommandContext.class);
- this.commandService = lookupService(CommandService.class);
-
this.interactionContext = lookupService(InteractionContext.class);
-
- this.clockService = lookupService(ClockService.class);
- this.userService = lookupService(UserService.class);
}
public PersistenceSession getPersistenceSession() {
@@ -262,40 +243,29 @@ public class IsisTransactionManager implements SessionScopedComponent {
if (getTransaction() == null || getTransaction().getState().isComplete()) {
noneInProgress = true;
- startRequestOnRequestScopedServices();
+ // previously we called __isis_startRequest here on all RequestScopedServices. This is now
+ // done earlier, in PersistenceSession#open(). If we introduce support for @TransactionScoped
+ // services, then this would be the place to initialize them.
- // note that at this point there may not be an EventBusService initialized. The PersistenceSession has
- // logic to suppress the posting of the ObjectCreatedEvent for the special case of Command objects.
- final Command command;
- final UUID transactionId;
+ // allow the command to be overridden (if running as a background command with a parent command supplied)
+
+ final Interaction interaction = interactionContext.getInteraction();
+ final Command command;
if (existingCommandIfAny != null) {
- command = existingCommandIfAny;
- transactionId = command.getTransactionId();
- }
- else {
- command = createCommand();
- transactionId = UUID.randomUUID();
+ commandContext.setCommand(existingCommandIfAny);
+ interaction.setTransactionId(existingCommandIfAny.getTransactionId());
}
- final Interaction interaction = factoryService.instantiate(Interaction.class);
-
- initCommandAndInteraction(transactionId, command, interaction);
+ command = commandContext.getCommand();
+ final UUID transactionId = command.getTransactionId();
- commandContext.setCommand(command);
- interactionContext.setInteraction(interaction);
-
- initOtherApplibServicesIfConfigured();
final MessageBroker messageBroker = MessageBroker.acquire(getAuthenticationSession());
this.transaction = new IsisTransaction(this, messageBroker, servicesInjector, transactionId);
transactionLevel = 0;
persistenceSession.startTransaction();
-
- // a no-op; the command will have been populated already
- // in the earlier call to #createCommandAndInitAndSetAsContext(...).
- commandService.startTransaction(command, transactionId);
}
transactionLevel++;
@@ -305,80 +275,6 @@ public class IsisTransactionManager implements SessionScopedComponent {
}
}
- private void initOtherApplibServicesIfConfigured() {
-
- final Bulk.InteractionContext bic = lookupServiceIfAny(Bulk.InteractionContext.class);
- if(bic != null) {
- Bulk.InteractionContext.current.set(bic);
- }
- }
-
- private void startRequestOnRequestScopedServices() {
-
- final List<Object> registeredServices = servicesInjector.getRegisteredServices();
-
- // tell the proxy of all request-scoped services to instantiate the underlying
- // services, store onto the thread-local and inject into them...
- for (final Object service : registeredServices) {
- if(service instanceof RequestScopedService) {
- ((RequestScopedService)service).__isis_startRequest(servicesInjector);
- }
- }
- // ... and invoke all @PostConstruct
- for (final Object service : registeredServices) {
- if(service instanceof RequestScopedService) {
- ((RequestScopedService)service).__isis_postConstruct();
- }
- }
- }
-
- private void endRequestOnRequestScopeServices() {
- // tell the proxy of all request-scoped services to invoke @PreDestroy
- // (if any) on all underlying services stored on their thread-locals...
- for (final Object service : servicesInjector.getRegisteredServices()) {
- if(service instanceof RequestScopedService) {
- ((RequestScopedService)service).__isis_preDestroy();
- }
- }
-
- // ... and then remove those underlying services from the thread-local
- for (final Object service : servicesInjector.getRegisteredServices()) {
- if(service instanceof RequestScopedService) {
- ((RequestScopedService)service).__isis_endRequest();
- }
- }
- }
-
- private Command createCommand() {
- final Command command = commandService.create();
-
- servicesInjector.injectServicesInto(command);
- return command;
- }
-
- /**
- * Sets up {@link Command#getTransactionId()}, {@link Command#getUser()} and {@link Command#getTimestamp()}.
- *
- * The remaining properties are set further down the call-stack, if an action is actually performed
- * @param transactionId
- * @param interaction
- */
- private void initCommandAndInteraction(
- final UUID transactionId,
- final Command command,
- final Interaction interaction) {
-
- final Timestamp timestamp = clockService.nowAsJavaSqlTimestamp();
- final String userName = userService.getUser().getName();
-
- command.setTimestamp(timestamp);
- command.setUser(userName);
- command.setTransactionId(transactionId);
-
- interaction.setTransactionId(transactionId);
- }
-
-
// //////////////////////////////////////////////////////
// flush
// //////////////////////////////////////////////////////
@@ -498,9 +394,11 @@ public class IsisTransactionManager implements SessionScopedComponent {
transactionLevel = 1; // because the transactionLevel was decremented earlier
}
}
-
-
- endRequestOnRequestScopeServices();
+
+
+ // previously we called __isis_endRequest here on all RequestScopedServices. This is now
+ // done later, in PersistenceSession#close(). If we introduce support for @TransactionScoped
+ // services, then this would be the place to finalize them.
if(abortCause != null) {