package xapi.source.impl; import xapi.collect.api.Fifo; import xapi.collect.impl.SimpleFifo; import xapi.except.NotYetImplemented; import xapi.source.X_Modifier; import xapi.source.api.IsAnnotation; import xapi.source.api.IsClass; import xapi.source.api.IsField; import xapi.source.api.IsGeneric; import xapi.source.api.IsMethod; import xapi.source.api.IsType; import xapi.source.service.SourceService; public class AbstractClass extends AbstractMember<AbstractClass> implements IsClass{ IsClass parentClass; private boolean isInterface; final Fifo<IsClass> interfaces; final Fifo<IsGeneric> generics; final Fifo<IsClass> exceptions; final Fifo<IsClass> innerClasses; final Fifo<IsMethod> methods; final Fifo<IsField> fields; IsMethod enclosing; IsMethod defaultValue; public AbstractClass(SourceService service, String pkg, String simple, int modifiers) { super(service, pkg, simple, modifiers); setPackage(pkg); innerClasses = new SimpleFifo<IsClass>(); methods = new SimpleFifo<IsMethod>(); fields = new SimpleFifo<IsField>(); interfaces = new SimpleFifo<IsClass>(); generics = new SimpleFifo<IsGeneric>(); exceptions = new SimpleFifo<IsClass>(); } @Override public boolean isPrimitive() { return "java.lang".equals(getPackage()) && Character.isLowerCase(getSimpleName().charAt(0)); } @Override public String getPackage() { return packageName; } @Override public String getSimpleName() { return simpleName; } @Override public String getEnclosedName() { return parentClass == null ? getSimpleName() : parentClass.getEnclosedName() + classSeparator() + getSimpleName(); } @Override public String getQualifiedName() { assert parentClass == null || parentClass.getPackage().equals(getPackage()) : "Packaging error: parent != child.\nParent: "+parentClass.getQualifiedName() +"\nChild: "+getPackage()+pathSeparator()+getEnclosedName(); return getPackage()+pathSeparator()+getEnclosedName(); } @Override protected char classSeparator() { return '.'; } private char pathSeparator() { return '.'; } @Override public Iterable<IsAnnotation> getAnnotations() { return annotations.forEach(); } @Override public Iterable<IsMethod> getDeclaredMethods() { return new DeclaredMemberFilter<IsMethod>(getMethods(), this); } @Override public Iterable<IsMethod> getMethods() { return methods.forEach(); } @Override public IsMethod getMethod(String name, IsType ... params) { throw new NotYetImplemented("getMethod in AbstractClass not yet implemented"); } @Override public IsMethod getMethod(String name, boolean checkErased, Class<?> ... params) { throw new NotYetImplemented("getMethod in AbstractClass not yet implemented"); } @Override public Iterable<IsField> getFields() { return fields.forEach(); } @Override public IsField getField(String name) { throw new NotYetImplemented("getField in AbstractClass not yet implemented"); } @Override public Iterable<IsGeneric> getGenerics() { return generics.forEach(); } @Override public IsGeneric getGeneric(String name) { throw new NotYetImplemented("getGeneric in AbstractClass not yet implemented"); } @Override public IsMethod getEnclosingMethod() { return enclosing; } @Override public Iterable<IsClass> getInnerClasses() { return innerClasses.forEach(); } @Override public Class<?> toClass(ClassLoader loader) throws ClassNotFoundException { return loader.loadClass(getQualifiedName()); } @Override public Iterable<IsClass> getInterfaces() { return interfaces.forEach(); } @Override public boolean hasInterface() { return !interfaces.isEmpty(); } @Override public boolean hasGenerics() { return !generics.isEmpty(); } protected AbstractClass setEnclosingClass(IsClass parentClass) { this.parentClass = parentClass; setEnclosingType(parentClass); return this; } protected AbstractClass setEnclosingMethod(IsMethod method) { this.enclosing = method; setEnclosingType(method); return this; } @Override protected AbstractClass setPackage(String pkg) { packageName = pkg; return this; } @Override protected AbstractClass setSimpleName(String simpleName) { this.simpleName = simpleName; return this; } @Override protected AbstractClass addAnnotations(Iterable<IsAnnotation> annos) { for (IsAnnotation anno : annos) annotations.give(anno); return this; } protected AbstractClass addMethod(IsMethod method) { this.methods.give(method); return this; } protected AbstractClass addMethods(Iterable<IsMethod> methods) { for (IsMethod method : methods) this.methods.give(method); return this; } protected AbstractClass setMethods(Iterable<IsMethod> methods) { this.methods.clear(); return addMethods(methods); } protected AbstractClass setFields(Iterable<IsField> fields) { this.fields.clear(); return addFields(fields); } protected AbstractClass addFields(Iterable<IsField> fields) { for (IsField field : fields) this.fields.give(field); return this; } protected AbstractClass addField(IsField field) { this.fields.give(field); return this; } protected AbstractClass setGenerics(Iterable<IsGeneric> generics) { this.generics.clear(); addGenerics(generics); return this; } protected AbstractClass addGenerics(Iterable<IsGeneric> generics) { for (IsGeneric generic : generics) { this.generics.give(generic); } return this; } protected AbstractClass addInnerClasses(Iterable<IsClass> clses) { for (IsClass cls : clses) { innerClasses.give(cls); } return this; } protected AbstractClass setInnerClasses(Iterable<IsClass> clses) { this.innerClasses.clear(); return addInnerClasses(clses); } protected AbstractClass addInterface(IsClass iface) { interfaces.give(iface); return this; } protected AbstractClass addInterfaces(Iterable<IsClass> ifaces) { for (IsClass iface : ifaces) interfaces.give(iface); return this; } protected AbstractClass setInterfaces(Iterable<IsClass> ifaces) { this.interfaces.clear(); return addInterfaces(ifaces); } @Override public String toSignature() { return X_Modifier.classModifiers(getModifier()) + (hasInterface() ? " interface " : " class ") + (hasGenerics() ? "<"+ generics.join(", ") + ">" : "") + (parentClass == null ? ( // no superclass, maybe print interface extends hasInterface() ? "\nextends " + interfaces.join(", ") : "" ) : // we have a superclass "\nextends "+parentClass.getEnclosedName() + (// do we have interfaces? hasInterface() ? "\nimplements "+interfaces.join(", ") : "" ) ) // end parentClass == null ? ; } @Override public boolean isInterface() { return isInterface; } @Override public boolean isAnnotation() { return hasModifier(X_Modifier.ANNOTATION); } @Override public boolean isEnum() { return hasModifier(X_Modifier.ENUM); } protected AbstractClass makeInterface(boolean add) { isInterface = add; return this; } public boolean isArray() { return getSimpleName().contains("[]"); }; }