/*
* 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;
import org.datanucleus.ExecutionContext;
import org.datanucleus.cache.CachedPC;
import org.datanucleus.enhancement.Persistable;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.state.ReferentialStateManagerImpl;
import org.datanucleus.store.FieldValues;
import org.datanucleus.store.fieldmanager.FieldManager;
import org.apache.isis.core.metamodel.services.ServicesInjector;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
public class JDOStateManagerForIsis extends ReferentialStateManagerImpl {
public JDOStateManagerForIsis(ExecutionContext ec, AbstractClassMetaData cmd) {
super(ec, cmd);
}
public enum Hint {
NONE,
REPLACE_FIELDS,
POST_COMMIT
}
/**
* Tunnel down the thread stack as a hint to the {@link org.apache.isis.objectstore.jdo.datanucleus.service.eventbus.EventBusServiceJdo}.
*/
public final static ThreadLocal<Hint> hint = new ThreadLocal<JDOStateManagerForIsis.Hint>() {
protected Hint initialValue() {
return Hint.NONE;
};
};
@Override
public void initialiseForHollow(Object id, FieldValues fv, Class pcClass) {
super.initialiseForHollow(id, fv, pcClass);
mapIntoIsis(myPC);
}
@Override
public void initialiseForHollowAppId(FieldValues fv, Class pcClass) {
super.initialiseForHollowAppId(fv, pcClass);
mapIntoIsis(myPC);
}
@Override
public void initialiseForHollowPreConstructed(Object id, Persistable pc) {
super.initialiseForHollowPreConstructed(id, pc);
mapIntoIsis(myPC);
}
@Override
public void initialiseForPersistentClean(Object id, Persistable pc) {
super.initialiseForPersistentClean(id, pc);
mapIntoIsis(myPC);
}
@Override
public void initialiseForEmbedded(Persistable pc, boolean copyPc) {
super.initialiseForEmbedded(pc, copyPc);
mapIntoIsis(myPC);
}
@Override
public void initialiseForPersistentNew(Persistable pc,
FieldValues preInsertChanges) {
super.initialiseForPersistentNew(pc, preInsertChanges);
mapIntoIsis(myPC);
}
@Override
public void initialiseForTransactionalTransient(Persistable pc) {
super.initialiseForTransactionalTransient(pc);
mapIntoIsis(myPC);
}
@Override
public void initialiseForDetached(Persistable pc, Object id, Object version) {
super.initialiseForDetached(pc, id, version);
mapIntoIsis(myPC);
}
@Override
public void initialiseForPNewToBeDeleted(Persistable pc) {
super.initialiseForPNewToBeDeleted(pc);
mapIntoIsis(myPC);
}
@Override
public void initialiseForCachedPC(CachedPC cachedPC, Object id) {
super.initialiseForCachedPC(cachedPC, id);
mapIntoIsis(myPC);
}
@Override
public void replaceField(Persistable pc, int fieldNumber, Object value) {
final Hint previous = hint.get();
try {
hint.set(Hint.REPLACE_FIELDS);
super.replaceField(pc, fieldNumber, value);
} finally {
hint.set(previous);
}
}
@Override
public void replaceFieldValue(int fieldNumber, Object value) {
final Hint previous = hint.get();
try {
hint.set(Hint.REPLACE_FIELDS);
super.replaceField(fieldNumber, value);
} finally {
hint.set(previous);
}
}
@Override
public void replaceField(int fieldNumber, Object value) {
final Hint previous = hint.get();
try {
hint.set(Hint.REPLACE_FIELDS);
super.replaceField(fieldNumber, value);
} finally {
hint.set(previous);
}
}
@Override
public void replaceFieldMakeDirty(int fieldNumber, Object value) {
final Hint previous = hint.get();
try {
hint.set(Hint.REPLACE_FIELDS);
super.replaceField(fieldNumber, value);
} finally {
hint.set(previous);
}
}
@Override
public void replaceField(Persistable pc, int fieldNumber, Object value, boolean makeDirty) {
final Hint previous = hint.get();
try {
hint.set(Hint.REPLACE_FIELDS);
super.replaceField(pc, fieldNumber, value, makeDirty);
} finally {
hint.set(previous);
}
}
@Override
public void replaceFields(int[] fieldNumbers, FieldManager fm) {
final Hint previous = hint.get();
try {
hint.set(Hint.REPLACE_FIELDS);
super.replaceFields(fieldNumbers, fm);
} finally {
hint.set(previous);
}
}
@Override
public void replaceFields(int[] fieldNumbers, FieldManager fm, boolean replaceWhenDirty) {
final Hint previous = hint.get();
try {
hint.set(Hint.REPLACE_FIELDS);
super.replaceFields(fieldNumbers, fm, replaceWhenDirty);
} finally {
hint.set(previous);
}
}
@Override
public void replaceNonLoadedFields(int fieldNumbers[], FieldManager fm) {
final Hint previous = hint.get();
try {
hint.set(Hint.REPLACE_FIELDS);
super.replaceNonLoadedFields(fieldNumbers, fm);
} finally {
hint.set(previous);
}
}
public void postCommit(org.datanucleus.Transaction tx) {
final Hint previous = hint.get();
try {
hint.set(Hint.POST_COMMIT);
super.postCommit(tx);
} finally {
hint.set(previous);
}
}
protected void mapIntoIsis(Persistable pc) {
getServicesInjector().injectServicesInto(pc);
}
protected ServicesInjector getServicesInjector() {
return getSessionFactory().getServicesInjector();
}
IsisSessionFactory getSessionFactory() {
return IsisContext.getSessionFactory();
}
}