TransformerFactorypublic class TransformerFactory extends Object INTERNAL:
This class creates a ClassFileTransformer that is used for dynamic bytecode
weaving. It is called by {@link oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl#predeploy}
Note: The Session's Project is is scanned to ensure that weaving is
supported and is modified to suit (set the {@link ObjectChangePolicy}
for the Descriptor).
|
Fields Summary |
---|
public static final String | WEAVER_NULL_PROJECT | public static final String | WEAVER_DISABLE_BY_SYSPROP | public static final String | WEAVER_ADDING_EMBEDDABLE | public static final String | WEAVER_FOUND_FIELD_LOCK | public static final String | WEAVER_CLASS_NOT_IN_PROJECT | public static final String | WEAVER_PROCESSING_CLASS | protected Session | session | protected Collection | entityClasses | protected List | embeddableClasses | protected Map | classDetailsMap | protected ClassLoader | classLoader |
Constructors Summary |
---|
public TransformerFactory(Session session, Collection entityClasses, ClassLoader classLoader)
this.session = session;
this.entityClasses = entityClasses;
this.classLoader = classLoader;
embeddableClasses = new ArrayList();
classDetailsMap = new HashMap();
|
Methods Summary |
---|
public void | addClassDetailsForMappedSuperClasses(java.lang.Class clz, oracle.toplink.essentials.descriptors.ClassDescriptor initialDescriptor, oracle.toplink.essentials.internal.weaving.ClassDetails classDetails, java.util.Map classDetailsMap, java.util.List unMappedAttributes)INTERNAL:
Look higher in the hierarchy for the mappings listed in the unMappedAttribute list.
We assume that if a mapping exists, the attribute must either be mapped from the owninig
class or from a superclass.
// This class has inheritance to a mapped entity rather than a MappedSuperClass
if (initialDescriptor.getInheritancePolicyOrNull() != null && initialDescriptor.getInheritancePolicyOrNull().getParentClass() != null){
return;
}
if (unMappedAttributes.isEmpty()){
return;
}
Class superClz = clz.getSuperclass();
if (superClz == null || superClz == java.lang.Object.class){
return;
}
boolean weaveValueHolders = canWeaveValueHolders(superClz, unMappedAttributes);
List stillUnMappedMappings = null;
ClassDetails superClassDetails = createClassDetails(superClz, weaveValueHolders);
superClassDetails.setIsMappedSuperClass(true);
if (!classDetailsMap.containsKey(superClassDetails.getClassName())){
stillUnMappedMappings = storeAttributeMappings(superClz, superClassDetails, unMappedAttributes, weaveValueHolders);
classDetailsMap.put(superClassDetails.getClassName() ,superClassDetails);
}
if (stillUnMappedMappings != null && !stillUnMappedMappings.isEmpty()){
addClassDetailsForMappedSuperClasses(superClz, initialDescriptor, classDetails, classDetailsMap, stillUnMappedMappings);
}
| public void | buildClassDetailsAndModifyProject()Build a list ClassDetails instance that contains a ClassDetails for each class
in our entities list.
if (entityClasses != null && entityClasses.size() > 0) {
// scan thru list building details of persistent classes
// do @Entity's next
for (Iterator i = entityClasses.iterator(); i.hasNext();) {
Class clz = (Class)i.next();
// check to ensure that class is present in project
ClassDescriptor descriptor = findDescriptor(session.getProject(), clz.getName());
if (descriptor == null) {
log(SessionLog.FINER, WEAVER_CLASS_NOT_IN_PROJECT,
new Object[]{clz.getName()});
} else {
log(SessionLog.FINER, WEAVER_PROCESSING_CLASS,
new Object[]{clz.getName()});
boolean weaveValueHolders = canWeaveValueHolders(clz, descriptor.getMappings());
if (weaveValueHolders) {
ClassDetails classDetails = createClassDetails(clz, weaveValueHolders);
List unMappedAttributes = storeAttributeMappings(clz, classDetails, descriptor.getMappings(), weaveValueHolders);
classDetailsMap.put(classDetails.getClassName() ,classDetails);
if (!unMappedAttributes.isEmpty()){
addClassDetailsForMappedSuperClasses(clz, descriptor, classDetails, classDetailsMap, unMappedAttributes);
}
if (classDetails.getLazyOneToOneMappings() != null){
Iterator iterator = classDetails.getLazyOneToOneMappings().iterator();
while(iterator.hasNext()){
OneToOneMapping mapping = (OneToOneMapping)iterator.next();
mapping.setGetMethodName("_toplink_get" + mapping.getAttributeName() + "_vh");
mapping.setSetMethodName("_toplink_set" + mapping.getAttributeName() + "_vh");
}
}
}
}
}
// hookup superClassDetails
for (Iterator i = classDetailsMap.values().iterator(); i.hasNext();) {
ClassDetails classDetails = (ClassDetails)i.next();
ClassDetails superClassDetails =
(ClassDetails)classDetailsMap.get(
classDetails.getSuperClassName());
if (superClassDetails != null) {
classDetails.setSuperClassDetails(superClassDetails);
}
}
// combine lists: add entities to end of embeddables,
// then clear entities and re-populate from embeddables.
embeddableClasses.addAll(entityClasses);
entityClasses.clear();
entityClasses.addAll(embeddableClasses);
}
| public javax.persistence.spi.ClassTransformer | buildTopLinkWeaver()
return new TopLinkWeaver(session, classDetailsMap);
| protected boolean | canWeaveValueHolders(java.lang.Class clz, java.util.List mappings)
// we intend to change to fetch=LAZY 1:1 attributes to ValueHolders
boolean weaveValueHolders = true;
boolean foundOTOM = false;
for (Iterator j = mappings.iterator(); j.hasNext();) {
DatabaseMapping dm = (DatabaseMapping)j.next();
String attributeName = dm.getAttributeName();
if (dm.isOneToOneMapping()) {
OneToOneMapping otom = (OneToOneMapping)dm;
Class typeClz = getAttributeTypeFromClass(clz, attributeName, dm, true);
if (otom.getIndirectionPolicy().usesIndirection() &&
typeClz != null && !typeClz.isAssignableFrom(
ValueHolderInterface.class)) {
foundOTOM = true;
weaveValueHolders = true;
}
}
}
// did we actually <b>find</b> any attributes to change?
return weaveValueHolders & foundOTOM;
| private oracle.toplink.essentials.internal.weaving.ClassDetails | createClassDetails(java.lang.Class clz, boolean weaveValueHolders)
// compose className in JVM 'slash' format
// instead of regular Java 'dotted' format
String className = clz.getName().replace('.",'/");
String superClassName = clz.getSuperclass().getName().replace('.",'/");
ClassDetails classDetails = new ClassDetails();
classDetails.setClassName(className);
classDetails.setSuperClassName(superClassName);
classDetails.weaveValueHolders(weaveValueHolders);
return classDetails;
| public static javax.persistence.spi.ClassTransformer | createTransformerAndModifyProject(oracle.toplink.essentials.sessions.Session session, java.util.Collection entityClasses, java.lang.ClassLoader classLoader)
if (session == null) {
throw new IllegalArgumentException("Weaver session cannot be null");
}
if (session.getProject() == null) {
((oracle.toplink.essentials.internal.sessions.AbstractSession)session).log(
SessionLog.SEVERE, SessionLog.WEAVER, WEAVER_NULL_PROJECT, null);
throw new IllegalArgumentException("Weaver session's project cannot be null");
}
TransformerFactory tf = new TransformerFactory(session, entityClasses, classLoader);
tf.buildClassDetailsAndModifyProject();
return tf.buildTopLinkWeaver();
| protected oracle.toplink.essentials.descriptors.ClassDescriptor | findDescriptor(oracle.toplink.essentials.sessions.Project project, java.lang.String className)Find a descriptor by name in the given project
used to avoid referring to descriptors by class.
This avoids having to construct a project by class facilitating weaving
Iterator iterator = project.getOrderedDescriptors().iterator();
while (iterator.hasNext()){
ClassDescriptor descriptor = (ClassDescriptor)iterator.next();
if (descriptor.getJavaClassName().equals(className)){
return descriptor;
}
}
return null;
| private java.lang.Class | getAttributeTypeFromClass(java.lang.Class clz, java.lang.String attributeName, oracle.toplink.essentials.mappings.DatabaseMapping mapping, boolean checkSuperclass)Use the database mapping for an attribute to find it's type. The type returned will either be
the field type of the field in the object or the type returned by the getter method.
String getterMethod = mapping.getGetMethodName();
if (mapping != null && getterMethod != null){
try{
Method method = null;
if (checkSuperclass){
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
method = (Method)AccessController.doPrivileged(new PrivilegedGetMethod(clz, getterMethod, null, false));
} catch (PrivilegedActionException exception) {
}
} else {
method = PrivilegedAccessHelper.getMethod(clz, getterMethod, null, false);
}
} else {
method = null;
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
method = (Method)AccessController.doPrivileged(new PrivilegedGetDeclaredMethod(clz, getterMethod, null));
} catch (PrivilegedActionException exception) {
}
} else {
method = PrivilegedAccessHelper.getDeclaredMethod(clz, getterMethod, null);
}
}
if (method != null){
return method.getReturnType();
}
} catch (Exception e) { }
} else {
try {
Class typeClz = null;
if (checkSuperclass){
Field field = null;
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
field = (Field)AccessController.doPrivileged(new PrivilegedGetField(clz, attributeName, false));
} catch (PrivilegedActionException exception) {
}
} else {
field = PrivilegedAccessHelper.getField(clz, attributeName, false);
}
typeClz = field.getType();
} else {
Field field = null;
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
field = (Field)AccessController.doPrivileged(new PrivilegedGetDeclaredField(clz, attributeName, false));
} catch (PrivilegedActionException exception) {
}
} else {
field = PrivilegedAccessHelper.getDeclaredField(clz, attributeName, false);
}
typeClz = field.getType();
}
if (typeClz != null){
return typeClz;
}
} catch (Exception e) { }
}
return null;
| protected static boolean | hasField(java.lang.Class clz, java.lang.String fieldName)
if ("java.lang.Object".equals(clz.getName())) {
return false;
}
else {
boolean hasField = false;
// check to see if the mapping's attribute exists as a field on the
// class; failing that, recurse up super-class(es).
try {
Field f = null;
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
f = (Field)AccessController.doPrivileged(new PrivilegedGetDeclaredField(clz, fieldName, false));
} catch (PrivilegedActionException exception) {
}
} else {
f = PrivilegedAccessHelper.getDeclaredField(clz, fieldName, false);
}
hasField = true;
}
catch (Exception e) { /* ignore */ }
return hasField ? hasField : hasField(clz.getSuperclass(), fieldName);
}
| protected void | log(int level, java.lang.String msg, java.lang.Object[] params)
((oracle.toplink.essentials.internal.sessions.AbstractSession)session).log(level,
SessionLog.WEAVER, msg, params);
| protected java.util.List | storeAttributeMappings(java.lang.Class clz, oracle.toplink.essentials.internal.weaving.ClassDetails classDetails, java.util.List mappings, boolean weaveValueHolders)INTERNAL:
Store a set of attribute mappings on the given ClassDetails taht correspont to the given class.
Return the list of mappings that is not specifically found on the given class. These attributes will
be found on MappedSuperclasses
List unMappedAttributes = new Vector();
Map attributesMap = new HashMap();
Map settersMap = new HashMap();
Map gettersMap = new HashMap();
List lazyMappings = new Vector();
for (Iterator j = mappings.iterator(); j.hasNext();) {
DatabaseMapping dm = (DatabaseMapping)j.next();
String attribute = dm.getAttributeName();
AttributeDetails attributeDetails = new AttributeDetails(attribute);
Class typeClz = getAttributeTypeFromClass(clz, attribute, dm, false);
if (typeClz == null){
attributeDetails.setAttributeOnSuperClass(true);
if (dm.isOneToOneMapping()){
unMappedAttributes.add(dm);
}
}
if (dm.isCollectionMapping()) {
attributeDetails.setCollectionMapping(true);
} else if (dm.isOneToOneMapping()) {
OneToOneMapping otom = (OneToOneMapping)dm;
attributeDetails.referenceClass = otom.getReferenceClassName();
attributeDetails.weaveVH(weaveValueHolders, otom);
if (otom.getGetMethodName() != null){
gettersMap.put(otom.getGetMethodName(), attributeDetails);
if (otom.getSetMethodName() != null){
settersMap.put(otom.getSetMethodName(), attributeDetails);
}
} else {
attributeDetails.setIsMappedWithAttributeAccess(true);
}
if (typeClz == null){
typeClz = getAttributeTypeFromClass(clz, attribute, dm, true);
}
if (weaveValueHolders && otom.getIndirectionPolicy().usesIndirection() &&
typeClz != null && !typeClz.isAssignableFrom(ValueHolderInterface.class)) {
lazyMappings.add(otom);
}
}
attributesMap.put(attribute, attributeDetails);
}
classDetails.setAttributesMap(attributesMap);
classDetails.setGetterMethodToAttributeDetails(gettersMap);
classDetails.setSetterMethodToAttributeDetails(settersMap);
classDetails.setLazyOneToOneMappings(lazyMappings);
return unMappedAttributes;
|
|