
org.datanucleus.identity.IdentityUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datanucleus-core Show documentation
Show all versions of datanucleus-core Show documentation
DataNucleus Core provides the primary components of a heterogenous Java persistence solution.
It supports persistence API's being layered on top of the core functionality.
Also includes the JDO API.
/**********************************************************************
Copyright (c) 2010 Andy Jefferson and others. All rights reserved.
Licensed 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.
Contributors:
...
**********************************************************************/
package org.datanucleus.identity;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.datanucleus.ClassConstants;
import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.ClassNameConstants;
import org.datanucleus.ExecutionContext;
import org.datanucleus.api.ApiAdapter;
import org.datanucleus.exceptions.NucleusException;
import org.datanucleus.exceptions.NucleusObjectNotFoundException;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.metadata.AbstractMemberMetaData;
import org.datanucleus.metadata.FieldMetaData;
import org.datanucleus.metadata.FieldRole;
import org.datanucleus.metadata.IdentityType;
import org.datanucleus.metadata.MetaDataUtils;
import org.datanucleus.store.fieldmanager.FieldManager;
import org.datanucleus.util.ClassUtils;
/**
* Series of utilities for handling identities of objects.
*/
public class IdentityUtils
{
/**
* Checks whether the passed class name is valid for a single field application-identity.
* @param className the identity class name
* @return Whether it is a single field class
*/
public static boolean isSingleFieldIdentityClass(String className)
{
if (className == null || className.length() < 1)
{
return false;
}
return (className.equals(ClassNameConstants.IDENTITY_SINGLEFIELD_BYTE) ||
className.equals(ClassNameConstants.IDENTITY_SINGLEFIELD_CHAR) ||
className.equals(ClassNameConstants.IDENTITY_SINGLEFIELD_INT) ||
className.equals(ClassNameConstants.IDENTITY_SINGLEFIELD_LONG) ||
className.equals(ClassNameConstants.IDENTITY_SINGLEFIELD_OBJECT) ||
className.equals(ClassNameConstants.IDENTITY_SINGLEFIELD_SHORT) ||
className.equals(ClassNameConstants.IDENTITY_SINGLEFIELD_STRING));
}
/**
* Simple method to return the target class name of the persistable object that the provided id represents.
* If this is a datastore identity (OID) or single-field identity then returns the class name.
* Otherwise returns null. Does no inheritance checking.
* @param id The identity
* @return Class name for the identity if easily determinable
*/
public static String getTargetClassNameForIdentitySimple(Object id)
{
if (id instanceof DatastoreId)
{
// Object is an OID
return ((DatastoreId)id).getTargetClassName();
}
else if (id instanceof SingleFieldId)
{
// Using SingleFieldIdentity so can assume that object is of the target class
return ((SingleFieldId)id).getTargetClassName();
}
// Must be user-specified identity so just return
return null;
}
/**
* Accessor for whether the passed identity is a valid single-field application-identity for this API.
* @param id The id
* @return Whether it is valid
*/
public static boolean isSingleFieldIdentity(Object id)
{
return (id instanceof SingleFieldId);
}
/* (non-Javadoc)
* @see org.datanucleus.api.ApiAdapter#isDatastoreIdentity(java.lang.Object)
*/
public static boolean isDatastoreIdentity(Object id)
{
return (id != null && id instanceof DatastoreId);
}
/**
* Accessor for the key object for the specified single field application-identity.
* @param id The identity
* @return The key object
*/
public static Object getTargetKeyForSingleFieldIdentity(Object id)
{
return (id instanceof SingleFieldId ? ((SingleFieldId)id).getKeyAsObject() : null);
}
/**
* Accessor for the key object for the specified datastore-identity.
* @param id The identity
* @return The key object
*/
public static Object getTargetKeyForDatastoreIdentity(Object id)
{
return (id instanceof DatastoreId ? ((DatastoreId)id).getKeyAsObject() : null);
}
/**
* Accessor for the type of the single field application-identity key given the single field identity type.
* @param idType Single field identity type
* @return key type
*/
public static Class getKeyTypeForSingleFieldIdentityType(Class idType)
{
if (idType == null)
{
return null;
}
if (!IdentityUtils.isSingleFieldIdentityClass(idType.getName()))
{
return null;
}
if (ClassConstants.IDENTITY_SINGLEFIELD_LONG.isAssignableFrom(idType))
{
return Long.class;
}
else if (ClassConstants.IDENTITY_SINGLEFIELD_INT.isAssignableFrom(idType))
{
return Integer.class;
}
else if (ClassConstants.IDENTITY_SINGLEFIELD_SHORT.isAssignableFrom(idType))
{
return Short.class;
}
else if (ClassConstants.IDENTITY_SINGLEFIELD_BYTE.isAssignableFrom(idType))
{
return Byte.class;
}
else if (ClassConstants.IDENTITY_SINGLEFIELD_CHAR.isAssignableFrom(idType))
{
return Character.class;
}
else if (ClassConstants.IDENTITY_SINGLEFIELD_STRING.isAssignableFrom(idType))
{
return String.class;
}
else if (ClassConstants.IDENTITY_SINGLEFIELD_OBJECT.isAssignableFrom(idType))
{
return Object.class;
}
return null;
}
/**
* Method to return a persistable form of the identity of a persistable object.
* This can be used by datastores that don't use foreign keys and want to store the explicit class of the persistable object.
* @param id The id
* @return String form
*/
public static String getPersistableIdentityForId(Object id)
{
if (id == null)
{
return null;
}
if (IdentityUtils.isSingleFieldIdentity(id))
{
return ((SingleFieldId)id).getTargetClassName() + ":" + ((SingleFieldId)id).getKeyAsObject();
}
return id.toString();
}
/**
* Convenience method to find an object given a string form of its identity, and the metadata for the class (or a superclass).
* @param persistableId The persistable id
* @param cmd (Root) metadata for the class
* @param ec Execution Context
* @return The object
*/
public static Object getObjectFromPersistableIdentity(String persistableId, AbstractClassMetaData cmd, ExecutionContext ec)
{
ClassLoaderResolver clr = ec.getClassLoaderResolver();
Object id = null;
if (cmd == null)
{
throw new NucleusException("Cannot get object from id=" + persistableId + " since class name was not supplied!");
}
if (cmd.getIdentityType() == IdentityType.DATASTORE)
{
id = ec.getNucleusContext().getIdentityManager().getDatastoreId(persistableId);
}
else if (cmd.getIdentityType() == IdentityType.APPLICATION)
{
if (cmd.usesSingleFieldIdentityClass())
{
String className = persistableId.substring(0, persistableId.indexOf(':'));
cmd = ec.getMetaDataManager().getMetaDataForClass(className, clr);
String idStr = persistableId.substring(persistableId.indexOf(':')+1);
id = ec.getNucleusContext().getIdentityManager().getApplicationId(clr, cmd, idStr);
}
else
{
Class cls = clr.classForName(cmd.getFullClassName());
id = ec.newObjectId(cls, persistableId);
}
}
return ec.findObject(id, true, false, null);
}
/**
* Method to return the object application identity for a row of the result set.
* If the class isn't using application identity then returns null
* @param ec Execution Context
* @param cmd Metadata for the class
* @param pcClass The class required
* @param inheritanceCheck Whether need an inheritance check (may be for a subclass)
* @param resultsFM FieldManager servicing the results
* @return The identity (if found) or null (if either not sure of inheritance, or not known).
*/
public static Object getApplicationIdentityForResultSetRow(ExecutionContext ec, AbstractClassMetaData cmd,
Class pcClass, boolean inheritanceCheck, FieldManager resultsFM)
{
if (cmd.getIdentityType() == IdentityType.APPLICATION)
{
if (pcClass == null)
{
pcClass = ec.getClassLoaderResolver().classForName(cmd.getFullClassName());
}
ApiAdapter api = ec.getApiAdapter();
int[] pkFieldNums = cmd.getPKMemberPositions();
Object[] pkFieldValues = new Object[pkFieldNums.length];
for (int i=0;iDevelopers should move to using "persistable identity" and method getObjectFromPersistableIdentity().
* @param idStr The id string
* @param cmd Metadata for the class
* @param ec Execution Context
* @param checkInheritance Whether to check the inheritance level of this object
* @return The object
*/
public static Object getObjectFromIdString(String idStr, AbstractClassMetaData cmd, ExecutionContext ec, boolean checkInheritance)
{
ClassLoaderResolver clr = ec.getClassLoaderResolver();
Object id = null;
if (cmd.getIdentityType() == IdentityType.DATASTORE)
{
id = ec.getNucleusContext().getIdentityManager().getDatastoreId(idStr);
}
else if (cmd.getIdentityType() == IdentityType.APPLICATION)
{
if (cmd.usesSingleFieldIdentityClass())
{
id = ec.getNucleusContext().getIdentityManager().getApplicationId(clr, cmd, idStr);
}
else
{
Class cls = clr.classForName(cmd.getFullClassName());
id = ec.newObjectId(cls, idStr);
}
}
return ec.findObject(id, true, checkInheritance, null);
}
/**
* Convenience method to find an object given a string form of its identity, and the metadata for the member.
* @param idStr The id string
* @param mmd Metadata for the member
* @param fieldRole Role of this field (see org.datanucleus.metadata.FieldRole)
* @param ec Execution Context
* @param checkInheritance Whether to check the inheritance level of this object
* @return The object
*/
public static Object getObjectFromIdString(String idStr, AbstractMemberMetaData mmd, FieldRole fieldRole, ExecutionContext ec, boolean checkInheritance)
{
ClassLoaderResolver clr = ec.getClassLoaderResolver();
if (fieldRole == FieldRole.ROLE_FIELD && mmd.getType().isInterface())
{
// Interface field, so use information about possible implementation types
String[] implNames = MetaDataUtils.getInstance().getImplementationNamesForReferenceField(mmd, fieldRole,
clr, ec.getMetaDataManager());
if (implNames == null || implNames.length == 0)
{
// No known implementations so no way of knowing the type
return null;
}
AbstractClassMetaData cmd = ec.getMetaDataManager().getMetaDataForClass(implNames[0], clr);
if (cmd.getIdentityType() == IdentityType.DATASTORE)
{
Object id = ec.getNucleusContext().getIdentityManager().getDatastoreId(idStr);
return ec.findObject(id, true, checkInheritance, null);
}
else if (cmd.getIdentityType() == IdentityType.APPLICATION)
{
Object id = null;
for (int i=0;i, map, map, interface>, interface[]
else
{
AbstractClassMetaData cmd = null;
if (fieldRole == FieldRole.ROLE_COLLECTION_ELEMENT)
{
cmd = mmd.getCollection().getElementClassMetaData(clr, ec.getMetaDataManager());
}
else if (fieldRole == FieldRole.ROLE_ARRAY_ELEMENT)
{
cmd = mmd.getArray().getElementClassMetaData(clr, ec.getMetaDataManager());
}
else if (fieldRole == FieldRole.ROLE_MAP_KEY)
{
cmd = mmd.getMap().getKeyClassMetaData(clr, ec.getMetaDataManager());
}
else if (fieldRole == FieldRole.ROLE_MAP_KEY)
{
cmd = mmd.getMap().getKeyClassMetaData(clr, ec.getMetaDataManager());
}
else
{
cmd = ec.getMetaDataManager().getMetaDataForClass(mmd.getType(), clr);
}
Object id = null;
if (cmd.getIdentityType() == IdentityType.DATASTORE)
{
id = ec.getNucleusContext().getIdentityManager().getDatastoreId(idStr);
}
else if (cmd.getIdentityType() == IdentityType.APPLICATION)
{
if (cmd.usesSingleFieldIdentityClass())
{
// Single-Field identity doesn't have the class name in the string, so cater for the root being abstract
Class cls = clr.classForName(cmd.getFullClassName());
if (Modifier.isAbstract(cls.getModifiers()))
{
// Try to find a non-abstract subclass candidate
// TODO Allow for all possibilities rather than just first non-abstract branch
String[] subclasses = ec.getMetaDataManager().getSubclassesForClass(cmd.getFullClassName(), false);
if (subclasses != null)
{
for (int i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy