Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**********************************************************************
Copyright (c) 2002 Kelly Grizzle (TJDO) 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:
2003 Erik Bengtson - removed subclasses operation
2003 Andy Jefferson - comments, and update to returned class name
2003 Erik Bengtson - added getObjectByAid
2004 Erik Bengtson - throws an JDOObjectNotFoundException
2004 Erik Bengtson - removed unused variable and import
2004 Erik Bengtson - added support for ignoreCache
2004 Andy Jefferson - coding standards
2005 Andy Jefferson - added support for using discriminator to distinguish objects
...
**********************************************************************/
package org.datanucleus.store.rdbms.query;
import java.lang.reflect.Modifier;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.ExecutionContext;
import org.datanucleus.FetchPlan;
import org.datanucleus.FetchPlanForClass;
import org.datanucleus.exceptions.NucleusException;
import org.datanucleus.exceptions.NucleusUserException;
import org.datanucleus.identity.IdentityUtils;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.metadata.AbstractMemberMetaData;
import org.datanucleus.metadata.DiscriminatorMetaData;
import org.datanucleus.metadata.IdentityType;
import org.datanucleus.metadata.InterfaceMetaData;
import org.datanucleus.metadata.RelationType;
import org.datanucleus.metadata.VersionMetaData;
import org.datanucleus.state.DNStateManager;
import org.datanucleus.store.FieldValues;
import org.datanucleus.store.StoreManager;
import org.datanucleus.store.rdbms.RDBMSStoreManager;
import org.datanucleus.store.rdbms.discriminator.DiscriminatorClassNameResolver;
import org.datanucleus.store.rdbms.discriminator.DiscriminatorDefiner;
import org.datanucleus.store.rdbms.fieldmanager.ResultSetGetter;
import org.datanucleus.store.rdbms.mapping.MappingHelper;
import org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping;
import org.datanucleus.store.rdbms.mapping.java.PersistableMapping;
import org.datanucleus.store.schema.table.SurrogateColumnType;
import org.datanucleus.util.ConcurrentReferenceHashMap;
import org.datanucleus.util.Localiser;
import org.datanucleus.util.NucleusLogger;
import org.datanucleus.util.StringUtils;
import org.datanucleus.util.ConcurrentReferenceHashMap.ReferenceType;
/**
* Result-object factory that takes a JDBC ResultSet, a results mapping, and creates a persistable object instance for each row in the ResultSet.
* We use information in the result set to determine the object type; this can be a discriminator column, or can be a special "NucleusType" column defined just for result processing.
* @param Type of the persistent object that this creates
*/
public final class PersistentClassROF extends AbstractROF
{
/** Metadata for the (root) persistable candidate class. */
protected final AbstractClassMetaData rootCmd;
/** Persistent class that this factory will generate (may be the root class). */
protected Class persistentClass;
/** Mapping of the results to members of this class (and sub-objects). */
protected StatementClassMapping resultMapping = null;
protected ResultSetGetter resultSetGetter = null;
protected StatementClassMapping mappingDefinition;
protected int[] mappedFieldNumbers;
/** Resolved classes for metadata / discriminator keyed by class names. */
private Map resolvedClasses = new ConcurrentReferenceHashMap<>(1, ReferenceType.STRONG, ReferenceType.SOFT);
private final DiscriminatorClassNameResolver discriminatorClassNameResolver;
/**
* Constructor.
* @param ec ExecutionContext
* @param rs ResultSet being processed
* @param fp FetchPlan
* @param resultMapping Mapping information for the result set and how it maps to the class
* @param acmd MetaData for the (root) candidate class
* @param persistentClass Class that this factory will create instances of (or subclasses)
*/
public PersistentClassROF(ExecutionContext ec, ResultSet rs, FetchPlan fp, StatementClassMapping resultMapping, AbstractClassMetaData acmd, Class persistentClass)
{
super(ec, rs, fp);
this.resultMapping = resultMapping;
this.rootCmd = acmd;
this.persistentClass = persistentClass;
final StoreManager storeManager = ec.getStoreManager();
if (acmd.getDiscriminatorMetaData() != null)
{
final DiscriminatorDefiner discriminatorDefiner = ((RDBMSStoreManager) storeManager).getDiscriminatorDefiner(acmd.getBaseAbstractClassMetaData(), ec.getClassLoaderResolver());
this.discriminatorClassNameResolver = discriminatorDefiner != null ?
discriminatorDefiner.getDiscriminatorClassNameResolver(ec, resultMapping) : null;
}
else
{
this.discriminatorClassNameResolver = null;
}
}
/* (non-Javadoc)
* @see org.datanucleus.store.rdbms.query.ResultObjectFactory#getResultSet()
*/
@Override
public ResultSet getResultSet()
{
return rs;
}
/**
* Method to convert the current ResultSet row into a persistable Object.
* @return The persistable object.
*/
public T getObject()
{
// Find the class of the returned object in this row of the ResultSet
String className = null;
boolean requiresInheritanceCheck = true;
String discrimValue = null;
// Used for reporting details of a failed class lookup by discriminator
boolean hasDiscrimValue = false;
boolean foundClassByDiscrim = false;
StatementMappingIndex discrimMapIdx = resultMapping.getMappingForMemberPosition(SurrogateColumnType.DISCRIMINATOR.getFieldNumber());
if (discriminatorClassNameResolver != null)
{
className = discriminatorClassNameResolver.getClassName(rs);
if (className != null)
{
foundClassByDiscrim = true;
requiresInheritanceCheck = false;
}
}
if (className == null && discrimMapIdx != null)
{
// Discriminator mapping registered so use that
try
{
discrimValue = rs.getString(discrimMapIdx.getColumnPositions()[0]);
if (discrimValue == null)
{
// Discriminator has no value so return null object
NucleusLogger.DATASTORE_RETRIEVE.debug("Value of discriminator is null so assuming object is null");
return null;
}
hasDiscrimValue = true;
JavaTypeMapping discrimMapping = discrimMapIdx.getMapping();
DiscriminatorMetaData dismd = (discrimMapping != null ? discrimMapping.getTable().getDiscriminatorMetaData() : null);
className = ec.getMetaDataManager().getClassNameFromDiscriminatorValue(discrimValue, dismd);
if (className != null)
{
foundClassByDiscrim = true;
}
requiresInheritanceCheck = false;
}
catch (SQLException sqle)
{
NucleusLogger.DATASTORE_RETRIEVE.debug("Exception obtaining value of discriminator : " + sqle.getMessage());
}
}
else if (className == null && resultMapping.getNucleusTypeColumnName() != null)
{
// Extract the object type using the NucleusType column (if available)
try
{
className = rs.getString(resultMapping.getNucleusTypeColumnName());
if (className == null)
{
// Discriminator has no value so return null object
NucleusLogger.DATASTORE_RETRIEVE.debug("Value of determiner column is null so assuming object is null");
return null;
}
className = className.trim();
requiresInheritanceCheck = false;
}
catch (SQLException sqle)
{
// NucleusType column not found so ignore
}
}
ClassLoaderResolver clr = ec.getClassLoaderResolver();
Class pcClassForObject = persistentClass;
if (className != null)
{
Class cls = resolvedClasses.get(className);
if (cls != null)
{
pcClassForObject = cls;
}
else
{
if (persistentClass.getName().equals(className))
{
pcClassForObject = persistentClass;
}
else
{
pcClassForObject = clr.classForName(className, persistentClass.getClassLoader());
}
resolvedClasses.put(className, pcClassForObject);
}
}
if (requiresInheritanceCheck)
{
// Check if no instantiable subclasses
String[] subclasses = ec.getMetaDataManager().getSubclassesForClass(pcClassForObject.getName(), false);
if (subclasses == null || subclasses.length == 0)
{
requiresInheritanceCheck = false;
}
}
String warnMsg = null;
if (Modifier.isAbstract(pcClassForObject.getModifiers()))
{
// Persistent class is abstract so we can't create instances of that type!
// This can happen if the user is using subclass-table and hasn't provided a discriminator in the table.
// Try going out one level and find a (single) concrete subclass. TODO make this more robust and go out further
String[] subclasses = ec.getMetaDataManager().getSubclassesForClass(pcClassForObject.getName(), false);
if (subclasses != null)
{
Class concreteSubclass = null;
int numConcreteSubclasses = 0;
for (int i=0;i memberNumbersToStoreTmp = new ArrayList<>();
for (int i=0;i 0)
{
int[] memberNumberTmp = new int[mappedFieldNumbers.length - memberNumbersToStoreTmp.size()];
int j = 0;
for (int i=0;i pcClass, final AbstractClassMetaData cmd,
final Object surrogateVersion)
{
return (T) ec.findObject(id, new FieldValues()
{
public void fetchFields(DNStateManager sm)
{
resultSetGetter.setStateManager(sm);
sm.replaceFields(membersToLoad, resultSetGetter, false);
// Set version
if (surrogateVersion != null)
{
// Surrogate version field
sm.setVersion(surrogateVersion);
}
else if (cmd.getVersionMetaData() != null && cmd.getVersionMetaData().getMemberName() != null)
{
// Version stored in a normal field
VersionMetaData vermd = cmd.getVersionMetaData();
int versionFieldNumber = rootCmd.getMetaDataForMember(vermd.getMemberName()).getAbsoluteFieldNumber();
if (resultMapping.getMappingForMemberPosition(versionFieldNumber) != null)
{
Object verFieldValue = sm.provideField(versionFieldNumber);
if (verFieldValue != null)
{
sm.setVersion(verFieldValue);
}
}
}
if (membersToStore != null)
{
for (int i=0;i