d51f84
From 928bd5a98dc500a31197a56c8f6c5e19a3a273f8 Mon Sep 17 00:00:00 2001
d51f84
From: Mikolaj Izdebski <mizdebsk@redhat.com>
d51f84
Date: Fri, 21 Nov 2014 10:51:38 +0100
d51f84
Subject: [PATCH 3/3] Port to QDox 2.0
d51f84
d51f84
---
d51f84
 pom.xml                                            |   2 +-
d51f84
 .../blueprint/generator/QdoxMappingLoader.java     | 144 +++++++++++---------
d51f84
 .../xbean/spring/generator/QdoxMappingLoader.java  | 148 ++++++++++++---------
d51f84
 .../org/apache/xbean/spring/generator/Type.java    |   7 +-
d51f84
 4 files changed, 166 insertions(+), 135 deletions(-)
d51f84
d51f84
diff --git a/pom.xml b/pom.xml
d51f84
index 6e53649..9132fe4 100644
d51f84
--- a/pom.xml
d51f84
+++ b/pom.xml
d51f84
@@ -297,7 +297,7 @@
d51f84
             <dependency>
d51f84
                 <groupId>com.thoughtworks.qdox</groupId>
d51f84
                 <artifactId>qdox</artifactId>
d51f84
-                <version>1.6.3</version>
d51f84
+                <version>2.0-M5</version>
d51f84
             </dependency>
d51f84
             
d51f84
             <dependency>
d51f84
diff --git a/xbean-blueprint/src/main/java/org/apache/xbean/blueprint/generator/QdoxMappingLoader.java b/xbean-blueprint/src/main/java/org/apache/xbean/blueprint/generator/QdoxMappingLoader.java
d51f84
index 6635937..e17fd08 100644
d51f84
--- a/xbean-blueprint/src/main/java/org/apache/xbean/blueprint/generator/QdoxMappingLoader.java
d51f84
+++ b/xbean-blueprint/src/main/java/org/apache/xbean/blueprint/generator/QdoxMappingLoader.java
d51f84
@@ -20,6 +20,7 @@ import java.io.File;
d51f84
 import java.io.IOException;
d51f84
 import java.net.URL;
d51f84
 import java.util.ArrayList;
d51f84
+import java.util.Collection;
d51f84
 import java.util.Collections;
d51f84
 import java.util.Enumeration;
d51f84
 import java.util.HashMap;
d51f84
@@ -31,14 +32,17 @@ import java.util.TreeSet;
d51f84
 import java.util.jar.JarEntry;
d51f84
 import java.util.jar.JarFile;
d51f84
 
d51f84
-import com.thoughtworks.qdox.JavaDocBuilder;
d51f84
+import com.thoughtworks.qdox.JavaProjectBuilder;
d51f84
 import com.thoughtworks.qdox.model.BeanProperty;
d51f84
 import com.thoughtworks.qdox.model.DocletTag;
d51f84
 import com.thoughtworks.qdox.model.JavaClass;
d51f84
+import com.thoughtworks.qdox.model.JavaConstructor;
d51f84
 import com.thoughtworks.qdox.model.JavaMethod;
d51f84
+import com.thoughtworks.qdox.model.JavaModel;
d51f84
 import com.thoughtworks.qdox.model.JavaParameter;
d51f84
 import com.thoughtworks.qdox.model.JavaSource;
d51f84
-import com.thoughtworks.qdox.model.Type;
d51f84
+import com.thoughtworks.qdox.model.JavaType;
d51f84
+
d51f84
 import org.apache.commons.logging.Log;
d51f84
 import org.apache.commons.logging.LogFactory;
d51f84
 
d51f84
@@ -62,7 +66,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
     private final String defaultNamespace;
d51f84
     private final File[] srcDirs;
d51f84
     private final String[] excludedClasses;
d51f84
-    private Type collectionType;
d51f84
+    private JavaClass collectionType;
d51f84
 
d51f84
     public QdoxMappingLoader(String defaultNamespace, File[] srcDirs, String[] excludedClasses) {
d51f84
         this.defaultNamespace = defaultNamespace;
d51f84
@@ -79,7 +83,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
     }
d51f84
 
d51f84
     public Set<NamespaceMapping> loadNamespaces() throws IOException {
d51f84
-        JavaDocBuilder builder = new JavaDocBuilder();
d51f84
+        JavaProjectBuilder builder = new JavaProjectBuilder();
d51f84
 
d51f84
         log.debug("Source directories: ");
d51f84
 
d51f84
@@ -92,11 +96,11 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
             getSourceFiles(sourceDirectory, excludedClasses, builder);
d51f84
         }
d51f84
 
d51f84
-        collectionType = builder.getClassByName("java.util.Collection").asType();
d51f84
+        collectionType = builder.getClassByName("java.util.Collection");
d51f84
         return loadNamespaces(builder);
d51f84
     }
d51f84
 
d51f84
-    private Set<NamespaceMapping> loadNamespaces(JavaDocBuilder builder) {
d51f84
+    private Set<NamespaceMapping> loadNamespaces(JavaProjectBuilder builder) {
d51f84
         // load all of the elements
d51f84
         List<ElementMapping> elements = loadElements(builder);
d51f84
 
d51f84
@@ -131,14 +135,14 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return Collections.unmodifiableSet(namespaces);
d51f84
     }
d51f84
 
d51f84
-    private List<ElementMapping> loadElements(JavaDocBuilder builder) {
d51f84
-        JavaSource[] javaSources = builder.getSources();
d51f84
+    private List<ElementMapping> loadElements(JavaProjectBuilder builder) {
d51f84
+        Collection<JavaSource> javaSources = builder.getSources();
d51f84
         List<ElementMapping> elements = new ArrayList<ElementMapping>();
d51f84
         for (JavaSource javaSource : javaSources) {
d51f84
-            if (javaSource.getClasses().length == 0) {
d51f84
+            if (javaSource.getClasses().isEmpty()) {
d51f84
                 log.info("No Java Classes defined in: " + javaSource.getURL());
d51f84
             } else {
d51f84
-                JavaClass[] classes = javaSource.getClasses();
d51f84
+                Collection<JavaClass> classes = javaSource.getClasses();
d51f84
                 for (JavaClass javaClass : classes) {
d51f84
                     ElementMapping element = loadElement(builder, javaClass);
d51f84
                     if (element != null && !javaClass.isAbstract()) {
d51f84
@@ -152,7 +156,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return elements;
d51f84
     }
d51f84
 
d51f84
-    private ElementMapping loadElement(JavaDocBuilder builder, JavaClass javaClass) {
d51f84
+    private ElementMapping loadElement(JavaProjectBuilder builder, JavaClass javaClass) {
d51f84
         DocletTag xbeanTag = javaClass.getTagByName(XBEAN_ANNOTATION);
d51f84
         if (xbeanTag == null) {
d51f84
             return null;
d51f84
@@ -176,7 +180,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         Map<String, AttributeMapping> attributesByPropertyName = new HashMap<String, AttributeMapping>();
d51f84
 
d51f84
         for (JavaClass jClass = javaClass; jClass != null; jClass = jClass.getSuperJavaClass()) {
d51f84
-            BeanProperty[] beanProperties = jClass.getBeanProperties();
d51f84
+            Collection<BeanProperty> beanProperties = jClass.getBeanProperties();
d51f84
             for (BeanProperty beanProperty : beanProperties) {
d51f84
                 // we only care about properties with a setter
d51f84
                 if (beanProperty.getMutator() != null) {
d51f84
@@ -219,9 +223,9 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         String destroyMethod = null;
d51f84
         String factoryMethod = null;
d51f84
         for (JavaClass jClass = javaClass; jClass != null; jClass = jClass.getSuperJavaClass()) {
d51f84
-            JavaMethod[] methods = javaClass.getMethods();
d51f84
+            Collection<JavaMethod> methods = javaClass.getMethods();
d51f84
             for (JavaMethod method : methods) {
d51f84
-                if (method.isPublic() && !method.isConstructor()) {
d51f84
+                if (method.isPublic()) {
d51f84
                     if (initMethod == null && method.getTagByName(INIT_METHOD_ANNOTATION) != null) {
d51f84
                         initMethod = method.getName();
d51f84
                     }
d51f84
@@ -237,22 +241,43 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         }
d51f84
 
d51f84
         List<List<ParameterMapping>> constructorArgs = new ArrayList<List<ParameterMapping>>();
d51f84
-        JavaMethod[] methods = javaClass.getMethods();
d51f84
-        for (JavaMethod method : methods) {
d51f84
-            JavaParameter[] parameters = method.getParameters();
d51f84
-            if (isValidConstructor(factoryMethod, method, parameters)) {
d51f84
-                List<ParameterMapping> args = new ArrayList<ParameterMapping>(parameters.length);
d51f84
-                for (JavaParameter parameter : parameters) {
d51f84
-                    AttributeMapping attributeMapping = attributesByPropertyName.get(parameter.getName());
d51f84
-                    if (attributeMapping == null) {
d51f84
-                        attributeMapping = loadParameter(parameter);
d51f84
-
d51f84
-                        attributes.add(attributeMapping);
d51f84
-                        attributesByPropertyName.put(attributeMapping.getPropertyName(), attributeMapping);
d51f84
+        if (factoryMethod == null) {
d51f84
+            Collection<JavaConstructor> constructors = javaClass.getConstructors();
d51f84
+            for (JavaConstructor constructor : constructors) {
d51f84
+                Collection<JavaParameter> parameters = constructor.getParameters();
d51f84
+                if (constructor.isPublic() && parameters.size() > 0) {
d51f84
+                    List<ParameterMapping> args = new ArrayList<ParameterMapping>(parameters.size());
d51f84
+                    for (JavaParameter parameter : parameters) {
d51f84
+                        AttributeMapping attributeMapping = attributesByPropertyName.get(parameter.getName());
d51f84
+                        if (attributeMapping == null) {
d51f84
+                            attributeMapping = loadParameter(parameter, constructor);
d51f84
+
d51f84
+                            attributes.add(attributeMapping);
d51f84
+                            attributesByPropertyName.put(attributeMapping.getPropertyName(), attributeMapping);
d51f84
+                        }
d51f84
+                        args.add(new ParameterMapping(attributeMapping.getPropertyName(), toMappingType(parameter.getType(), null)));
d51f84
                     }
d51f84
-                    args.add(new ParameterMapping(attributeMapping.getPropertyName(), toMappingType(parameter.getType(), null)));
d51f84
+                    constructorArgs.add(Collections.unmodifiableList(args));
d51f84
+                }
d51f84
+            }
d51f84
+        } else {
d51f84
+            Collection<JavaMethod> methods = javaClass.getMethods();
d51f84
+            for (JavaMethod method : methods) {
d51f84
+                Collection<JavaParameter> parameters = method.getParameters();
d51f84
+                if (method.isPublic() && parameters.size() > 0 && method.getName().equals(factoryMethod)) {
d51f84
+                    List<ParameterMapping> args = new ArrayList<ParameterMapping>(parameters.size());
d51f84
+                    for (JavaParameter parameter : parameters) {
d51f84
+                        AttributeMapping attributeMapping = attributesByPropertyName.get(parameter.getName());
d51f84
+                        if (attributeMapping == null) {
d51f84
+                            attributeMapping = loadParameter(parameter, method);
d51f84
+
d51f84
+                            attributes.add(attributeMapping);
d51f84
+                            attributesByPropertyName.put(attributeMapping.getPropertyName(), attributeMapping);
d51f84
+                        }
d51f84
+                        args.add(new ParameterMapping(attributeMapping.getPropertyName(), toMappingType(parameter.getType(), null)));
d51f84
+                    }
d51f84
+                    constructorArgs.add(Collections.unmodifiableList(args));
d51f84
                 }
d51f84
-                constructorArgs.add(Collections.unmodifiableList(args));
d51f84
             }
d51f84
         }
d51f84
 
d51f84
@@ -303,7 +328,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
                 interfaces);
d51f84
     }
d51f84
 
d51f84
-    private List<String> getFullyQualifiedNames(JavaClass[] implementedInterfaces) {
d51f84
+    private List<String> getFullyQualifiedNames(Collection<JavaClass> implementedInterfaces) {
d51f84
         ArrayList<String> l = new ArrayList<String>();
d51f84
         for (JavaClass implementedInterface : implementedInterfaces) {
d51f84
             l.add(implementedInterface.getFullyQualifiedName());
d51f84
@@ -395,19 +420,19 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return defaultDescription;
d51f84
     }
d51f84
 
d51f84
-    private AttributeMapping loadParameter(JavaParameter parameter) {
d51f84
+    private AttributeMapping loadParameter(JavaParameter parameter, JavaModel methodOrConstructor) {
d51f84
         String parameterName = parameter.getName();
d51f84
         String parameterDescription = getParameterDescription(parameter);
d51f84
 
d51f84
         // first attempt to load the attribute from the java beans accessor methods
d51f84
-        JavaClass javaClass = parameter.getParentMethod().getParentClass();
d51f84
+        JavaClass javaClass = parameter.getParentClass();
d51f84
         BeanProperty beanProperty = javaClass.getBeanProperty(parameterName);
d51f84
         if (beanProperty != null) {
d51f84
             AttributeMapping attributeMapping = loadAttribute(beanProperty, parameterDescription);
d51f84
             // if the attribute mapping is null, the property was tagged as hidden and this is an error
d51f84
             if (attributeMapping == null) {
d51f84
                 throw new InvalidModelException("Hidden property usage: " +
d51f84
-                        "The construction method " + toMethodLocator(parameter.getParentMethod()) +
d51f84
+                        "The construction method " + toMethodLocator(parameter.getParentClass(), methodOrConstructor) +
d51f84
                         " can not use a hidded property " + parameterName);
d51f84
             }
d51f84
             return attributeMapping;
d51f84
@@ -426,9 +451,9 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
 
d51f84
     private String getParameterDescription(JavaParameter parameter) {
d51f84
         String parameterName = parameter.getName();
d51f84
-        DocletTag[] tags = parameter.getParentMethod().getTagsByName("param");
d51f84
+        Collection<DocletTag> tags = parameter.getTagsByName("param");
d51f84
         for (DocletTag tag : tags) {
d51f84
-            if (tag.getParameters()[0].equals(parameterName)) {
d51f84
+            if (tag.getParameters().get(0).equals(parameterName)) {
d51f84
                 String parameterDescription = tag.getValue().trim();
d51f84
                 if (parameterDescription.startsWith(parameterName)) {
d51f84
                     parameterDescription = parameterDescription.substring(parameterName.length()).trim();
d51f84
@@ -439,18 +464,6 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return null;
d51f84
     }
d51f84
 
d51f84
-    private boolean isValidConstructor(String factoryMethod, JavaMethod method, JavaParameter[] parameters) {
d51f84
-        if (!method.isPublic() || parameters.length == 0) {
d51f84
-            return false;
d51f84
-        }
d51f84
-
d51f84
-        if (factoryMethod == null) {
d51f84
-            return method.isConstructor();
d51f84
-        } else {
d51f84
-            return method.getName().equals(factoryMethod);
d51f84
-        }
d51f84
-    }
d51f84
-
d51f84
     private static String getProperty(DocletTag propertyTag, String propertyName) {
d51f84
         return getProperty(propertyTag, propertyName, null);
d51f84
     }
d51f84
@@ -477,14 +490,17 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return false;
d51f84
     }
d51f84
 
d51f84
-    private org.apache.xbean.blueprint.generator.Type toMappingType(Type type, String nestedType) {
d51f84
+    private org.apache.xbean.blueprint.generator.Type toMappingType(JavaType type, String nestedType) {
d51f84
         try {
d51f84
-            if (type.isArray()) {
d51f84
-                return org.apache.xbean.blueprint.generator.Type.newArrayType(type.getValue(), type.getDimensions());
d51f84
-            } else if (type.isA(collectionType)) {
d51f84
-                if (nestedType == null) nestedType = "java.lang.Object";
d51f84
-                return org.apache.xbean.blueprint.generator.Type.newCollectionType(type.getValue(),
d51f84
-                        org.apache.xbean.blueprint.generator.Type.newSimpleType(nestedType));
d51f84
+	    if (type instanceof JavaClass) {
d51f84
+                JavaClass clazz = (JavaClass)type;
d51f84
+                if (clazz.isArray()) {
d51f84
+                    return org.apache.xbean.blueprint.generator.Type.newArrayType(type.getValue(), clazz.getDimensions());
d51f84
+                } else if (clazz.isA(collectionType)) {
d51f84
+                    if (nestedType == null) nestedType = "java.lang.Object";
d51f84
+                    return org.apache.xbean.blueprint.generator.Type.newCollectionType(type.getValue(),
d51f84
+                            org.apache.xbean.blueprint.generator.Type.newSimpleType(nestedType));
d51f84
+                }
d51f84
             }
d51f84
         } catch (Throwable t) {
d51f84
             log.debug("Could not load type mapping", t);
d51f84
@@ -492,26 +508,28 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return org.apache.xbean.blueprint.generator.Type.newSimpleType(type.getValue());
d51f84
     }
d51f84
 
d51f84
-    private static String toMethodLocator(JavaMethod method) {
d51f84
+    private static String toMethodLocator(JavaClass parentClass, JavaModel methodOrConstructor) {
d51f84
+        JavaMethod method = methodOrConstructor instanceof JavaMethod ? (JavaMethod) methodOrConstructor : null;
d51f84
+        JavaConstructor constructor = methodOrConstructor instanceof JavaConstructor ? (JavaConstructor) methodOrConstructor : null;
d51f84
         StringBuffer buf = new StringBuffer();
d51f84
-        buf.append(method.getParentClass().getFullyQualifiedName());
d51f84
-        if (!method.isConstructor()) {
d51f84
+        buf.append(parentClass.getFullyQualifiedName());
d51f84
+        if (method != null) {
d51f84
             buf.append(".").append(method.getName());
d51f84
         }
d51f84
         buf.append("(");
d51f84
-        JavaParameter[] parameters = method.getParameters();
d51f84
-        for (int i = 0; i < parameters.length; i++) {
d51f84
-            JavaParameter parameter = parameters[i];
d51f84
+        List<JavaParameter> parameters = method != null ? method.getParameters() : constructor.getParameters();
d51f84
+        for (int i = 0; i < parameters.size(); i++) {
d51f84
+            JavaParameter parameter = parameters.get(i);
d51f84
             if (i > 0) {
d51f84
                 buf.append(", ");
d51f84
             }
d51f84
             buf.append(parameter.getName());
d51f84
         }
d51f84
-        buf.append(") : ").append(method.getLineNumber());
d51f84
+        buf.append(") : ").append(method != null ? method.getLineNumber() : constructor.getLineNumber());
d51f84
         return buf.toString();
d51f84
     }
d51f84
 
d51f84
-    private static void getSourceFiles(File base, String[] excludedClasses, JavaDocBuilder builder) throws IOException {
d51f84
+    private static void getSourceFiles(File base, String[] excludedClasses, JavaProjectBuilder builder) throws IOException {
d51f84
         if (base.isDirectory()) {
d51f84
             listAllFileNames(base, "", excludedClasses, builder);
d51f84
         } else {
d51f84
@@ -519,7 +537,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         }
d51f84
     }
d51f84
 
d51f84
-    private static void listAllFileNames(File base, String prefix, String[] excludedClasses, JavaDocBuilder builder) throws IOException {
d51f84
+    private static void listAllFileNames(File base, String prefix, String[] excludedClasses, JavaProjectBuilder builder) throws IOException {
d51f84
         if (!base.canRead() || !base.isDirectory()) {
d51f84
             throw new IllegalArgumentException(base.getAbsolutePath());
d51f84
         }
d51f84
@@ -536,7 +554,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         }
d51f84
     }
d51f84
 
d51f84
-    private static void listAllJarEntries(File base, String[] excludedClasses, JavaDocBuilder builder) throws IOException {
d51f84
+    private static void listAllJarEntries(File base, String[] excludedClasses, JavaProjectBuilder builder) throws IOException {
d51f84
         JarFile jarFile = new JarFile(base);
d51f84
         for (Enumeration entries = jarFile.entries(); entries.hasMoreElements(); ) {
d51f84
             JarEntry entry = (JarEntry) entries.nextElement();
d51f84
diff --git a/xbean-spring/src/main/java/org/apache/xbean/spring/generator/QdoxMappingLoader.java b/xbean-spring/src/main/java/org/apache/xbean/spring/generator/QdoxMappingLoader.java
d51f84
index 94bd7a1..228117e 100644
d51f84
--- a/xbean-spring/src/main/java/org/apache/xbean/spring/generator/QdoxMappingLoader.java
d51f84
+++ b/xbean-spring/src/main/java/org/apache/xbean/spring/generator/QdoxMappingLoader.java
d51f84
@@ -20,6 +20,7 @@ import java.io.File;
d51f84
 import java.io.IOException;
d51f84
 import java.net.URL;
d51f84
 import java.util.ArrayList;
d51f84
+import java.util.Collection;
d51f84
 import java.util.Collections;
d51f84
 import java.util.Enumeration;
d51f84
 import java.util.HashMap;
d51f84
@@ -31,14 +32,17 @@ import java.util.TreeSet;
d51f84
 import java.util.jar.JarEntry;
d51f84
 import java.util.jar.JarFile;
d51f84
 
d51f84
-import com.thoughtworks.qdox.JavaDocBuilder;
d51f84
+import com.thoughtworks.qdox.JavaProjectBuilder;
d51f84
 import com.thoughtworks.qdox.model.BeanProperty;
d51f84
 import com.thoughtworks.qdox.model.DocletTag;
d51f84
 import com.thoughtworks.qdox.model.JavaClass;
d51f84
+import com.thoughtworks.qdox.model.JavaConstructor;
d51f84
 import com.thoughtworks.qdox.model.JavaMethod;
d51f84
+import com.thoughtworks.qdox.model.JavaModel;
d51f84
 import com.thoughtworks.qdox.model.JavaParameter;
d51f84
 import com.thoughtworks.qdox.model.JavaSource;
d51f84
-import com.thoughtworks.qdox.model.Type;
d51f84
+import com.thoughtworks.qdox.model.JavaType;
d51f84
+
d51f84
 import org.apache.commons.logging.Log;
d51f84
 import org.apache.commons.logging.LogFactory;
d51f84
 
d51f84
@@ -62,7 +66,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
     private final String defaultNamespace;
d51f84
     private final File[] srcDirs;
d51f84
     private final String[] excludedClasses;
d51f84
-    private Type collectionType;
d51f84
+    private JavaClass collectionType;
d51f84
 
d51f84
     public QdoxMappingLoader(String defaultNamespace, File[] srcDirs, String[] excludedClasses) {
d51f84
         this.defaultNamespace = defaultNamespace;
d51f84
@@ -79,7 +83,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
     }
d51f84
 
d51f84
     public Set<NamespaceMapping> loadNamespaces() throws IOException {
d51f84
-        JavaDocBuilder builder = new JavaDocBuilder();
d51f84
+        JavaProjectBuilder builder = new JavaProjectBuilder();
d51f84
 
d51f84
         log.debug("Source directories: ");
d51f84
 
d51f84
@@ -92,11 +96,11 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
             getSourceFiles(sourceDirectory, excludedClasses, builder);
d51f84
         }
d51f84
 
d51f84
-        collectionType = builder.getClassByName("java.util.Collection").asType();
d51f84
+        collectionType = builder.getClassByName("java.util.Collection");
d51f84
         return loadNamespaces(builder);
d51f84
     }
d51f84
 
d51f84
-    private Set<NamespaceMapping> loadNamespaces(JavaDocBuilder builder) {
d51f84
+    private Set<NamespaceMapping> loadNamespaces(JavaProjectBuilder builder) {
d51f84
         // load all of the elements
d51f84
         List<ElementMapping> elements = loadElements(builder);
d51f84
 
d51f84
@@ -131,14 +135,14 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return Collections.unmodifiableSet(namespaces);
d51f84
     }
d51f84
 
d51f84
-    private List<ElementMapping> loadElements(JavaDocBuilder builder) {
d51f84
-        JavaSource[] javaSources = builder.getSources();
d51f84
+    private List<ElementMapping> loadElements(JavaProjectBuilder builder) {
d51f84
+        Collection<JavaSource> javaSources = builder.getSources();
d51f84
         List<ElementMapping> elements = new ArrayList<ElementMapping>();
d51f84
         for (JavaSource javaSource : javaSources) {
d51f84
-            if (javaSource.getClasses().length == 0) {
d51f84
+            if (javaSource.getClasses().isEmpty()) {
d51f84
                 log.info("No Java Classes defined in: " + javaSource.getURL());
d51f84
             } else {
d51f84
-                JavaClass[] classes = javaSource.getClasses();
d51f84
+                Collection<JavaClass> classes = javaSource.getClasses();
d51f84
                 for (JavaClass javaClass : classes) {
d51f84
                     ElementMapping element = loadElement(builder, javaClass);
d51f84
                     if (element != null && !javaClass.isAbstract()) {
d51f84
@@ -152,7 +156,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return elements;
d51f84
     }
d51f84
 
d51f84
-    private ElementMapping loadElement(JavaDocBuilder builder, JavaClass javaClass) {
d51f84
+    private ElementMapping loadElement(JavaProjectBuilder builder, JavaClass javaClass) {
d51f84
         DocletTag xbeanTag = javaClass.getTagByName(XBEAN_ANNOTATION);
d51f84
         if (xbeanTag == null) {
d51f84
             return null;
d51f84
@@ -176,7 +180,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         Map<String, AttributeMapping> attributesByPropertyName = new HashMap<String, AttributeMapping>();
d51f84
 
d51f84
         for (JavaClass jClass = javaClass; jClass != null; jClass = jClass.getSuperJavaClass()) {
d51f84
-            BeanProperty[] beanProperties = jClass.getBeanProperties();
d51f84
+            Collection<BeanProperty> beanProperties = jClass.getBeanProperties();
d51f84
             for (BeanProperty beanProperty : beanProperties) {
d51f84
                 // we only care about properties with a setter
d51f84
                 if (beanProperty.getMutator() != null) {
d51f84
@@ -219,9 +223,9 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         String destroyMethod = null;
d51f84
         String factoryMethod = null;
d51f84
         for (JavaClass jClass = javaClass; jClass != null; jClass = jClass.getSuperJavaClass()) {
d51f84
-            JavaMethod[] methods = javaClass.getMethods();
d51f84
+            Collection<JavaMethod> methods = javaClass.getMethods();
d51f84
             for (JavaMethod method : methods) {
d51f84
-                if (method.isPublic() && !method.isConstructor()) {
d51f84
+                if (method.isPublic()) {
d51f84
                     if (initMethod == null && method.getTagByName(INIT_METHOD_ANNOTATION) != null) {
d51f84
                         initMethod = method.getName();
d51f84
                     }
d51f84
@@ -237,27 +241,48 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         }
d51f84
 
d51f84
         List<List<ParameterMapping>> constructorArgs = new ArrayList<List<ParameterMapping>>();
d51f84
-        JavaMethod[] methods = javaClass.getMethods();
d51f84
-        for (JavaMethod method : methods) {
d51f84
-            JavaParameter[] parameters = method.getParameters();
d51f84
-            if (isValidConstructor(factoryMethod, method, parameters)) {
d51f84
-                List<ParameterMapping> args = new ArrayList<ParameterMapping>(parameters.length);
d51f84
-                for (JavaParameter parameter : parameters) {
d51f84
-                    AttributeMapping attributeMapping = attributesByPropertyName.get(parameter.getName());
d51f84
-                    if (attributeMapping == null) {
d51f84
-                        attributeMapping = loadParameter(parameter);
d51f84
-
d51f84
-                        attributes.add(attributeMapping);
d51f84
-                        attributesByPropertyName.put(attributeMapping.getPropertyName(), attributeMapping);
d51f84
+        if (factoryMethod == null) {
d51f84
+            Collection<JavaConstructor> constructors = javaClass.getConstructors();
d51f84
+            for (JavaConstructor constructor : constructors) {
d51f84
+                Collection<JavaParameter> parameters = constructor.getParameters();
d51f84
+                if (constructor.isPublic() && parameters.size() > 0) {
d51f84
+                    List<ParameterMapping> args = new ArrayList<ParameterMapping>(parameters.size());
d51f84
+                    for (JavaParameter parameter : parameters) {
d51f84
+                        AttributeMapping attributeMapping = attributesByPropertyName.get(parameter.getName());
d51f84
+                        if (attributeMapping == null) {
d51f84
+                            attributeMapping = loadParameter(parameter, constructor);
d51f84
+
d51f84
+                            attributes.add(attributeMapping);
d51f84
+                            attributesByPropertyName.put(attributeMapping.getPropertyName(), attributeMapping);
d51f84
+                        }
d51f84
+                        args.add(new ParameterMapping(attributeMapping.getPropertyName(), toMappingType(parameter.getType(), null)));
d51f84
                     }
d51f84
-                    args.add(new ParameterMapping(attributeMapping.getPropertyName(), toMappingType(parameter.getType(), null)));
d51f84
+                    constructorArgs.add(Collections.unmodifiableList(args));
d51f84
+                }
d51f84
+            }
d51f84
+        } else {
d51f84
+            Collection<JavaMethod> methods = javaClass.getMethods();
d51f84
+            for (JavaMethod method : methods) {
d51f84
+                Collection<JavaParameter> parameters = method.getParameters();
d51f84
+                if (method.isPublic() && parameters.size() > 0 && method.getName().equals(factoryMethod)) {
d51f84
+                    List<ParameterMapping> args = new ArrayList<ParameterMapping>(parameters.size());
d51f84
+                    for (JavaParameter parameter : parameters) {
d51f84
+                        AttributeMapping attributeMapping = attributesByPropertyName.get(parameter.getName());
d51f84
+                        if (attributeMapping == null) {
d51f84
+                            attributeMapping = loadParameter(parameter, method);
d51f84
+
d51f84
+                            attributes.add(attributeMapping);
d51f84
+                            attributesByPropertyName.put(attributeMapping.getPropertyName(), attributeMapping);
d51f84
+                        }
d51f84
+                        args.add(new ParameterMapping(attributeMapping.getPropertyName(), toMappingType(parameter.getType(), null)));
d51f84
+                    }
d51f84
+                    constructorArgs.add(Collections.unmodifiableList(args));
d51f84
                 }
d51f84
-                constructorArgs.add(Collections.unmodifiableList(args));
d51f84
             }
d51f84
         }
d51f84
 
d51f84
         HashSet<String> interfaces = new HashSet<String>();
d51f84
-        interfaces.addAll(getFullyQualifiedNames(javaClass.getImplementedInterfaces()));
d51f84
+        interfaces.addAll(getFullyQualifiedNames(javaClass.getInterfaces()));
d51f84
 
d51f84
         JavaClass actualClass = javaClass;
d51f84
         if (factoryClass != null) {
d51f84
@@ -282,7 +307,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
             }
d51f84
             p = s;
d51f84
             superClasses.add(p.getFullyQualifiedName());
d51f84
-            interfaces.addAll(getFullyQualifiedNames(p.getImplementedInterfaces()));
d51f84
+            interfaces.addAll(getFullyQualifiedNames(p.getInterfaces()));
d51f84
         }
d51f84
 
d51f84
         return new ElementMapping(namespace,
d51f84
@@ -303,7 +328,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
                 interfaces);
d51f84
     }
d51f84
 
d51f84
-    private List<String> getFullyQualifiedNames(JavaClass[] implementedInterfaces) {
d51f84
+    private List<String> getFullyQualifiedNames(Collection<JavaClass> implementedInterfaces) {
d51f84
         ArrayList<String> l = new ArrayList<String>();
d51f84
         for (JavaClass implementedInterface : implementedInterfaces) {
d51f84
             l.add(implementedInterface.getFullyQualifiedName());
d51f84
@@ -395,19 +420,19 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return defaultDescription;
d51f84
     }
d51f84
 
d51f84
-    private AttributeMapping loadParameter(JavaParameter parameter) {
d51f84
+    private AttributeMapping loadParameter(JavaParameter parameter, JavaModel methodOrConstructor) {
d51f84
         String parameterName = parameter.getName();
d51f84
         String parameterDescription = getParameterDescription(parameter);
d51f84
 
d51f84
         // first attempt to load the attribute from the java beans accessor methods
d51f84
-        JavaClass javaClass = parameter.getParentMethod().getParentClass();
d51f84
+        JavaClass javaClass = parameter.getDeclaringClass();
d51f84
         BeanProperty beanProperty = javaClass.getBeanProperty(parameterName);
d51f84
         if (beanProperty != null) {
d51f84
             AttributeMapping attributeMapping = loadAttribute(beanProperty, parameterDescription);
d51f84
             // if the attribute mapping is null, the property was tagged as hidden and this is an error
d51f84
             if (attributeMapping == null) {
d51f84
                 throw new InvalidModelException("Hidden property usage: " +
d51f84
-                        "The construction method " + toMethodLocator(parameter.getParentMethod()) +
d51f84
+                        "The construction method " + toMethodLocator(parameter.getDeclaringClass(), methodOrConstructor) +
d51f84
                         " can not use a hidded property " + parameterName);
d51f84
             }
d51f84
             return attributeMapping;
d51f84
@@ -426,9 +451,9 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
 
d51f84
     private String getParameterDescription(JavaParameter parameter) {
d51f84
         String parameterName = parameter.getName();
d51f84
-        DocletTag[] tags = parameter.getParentMethod().getTagsByName("param");
d51f84
+        Collection<DocletTag> tags = parameter.getTagsByName("param");
d51f84
         for (DocletTag tag : tags) {
d51f84
-            if (tag.getParameters()[0].equals(parameterName)) {
d51f84
+            if (tag.getParameters().get(0).equals(parameterName)) {
d51f84
                 String parameterDescription = tag.getValue().trim();
d51f84
                 if (parameterDescription.startsWith(parameterName)) {
d51f84
                     parameterDescription = parameterDescription.substring(parameterName.length()).trim();
d51f84
@@ -439,18 +464,6 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return null;
d51f84
     }
d51f84
 
d51f84
-    private boolean isValidConstructor(String factoryMethod, JavaMethod method, JavaParameter[] parameters) {
d51f84
-        if (!method.isPublic() || parameters.length == 0) {
d51f84
-            return false;
d51f84
-        }
d51f84
-
d51f84
-        if (factoryMethod == null) {
d51f84
-            return method.isConstructor();
d51f84
-        } else {
d51f84
-            return method.getName().equals(factoryMethod);
d51f84
-        }
d51f84
-    }
d51f84
-
d51f84
     private static String getProperty(DocletTag propertyTag, String propertyName) {
d51f84
         return getProperty(propertyTag, propertyName, null);
d51f84
     }
d51f84
@@ -477,14 +490,17 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return false;
d51f84
     }
d51f84
 
d51f84
-    private org.apache.xbean.spring.generator.Type toMappingType(Type type, String nestedType) {
d51f84
+    private org.apache.xbean.spring.generator.Type toMappingType(JavaType type, String nestedType) {
d51f84
         try {
d51f84
-            if (type.isArray()) {
d51f84
-                return org.apache.xbean.spring.generator.Type.newArrayType(type.getValue(), type.getDimensions());
d51f84
-            } else if (type.isA(collectionType)) {
d51f84
-                if (nestedType == null) nestedType = "java.lang.Object";
d51f84
-                return org.apache.xbean.spring.generator.Type.newCollectionType(type.getValue(),
d51f84
-                        org.apache.xbean.spring.generator.Type.newSimpleType(nestedType));
d51f84
+	    if (type instanceof JavaClass) {
d51f84
+                JavaClass clazz = (JavaClass)type;
d51f84
+                if (clazz.isArray()) {
d51f84
+                    return org.apache.xbean.spring.generator.Type.newArrayType(type.getValue(), clazz.getDimensions());
d51f84
+                } else if (clazz.isA(collectionType)) {
d51f84
+                    if (nestedType == null) nestedType = "java.lang.Object";
d51f84
+                    return org.apache.xbean.spring.generator.Type.newCollectionType(type.getValue(),
d51f84
+                            org.apache.xbean.spring.generator.Type.newSimpleType(nestedType));
d51f84
+                }
d51f84
             }
d51f84
         } catch (Throwable t) {
d51f84
             log.debug("Could not load type mapping", t);
d51f84
@@ -492,26 +508,28 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         return org.apache.xbean.spring.generator.Type.newSimpleType(type.getValue());
d51f84
     }
d51f84
 
d51f84
-    private static String toMethodLocator(JavaMethod method) {
d51f84
+    private static String toMethodLocator(JavaClass parentClass, JavaModel methodOrConstructor) {
d51f84
+        JavaMethod method = methodOrConstructor instanceof JavaMethod ? (JavaMethod) methodOrConstructor : null;
d51f84
+        JavaConstructor constructor = methodOrConstructor instanceof JavaConstructor ? (JavaConstructor) methodOrConstructor : null;
d51f84
         StringBuffer buf = new StringBuffer();
d51f84
-        buf.append(method.getParentClass().getFullyQualifiedName());
d51f84
-        if (!method.isConstructor()) {
d51f84
+        buf.append(parentClass.getFullyQualifiedName());
d51f84
+        if (method != null) {
d51f84
             buf.append(".").append(method.getName());
d51f84
         }
d51f84
         buf.append("(");
d51f84
-        JavaParameter[] parameters = method.getParameters();
d51f84
-        for (int i = 0; i < parameters.length; i++) {
d51f84
-            JavaParameter parameter = parameters[i];
d51f84
+        List<JavaParameter> parameters = method != null ? method.getParameters() : constructor.getParameters();
d51f84
+        for (int i = 0; i < parameters.size(); i++) {
d51f84
+            JavaParameter parameter = parameters.get(i);
d51f84
             if (i > 0) {
d51f84
                 buf.append(", ");
d51f84
             }
d51f84
             buf.append(parameter.getName());
d51f84
         }
d51f84
-        buf.append(") : ").append(method.getLineNumber());
d51f84
+        buf.append(") : ").append(method != null ? method.getLineNumber() : constructor.getLineNumber());
d51f84
         return buf.toString();
d51f84
     }
d51f84
 
d51f84
-    private static void getSourceFiles(File base, String[] excludedClasses, JavaDocBuilder builder) throws IOException {
d51f84
+    private static void getSourceFiles(File base, String[] excludedClasses, JavaProjectBuilder builder) throws IOException {
d51f84
         if (base.isDirectory()) {
d51f84
             listAllFileNames(base, "", excludedClasses, builder);
d51f84
         } else {
d51f84
@@ -519,7 +537,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         }
d51f84
     }
d51f84
 
d51f84
-    private static void listAllFileNames(File base, String prefix, String[] excludedClasses, JavaDocBuilder builder) throws IOException {
d51f84
+    private static void listAllFileNames(File base, String prefix, String[] excludedClasses, JavaProjectBuilder builder) throws IOException {
d51f84
         if (!base.canRead() || !base.isDirectory()) {
d51f84
             throw new IllegalArgumentException(base.getAbsolutePath());
d51f84
         }
d51f84
@@ -536,7 +554,7 @@ public class QdoxMappingLoader implements MappingLoader {
d51f84
         }
d51f84
     }
d51f84
 
d51f84
-    private static void listAllJarEntries(File base, String[] excludedClasses, JavaDocBuilder builder) throws IOException {
d51f84
+    private static void listAllJarEntries(File base, String[] excludedClasses, JavaProjectBuilder builder) throws IOException {
d51f84
         JarFile jarFile = new JarFile(base);
d51f84
         for (Enumeration entries = jarFile.entries(); entries.hasMoreElements(); ) {
d51f84
             JarEntry entry = (JarEntry) entries.nextElement();
d51f84
diff --git a/xbean-spring/src/main/java/org/apache/xbean/spring/generator/Type.java b/xbean-spring/src/main/java/org/apache/xbean/spring/generator/Type.java
d51f84
index 5eac64c..0d9fa63 100644
d51f84
--- a/xbean-spring/src/main/java/org/apache/xbean/spring/generator/Type.java
d51f84
+++ b/xbean-spring/src/main/java/org/apache/xbean/spring/generator/Type.java
d51f84
@@ -41,12 +41,7 @@ public class Type {
d51f84
     public static Type newArrayType(String type, int dimensions) {
d51f84
         if (type == null) throw new NullPointerException("type");
d51f84
         if (dimensions < 1) throw new IllegalArgumentException("dimensions must be atleast one");
d51f84
-        StringBuffer buf = new StringBuffer(type.length() + (dimensions * 2));
d51f84
-        buf.append(type);
d51f84
-        for (int i = 0; i < dimensions; i ++) {
d51f84
-            buf.append("[]");
d51f84
-        }
d51f84
-        return new Type(buf.toString(), newSimpleType(type));
d51f84
+        return new Type(type, newSimpleType(type.replaceAll("\\[\\]", "")));
d51f84
     }
d51f84
 
d51f84
     public static Type newCollectionType(String collectionType, Type elementType) {
d51f84
-- 
d51f84
2.9.3
d51f84