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 2012/12/13 08:30:03 UTC
[10/58] [partial] ISIS-188: renaming packages in line with
groupId:artifactId
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/FrameworkSynchronizer.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/FrameworkSynchronizer.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/FrameworkSynchronizer.java
new file mode 100644
index 0000000..71ad1cb
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/FrameworkSynchronizer.java
@@ -0,0 +1,342 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence;
+
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import javax.jdo.JDOHelper;
+import javax.jdo.PersistenceManager;
+import javax.jdo.spi.PersistenceCapable;
+
+import org.apache.log4j.Logger;
+import org.datanucleus.api.jdo.NucleusJDOHelper;
+
+import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ResolveState;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
+import org.apache.isis.core.metamodel.adapter.version.Version;
+import org.apache.isis.core.metamodel.facets.object.callbacks.CallbackFacet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.CallbackUtils;
+import org.apache.isis.core.metamodel.facets.object.callbacks.PersistedCallbackFacet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatedCallbackFacet;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.runtime.persistence.PersistorUtil;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.OidGenerator;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
+import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.spi.JdoObjectIdSerializer;
+
+public class FrameworkSynchronizer {
+
+ private static final Logger LOG = Logger.getLogger(FrameworkSynchronizer.class);
+
+ /**
+ * Categorises where called from.
+ *
+ * <p>
+ * Just used for logging.
+ */
+ public enum CalledFrom {
+ EVENT_LOAD, EVENT_STORE, EVENT_PREDIRTY, OS_QUERY, OS_RESOLVE, OS_LAZILYLOADED
+ }
+
+
+ public void postLoadProcessingFor(final PersistenceCapable pojo, CalledFrom calledFrom) {
+
+ withLogging(pojo, new Runnable() {
+ @Override
+ public void run() {
+ final Version datastoreVersion = getVersionIfAny(pojo);
+
+ final RootOid oid ;
+ ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+ if(adapter != null) {
+ ensureRootObject(pojo);
+ oid = (RootOid) adapter.getOid();
+
+ final Version previousVersion = adapter.getVersion();
+
+ // sync the pojo held by the adapter with that just loaded
+ getPersistenceSession().remapRecreatedPojo(adapter, pojo);
+
+ // since there was already an adapter, do concurrency check
+ if(previousVersion != null && datastoreVersion != null) {
+ if(previousVersion.different(datastoreVersion)) {
+ getCurrentTransaction().addException(new ConcurrencyException(getAuthenticationSession().getUserName(), oid, previousVersion, datastoreVersion));
+ }
+ }
+ } else {
+ final OidGenerator oidGenerator = getOidGenerator();
+ oid = oidGenerator.createPersistent(pojo, null);
+
+ // it appears to be possible that there is already an adapter for this Oid,
+ // ie from ObjectStore#resolveImmediately()
+ adapter = getAdapterManager().getAdapterFor(oid);
+ if(adapter != null) {
+ getPersistenceSession().remapRecreatedPojo(adapter, pojo);
+ } else {
+ adapter = getPersistenceSession().mapRecreatedPojo(oid, pojo);
+ }
+ }
+ if(!adapter.isResolved()) {
+ PersistorUtil.startResolving(adapter);
+ PersistorUtil.toEndState(adapter);
+ }
+ adapter.setVersion(datastoreVersion);
+
+ ensureFrameworksInAgreement(pojo);
+ }
+ }, calledFrom);
+ }
+
+
+ public void postStoreProcessingFor(final PersistenceCapable pojo, CalledFrom calledFrom) {
+ withLogging(pojo, new Runnable() {
+ @Override
+ public void run() {
+ ensureRootObject(pojo);
+
+ // assert is persistent
+ if(!pojo.jdoIsPersistent()) {
+ throw new IllegalStateException("Pojo JDO state is not persistent! pojo dnOid: " + JDOHelper.getObjectId(pojo));
+ }
+
+ final ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+ final RootOid isisOid = (RootOid) adapter.getOid();
+
+ Class<? extends CallbackFacet> callbackFacetClass;
+ if (isisOid.isTransient()) {
+ final RootOid persistentOid = getOidGenerator().createPersistent(pojo, isisOid);
+
+ getPersistenceSession().remapAsPersistent(adapter, persistentOid);
+
+ callbackFacetClass = PersistedCallbackFacet.class;
+ } else {
+ callbackFacetClass = UpdatedCallbackFacet.class;
+ }
+
+ Utils.clearDirtyFor(adapter);
+
+ Version versionIfAny = getVersionIfAny(pojo);
+ adapter.setVersion(versionIfAny);
+ CallbackUtils.callCallback(adapter, callbackFacetClass);
+
+ ensureFrameworksInAgreement(pojo);
+ }
+ }, calledFrom);
+ }
+
+ public void preDirtyProcessingFor(final PersistenceCapable pojo, CalledFrom calledFrom) {
+ withLogging(pojo, new Runnable() {
+ @Override
+ public void run() {
+ final IsisTransaction transaction = getCurrentTransaction();
+ final ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+
+ if(adapter.isTransient()) {
+ // seen this happen in the case when there's a 1<->m bidirectional collection, and we're
+ // attaching the child object, which is being persisted by DN as a result of persistence-by-reachability,
+ // and it "helpfully" sets up the parent attribute on the child, causing this callback to fire.
+ //
+ // however, at the same time, Isis has only queued up a CreateObjectCommand for the transient object, but it
+ // hasn't yet executed, so thinks that the adapter is still transient.
+ return;
+ }
+ transaction.auditDirty(adapter);
+
+ ensureRootObject(pojo);
+ ensureFrameworksInAgreement(pojo);
+ }
+ }, calledFrom);
+ }
+
+
+
+ public ObjectAdapter lazilyLoaded(final PersistenceCapable pojo, CalledFrom calledFrom) {
+ return withLogging(pojo, new Callable<ObjectAdapter>() {
+ @Override
+ public ObjectAdapter call() {
+ if(getJdoPersistenceManager().getObjectId(pojo) == null) {
+ return null;
+ }
+ final RootOid oid = getPersistenceSession().getOidGenerator().createPersistent(pojo, null);
+ final ObjectAdapter adapter = getPersistenceSession().mapRecreatedPojo(oid, pojo);
+ return adapter;
+ }
+ }, calledFrom);
+ }
+
+ // /////////////////////////////////////////////////////////
+ // Helpers
+ // /////////////////////////////////////////////////////////
+
+ private <T> T withLogging(PersistenceCapable pojo, Callable<T> runnable, CalledFrom calledFrom) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(logString(calledFrom, LoggingLocation.ENTRY, pojo));
+ }
+ try {
+ return runnable.call();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(logString(calledFrom, LoggingLocation.EXIT, pojo));
+ }
+ }
+ }
+
+ private void withLogging(PersistenceCapable pojo, final Runnable runnable, CalledFrom calledFrom) {
+ withLogging(pojo, new Callable<Void>() {
+
+ @Override
+ public Void call() throws Exception {
+ runnable.run();
+ return null;
+ }
+
+ }, calledFrom);
+ }
+
+ private String logString(CalledFrom calledFrom, LoggingLocation location, PersistenceCapable pojo) {
+ final AdapterManager adapterManager = getAdapterManager();
+ final ObjectAdapter adapter = adapterManager.getAdapterFor(pojo);
+ // initial spaces just to look better in log when wrapped by IsisLifecycleListener...
+ return calledFrom.name() + " " + location.prefix + " oid=" + (adapter !=null? adapter.getOid(): "(null)") + " ,pojo " + pojo;
+ }
+
+
+ // /////////////////////////////////////////////////////////
+ // Helpers
+ // /////////////////////////////////////////////////////////
+
+ void ensureFrameworksInAgreement(final PersistenceCapable pojo) {
+ final ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+ final Oid oid = adapter.getOid();
+
+ if(!pojo.jdoIsPersistent()) {
+ // make sure the adapter is transient
+ if (!adapter.getResolveState().isTransient()) {
+ throw new IsisException(MessageFormat.format("adapter oid={0} has resolve state in invalid state; should be transient but is {1}; pojo: {2}", oid, adapter.getResolveState(), pojo));
+ }
+
+ // make sure the oid is transient
+ if (!oid.isTransient()) {
+ throw new IsisException(MessageFormat.format("adapter oid={0} has oid in invalid state; should be transient; pojo: {1}", oid, pojo));
+ }
+
+ } else {
+ // make sure the adapter is persistent
+ if (!adapter.getResolveState().representsPersistent()) {
+ throw new IsisException(MessageFormat.format("adapter oid={0} has resolve state in invalid state; should be in a persistent but is {1}; pojo: {2}", oid, adapter.getResolveState(), pojo));
+ }
+
+ // make sure the oid is persistent
+ if (oid.isTransient()) {
+ throw new IsisException(MessageFormat.format("adapter oid={0} has oid in invalid state; should be persistent; pojo: {1}", oid, pojo));
+ }
+ }
+ }
+
+ // make sure the entity is known to Isis and is a root
+ // TODO: will probably need to handle aggregated entities at some point...
+ void ensureRootObject(final PersistenceCapable pojo) {
+ final ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+ if(adapter == null) {
+ throw new IsisException(MessageFormat.format("Object not yet known to Isis: {0}", pojo));
+ }
+ final Oid oid = adapter.getOid();
+ if (!(oid instanceof RootOid)) {
+ throw new IsisException(MessageFormat.format("Not a RootOid: oid={0}, for {1}", oid, pojo));
+ }
+ }
+
+ private Version getVersionIfAny(final PersistenceCapable pojo) {
+ return Utils.getVersionIfAny(pojo, getAuthenticationSession());
+ }
+
+ @SuppressWarnings("unused")
+ private static Filter<ObjectAssociation> dirtyFieldFilterFor(final PersistenceCapable pojo) {
+ String[] dirtyFields = NucleusJDOHelper.getDirtyFields(pojo, JDOHelper.getPersistenceManager(pojo));
+ final List<String> dirtyFieldList = Arrays.asList(dirtyFields);
+ Filter<ObjectAssociation> dirtyFieldsFilter = new Filter<ObjectAssociation>() {
+ @Override
+ public boolean accept(final ObjectAssociation t) {
+ String id = t.getId();
+ return dirtyFieldList.contains(id);
+ }};
+ return dirtyFieldsFilter;
+ }
+
+ @SuppressWarnings("unused")
+ private void ensureObjectNotLoaded(final PersistenceCapable pojo) {
+ final ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+ if(adapter != null) {
+ final Oid oid = adapter.getOid();
+ throw new IsisException(MessageFormat.format("Object is already mapped in Isis: oid={0}, for {1}", oid, pojo));
+ }
+ }
+
+
+
+ // /////////////////////////////////////////////////////////
+ // Dependencies (from context)
+ // /////////////////////////////////////////////////////////
+
+ protected AdapterManager getAdapterManager() {
+ return getPersistenceSession().getAdapterManager();
+ }
+
+ protected OidGenerator getOidGenerator() {
+ return getPersistenceSession().getOidGenerator();
+ }
+
+ protected PersistenceSession getPersistenceSession() {
+ return IsisContext.getPersistenceSession();
+ }
+
+ protected AuthenticationSession getAuthenticationSession() {
+ return IsisContext.getAuthenticationSession();
+ }
+
+ protected IsisTransaction getCurrentTransaction() {
+ return IsisContext.getCurrentTransaction();
+ }
+
+ protected PersistenceManager getJdoPersistenceManager() {
+ final DataNucleusObjectStore objectStore = getObjectStore();
+ return objectStore.getPersistenceManager();
+ }
+
+ protected DataNucleusObjectStore getObjectStore() {
+ return (DataNucleusObjectStore) IsisContext.getPersistenceSession().getObjectStore();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/IsisLifecycleListener.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/IsisLifecycleListener.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/IsisLifecycleListener.java
new file mode 100644
index 0000000..41266c6
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/IsisLifecycleListener.java
@@ -0,0 +1,266 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence;
+
+import java.util.Map;
+
+import javax.jdo.listener.AttachLifecycleListener;
+import javax.jdo.listener.ClearLifecycleListener;
+import javax.jdo.listener.CreateLifecycleListener;
+import javax.jdo.listener.DeleteLifecycleListener;
+import javax.jdo.listener.DetachLifecycleListener;
+import javax.jdo.listener.DirtyLifecycleListener;
+import javax.jdo.listener.InstanceLifecycleEvent;
+import javax.jdo.listener.LoadLifecycleListener;
+import javax.jdo.listener.StoreLifecycleListener;
+import javax.jdo.spi.PersistenceCapable;
+
+import com.google.common.collect.Maps;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer.CalledFrom;
+
+public class IsisLifecycleListener implements AttachLifecycleListener, ClearLifecycleListener, CreateLifecycleListener, DeleteLifecycleListener, DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLifecycleListener, SuspendableListener {
+
+ private static final Logger LOG = Logger.getLogger(IsisLifecycleListener.class);
+
+ private final FrameworkSynchronizer synchronizer;
+
+ public IsisLifecycleListener(FrameworkSynchronizer synchronizer) {
+ this.synchronizer = synchronizer;
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////
+ // callbacks
+ /////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void postCreate(final InstanceLifecycleEvent event) {
+ withLogging(Phase.POST, event, new RunnableNoop(event));
+ }
+
+ @Override
+ public void preAttach(final InstanceLifecycleEvent event) {
+ withLogging(Phase.PRE, event, new RunnableEnsureFrameworksInAgreement(event));
+ }
+
+ @Override
+ public void postAttach(final InstanceLifecycleEvent event) {
+ withLogging(Phase.POST, event, new RunnableEnsureFrameworksInAgreement(event));
+ }
+
+ @Override
+ public void postLoad(final InstanceLifecycleEvent event) {
+ withLogging(Phase.POST, event, new RunnableAbstract(event){
+ @Override
+ protected void doRun() {
+ final PersistenceCapable pojo = Utils.persistenceCapableFor(event);
+ synchronizer.postLoadProcessingFor(pojo, CalledFrom.EVENT_LOAD);
+ }});
+ }
+
+ @Override
+ public void preStore(InstanceLifecycleEvent event) {
+ withLogging(Phase.PRE, event, new RunnableNoop(event));
+ }
+
+ @Override
+ public void postStore(InstanceLifecycleEvent event) {
+ withLogging(Phase.POST, event, new RunnableAbstract(event){
+ @Override
+ protected void doRun() {
+ final PersistenceCapable pojo = Utils.persistenceCapableFor(event);
+ synchronizer.postStoreProcessingFor(pojo, CalledFrom.EVENT_STORE);
+
+ }});
+ }
+
+ @Override
+ public void preDirty(InstanceLifecycleEvent event) {
+ withLogging(Phase.PRE, event, new RunnableAbstract(event){
+ @Override
+ protected void doRun() {
+ final PersistenceCapable pojo = Utils.persistenceCapableFor(event);
+ synchronizer.preDirtyProcessingFor(pojo, CalledFrom.EVENT_PREDIRTY);
+ }});
+ }
+
+ @Override
+ public void postDirty(InstanceLifecycleEvent event) {
+
+ // cannot assert on the frameworks being in agreement, due to the scenario documented
+ // in the FrameworkSynchronizer#preDirtyProcessing(...)
+ //
+ // 1<->m bidirectional, persistence-by-reachability
+
+ withLogging(Phase.POST, event, new RunnableNoop(event));
+ }
+
+ @Override
+ public void preDelete(InstanceLifecycleEvent event) {
+ withLogging(Phase.PRE, event, new RunnableEnsureFrameworksInAgreement(event));
+ }
+
+ @Override
+ public void postDelete(InstanceLifecycleEvent event) {
+ withLogging(Phase.POST, event, new RunnableEnsureFrameworksInAgreement(event));
+ }
+
+ /**
+ * Does nothing, not important event for Isis to track.
+ */
+ @Override
+ public void preClear(InstanceLifecycleEvent event) {
+ // ignoring, not important to us
+ }
+
+ /**
+ * Does nothing, not important event for Isis to track.
+ */
+ @Override
+ public void postClear(InstanceLifecycleEvent event) {
+ // ignoring, not important to us
+ }
+
+ @Override
+ public void preDetach(InstanceLifecycleEvent event) {
+ withLogging(Phase.PRE, event, new RunnableEnsureFrameworksInAgreement(event));
+ }
+
+ @Override
+ public void postDetach(InstanceLifecycleEvent event) {
+ withLogging(Phase.POST, event, new RunnableEnsureFrameworksInAgreement(event));
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////
+ // withLogging
+ /////////////////////////////////////////////////////////////////////////
+
+ private void withLogging(Phase phase, InstanceLifecycleEvent event, Runnable runnable) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(logString(phase, LoggingLocation.ENTRY, event));
+ }
+ try {
+ runnable.run();
+ } finally {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(logString(phase, LoggingLocation.EXIT, event));
+ }
+ }
+ }
+
+ private abstract class RunnableAbstract implements Runnable {
+ final InstanceLifecycleEvent event;
+ public RunnableAbstract(final InstanceLifecycleEvent event) {
+ this.event = event;
+ }
+ @Override
+ public void run() {
+ if (isSuspended()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(" [currently suspended - ignoring]");
+ }
+ return;
+ }
+ doRun();
+ }
+
+ protected abstract void doRun();
+ }
+
+ private class RunnableNoop extends RunnableAbstract {
+ RunnableNoop(InstanceLifecycleEvent event) {
+ super(event);
+ }
+ protected void doRun() {}
+ }
+
+ private class RunnableEnsureFrameworksInAgreement extends RunnableAbstract {
+ RunnableEnsureFrameworksInAgreement(InstanceLifecycleEvent event) {
+ super(event);
+ }
+ protected void doRun() {
+ final PersistenceCapable pojo = Utils.persistenceCapableFor(event);
+ synchronizer.ensureRootObject(pojo);
+ synchronizer.ensureFrameworksInAgreement(pojo);
+ }
+ }
+
+
+ // /////////////////////////////////////////////////////////
+ // SuspendListener
+ // /////////////////////////////////////////////////////////
+
+ private boolean suspended;
+
+
+ @Override
+ public boolean isSuspended() {
+ return suspended;
+ }
+
+ @Override
+ public void setSuspended(boolean suspended) {
+ this.suspended = suspended;
+ }
+
+ // /////////////////////////////////////////////////////////
+ // Logging
+ // /////////////////////////////////////////////////////////
+
+ private enum Phase {
+ PRE, POST
+ }
+
+ private static Map<Integer, LifecycleEventType> events = Maps.newHashMap();
+
+ private enum LifecycleEventType {
+ CREATE(0), LOAD(1), STORE(2), CLEAR(3), DELETE(4), DIRTY(5), DETACH(6), ATTACH(7);
+
+ private LifecycleEventType(int code) {
+ events.put(code, this);
+ }
+
+ public static LifecycleEventType lookup(int code) {
+ return events.get(code);
+ }
+ }
+
+ private String logString(Phase phase, LoggingLocation location, InstanceLifecycleEvent event) {
+ final PersistenceCapable pojo = Utils.persistenceCapableFor(event);
+ final AdapterManager adapterManager = getAdapterManager();
+ final ObjectAdapter adapter = adapterManager.getAdapterFor(pojo);
+ return phase + " " + location.prefix + " " + LifecycleEventType.lookup(event.getEventType()) + ": oid=" + (adapter !=null? adapter.getOid(): "(null)") + " ,pojo " + pojo;
+ }
+
+
+ // /////////////////////////////////////////////////////////
+ // Dependencies (from context)
+ // /////////////////////////////////////////////////////////
+
+ protected AdapterManager getAdapterManager() {
+ return IsisContext.getPersistenceSession().getAdapterManager();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/LoggingLocation.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/LoggingLocation.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/LoggingLocation.java
new file mode 100644
index 0000000..a58d0b5
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/LoggingLocation.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.objectstore.jdo.datanucleus.persistence;
+
+public enum LoggingLocation {
+ ENTRY(">>"), EXIT("<<");
+ final String prefix;
+ private LoggingLocation(String prefix) {
+ this.prefix = prefix;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/SuspendableListener.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/SuspendableListener.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/SuspendableListener.java
new file mode 100644
index 0000000..4196e49
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/SuspendableListener.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.objectstore.jdo.datanucleus.persistence;
+
+public interface SuspendableListener {
+
+ boolean isSuspended();
+
+ void setSuspended(boolean suspend);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/Utils.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/Utils.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/Utils.java
new file mode 100644
index 0000000..be82019
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/Utils.java
@@ -0,0 +1,56 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence;
+
+import java.util.Date;
+
+import javax.jdo.listener.InstanceLifecycleEvent;
+import javax.jdo.spi.PersistenceCapable;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.version.SerialNumberVersion;
+import org.apache.isis.core.metamodel.adapter.version.Version;
+
+public class Utils {
+
+ @SuppressWarnings("unused")
+ private static Object jdoObjectIdFor(InstanceLifecycleEvent event) {
+ PersistenceCapable persistenceCapable = Utils.persistenceCapableFor(event);
+ Object jdoObjectId = persistenceCapable.jdoGetObjectId();
+ return jdoObjectId;
+ }
+
+ static PersistenceCapable persistenceCapableFor(InstanceLifecycleEvent event) {
+ return (PersistenceCapable)event.getSource();
+ }
+
+ static void clearDirtyFor(final ObjectAdapter adapter) {
+ adapter.getSpecification().clearDirty(adapter);
+ }
+
+ static Version getVersionIfAny(final PersistenceCapable pojo, final AuthenticationSession authenticationSession) {
+ Object jdoVersion = pojo.jdoGetVersion();
+ if(jdoVersion instanceof Long) {
+ return SerialNumberVersion.create((Long) jdoVersion, authenticationSession.getUserName(), new Date());
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/adaptermanager/DataNucleusPojoRecreator.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/adaptermanager/DataNucleusPojoRecreator.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/adaptermanager/DataNucleusPojoRecreator.java
new file mode 100644
index 0000000..edd883d
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/adaptermanager/DataNucleusPojoRecreator.java
@@ -0,0 +1,62 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.adaptermanager;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.TypedOid;
+import org.apache.isis.core.runtime.persistence.adaptermanager.PojoRecreator;
+import org.apache.isis.core.runtime.persistence.adaptermanager.PojoRecreatorDefault;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore;
+
+public class DataNucleusPojoRecreator implements PojoRecreator {
+
+ private final PojoRecreator delegate = new PojoRecreatorDefault();
+
+ @Override
+ public Object recreatePojo(TypedOid oid) {
+ if(oid.isTransient()) {
+ return delegate.recreatePojo(oid);
+ }
+ return getObjectStore().loadPojo(oid);
+ }
+
+
+ @Override
+ public ObjectAdapter lazilyLoaded(Object pojo) {
+ return getObjectStore().lazilyLoaded(pojo);
+ }
+
+ ///////////////////////////////
+
+
+ protected PersistenceSession getPersistenceSession() {
+ return IsisContext.getPersistenceSession();
+ }
+
+ protected DataNucleusObjectStore getObjectStore() {
+ return (DataNucleusObjectStore) getPersistenceSession().getObjectStore();
+ }
+
+
+
+
+}
+
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/AbstractDataNucleusObjectCommand.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/AbstractDataNucleusObjectCommand.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/AbstractDataNucleusObjectCommand.java
new file mode 100644
index 0000000..03bcc06
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/AbstractDataNucleusObjectCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.commands;
+
+import javax.jdo.PersistenceManager;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommandAbstract;
+import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommandContext;
+
+public abstract class AbstractDataNucleusObjectCommand extends PersistenceCommandAbstract {
+
+ private final PersistenceManager persistenceManager;
+
+ AbstractDataNucleusObjectCommand(final ObjectAdapter adapter,
+ final PersistenceManager persistenceManager) {
+ super(adapter);
+ this.persistenceManager = persistenceManager;
+
+ }
+
+ protected PersistenceManager getPersistenceManager() {
+ return persistenceManager;
+ }
+
+ public abstract void execute(final PersistenceCommandContext context);
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusCreateObjectCommand.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusCreateObjectCommand.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusCreateObjectCommand.java
new file mode 100644
index 0000000..36c32b7
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusCreateObjectCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.commands;
+
+import javax.jdo.PersistenceManager;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.persistence.objectstore.transaction.CreateObjectCommand;
+import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommandContext;
+
+public class DataNucleusCreateObjectCommand extends AbstractDataNucleusObjectCommand implements CreateObjectCommand {
+
+ private static final Logger LOG = Logger
+ .getLogger(DataNucleusCreateObjectCommand.class);
+
+ public DataNucleusCreateObjectCommand(ObjectAdapter adapter, PersistenceManager persistenceManager) {
+ super(adapter, persistenceManager);
+ }
+
+
+ @Override
+ public void execute(final PersistenceCommandContext context) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("create object - executing command for: " + onAdapter());
+ }
+ final ObjectAdapter adapter = onAdapter();
+ if(!adapter.isTransient()) {
+ // this could happen if DN's persistence-by-reachability has already caused the domainobject
+ // to be persisted. It's Isis adapter will have been updated as a result of the postStore
+ // lifecycle callback, so in essence there's nothing to be done.
+ return;
+ }
+ final Object domainObject = adapter.getObject();
+
+ getPersistenceManager().makePersistent(domainObject);
+ }
+
+ @Override
+ public String toString() {
+ return "CreateObjectCommand [adapter=" + onAdapter() + "]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusDeleteObjectCommand.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusDeleteObjectCommand.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusDeleteObjectCommand.java
new file mode 100644
index 0000000..ea6b3ad
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusDeleteObjectCommand.java
@@ -0,0 +1,50 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.commands;
+
+import javax.jdo.PersistenceManager;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.persistence.objectstore.transaction.DestroyObjectCommand;
+import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommandContext;
+
+public class DataNucleusDeleteObjectCommand extends AbstractDataNucleusObjectCommand implements DestroyObjectCommand {
+
+ private static final Logger LOG = Logger.getLogger(DataNucleusDeleteObjectCommand.class);
+
+ public DataNucleusDeleteObjectCommand(ObjectAdapter adapter, PersistenceManager persistenceManager) {
+ super(adapter, persistenceManager);
+ }
+
+ @Override
+ public void execute(final PersistenceCommandContext context) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("destroy object - executing command for " + onAdapter());
+ }
+ getPersistenceManager().deletePersistent(onAdapter().getObject());
+ }
+
+ @Override
+ public String toString() {
+ return "DestroyObjectCommand [adapter=" + onAdapter() + "]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusUpdateObjectCommand.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusUpdateObjectCommand.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusUpdateObjectCommand.java
new file mode 100644
index 0000000..93441ec
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/commands/DataNucleusUpdateObjectCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.commands;
+
+import javax.jdo.PersistenceManager;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommandContext;
+import org.apache.isis.core.runtime.persistence.objectstore.transaction.SaveObjectCommand;
+
+public class DataNucleusUpdateObjectCommand extends AbstractDataNucleusObjectCommand implements SaveObjectCommand {
+ private static final Logger LOG = Logger
+ .getLogger(DataNucleusDeleteObjectCommand.class);
+
+ public DataNucleusUpdateObjectCommand(ObjectAdapter adapter, PersistenceManager persistenceManager) {
+ super(adapter, persistenceManager);
+ }
+
+ @Override
+ public void execute(final PersistenceCommandContext context) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("save object - executing command for: " + onAdapter());
+ }
+
+ // TODO: this might be a no-op; JDO doesn't seem to have an equivalent of JPA's merge() ...
+ // getEntityManager().merge(onAdapter().getObject());
+ }
+
+ @Override
+ public String toString() {
+ return "SaveObjectCommand [adapter=" + onAdapter() + "]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindAllInstancesProcessor.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindAllInstancesProcessor.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindAllInstancesProcessor.java
new file mode 100644
index 0000000..a54ff59
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindAllInstancesProcessor.java
@@ -0,0 +1,56 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.queries;
+
+import java.util.List;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.Query;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindAllInstances;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer;
+
+public class PersistenceQueryFindAllInstancesProcessor extends PersistenceQueryProcessorAbstract<PersistenceQueryFindAllInstances> {
+
+ private static final Logger LOG = Logger.getLogger(PersistenceQueryFindAllInstancesProcessor.class);
+
+ public PersistenceQueryFindAllInstancesProcessor(final PersistenceManager persistenceManager, final FrameworkSynchronizer frameworkSynchronizer) {
+ super(persistenceManager, frameworkSynchronizer);
+ }
+
+ public List<ObjectAdapter> process(final PersistenceQueryFindAllInstances persistenceQuery) {
+
+ final ObjectSpecification specification = persistenceQuery.getSpecification();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("getInstances: class=" + specification.getFullIdentifier());
+ }
+
+ Class<?> cls = specification.getCorrespondingClass();
+ final Query query = getPersistenceManager().newQuery(cls);
+
+ final List<?> pojos = (List<?>) query.execute();
+ return loadAdapters(specification, pojos);
+ }
+}
+
+// Copyright (c) Naked Objects Group Ltd.
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindByPatternProcessor.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindByPatternProcessor.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindByPatternProcessor.java
new file mode 100644
index 0000000..cc8112b
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindByPatternProcessor.java
@@ -0,0 +1,59 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.queries;
+
+import java.util.List;
+
+import javax.jdo.PersistenceManager;
+
+import org.apache.isis.core.commons.exceptions.NotYetImplementedException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindByPattern;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer;
+
+public class PersistenceQueryFindByPatternProcessor extends
+ PersistenceQueryProcessorAbstract<PersistenceQueryFindByPattern> {
+
+ public PersistenceQueryFindByPatternProcessor(
+ final PersistenceManager persistenceManager, final FrameworkSynchronizer frameworkSynchronizer) {
+ super(persistenceManager, frameworkSynchronizer);
+ }
+
+ public List<ObjectAdapter> process(
+ final PersistenceQueryFindByPattern persistenceQuery) {
+
+
+
+
+// final Object pojoPattern = persistenceQuery.getPattern().getObject();
+//
+// final CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
+//
+//
+// final CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
+//
+// final Query query = getEntityManager().createQuery(criteriaQuery);
+// final List<?> results = query.getResultList();
+// return loadAdapters(persistenceQuery.getSpecification(), results);
+
+ throw new NotYetImplementedException();
+ }
+}
+
+// Copyright (c) Naked Objects Group Ltd.
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindByTitleProcessor.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindByTitleProcessor.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindByTitleProcessor.java
new file mode 100644
index 0000000..7bdc524
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindByTitleProcessor.java
@@ -0,0 +1,63 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.queries;
+
+import java.util.List;
+
+import javax.jdo.PersistenceManager;
+
+import org.apache.isis.core.commons.exceptions.NotYetImplementedException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindByTitle;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer;
+
+public class PersistenceQueryFindByTitleProcessor extends PersistenceQueryProcessorAbstract<PersistenceQueryFindByTitle> {
+
+ public PersistenceQueryFindByTitleProcessor(final PersistenceManager persistenceManager, final FrameworkSynchronizer frameworkSynchronizer) {
+ super(persistenceManager, frameworkSynchronizer);
+ }
+
+ public List<ObjectAdapter> process(final PersistenceQueryFindByTitle persistenceQuery) {
+ final ObjectSpecification objectSpec = persistenceQuery.getSpecification();
+ final Class<?> correspondingClass = objectSpec.getCorrespondingClass();
+ return process(persistenceQuery, correspondingClass);
+ }
+
+ private <Z> List<ObjectAdapter> process(final PersistenceQueryFindByTitle persistenceQuery, Class<Z> correspondingClass) {
+ // TODO
+ throw new NotYetImplementedException();
+
+// final CriteriaQuery<Z> criteriaQuery = getEntityManager().getCriteriaBuilder().createQuery(correspondingClass);
+//
+// final ObjectSpecification objectSpec = persistenceQuery.getSpecification();
+// final Root<Z> from = criteriaQuery.from(correspondingClass);
+//
+// final EntityType<Z> model = from.getModel();
+// final SingularAttribute<? super Z, String> titleAttribute = model.getSingularAttribute("title", String.class);
+// final Path<String> titlePath = from.get(titleAttribute);
+// titlePath.equals(persistenceQuery.getTitle());
+//
+// final TypedQuery<Z> query = getPersistenceManager().createQuery(criteriaQuery);
+// final List<Z> pojos = query.getResultList();
+// return loadAdapters(objectSpec, pojos);
+ }
+}
+
+// Copyright (c) Naked Objects Group Ltd.
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindUsingApplibQueryProcessor.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindUsingApplibQueryProcessor.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindUsingApplibQueryProcessor.java
new file mode 100644
index 0000000..bf39cfe
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryFindUsingApplibQueryProcessor.java
@@ -0,0 +1,97 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.queries;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.Query;
+
+import com.google.common.collect.Maps;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.services.container.query.QueryCardinality;
+import org.apache.isis.core.metamodel.spec.ObjectAdapterUtils;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.runtime.persistence.query.PersistenceQueryFindUsingApplibQueryDefault;
+import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore;
+import org.apache.isis.objectstore.jdo.datanucleus.metamodel.JdoPropertyUtils;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer;
+
+public class PersistenceQueryFindUsingApplibQueryProcessor extends PersistenceQueryProcessorAbstract<PersistenceQueryFindUsingApplibQueryDefault> {
+
+ public PersistenceQueryFindUsingApplibQueryProcessor(final PersistenceManager persistenceManager, final FrameworkSynchronizer frameworkSynchronizer) {
+ super(persistenceManager, frameworkSynchronizer);
+ }
+
+ public List<ObjectAdapter> process(final PersistenceQueryFindUsingApplibQueryDefault persistenceQuery) {
+ final String queryName = persistenceQuery.getQueryName();
+ final Map<String, Object> map = unwrap(persistenceQuery.getArgumentsAdaptersByParameterName());
+ final QueryCardinality cardinality = persistenceQuery.getCardinality();
+ final ObjectSpecification objectSpec = persistenceQuery.getSpecification();
+
+ final List<?> results;
+ if((objectSpec.getFullIdentifier() + "#pk").equals(queryName)) {
+ // special case handling
+ final Class<?> cls = objectSpec.getCorrespondingClass();
+ if(!JdoPropertyUtils.hasPrimaryKeyProperty(objectSpec)) {
+ throw new UnsupportedOperationException("cannot search by primary key for DataStore-assigned entities");
+ }
+ final OneToOneAssociation pkOtoa = JdoPropertyUtils.getPrimaryKeyPropertyFor(objectSpec);
+ String pkOtoaId = pkOtoa.getId();
+ final String filter = pkOtoaId + "==" + map.get(pkOtoaId);
+ final Query jdoQuery = getPersistenceManager().newQuery(cls, filter);
+ results = (List<?>) jdoQuery.execute();
+ } else {
+ results = getResults(objectSpec, queryName, map, cardinality);
+ }
+
+ return loadAdapters(objectSpec, results);
+ }
+
+ private List<?> getResults(ObjectSpecification objectSpec, final String queryName, final Map<String, Object> argumentsByParameterName, final QueryCardinality cardinality) {
+
+ final PersistenceManager persistenceManager = getJdoObjectStore().getPersistenceManager();
+ final Class<?> cls = objectSpec.getCorrespondingClass();
+ final Query jdoQuery = persistenceManager.newNamedQuery(cls, queryName);
+
+ final List<?> results = (List<?>) jdoQuery.executeWithMap(argumentsByParameterName);
+ if (cardinality == QueryCardinality.MULTIPLE) {
+ return results;
+ }
+ return results.isEmpty()?Collections.emptyList():results.subList(0, 1);
+ }
+
+ private static Map<String, Object> unwrap(final Map<String, ObjectAdapter> argumentAdaptersByParameterName) {
+ final Map<String, Object> argumentsByParameterName = Maps.newHashMap();
+ for (final String parameterName : argumentAdaptersByParameterName.keySet()) {
+ final ObjectAdapter argumentAdapter = argumentAdaptersByParameterName.get(parameterName);
+ final Object argument = ObjectAdapterUtils.unwrapObject(argumentAdapter);
+ argumentsByParameterName.put(parameterName, argument);
+ }
+ return argumentsByParameterName;
+ }
+
+
+}
+
+// Copyright (c) Naked Objects Group Ltd.
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessor.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessor.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessor.java
new file mode 100644
index 0000000..6f9f187
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessor.java
@@ -0,0 +1,30 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.queries;
+
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.runtime.system.persistence.PersistenceQuery;
+
+public interface PersistenceQueryProcessor<T extends PersistenceQuery> {
+ List<ObjectAdapter> process(T query);
+}
+
+// Copyright (c) Naked Objects Group Ltd.
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessorAbstract.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessorAbstract.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessorAbstract.java
new file mode 100644
index 0000000..35a5691
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/PersistenceQueryProcessorAbstract.java
@@ -0,0 +1,107 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.queries;
+
+import java.util.List;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.listener.InstanceLifecycleEvent;
+import javax.jdo.metadata.TypeMetadata;
+import javax.jdo.spi.PersistenceCapable;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.core.commons.ensure.Assert;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.AdapterManagerSpi;
+import org.apache.isis.core.runtime.system.persistence.PersistenceQuery;
+import org.apache.isis.core.runtime.system.persistence.Persistor;
+import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.IsisLifecycleListener;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer.CalledFrom;
+
+public abstract class PersistenceQueryProcessorAbstract<T extends PersistenceQuery>
+ implements PersistenceQueryProcessor<T> {
+
+ private final PersistenceManager persistenceManager;
+ private final FrameworkSynchronizer frameworkSynchronizer;
+
+ protected PersistenceQueryProcessorAbstract(final PersistenceManager persistenceManager, final FrameworkSynchronizer frameworkSynchronizer) {
+ this.persistenceManager = persistenceManager;
+ this.frameworkSynchronizer = frameworkSynchronizer;
+ }
+
+ protected PersistenceManager getPersistenceManager() {
+ return persistenceManager;
+ }
+
+
+ // /////////////////////////////////////////////////////////////
+ // helpers for subclasses
+ // /////////////////////////////////////////////////////////////
+
+ protected PersistenceManagerFactory getPersistenceManagerFactory() {
+ return getPersistenceManager().getPersistenceManagerFactory();
+ }
+
+ protected TypeMetadata getTypeMetadata(final String classFullName) {
+ return getPersistenceManagerFactory().getMetadata(classFullName);
+ }
+
+ /**
+ * Traversing the provided list causes (or should cause) the
+ * {@link IsisLifecycleListener#postLoad(InstanceLifecycleEvent) {
+ * to be called.
+ */
+ protected List<ObjectAdapter> loadAdapters(
+ final ObjectSpecification specification, final List<?> pojos) {
+ final List<ObjectAdapter> adapters = Lists.newArrayList();
+ for (final Object pojo : pojos) {
+ // ought not to be necessary, however for some queries it seems that the
+ // lifecycle listener is not called
+ frameworkSynchronizer.postLoadProcessingFor((PersistenceCapable) pojo, CalledFrom.OS_QUERY);
+ ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+ Assert.assertNotNull(adapter);
+ adapters.add(adapter);
+ }
+ return adapters;
+ }
+
+ // /////////////////////////////////////////////////////////////
+ // Dependencies (from context)
+ // /////////////////////////////////////////////////////////////
+
+ protected Persistor getPersistenceSession() {
+ return IsisContext.getPersistenceSession();
+ }
+
+ protected AdapterManager getAdapterManager() {
+ return IsisContext.getPersistenceSession().getAdapterManager();
+ }
+
+ protected DataNucleusObjectStore getJdoObjectStore() {
+ return (DataNucleusObjectStore) IsisContext.getPersistenceSession().getObjectStore();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/QueryUtil.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/QueryUtil.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/QueryUtil.java
new file mode 100644
index 0000000..0e45cf6
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/queries/QueryUtil.java
@@ -0,0 +1,89 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.queries;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.Query;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+public final class QueryUtil {
+
+ private static final Logger LOG = Logger.getLogger(QueryUtil.class);
+
+ private QueryUtil() {}
+
+ public static Query createQuery(
+ final PersistenceManager persistenceManager,
+ final String alias,
+ final String select,
+ final ObjectSpecification specification,
+ final String whereClause) {
+
+ final StringBuilder buf = new StringBuilder(128);
+ appendSelect(buf, select, alias);
+ appendFrom(buf, specification, alias);
+ appendWhere(buf, whereClause);
+
+ final String queryString = buf.toString();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("creating query: " + queryString);
+ }
+
+ return persistenceManager.newQuery(queryString);
+ }
+
+ private static StringBuilder appendSelect(
+ final StringBuilder buf,
+ final String select,
+ String alias) {
+ if (select != null) {
+ buf.append(select);
+ } else {
+ buf.append("select ");
+ // not required in JDOQL (cf JPA QL)
+ // buf.append(alias);
+ }
+ buf.append(" ");
+ return buf;
+ }
+
+ private static void appendWhere(StringBuilder buf, String whereClause) {
+ if(whereClause == null) {
+ return;
+ }
+ buf.append(" where ").append(whereClause);
+ }
+
+
+ private static StringBuilder appendFrom(
+ final StringBuilder buf,
+ final ObjectSpecification specification,
+ final String alias) {
+ return buf.append("from ")
+ .append(specification.getFullIdentifier())
+ .append(" as ")
+ .append(alias);
+ }
+}
+
+
+// Copyright (c) Naked Objects Group Ltd.
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
new file mode 100644
index 0000000..f848676
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
@@ -0,0 +1,106 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.spi;
+
+import java.util.UUID;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.spi.PersistenceCapable;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.IdentifierGenerator;
+import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore;
+
+public class DataNucleusIdentifierGenerator implements IdentifierGenerator {
+
+ @SuppressWarnings("unused")
+ private static final Logger LOG = Logger.getLogger(DataNucleusIdentifierGenerator.class);
+
+
+
+ // //////////////////////////////////////////////////////////////
+ // main api
+ // //////////////////////////////////////////////////////////////
+
+ @Override
+ public String createTransientIdentifierFor(ObjectSpecId objectSpecId, Object pojo) {
+ return UUID.randomUUID().toString();
+ }
+
+
+ @Override
+ public String createAggregateLocalId(ObjectSpecId objectSpecId, Object pojo, ObjectAdapter parentAdapter) {
+ return UUID.randomUUID().toString();
+ }
+
+
+ @Override
+ public String createPersistentIdentifierFor(ObjectSpecId objectSpecId, Object pojo, RootOid transientRootOid) {
+
+ // hack to deal with services
+ if(!(pojo instanceof PersistenceCapable)) {
+ return "1";
+ }
+
+ final Object jdoOid = getJdoPersistenceManager().getObjectId(pojo);
+
+ return JdoObjectIdSerializer.toOidIdentifier(jdoOid);
+ }
+
+
+
+ // //////////////////////////////////////////////////////////////
+ // Debugging
+ // //////////////////////////////////////////////////////////////
+
+
+ public String debugTitle() {
+ return "DataNucleus Identifier Generator";
+ }
+
+
+ @Override
+ public void debugData(DebugBuilder debug) {
+
+ }
+
+
+ // //////////////////////////////////////////////////////////////
+ // Dependencies (from context)
+ // //////////////////////////////////////////////////////////////
+
+
+ protected PersistenceManager getJdoPersistenceManager() {
+ final DataNucleusObjectStore objectStore = getDataNucleusObjectStore();
+ return objectStore.getPersistenceManager();
+ }
+
+
+ protected DataNucleusObjectStore getDataNucleusObjectStore() {
+ return (DataNucleusObjectStore) IsisContext.getPersistenceSession().getObjectStore();
+ }
+
+}
+// Copyright (c) Naked Objects Group Ltd.
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusSimplePersistAlgorithm.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusSimplePersistAlgorithm.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusSimplePersistAlgorithm.java
new file mode 100644
index 0000000..80a0dc2
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusSimplePersistAlgorithm.java
@@ -0,0 +1,77 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.spi;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.commons.lang.ToString;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.object.callbacks.CallbackUtils;
+import org.apache.isis.core.metamodel.facets.object.callbacks.PersistingCallbackFacet;
+import org.apache.isis.core.runtime.persistence.objectstore.algorithm.PersistAlgorithm;
+import org.apache.isis.core.runtime.persistence.objectstore.algorithm.PersistAlgorithmAbstract;
+import org.apache.isis.core.runtime.persistence.objectstore.algorithm.ToPersistObjectSet;
+
+
+/**
+ * A {@link PersistAlgorithm} which simply saves the object made persistent.
+ */
+public class DataNucleusSimplePersistAlgorithm extends PersistAlgorithmAbstract {
+
+ private static final Logger LOG = Logger
+ .getLogger(DataNucleusSimplePersistAlgorithm.class);
+
+
+ // ////////////////////////////////////////////////////////////////
+ // name
+ // ////////////////////////////////////////////////////////////////
+
+ public String name() {
+ return "SimplePersistAlgorithm";
+ }
+
+
+ // ////////////////////////////////////////////////////////////////
+ // makePersistent
+ // ////////////////////////////////////////////////////////////////
+
+ public void makePersistent(final ObjectAdapter adapter,
+ final ToPersistObjectSet toPersistObjectSet) {
+ if (alreadyPersistedOrNotPersistable(adapter)) {
+ return;
+ }
+ if (LOG.isInfoEnabled()) {
+ LOG.info("persist " + adapter);
+ }
+ CallbackUtils.callCallback(adapter, PersistingCallbackFacet.class);
+ toPersistObjectSet.addCreateObjectCommand(adapter);
+ }
+
+
+ // ////////////////////////////////////////////////////////////////
+ // toString
+ // ////////////////////////////////////////////////////////////////
+
+ @Override
+ public String toString() {
+ final ToString toString = new ToString(this);
+ return toString.toString();
+ }
+}
+// Copyright (c) Naked Objects Group Ltd.
http://git-wip-us.apache.org/repos/asf/isis/blob/951a0fe4/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusTransaction.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusTransaction.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusTransaction.java
new file mode 100644
index 0000000..4427f7d
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusTransaction.java
@@ -0,0 +1,92 @@
+/*
+ * 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.objectstore.jdo.datanucleus.persistence.spi;
+
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.isis.applib.clock.Clock;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.runtime.persistence.objectstore.transaction.TransactionalResource;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
+import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
+import org.apache.isis.core.runtime.system.transaction.MessageBroker;
+import org.apache.isis.core.runtime.system.transaction.UpdateNotifier;
+import org.apache.isis.objectstore.jdo.applib.AuditService;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.auditable.AuditableFacet;
+
+public class DataNucleusTransaction extends IsisTransaction {
+
+ private final AuditService auditService;
+
+ public DataNucleusTransaction(
+ final IsisTransactionManager transactionManager,
+ final MessageBroker messageBroker,
+ final UpdateNotifier updateNotifier,
+ final TransactionalResource objectStore,
+ final AuditService auditService) {
+ super(transactionManager, messageBroker, updateNotifier, objectStore);
+ this.auditService = auditService;
+ }
+
+ @Override
+ protected void doAudit(final Set<Entry<AdapterAndProperty, PreAndPostValues>> auditEntries) {
+ if(auditService == null) {
+ super.doAudit(auditEntries);
+ return;
+ }
+ final String currentUser = getAuthenticationSession().getUserName();
+ final long currentTimestampEpoch = currentTimestampEpoch();
+ for (Entry<AdapterAndProperty, PreAndPostValues> auditEntry : auditEntries) {
+ audit(currentUser, currentTimestampEpoch, auditEntry);
+ }
+ }
+
+ private long currentTimestampEpoch() {
+ return Clock.getTime();
+ }
+
+ private void audit(final String currentUser, final long currentTimestampEpoch, final Entry<AdapterAndProperty, PreAndPostValues> auditEntry) {
+ final AdapterAndProperty aap = auditEntry.getKey();
+ final ObjectAdapter adapter = aap.getAdapter();
+ if(!adapter.getSpecification().containsFacet(AuditableFacet.class)) {
+ return;
+ }
+ final RootOid oid = (RootOid) adapter.getOid();
+ final String objectType = oid.getObjectSpecId().asString();
+ final String identifier = oid.getIdentifier();
+ final PreAndPostValues papv = auditEntry.getValue();
+ final String preValue = asString(papv.getPre());
+ final String postValue = asString(papv.getPost());
+ auditService.audit(currentUser, currentTimestampEpoch, objectType, identifier, preValue, postValue);
+ }
+
+ private static String asString(Object object) {
+ return object != null? object.toString(): null;
+ }
+
+
+ protected AuthenticationSession getAuthenticationSession() {
+ return IsisContext.getAuthenticationSession();
+ }
+
+}