org.datanucleus.enhancer.asm.JdoClassChecker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datanucleus-enhancer
Show all versions of datanucleus-enhancer
DataNucleus Enhancer is a Java byte-code enhancer for use with DataNucleus.
/**********************************************************************
Copyright (c) 2007 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.enhancer.asm;
import java.util.HashSet;
import java.util.Iterator;
import org.datanucleus.enhancer.ClassEnhancer;
import org.datanucleus.enhancer.ClassField;
import org.datanucleus.enhancer.ClassMethod;
import org.datanucleus.enhancer.DataNucleusEnhancer;
import org.datanucleus.metadata.ClassPersistenceModifier;
import org.datanucleus.util.Localiser;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
/**
* Visitor used to check the enhancement state of a class.
* Checks the methods/fields present against what is required for JDO enhancement.
*/
public class JdoClassChecker implements ClassVisitor
{
/** Message resource */
protected static final Localiser LOCALISER=Localiser.getInstance("org.datanucleus.enhancer.Localisation",
ClassEnhancer.class.getClassLoader());
/** Enhancer for the class. */
protected ASMClassEnhancer enhancer;
/** Set of fields required to be present for JDO. */
protected HashSet fieldsRequired = new HashSet();
/** Set of methods required to be present for JDO. */
protected HashSet methodsRequired = new HashSet();
/** Flag for whether the class is enhanced. Set in the visit process. */
protected boolean enhanced = false;
/** Whether to log any errors at error level. */
protected boolean logErrors = true;
/**
* Constructor.
* @param enhancer The class enhancer
* @param logErrors Whether to log any errors at error level
*/
public JdoClassChecker(ASMClassEnhancer enhancer, boolean logErrors)
{
this.enhancer = enhancer;
this.logErrors = logErrors;
if (enhancer.getClassMetaData().getPersistenceModifier() == ClassPersistenceModifier.PERSISTENCE_CAPABLE)
{
fieldsRequired.addAll(enhancer.getFieldsList());
methodsRequired.addAll(enhancer.getMethodsList());
}
}
/**
* Accessor for whether the class is considered enhanced.
* Should only be run after passing this class to the reader as a visitor.
* @return Whether the class is enhanced.
*/
public boolean isEnhanced()
{
return enhanced;
}
/**
* Convenience method to report an error in the enhancement of this class.
* @param msg The message
*/
protected void reportError(String msg)
{
if (logErrors)
{
DataNucleusEnhancer.LOGGER.error(msg);
}
else
{
if (DataNucleusEnhancer.LOGGER.isDebugEnabled())
{
DataNucleusEnhancer.LOGGER.debug(msg);
}
}
enhanced = false;
}
/**
* Method to visit the header of the class
* @param version Version of the class file
* @param access Access type
* @param name name of the class
* @param signature signature of the class
* @param supername superclass name
* @param interfaces interface(s)
*/
public void visit(int version, int access, String name, String signature, String supername, String[] interfaces)
{
enhanced = true; // Default to true unless we find a problem
if (enhancer.getClassMetaData().getPersistenceModifier() == ClassPersistenceModifier.PERSISTENCE_CAPABLE)
{
if (interfaces == null)
{
enhanced = false;
return;
}
if (!hasInterface(interfaces, enhancer.getPersistableAsmClassName()))
{
reportError(LOCALISER.msg("Enhancer.Check.InterfaceMissing", enhancer.className,
"javax.jdo.spi.PersistenceCapable"));
}
if (enhancer.getClassMetaData().isDetachable())
{
if (!hasInterface(interfaces, enhancer.getDetachableAsmClassName()))
{
reportError(LOCALISER.msg("Enhancer.Check.InterfaceMissing", enhancer.className,
"javax.jdo.spi.Detachable"));
}
}
}
}
/**
* Convenience method to check if a particular interface is present in the list.
* @param interfaces The list of interfaces implemented
* @param intf The interface we are looking for
* @return Whether it is present
*/
protected boolean hasInterface(String[] interfaces, String intf)
{
if (interfaces == null || interfaces.length <= 0)
{
return false;
}
for (int i=0;i