use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-core by datanucleus.
the class PersistenceNucleusContextImpl method initialise.
public synchronized void initialise() {
final ClassLoaderResolver clr = getClassLoaderResolver(null);
clr.registerUserClassLoader((ClassLoader) config.getProperty(PropertyNames.PROPERTY_CLASSLOADER_PRIMARY));
boolean generateSchema = false;
boolean generateScripts = false;
String generateModeStr = config.getStringProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_DATABASE_MODE);
if (generateModeStr == null || generateModeStr.equalsIgnoreCase("none")) {
// Try scripts instead of database since that wasn't set
generateModeStr = config.getStringProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_SCRIPTS_MODE);
generateScripts = true;
}
if (generateModeStr != null && !generateModeStr.equalsIgnoreCase("none")) {
generateSchema = true;
// Add any properties that are needed by schema generation (before we create StoreManager)
if (!config.getBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL)) {
config.setProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL, "true");
}
if (!config.getBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_TABLES)) {
config.setProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_TABLES, "true");
}
if (!config.getBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_COLUMNS)) {
config.setProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_COLUMNS, "true");
}
if (!config.getBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_CONSTRAINTS)) {
config.setProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_CONSTRAINTS, "true");
}
if (!config.getBooleanProperty(PropertyNames.PROPERTY_DATASTORE_READONLY)) {
config.setProperty(PropertyNames.PROPERTY_DATASTORE_READONLY, "false");
}
}
// Create the StoreManager
try {
Set<String> propNamesWithDatastore = config.getPropertyNamesWithPrefix("datanucleus.datastore.");
if (propNamesWithDatastore == null) {
// Find the StoreManager using the persistence property if specified
NucleusLogger.DATASTORE.debug("Creating StoreManager for datastore");
Map<String, Object> datastoreProps = config.getDatastoreProperties();
this.storeMgr = NucleusContextHelper.createStoreManagerForProperties(config.getPersistenceProperties(), datastoreProps, clr, this);
// Make sure the isolation level is valid for this StoreManager and correct if necessary
String transactionIsolation = config.getStringProperty(PropertyNames.PROPERTY_TRANSACTION_ISOLATION);
if (transactionIsolation != null) {
String reqdIsolation = NucleusContextHelper.getTransactionIsolationForStoreManager(storeMgr, transactionIsolation);
if (!transactionIsolation.equalsIgnoreCase(reqdIsolation)) {
config.setProperty(PropertyNames.PROPERTY_TRANSACTION_ISOLATION, reqdIsolation);
}
}
} else {
NucleusLogger.DATASTORE.debug("Creating FederatedStoreManager to handle federation of primary StoreManager and " + propNamesWithDatastore.size() + " secondary datastores");
this.storeMgr = new FederatedStoreManager(clr, this);
this.federated = true;
}
} catch (NucleusException ne) {
NucleusLogger.DATASTORE.error("Exception thrown creating StoreManager : " + StringUtils.getMessageFromRootCauseOfThrowable(ne));
throw ne;
}
NucleusLogger.DATASTORE.debug("StoreManager now created");
// Make sure MetaDataManager is initialised
MetaDataManager mmgr = getMetaDataManager();
final Level2Cache cache = getLevel2Cache();
if (cache != null) {
// Add listener for metadata loading so we can pin any classes in the L2 cache that are marked for that
mmgr.registerListener(new MetaDataListener() {
@Override
public void loaded(AbstractClassMetaData cmd) {
if (cmd.hasExtension("cache-pin") && cmd.getValueForExtension("cache-pin").equalsIgnoreCase("true")) {
// Register as auto-pinned in the L2 cache
Class cls = clr.classForName(cmd.getFullClassName());
cache.pinAll(cls, false);
}
}
});
}
// ========== Initialise the StoreManager contents ==========
// A). Load any classes specified by auto-start
String autoStartMechanism = config.getStringProperty(PropertyNames.PROPERTY_AUTOSTART_MECHANISM);
if (autoStartMechanism != null && !autoStartMechanism.equals("None")) {
initialiseAutoStart(clr);
}
// B). Schema Generation
if (generateSchema) {
initialiseSchema(generateModeStr, generateScripts);
}
// C). Load up internal representations of all persistence-unit classes
if (config.getStringProperty(PropertyNames.PROPERTY_PERSISTENCE_UNIT_NAME) != null && config.getBooleanProperty(PropertyNames.PROPERTY_PERSISTENCE_UNIT_LOAD_CLASSES)) {
// User is using a persistence-unit, so load up its persistence-unit classes into StoreManager
Collection<String> loadedClasses = getMetaDataManager().getClassesWithMetaData();
this.storeMgr.manageClasses(clr, loadedClasses.toArray(new String[loadedClasses.size()]));
}
if (config.getBooleanProperty(PropertyNames.PROPERTY_QUERY_COMPILE_NAMED_QUERIES_AT_STARTUP)) {
initialiseNamedQueries(clr);
}
if (ecPool == null) {
ecPool = new ExecutionContextPool(this);
}
if (opFactory == null) {
opFactory = new ObjectProviderFactoryImpl(this);
}
if (config.hasProperty(PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER)) {
try {
multiTenancyProvider = (MultiTenancyProvider) config.getProperty(PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER);
} catch (Throwable thr) {
NucleusLogger.PERSISTENCE.warn("Error accessing property " + PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER + "; should be an instance of MultiTenancyProvider but isnt! Ignored");
}
}
if (config.hasProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER)) {
try {
currentUserProvider = (CurrentUserProvider) config.getProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER);
} catch (Throwable thr) {
NucleusLogger.PERSISTENCE.warn("Error accessing property " + PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER + "; should be an instance of CurrentUserProvider but isnt! Ignored");
}
}
super.initialise();
}
use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-core by datanucleus.
the class EnhancerClassAdapter method visitEnd.
/**
* Method called at the end of the class.
*/
public void visitEnd() {
AbstractClassMetaData cmd = enhancer.getClassMetaData();
if (cmd.getPersistenceModifier() == ClassPersistenceModifier.PERSISTENCE_CAPABLE) {
// Add any new fields
List fields = enhancer.getFieldsList();
Iterator fieldsIter = fields.iterator();
while (fieldsIter.hasNext()) {
ClassField field = (ClassField) fieldsIter.next();
if (field.getName().equals(enhancer.getNamer().getDetachedStateFieldName()) && hasDetachedState) {
// No need to add this field since exists
continue;
}
if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005021", ((Class) field.getType()).getName() + " " + field.getName()));
}
cv.visitField(field.getAccess(), field.getName(), Type.getDescriptor((Class) field.getType()), null, null);
}
if (!hasStaticInitialisation) {
// Add a static initialisation block for the class since nothing added yet
InitClass method = InitClass.getInstance(enhancer);
method.initialise(cv);
method.execute();
method.close();
}
if (!hasDefaultConstructor && enhancer.hasOption(ClassEnhancer.OPTION_GENERATE_DEFAULT_CONSTRUCTOR)) {
// Add a default constructor
DefaultConstructor ctr = DefaultConstructor.getInstance(enhancer);
ctr.initialise(cv);
ctr.execute();
ctr.close();
}
// Add any new methods
List methods = enhancer.getMethodsList();
Iterator<ClassMethod> methodsIter = methods.iterator();
while (methodsIter.hasNext()) {
ClassMethod method = methodsIter.next();
method.initialise(cv);
method.execute();
method.close();
}
if (Serializable.class.isAssignableFrom(enhancer.getClassBeingEnhanced())) {
// Class is Serializable
if (!hasSerialVersionUID) {
// Needs "serialVersionUID" field
Long uid = null;
try {
uid = (Long) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return Long.valueOf(ObjectStreamClass.lookup(enhancer.getClassBeingEnhanced()).getSerialVersionUID());
}
});
} catch (Throwable e) {
DataNucleusEnhancer.LOGGER.warn(StringUtils.getStringFromStackTrace(e));
}
ClassField cf = new ClassField(enhancer, enhancer.getNamer().getSerialVersionUidFieldName(), Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, long.class, uid);
if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005021", ((Class) cf.getType()).getName() + " " + cf.getName()));
}
cv.visitField(cf.getAccess(), cf.getName(), Type.getDescriptor((Class) cf.getType()), null, cf.getInitialValue());
}
// pc class that implements Serializable in the inheritance hierarchy needs to be modified or generated to call it.
if (cmd.getSuperAbstractClassMetaData() == null && !hasWriteObject) {
// User hasn't provided their own writeObject, so provide the default but with a call to dnPreSerialize first
ClassMethod method = WriteObject.getInstance(enhancer);
method.initialise(cv);
method.execute();
method.close();
}
}
// Add dnGetXXX, dnSetXXX for each of the (managed) fields/properties
for (AbstractMemberMetaData mmd : cmd.getManagedMembers()) {
if (mmd.getPersistenceModifier() == FieldPersistenceModifier.NONE) {
// Field/Property is not persistent so ignore
continue;
}
ClassMethod getMethod = null;
ClassMethod setMethod = null;
if (mmd instanceof PropertyMetaData) {
// dnGetXXX, dnSetXXX for property are typically generated when processing existing getXXX, setXXX methods
// TODO What if the user overrode the getter and not the setter? or vice-versa?
} else {
// Generate dnGetXXX, dnSetXXX for field
byte persistenceFlags = mmd.getPersistenceFlags();
if ((persistenceFlags & Persistable.MEDIATE_READ) == Persistable.MEDIATE_READ) {
getMethod = new GetViaMediate(enhancer, mmd);
} else if ((persistenceFlags & Persistable.CHECK_READ) == Persistable.CHECK_READ) {
getMethod = new GetViaCheck(enhancer, mmd);
} else {
getMethod = new GetNormal(enhancer, mmd);
}
if ((persistenceFlags & Persistable.MEDIATE_WRITE) == Persistable.MEDIATE_WRITE) {
setMethod = new SetViaMediate(enhancer, mmd);
} else if ((persistenceFlags & Persistable.CHECK_WRITE) == Persistable.CHECK_WRITE) {
setMethod = new SetViaCheck(enhancer, mmd);
} else {
setMethod = new SetNormal(enhancer, mmd);
}
}
if (getMethod != null) {
getMethod.initialise(cv);
getMethod.execute();
getMethod.close();
}
if (setMethod != null) {
setMethod.initialise(cv);
setMethod.execute();
setMethod.close();
}
}
}
cv.visitEnd();
}
use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-core by datanucleus.
the class FetchGroupManager method createFetchGroup.
/**
* Method to create a new FetchGroup for the class and name.
* <b>Doesn't add it to the internally managed groups.</b>
* @param cls The class
* @param name Name of the group
* @return The FetchGroup
* @param <T> Type that the FetchGroup is for
*/
public <T> FetchGroup<T> createFetchGroup(Class<T> cls, String name) {
// Not present so create a new FetchGroup and add it
FetchGroup<T> fg = new FetchGroup(nucleusCtx, name, cls);
if (name.equals(FetchGroup.DEFAULT)) {
// Special case of wanting to create a group to override the DFG
fg.addCategory(FetchGroup.DEFAULT);
} else {
// Check if this class has a named FetchGroup of this name, so we start from the same members
ClassLoaderResolver clr = nucleusCtx.getClassLoaderResolver(cls.getClassLoader());
AbstractClassMetaData cmd = nucleusCtx.getMetaDataManager().getMetaDataForClass(cls, clr);
if (cmd != null) {
FetchGroupMetaData fgmd = cmd.getFetchGroupMetaData(name);
if (fgmd != null) {
Set<FetchGroupMemberMetaData> fgmmds = fgmd.getMembers();
for (FetchGroupMemberMetaData fgmmd : fgmmds) {
fg.addMember(fgmmd.getName());
if (fgmmd.getRecursionDepth() != 1) {
fg.setRecursionDepth(fgmmd.getName(), fgmmd.getRecursionDepth());
}
}
}
}
}
return fg;
}
use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-core by datanucleus.
the class FetchPlanForClass method getMemberNumbersByBitSet.
/**
* Get all members in the fetch plan for this class and superclasses.
* @param cmd metadata for the class
* @return an BitSet with the bits set in the absolute position of the members
*/
private BitSet getMemberNumbersByBitSet(AbstractClassMetaData cmd) {
FetchPlanForClass fpc = plan.getFetchPlanForClass(cmd);
BitSet bitSet = fpc.getMemberNumbersForFetchGroups(cmd.getFetchGroupMetaData());
if (cmd.getPersistableSuperclass() != null) {
// Recurse to superclass
AbstractClassMetaData superCmd = cmd.getSuperAbstractClassMetaData();
FetchPlanForClass superFpc = plan.getFetchPlanForClass(superCmd);
bitSet.or(superFpc.getMemberNumbersByBitSet(superCmd));
} else {
// Make sure that we always have the PK fields in the fetch plan = FetchPlanImpl.NONE
fpc.setAsNone(bitSet);
}
if (plan.dynamicGroups != null) {
// dynamic fetch groups
Iterator<FetchGroup> iter = plan.dynamicGroups.iterator();
while (iter.hasNext()) {
FetchGroup grp = iter.next();
if (grp.getType().getName().equals(cmd.getFullClassName())) {
// Dynamic fetch group applies
Set<String> members = grp.getMembers();
Iterator<String> membersIter = members.iterator();
while (membersIter.hasNext()) {
String memberName = membersIter.next();
int fieldPos = cmd.getAbsolutePositionOfMember(memberName);
if (fieldPos >= 0) {
bitSet.set(fieldPos);
}
}
}
}
}
return bitSet;
}
use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-core by datanucleus.
the class EnhancerMethodAdapter method visitFieldInsn.
/**
* Method to intercept any calls to fields.
* @param opcode Operation
* @param owner Owner class
* @param name Name of the field
* @param desc Descriptor for the field
*/
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
String ownerName = owner.replace('/', '.');
if (enhancer.isPersistable(ownerName)) {
AbstractClassMetaData cmd = null;
boolean fieldInThisClass = true;
if (enhancer.getClassMetaData().getFullClassName().equals(ownerName)) {
// Same class so use the input MetaData
cmd = enhancer.getClassMetaData();
} else {
fieldInThisClass = false;
cmd = enhancer.getMetaDataManager().getMetaDataForClass(ownerName, enhancer.getClassLoaderResolver());
}
// enhancing here would cause issues
if (!fieldInThisClass || !(methodName.equals("<init>"))) {
AbstractMemberMetaData fmd = cmd.getMetaDataForMember(name);
if (fmd != null && !fmd.isStatic() && !fmd.isFinal() && fmd.getPersistenceModifier() != FieldPersistenceModifier.NONE && fmd.getPersistenceFlags() != 0 && fmd instanceof FieldMetaData) {
// Field being accessed has its access mediated by the enhancer, so intercept it
// Make sure we address the field being in the class it is actually in
String fieldOwner = fmd.getClassName(true).replace('.', '/');
if (opcode == Opcodes.GETFIELD) {
// Read of a field of a PC class, so replace with dnGetXXX() call
mv.visitMethodInsn(Opcodes.INVOKESTATIC, fieldOwner, enhancer.getNamer().getGetMethodPrefixMethodName() + name, "(L" + fieldOwner + ";)" + desc);
if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005023", enhancer.getClassName() + "." + methodName, fmd.getClassName(true) + "." + name, enhancer.getNamer().getGetMethodPrefixMethodName() + name + "()"));
}
return;
} else if (opcode == Opcodes.PUTFIELD) {
// Write of a field of a PC class, so replace with dnSetXXX() call
mv.visitMethodInsn(Opcodes.INVOKESTATIC, fieldOwner, enhancer.getNamer().getSetMethodPrefixMethodName() + name, "(L" + fieldOwner + ";" + desc + ")V");
if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005023", enhancer.getClassName() + "." + methodName, fmd.getClassName(true) + "." + name, enhancer.getNamer().getSetMethodPrefixMethodName() + name + "()"));
}
return;
}
}
} else {
DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005024", enhancer.getClassName() + "." + methodName, opcode == Opcodes.GETFIELD ? "get" : "set", ownerName + "." + name));
}
}
super.visitFieldInsn(opcode, owner, name, desc);
}
Aggregations