com.thoughtworks.qdox.model.JavaClass Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.servicemix.bundles.qdox
Show all versions of org.apache.servicemix.bundles.qdox
This OSGi bundle wraps ${pkgArtifactId} ${pkgVersion} jar file.
The newest version!
package com.thoughtworks.qdox.model;
import com.thoughtworks.qdox.model.util.OrderedMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Joe Walnes
* @author Aslak Hellesøy
*/
public class JavaClass extends AbstractInheritableJavaEntity implements JavaClassParent {
private static Type OBJECT = new Type("java.lang.Object");
private List methods = new LinkedList();
private JavaMethod[] methodsArray;
private List fields = new LinkedList();
private JavaField[] fieldsArray;
private List classes = new LinkedList();
private JavaClass[] classesArray;
private boolean interfce;
// Don't access this directly. Use asType() to get my Type
private Type type;
private Type superClass;
private Type[] implementz = new Type[0];
private JavaClassCache javaClassCache;
public JavaClass() {
}
public JavaClass(String name) {
setName(name);
}
public void setJavaClassCache(JavaClassCache javaClassCache) {
this.javaClassCache = javaClassCache;
// reassign OBJECT. This will make it have a "source" too,
// causing Type.getJavaClass() to return a JavaClass, instead
// of null.
OBJECT = javaClassCache.getClassByName("java.lang.Object").asType();
}
/**
* Interface or class?
*/
public boolean isInterface() {
return interfce;
}
public Type getSuperClass() {
boolean iAmJavaLangObject = OBJECT.equals(asType());
if (!interfce && (superClass == null) && !iAmJavaLangObject) {
return OBJECT;
}
return superClass;
}
/**
* Shorthand for getSuperClass().getJavaClass() with null checking.
*/
public JavaClass getSuperJavaClass() {
if (getSuperClass() != null) {
return getSuperClass().getJavaClass();
} else {
return null;
}
}
public Type[] getImplements() {
return implementz;
}
/**
* @since 1.3
*/
public JavaClass[] getImplementedInterfaces() {
Type[] type = getImplements();
JavaClass[] result = new JavaClass[type.length];
for (int i = 0; i < result.length; i++) {
result[i] = type[i].getJavaClass();
}
return result;
}
protected void writeBody(IndentBuffer result) {
writeAccessibilityModifier(result);
writeNonAccessibilityModifiers(result);
result.write(interfce ? "interface " : "class ");
result.write(name);
// subclass
if (superClass != null) {
result.write(" extends ");
result.write(superClass.getValue());
}
// implements
if (implementz.length > 0) {
result.write(interfce ? " extends " : " implements ");
for (int i = 0; i < implementz.length; i++) {
if (i > 0) {
result.write(", ");
}
result.write(implementz[i].getValue());
}
}
result.write(" {");
result.newline();
result.indent();
// fields
for (Iterator iterator = fields.iterator(); iterator.hasNext();) {
JavaField javaField = (JavaField) iterator.next();
result.newline();
javaField.write(result);
}
// methods
for (Iterator iterator = methods.iterator(); iterator.hasNext();) {
JavaMethod javaMethod = (JavaMethod) iterator.next();
result.newline();
javaMethod.write(result);
}
// inner-classes
for (Iterator iterator = classes.iterator(); iterator.hasNext();) {
JavaClass javaClass = (JavaClass) iterator.next();
result.newline();
javaClass.write(result);
}
result.deindent();
result.newline();
result.write('}');
result.newline();
}
public void setInterface(boolean interfce) {
this.interfce = interfce;
}
public void addMethod(JavaMethod meth) {
meth.setParent(this);
methods.add(meth);
methodsArray = null;
}
public void setSuperClass(Type type) {
superClass = type;
}
public void setImplementz(Type[] implementz) {
this.implementz = implementz;
}
public void addField(JavaField javaField) {
javaField.setParent(this);
fields.add(javaField);
fieldsArray = null;
}
public JavaSource getParentSource() {
JavaClassParent parent = getParent();
return ((parent == null) ? null : parent.getParentSource());
}
public String getPackage() {
return getParentSource().getPackage();
}
public String getFullyQualifiedName() {
return getParent().getClassNamePrefix() + getName();
}
/**
* @since 1.3
*/
public boolean isInner() {
return getParent() instanceof JavaClass;
}
public String resolveType(String typeName) {
// Maybe it's an inner class?
JavaClass[] innerClasses = getNestedClasses();
for (int i = 0; i < innerClasses.length; i++) {
if (innerClasses[i].getName().equals(typeName)) {
return innerClasses[i].getFullyQualifiedName();
}
}
return getParent().resolveType(typeName);
}
public ClassLibrary getClassLibrary() {
return getParent().getClassLibrary();
}
public String getClassNamePrefix() {
return getFullyQualifiedName() + "$";
}
public Type asType() {
if (type == null) {
type = new Type(getFullyQualifiedName(), 0, this);
}
return type;
}
public JavaMethod[] getMethods() {
if (methodsArray == null) {
methodsArray = new JavaMethod[methods.size()];
methods.toArray(methodsArray);
}
return methodsArray;
}
/**
* @since 1.3
*/
public JavaMethod[] getMethods(boolean superclasses) {
if (superclasses) {
Set signatures = new HashSet();
List methods = new ArrayList();
addMethodsFromSuperclassAndInterfaces(signatures, methods, this);
return (JavaMethod[]) methods.toArray(new JavaMethod[methods.size()]);
} else {
return getMethods();
}
}
private void addMethodsFromSuperclassAndInterfaces(Set signatures,
List methodList, JavaClass clazz) {
JavaMethod[] methods = clazz.getMethods();
addNewMethods(signatures, methodList, methods);
JavaClass superclass = clazz.getSuperJavaClass();
// TODO workaround for a bug in getSuperJavaClass
if ((superclass != null) && (superclass != clazz)) {
addMethodsFromSuperclassAndInterfaces(signatures, methodList,
superclass);
}
JavaClass[] implementz = clazz.getImplementedInterfaces();
for (int i = 0; i < implementz.length; i++) {
if (implementz[i] != null) {
addMethodsFromSuperclassAndInterfaces(signatures, methodList,
implementz[i]);
}
}
}
private void addNewMethods(Set signatures, List methodList,
JavaMethod[] methods) {
for (int i = 0; i < methods.length; i++) {
JavaMethod method = methods[i];
if (!method.isPrivate()) {
String signature = method.getDeclarationSignature(false);
if (!signatures.contains(signature)) {
methodList.add(method);
signatures.add(signature);
}
}
}
}
/**
* @param name method name
* @param parameterTypes parameter types or null if there are no parameters.
* @return the matching method or null if no match is found.
*/
public JavaMethod getMethodBySignature(String name, Type[] parameterTypes) {
JavaMethod[] methods = getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].signatureMatches(name, parameterTypes)) {
return methods[i];
}
}
return null;
}
public JavaMethod getMethodBySignature(String name, Type[] parameterTypes,
boolean superclasses) {
JavaMethod[] result = getMethodsBySignature(name, parameterTypes,
superclasses);
return (result.length > 0) ? result[0] : null;
}
public JavaMethod[] getMethodsBySignature(String name,
Type[] parameterTypes, boolean superclasses) {
List result = new ArrayList();
JavaMethod methodInThisClass = getMethodBySignature(name, parameterTypes);
if (methodInThisClass != null) {
result.add(methodInThisClass);
}
if (superclasses) {
JavaClass superclass = getSuperJavaClass();
if (superclass != null) {
JavaMethod method = superclass.getMethodBySignature(name,
parameterTypes, true);
// todo: ideally we should check on package privacy too. oh well.
if ((method != null) && !method.isPrivate()) {
result.add(method);
}
}
JavaClass[] implementz = getImplementedInterfaces();
for (int i = 0; i < implementz.length; i++) {
JavaMethod method = implementz[i].getMethodBySignature(name,
parameterTypes, true);
if (method != null) {
result.add(method);
}
}
}
return (JavaMethod[]) result.toArray(new JavaMethod[result.size()]);
}
public JavaField[] getFields() {
if (fieldsArray == null) {
fieldsArray = new JavaField[fields.size()];
fields.toArray(fieldsArray);
}
return fieldsArray;
}
public JavaField getFieldByName(String name) {
JavaField[] fields = getFields();
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equals(name)) {
return fields[i];
}
}
return null;
}
public void addClass(JavaClass cls) {
cls.setParent(this);
classes.add(cls);
classesArray = null;
}
/**
* @deprecated Use {@link #getNestedClasses()} instead.
*/
public JavaClass[] getClasses() {
return getNestedClasses();
}
/**
* @since 1.3
*/
public JavaClass[] getNestedClasses() {
if (classesArray == null) {
classesArray = new JavaClass[classes.size()];
classes.toArray(classesArray);
}
return classesArray;
}
public JavaClass getNestedClassByName(String name) {
JavaClass[] classes = getNestedClasses();
for (int i = 0; i < classes.length; i++) {
if (classes[i].getName().equals(name)) {
return classes[i];
}
}
return null;
}
/**
* @deprecated old name for {@link #getNestedClasses()}
*/
public JavaClass[] getInnerClasses() {
return getNestedClasses();
}
/**
* @deprecated old name for {@link #getNestedClassByName(String)}
*/
public JavaClass getInnerClassByName(String name) {
return getNestedClassByName(name);
}
/**
* @since 1.3
*/
public boolean isA(String fullClassName) {
Type type = new Type(fullClassName, 0, this);
return asType().isA(type);
}
/**
* @since 1.3
*/
public boolean isA(JavaClass javaClass) {
return asType().isA(javaClass.asType());
}
/**
* Gets bean properties without looking in superclasses or interfaces.
*
* @since 1.3
*/
public BeanProperty[] getBeanProperties() {
return getBeanProperties(false);
}
/**
* @since 1.3
*/
public BeanProperty[] getBeanProperties(boolean superclasses) {
Map beanPropertyMap = getBeanPropertyMap(superclasses);
Collection beanPropertyCollection = beanPropertyMap.values();
return (BeanProperty[]) beanPropertyCollection.toArray(new BeanProperty[beanPropertyCollection
.size()]);
}
private Map getBeanPropertyMap(boolean superclasses) {
JavaMethod[] methods = getMethods(superclasses);
Map beanPropertyMap = new OrderedMap();
// loop over the methods.
for (int i = 0; i < methods.length; i++) {
JavaMethod method = methods[i];
if (method.isPropertyAccessor()) {
String propertyName = method.getPropertyName();
BeanProperty beanProperty = getOrCreateProperty(beanPropertyMap,
propertyName);
beanProperty.setAccessor(method);
beanProperty.setType(method.getPropertyType());
} else if (method.isPropertyMutator()) {
String propertyName = method.getPropertyName();
BeanProperty beanProperty = getOrCreateProperty(beanPropertyMap,
propertyName);
beanProperty.setMutator(method);
beanProperty.setType(method.getPropertyType());
}
}
return beanPropertyMap;
}
private BeanProperty getOrCreateProperty(Map beanPropertyMap,
String propertyName) {
BeanProperty result = (BeanProperty) beanPropertyMap.get(propertyName);
if (result == null) {
result = new BeanProperty(propertyName);
beanPropertyMap.put(propertyName, result);
}
return result;
}
/**
* Gets bean property without looking in superclasses or interfaces.
*
* @since 1.3
*/
public BeanProperty getBeanProperty(String propertyName) {
return getBeanProperty(propertyName, false);
}
/**
* @since 1.3
*/
public BeanProperty getBeanProperty(String propertyName,
boolean superclasses) {
return (BeanProperty) getBeanPropertyMap(superclasses).get(propertyName);
}
/**
* Gets the known derived classes. That is, subclasses or implementing classes.
*
* @return
*/
public JavaClass[] getDerivedClasses() {
List result = new ArrayList();
JavaClass[] classes = javaClassCache.getClasses();
for (int i = 0; i < classes.length; i++) {
JavaClass clazz = classes[i];
if (clazz.isA(this) && !(clazz == this)) {
result.add(clazz);
}
}
return (JavaClass[]) result.toArray(new JavaClass[result.size()]);
}
public DocletTag[] getTagsByName(String name, boolean superclasses) {
List result = new ArrayList();
addTagsRecursive(result, this, name, superclasses);
return (DocletTag[]) result.toArray(new DocletTag[result.size()]);
}
private void addTagsRecursive(List result, JavaClass javaClass,
String name, boolean superclasses) {
DocletTag[] tags = javaClass.getTagsByName(name);
addNewTags(result, tags);
if (superclasses) {
JavaClass superclass = javaClass.getSuperJavaClass();
// THIS IS A HACK AROUND A BUG THAT MUST BE SOLVED!!!
// SOMETIMES A CLASS RETURNS ITSELF AS SUPER ?!?!?!?!?!
if ((superclass != null) && (superclass != javaClass)) {
addTagsRecursive(result, superclass, name, superclasses);
}
JavaClass[] implementz = javaClass.getImplementedInterfaces();
for (int h = 0; h < implementz.length; h++) {
if (implementz[h] != null) {
addTagsRecursive(result, implementz[h], name, superclasses);
}
}
}
}
private void addNewTags(List list, DocletTag[] tags) {
for (int i = 0; i < tags.length; i++) {
DocletTag superTag = tags[i];
if (!list.contains(superTag)) {
list.add(superTag);
}
}
}
public int compareTo(Object o) {
return getFullyQualifiedName().compareTo(((JavaClass) o).getFullyQualifiedName());
}
}