qdox-qdox-1.12.1/ 0000775 0000000 0000000 00000000000 12045512336 0013521 5 ustar 00root root 0000000 0000000 qdox-qdox-1.12.1/LICENSE.txt 0000664 0000000 0000000 00000001101 12045512336 0015335 0 ustar 00root root 0000000 0000000 Copyright 2002-2009 Joe Walnes and QDox Project Team
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.
qdox-qdox-1.12.1/README.txt 0000664 0000000 0000000 00000002305 12045512336 0015217 0 ustar 00root root 0000000 0000000 To build QDox there are two prerequisites:
* Maven 2 (2.0.9 or later)
http://maven.apache.org
* BYacc/J (1.8 or later)
http://byaccj.sourceforge.net/
Paarser generator used to create an effective parser for JavaDoc.
If using Windows, Linux, Solaris or Mac OS X, no additional installation is
needed as yacc binaries are supplied in the bootstrap directory.
If using any other platform, download BYacc/J from the site or build it yourself, in which case
we would be grateful to receive a copy of your binary, so we can upgrade the bootstrap support.
Build goals:
mvn install - Create qdox jar
mvn generate-sources - Generate the Java parser code (allowing you to develop in an IDE).
mvn site - Build the QDox website
mvn release:prepare - Prepare release (confirm or change release version interactively)
mvn release:perform - Perform release (perform release from tag of prepare phase)
If you are releasing, remember to
1) Update src/site/content/download.html
2) Go to JIRA and release the applicable version for QDOX : http://jira.codehaus.org/secure/project/ManageVersions.jspa?pid=10103
3) Copy the contents of target/site/ to the DAV folder for QDox's website : https://dav.codehaus.org/qdox/ qdox-qdox-1.12.1/bootstrap/ 0000775 0000000 0000000 00000000000 12045512336 0015536 5 ustar 00root root 0000000 0000000 qdox-qdox-1.12.1/pom.xml 0000664 0000000 0000000 00000041246 12045512336 0015045 0 ustar 00root root 0000000 0000000 Note: This method is for backward naming compatiblity
* with xjavadoc.codeunit.CodeTestCase. As JavaClass doesn't not implements As JavaField doesn't not implements The fields are sorted by name before comparison to be sure
* that even if the fields are defined in a different order, the
* comparison is still right. The inner classes are sorted by name before comparison to be sure
* that even if the inner classes are defined in a different order, the
* comparison is still right. The implemented interfaces are sorted by name before comparison to be sure
* that even if the implemented interfaces are defined in a different order, the
* comparison is still right. The constructors and the methods are sorted by name before comparison to be sure
* that even if the constructors and methods are defined in a different order, the
* comparison is still right. The modifiers are sorted by name before comparison to be sure
* that even if the modifiers are defined in a different order, the
* comparison is still right.
* This map contains the parsed AnnotationValue for each property and allows
* access to the full parse tree, including typerefs and expressions.
*/
private final Map properties = new LinkedHashMap();
/**
* Annotation properties as Parameters
*/
private final Map namedParameters = new LinkedHashMap();
private AbstractBaseJavaEntity context;
public Annotation(Type type,
AbstractBaseJavaEntity context,
Map namedParameters,
int lineNumber)
{
this.type = type;
this.context = context;
this.lineNumber = lineNumber;
if(properties != null) {
for(Iterator i = this.properties.entrySet().iterator(); i.hasNext(); ) {
Entry entry = (Entry) i.next();
String name = (String) entry.getKey();
AnnotationValue value = (AnnotationValue) entry.getValue();
setProperty(name, value);
}
}
}
public Annotation( Type type, int line ) {
this(type, null, null, line);
}
public void setProperty(String name, AnnotationValue value) {
properties.put( name, value );
namedParameters.put( name, value.getParameterValue() );
}
/**
* @return the annotation type
*/
public Type getType() {
return type;
}
/**
* @param key name of a named-parameter
* @return the corresponding value,
* or null if no such named-parameter was present
*/
public Object getNamedParameter(String key) {
return namedParameters.get( key );
}
/**
* @return a Map containing all the named-parameters
*/
public Map getNamedParameterMap() {
return namedParameters;
}
public final AbstractBaseJavaEntity getContext() {
return context;
}
public int getLineNumber() {
return lineNumber;
}
public Object accept( AnnotationVisitor visitor ) {
return visitor.visitAnnotation( this );
}
public Object getParameterValue() {
return this;
}
public Map getPropertyMap() {
return properties;
}
public AnnotationValue getProperty(String name) {
return (AnnotationValue) properties.get( name );
}
public void setContext( AbstractBaseJavaEntity context ) {
this.context = context;
}
public String toString() {
StringBuffer result = new StringBuffer();
result.append('@');
result.append(type.getValue());
result.append('(');
if( !namedParameters.isEmpty() ) {
for(Iterator i = namedParameters.entrySet().iterator(); i.hasNext();) result.append( i.next() + ",");
result.deleteCharAt( result.length()-1 );
}
result.append(')');
return result.toString();
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/BeanProperty.java 0000664 0000000 0000000 00000001501 12045512336 0026104 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.model;
/**
*
* @author Aslak Hellesøy
* @version $Revision$
*/
public class BeanProperty {
private final String name;
private JavaMethod accessor;
private JavaMethod mutator;
private Type type;
public BeanProperty(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setType(Type type) {
this.type = type;
}
public Type getType() {
return type;
}
public JavaMethod getAccessor() {
return accessor;
}
public void setAccessor(JavaMethod accessor) {
this.accessor = accessor;
}
public JavaMethod getMutator() {
return mutator;
}
public void setMutator(JavaMethod mutator) {
this.mutator = mutator;
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/ClassLibrary.java 0000664 0000000 0000000 00000010346 12045512336 0026073 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.model;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map;
import java.util.HashMap;
/**
* Important!! Be sure to add a classloader with the bootstrap classes.
*
*
* Normally you can generate your classLibrary like this:
* If you want full control over the classLoaders you might want to create your library like:
* Follows the
* Java Language Specification, Version 3.0.
*
* Current resolution order is:
*
* Users of this class must override
* {@link EvaluatingVisitor#getFieldReferenceValue(JavaField)} to return values
* for referenced fields.
*
* @author Jochen Kuhnle
*/
public abstract class EvaluatingVisitor implements AnnotationVisitor {
public Object getValue( Annotation annotation, String property ) {
Object result = null;
AnnotationValue value = annotation.getProperty( property );
if( value != null ) {
result = value.accept( this );
}
return result;
}
public List getListValue( Annotation annotation, String property ) {
Object value = getValue( annotation, property );
List list = null;
if( value != null ) {
if( value instanceof List ) {
list = (List) value;
}
else {
list = Collections.singletonList( value );
}
}
return list;
}
/**
* Return the result type of a binary operator
*
* Performs binary numeric promotion as specified in the Java Language
* Specification,
* @see section 5.6.1
*/
protected static Class resultType( Object left, Object right ) {
Class type = void.class;
if( left instanceof String || right instanceof String ) {
type = String.class;
}
else if( left instanceof Number && right instanceof Number ) {
if( left instanceof Double || right instanceof Double ) {
type = Double.class;
}
else if( left instanceof Float || right instanceof Float ) {
type = Float.class;
}
else if( left instanceof Long || right instanceof Long ) {
type = Long.class;
}
else {
type = Integer.class;
}
}
return type;
}
/**
* Return the numeric result type of a binary operator
*
* Performs binary numeric promotion as specified in the Java Language
* Specification,
* @see section 5.6.1
*/
protected static Class numericResultType( Object left, Object right ) {
Class type = void.class;
if( left instanceof Number && right instanceof Number ) {
if( left instanceof Long || right instanceof Long ) {
type = Long.class;
}
else if( left instanceof Integer || right instanceof Integer ) {
type = Integer.class;
}
}
return type;
}
/**
* Return the result type of an unary operator
*
* Performs unary numeric promotion as specified in the Java Language
* Specification,
* @see section 5.6.2
*/
protected static Class unaryNumericResultType( Object value ) {
Class type = void.class;
if( value instanceof Byte || value instanceof Short || value instanceof Character || value instanceof Integer ) {
type = Integer.class;
}
else if( value instanceof Long ) {
value = Long.class;
}
return type;
}
protected static Class unaryResultType( Object value ) {
Class type = unaryNumericResultType( value );
if( type == void.class ) {
if( value instanceof Float ) {
value = Float.class;
}
else if( value instanceof Double ) {
value = Double.class;
}
}
return type;
}
public Object visitAnnotation( Annotation annotation ) {
throw new UnsupportedOperationException( "Illegal annotation value '" + annotation + "'." );
}
public Object visitAnnotationAdd( AnnotationAdd op ) {
Object left = op.getLeft().accept( this );
Object right = op.getRight().accept( this );
Class type = resultType( left, right );
Object result;
if( type == String.class ) {
result = left.toString() + right.toString();
}
else if( type == Double.class ) {
result = new Double( ((Number) left).doubleValue() + ((Number) right).doubleValue() );
}
else if( type == Float.class ) {
result = new Float( ((Number) left).floatValue() + ((Number) right).floatValue() );
}
else if( type == Long.class ) {
result = new Long( ((Number) left).longValue() + ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() + ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + op + "'." );
}
return result;
}
public Object visitAnnotationConstant( AnnotationConstant constant ) {
return constant.getValue();
}
public Object visitAnnotationDivide( AnnotationDivide op ) {
Object left = op.getLeft().accept( this );
Object right = op.getRight().accept( this );
Class type = resultType( left, right );
Object result;
if( type == Double.class ) {
result = new Double( ((Number) left).doubleValue() / ((Number) right).doubleValue() );
}
else if( type == Float.class ) {
result = new Float( ((Number) left).floatValue() / ((Number) right).floatValue() );
}
else if( type == Long.class ) {
result = new Long( ((Number) left).longValue() / ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() / ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + op + "'." );
}
return result;
}
public Object visitAnnotationFieldRef( AnnotationFieldRef fieldRef ) {
JavaField javaField = fieldRef.getField();
if( javaField == null ) {
throw new IllegalArgumentException( "Cannot resolve field reference '" + fieldRef + "'." );
}
if( !javaField.isFinal() || !javaField.isStatic() ) {
throw new IllegalArgumentException( "Field reference '" + fieldRef + "' must be static and final." );
}
Object result = getFieldReferenceValue( javaField );
return result;
}
protected abstract Object getFieldReferenceValue( JavaField javaField );
public Object visitAnnotationGreaterThan( AnnotationGreaterThan op ) {
Object left = op.getLeft().accept( this );
Object right = op.getRight().accept( this );
Class type = resultType( left, right );
boolean result;
if( type == Double.class ) {
result = ((Number) left).doubleValue() > ((Number) right).doubleValue();
}
else if( type == Float.class ) {
result = ((Number) left).floatValue() > ((Number) right).floatValue();
}
else if( type == Long.class ) {
result = ((Number) left).longValue() > ((Number) right).longValue();
}
else if( type == Integer.class ) {
result = ((Number) left).intValue() > ((Number) right).intValue();
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + op + "'." );
}
return result ? Boolean.TRUE : Boolean.FALSE;
}
public Object visitAnnotationLessThan( AnnotationLessThan op ) {
Object left = op.getLeft().accept( this );
Object right = op.getRight().accept( this );
Class type = resultType( left, right );
boolean result;
if( type == Double.class ) {
result = ((Number) left).doubleValue() < ((Number) right).doubleValue();
}
else if( type == Float.class ) {
result = ((Number) left).floatValue() < ((Number) right).floatValue();
}
else if( type == Long.class ) {
result = ((Number) left).longValue() < ((Number) right).longValue();
}
else if( type == Integer.class ) {
result = ((Number) left).intValue() < ((Number) right).intValue();
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + op + "'." );
}
return result ? Boolean.TRUE : Boolean.FALSE;
}
public Object visitAnnotationMultiply( AnnotationMultiply op ) {
Object left = op.getLeft().accept( this );
Object right = op.getRight().accept( this );
Class type = resultType( left, right );
Object result;
if( type == Double.class ) {
result = new Double( ((Number) left).doubleValue() * ((Number) right).doubleValue() );
}
else if( type == Float.class ) {
result = new Float( ((Number) left).floatValue() * ((Number) right).floatValue() );
}
else if( type == Long.class ) {
result = new Long( ((Number) left).longValue() * ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() * ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + op + "'." );
}
return result;
}
public Object visitAnnotationParenExpression( AnnotationParenExpression parenExpression ) {
return parenExpression.getValue().accept( this );
}
public Object visitAnnotationSubtract( AnnotationSubtract op ) {
Object left = op.getLeft().accept( this );
Object right = op.getRight().accept( this );
Class type = resultType( left, right );
Object result;
if( type == Double.class ) {
result = new Double( ((Number) left).doubleValue() - ((Number) right).doubleValue() );
}
else if( type == Float.class ) {
result = new Float( ((Number) left).floatValue() - ((Number) right).floatValue() );
}
else if( type == Long.class ) {
result = new Long( ((Number) left).longValue() - ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() - ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + op + "'." );
}
return result;
}
public Object visitAnnotationTypeRef( AnnotationTypeRef typeRef ) {
JavaClass javaClass = typeRef.getType().getJavaClass();
return javaClass;
}
public Object visitAnnotationValueList( AnnotationValueList valueList ) {
List list = new ArrayList();
for( ListIterator i = valueList.getValueList().listIterator(); i.hasNext(); ) {
AnnotationValue value = (AnnotationValue) i.next();
Object v = value.accept( this );
list.add( v );
}
return list;
}
public Object visitAnnotationAnd( AnnotationAnd and ) {
Object left = and.getLeft().accept( this );
Object right = and.getRight().accept( this );
Class type = numericResultType( left, right );
Object result;
if( type == Long.class ) {
result = new Long( ((Number) left).longValue() & ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() & ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + and + "'." );
}
return result;
}
public Object visitAnnotationGreaterEquals( AnnotationGreaterEquals greaterEquals ) {
Object left = greaterEquals.getLeft().accept( this );
Object right = greaterEquals.getRight().accept( this );
Class type = resultType( left, right );
boolean result;
if( type == Double.class ) {
result = ((Number) left).doubleValue() >= ((Number) right).doubleValue();
}
else if( type == Float.class ) {
result = ((Number) left).floatValue() >= ((Number) right).floatValue();
}
else if( type == Long.class ) {
result = ((Number) left).longValue() >= ((Number) right).longValue();
}
else if( type == Integer.class ) {
result = ((Number) left).intValue() >= ((Number) right).intValue();
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + greaterEquals + "'." );
}
return result ? Boolean.TRUE : Boolean.FALSE;
}
public Object visitAnnotationLessEquals( AnnotationLessEquals lessEquals ) {
Object left = lessEquals.getLeft().accept( this );
Object right = lessEquals.getRight().accept( this );
Class type = resultType( left, right );
boolean result;
if( type == Double.class ) {
result = ((Number) left).doubleValue() <= ((Number) right).doubleValue();
}
else if( type == Float.class ) {
result = ((Number) left).floatValue() <= ((Number) right).floatValue();
}
else if( type == Long.class ) {
result = ((Number) left).longValue() <= ((Number) right).longValue();
}
else if( type == Integer.class ) {
result = ((Number) left).intValue() <= ((Number) right).intValue();
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + lessEquals + "'." );
}
return result ? Boolean.TRUE : Boolean.FALSE;
}
public Object visitAnnotationLogicalAnd( AnnotationLogicalAnd and ) {
Object left = and.getLeft().accept( this );
Object right = and.getRight().accept( this );
boolean result;
if( left instanceof Boolean && right instanceof Boolean ) {
result = ((Boolean) left).booleanValue() && ((Boolean) right).booleanValue();
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + and + "'." );
}
return result ? Boolean.TRUE : Boolean.FALSE;
}
public Object visitAnnotationLogicalNot( AnnotationLogicalNot not ) {
Object value = not.getValue().accept( this );
boolean result;
if( value instanceof Boolean ) {
result = !((Boolean) value).booleanValue();
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + not + "'." );
}
return result ? Boolean.TRUE : Boolean.FALSE;
}
public Object visitAnnotationLogicalOr( AnnotationLogicalOr or ) {
Object left = or.getLeft().accept( this );
Object right = or.getRight().accept( this );
boolean result;
if( left instanceof Boolean && right instanceof Boolean ) {
result = ((Boolean) left).booleanValue() || ((Boolean) right).booleanValue();
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + or + "'." );
}
return result ? Boolean.TRUE : Boolean.FALSE;
}
public Object visitAnnotationMinusSign( AnnotationMinusSign sign ) {
Object value = sign.getValue().accept( this );
Class type = unaryResultType( value );
Object result;
if( type == Integer.class ) {
result = new Integer( -((Integer) value).intValue() );
}
else if( type == Long.class ) {
result = new Long( -((Long) value).longValue() );
}
else if( type == Float.class ) {
result = new Float( -((Float) value).floatValue() );
}
else if( type == Double.class ) {
result = new Double( -((Double) value).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + sign + "'." );
}
return result;
}
public Object visitAnnotationNot( AnnotationNot not ) {
Object value = not.getValue().accept( this );
Object type = unaryNumericResultType( value );
Object result;
if( type == Long.class ) {
result = new Long( ~((Long) value).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ~((Integer) value).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + not + "'." );
}
return result;
}
public Object visitAnnotationOr( AnnotationOr or ) {
Object left = or.getLeft().accept( this );
Object right = or.getRight().accept( this );
Class type = numericResultType( left, right );
Object result;
if( type == Long.class ) {
result = new Long( ((Number) left).longValue() | ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() | ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + or + "'." );
}
return result;
}
public Object visitAnnotationPlusSign( AnnotationPlusSign sign ) {
Object value = sign.getValue().accept( this );
Object result;
if( value instanceof Number ) {
result = value;
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + sign + "'." );
}
return result;
}
public Object visitAnnotationRemainder( AnnotationRemainder remainder ) {
Object left = remainder.getLeft().accept( this );
Object right = remainder.getRight().accept( this );
Class type = resultType( left, right );
Object result;
if( type == Double.class ) {
result = new Double( ((Number) left).doubleValue() % ((Number) right).doubleValue() );
}
else if( type == Float.class ) {
result = new Float( ((Number) left).floatValue() % ((Number) right).floatValue() );
}
else if( type == Long.class ) {
result = new Long( ((Number) left).longValue() % ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() % ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + remainder + "'." );
}
return result;
}
public Object visitAnnotationShiftLeft( AnnotationShiftLeft shiftLeft ) {
Object left = shiftLeft.getLeft().accept( this );
Object right = shiftLeft.getRight().accept( this );
Class type = numericResultType( left, right );
Object result;
if( type == Long.class ) {
result = new Long( ((Number) left).longValue() << ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() << ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + shiftLeft + "'." );
}
return result;
}
public Object visitAnnotationShiftRight( AnnotationShiftRight shiftRight ) {
Object left = shiftRight.getLeft().accept( this );
Object right = shiftRight.getRight().accept( this );
Class type = numericResultType( left, right );
Object result;
if( type == Long.class ) {
result = new Long( ((Number) left).longValue() >> ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() >> ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + shiftRight + "'." );
}
return result;
}
public Object visitAnnotationUnsignedShiftRight( AnnotationUnsignedShiftRight shiftRight ) {
Object left = shiftRight.getLeft().accept( this );
Object right = shiftRight.getRight().accept( this );
Class type = numericResultType( left, right );
Object result;
if( type == Long.class ) {
result = new Long( ((Number) left).longValue() >>> ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() >>> ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + shiftRight + "'." );
}
return result;
}
public Object visitAnnotationEquals( AnnotationEquals annotationEquals ) {
Object left = annotationEquals.getLeft().accept( this );
Object right = annotationEquals.getRight().accept( this );
Class type = resultType( left, right );
boolean result;
if( type == Double.class ) {
result = ((Number) left).doubleValue() == ((Number) right).doubleValue();
}
else if( type == Float.class ) {
result = ((Number) left).floatValue() == ((Number) right).floatValue();
}
else if( type == Long.class ) {
result = ((Number) left).longValue() == ((Number) right).longValue();
}
else if( type == Integer.class ) {
result = ((Number) left).intValue() == ((Number) right).intValue();
}
else {
result = (left == right);
}
return result ? Boolean.TRUE : Boolean.FALSE;
}
public Object visitAnnotationExclusiveOr( AnnotationExclusiveOr annotationExclusiveOr ) {
Object left = annotationExclusiveOr.getLeft().accept( this );
Object right = annotationExclusiveOr.getRight().accept( this );
Class type = numericResultType( left, right );
Object result;
if( type == Long.class ) {
result = new Long( ((Number) left).longValue() ^ ((Number) right).longValue() );
}
else if( type == Integer.class ) {
result = new Integer( ((Number) left).intValue() ^ ((Number) right).intValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + annotationExclusiveOr + "'." );
}
return result;
}
public Object visitAnnotationNotEquals( AnnotationNotEquals annotationNotEquals ) {
Object left = annotationNotEquals.getLeft().accept( this );
Object right = annotationNotEquals.getRight().accept( this );
Class type = resultType( left, right );
boolean result;
if( type == Double.class ) {
result = ((Number) left).doubleValue() != ((Number) right).doubleValue();
}
else if( type == Float.class ) {
result = ((Number) left).floatValue() != ((Number) right).floatValue();
}
else if( type == Long.class ) {
result = ((Number) left).longValue() != ((Number) right).longValue();
}
else if( type == Integer.class ) {
result = ((Number) left).intValue() != ((Number) right).intValue();
}
else {
result = (left == right);
}
return result ? Boolean.TRUE : Boolean.FALSE;
}
public Object visitAnnotationQuery( AnnotationQuery annotationQuery ) {
Object value = annotationQuery.getCondition().accept( this );
if( value == null || !(value instanceof Boolean) ) {
throw new IllegalArgumentException( "Cannot evaluate '" + annotationQuery + "'." );
}
AnnotationValue expression = ((Boolean) value).booleanValue() ? annotationQuery.getTrueExpression()
: annotationQuery.getFalseExpression();
return expression.accept( this );
}
public Object visitAnnotationCast( AnnotationCast annotationCast ) {
Object value = annotationCast.getValue().accept( this );
String type = annotationCast.getType().getJavaClass().getFullyQualifiedName();
Object result;
if( value instanceof Number ) {
Number n = (Number) value;
if( type.equals( "byte" ) ) {
result = new Byte( n.byteValue() );
}
else if( type.equals( "char" ) ) {
result = new Character( (char) n.intValue() );
}
else if( type.equals( "short" ) ) {
result = new Short( n.shortValue() );
}
else if( type.equals( "int" ) ) {
result = new Integer( n.intValue() );
}
else if( type.equals( "long" ) ) {
result = new Long( n.longValue() );
}
else if( type.equals( "float" ) ) {
result = new Float( n.floatValue() );
}
else if( type.equals( "double" ) ) {
result = new Double( n.doubleValue() );
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + annotationCast + "'." );
}
}
else if( value instanceof String ) {
if( type.equals( "java.lang.String" ) ) {
result = value;
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + annotationCast + "'." );
}
}
else {
throw new IllegalArgumentException( "Cannot evaluate '" + annotationCast + "'." );
}
return result;
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/annotation/RecursiveAnnotationVisitor.java 0000664 0000000 0000000 00000013341 12045512336 0033233 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.model.annotation;
import java.util.Iterator;
import java.util.ListIterator;
import com.thoughtworks.qdox.model.Annotation;
public class RecursiveAnnotationVisitor implements AnnotationVisitor {
public Object visitAnnotation( Annotation annotation ) {
for( Iterator i = annotation.getPropertyMap().values().iterator(); i.hasNext(); ) {
AnnotationValue value = (AnnotationValue) i.next();
value.accept( this );
}
return null;
}
public Object visitAnnotationAdd( AnnotationAdd op ) {
op.getLeft().accept( this );
op.getRight().accept( this );
return null;
}
public Object visitAnnotationConstant( AnnotationConstant constant ) {
return null;
}
public Object visitAnnotationDivide( AnnotationDivide op ) {
op.getLeft().accept( this );
op.getRight().accept( this );
return null;
}
public Object visitAnnotationFieldRef( AnnotationFieldRef fieldRef ) {
return null;
}
public Object visitAnnotationGreaterThan( AnnotationGreaterThan op ) {
op.getLeft().accept( this );
op.getRight().accept( this );
return null;
}
public Object visitAnnotationLessThan( AnnotationLessThan op ) {
op.getLeft().accept( this );
op.getRight().accept( this );
return null;
}
public Object visitAnnotationMultiply( AnnotationMultiply op ) {
op.getLeft().accept( this );
op.getRight().accept( this );
return null;
}
public Object visitAnnotationParenExpression( AnnotationParenExpression parenExpression ) {
parenExpression.getValue().accept( this );
return null;
}
public Object visitAnnotationSubtract( AnnotationSubtract op ) {
op.getLeft().accept( this );
op.getRight().accept( this );
return null;
}
public Object visitAnnotationTypeRef( AnnotationTypeRef typeRef ) {
return null;
}
public Object visitAnnotationValueList( AnnotationValueList valueList ) {
for( ListIterator i = valueList.getValueList().listIterator(); i.hasNext(); ) {
AnnotationValue value = (AnnotationValue) i.next();
value.accept( this );
}
return null;
}
public Object visitAnnotationAnd( AnnotationAnd and ) {
and.getLeft().accept( this );
and.getRight().accept( this );
return null;
}
public Object visitAnnotationGreaterEquals( AnnotationGreaterEquals greaterEquals ) {
greaterEquals.getLeft().accept( this );
greaterEquals.getRight().accept( this );
return null;
}
public Object visitAnnotationLessEquals( AnnotationLessEquals lessEquals ) {
lessEquals.getLeft().accept( this );
lessEquals.getRight().accept( this );
return null;
}
public Object visitAnnotationLogicalAnd( AnnotationLogicalAnd and ) {
and.getLeft().accept( this );
and.getRight().accept( this );
return null;
}
public Object visitAnnotationLogicalNot( AnnotationLogicalNot not ) {
not.getValue().accept( this );
return null;
}
public Object visitAnnotationLogicalOr( AnnotationLogicalOr or ) {
or.getLeft().accept( this );
or.getRight().accept( this );
return null;
}
public Object visitAnnotationMinusSign( AnnotationMinusSign sign ) {
sign.getValue().accept( this );
return null;
}
public Object visitAnnotationNot( AnnotationNot not ) {
not.getValue().accept( this );
return null;
}
public Object visitAnnotationOr( AnnotationOr or ) {
or.getLeft().accept( this );
or.getRight().accept( this );
return null;
}
public Object visitAnnotationPlusSign( AnnotationPlusSign sign ) {
sign.getValue().accept( this );
return null;
}
public Object visitAnnotationRemainder( AnnotationRemainder remainder ) {
remainder.getLeft().accept( this );
remainder.getRight().accept( this );
return null;
}
public Object visitAnnotationShiftLeft( AnnotationShiftLeft left ) {
left.getLeft().accept( this );
left.getRight().accept( this );
return null;
}
public Object visitAnnotationShiftRight( AnnotationShiftRight right ) {
right.getLeft().accept( this );
right.getRight().accept( this );
return null;
}
public Object visitAnnotationUnsignedShiftRight( AnnotationUnsignedShiftRight right ) {
right.getLeft().accept( this );
right.getRight().accept( this );
return null;
}
public Object visitAnnotationEquals( AnnotationEquals annotationEquals ) {
annotationEquals.getLeft().accept( this );
annotationEquals.getRight().accept( this );
return null;
}
public Object visitAnnotationExclusiveOr( AnnotationExclusiveOr annotationExclusiveOr ) {
annotationExclusiveOr.getLeft().accept( this );
annotationExclusiveOr.getRight().accept( this );
return null;
}
public Object visitAnnotationNotEquals( AnnotationNotEquals annotationNotEquals ) {
annotationNotEquals.getLeft().accept( this );
annotationNotEquals.getRight().accept( this );
return null;
}
public Object visitAnnotationQuery( AnnotationQuery annotationQuery ) {
annotationQuery.getCondition().accept( this );
annotationQuery.getTrueExpression().accept( this );
annotationQuery.getFalseExpression().accept( this );
return null;
}
public Object visitAnnotationCast( AnnotationCast annotationCast ) {
annotationCast.getValue().accept( this );
return null;
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/util/ 0000775 0000000 0000000 00000000000 12045512336 0023607 5 ustar 00root root 0000000 0000000 qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/util/OrderedMap.java 0000664 0000000 0000000 00000006016 12045512336 0026477 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.model.util;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* This is a simple Map implementation backed by a List of Map.Entry objects.
* It has the property that iterators return entries in the order in whick
* they were inserted.
*
* Operations involving searching, including get() and put(), have cost linear
* to the size of the map. In other words, avoid this implementation if your
* Map might get large.
*
* If we could assume Java 1.4+, we'd just use java.util.LinkedHashMap
* instead of this class. But we can't.
*
* @author Mike Williams
*/
public class OrderedMap extends AbstractMap {
private Set _entrySet = new OrderedSet();
public Set entrySet() {
return _entrySet;
}
public Object put(Object key, Object value) {
Entry existingEntry = getEntryWithKey(key);
if (existingEntry == null) {
entrySet().add(new Entry(key, value));
return null;
}
Object previousValue = existingEntry.getValue();
existingEntry.setValue(value);
return previousValue;
}
private Entry getEntryWithKey(Object key) {
Iterator i = entrySet().iterator();
while (i.hasNext()) {
Entry e = (Entry) i.next();
if (eq(e.getKey(), key)) {
return e;
}
}
return null;
}
static class OrderedSet extends AbstractSet {
private List _elementList = new LinkedList();
public int size() {
return _elementList.size();
}
public Iterator iterator() {
return _elementList.iterator();
}
public boolean add(Object o) {
_elementList.add(o);
return true;
}
}
static class Entry implements Map.Entry {
Object _key;
Object _value;
public Entry(Object key, Object value) {
_key = key;
_value = value;
}
public Object getKey() {
return _key;
}
public Object getValue() {
return _value;
}
public Object setValue(Object value) {
Object oldValue = _value;
_value = value;
return oldValue;
}
public boolean equals(Object o) {
if (!(o instanceof Map.Entry)) {
return false;
}
Map.Entry e = (Map.Entry) o;
return eq(_key, e.getKey()) && eq(_value, e.getValue());
}
public int hashCode() {
return ((_key == null) ? 0 : _key.hashCode()) ^
((_value == null) ? 0 : _value.hashCode());
}
public String toString() {
return _key + "=" + _value;
}
}
private static boolean eq(Object o1, Object o2) {
return (o1 == null ? o2 == null : o1.equals(o2));
}
} qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/util/TagParser.java 0000664 0000000 0000000 00000010343 12045512336 0026343 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.model.util;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Map;
public class TagParser {
/**
* Create a StreamTokenizer suitable for parsing the tag text.
*/
static StreamTokenizer makeTokenizer(String tagValue) {
StreamTokenizer tokenizer =
new StreamTokenizer(new StringReader(tagValue));
tokenizer.resetSyntax();
tokenizer.wordChars('A','Z');
tokenizer.wordChars('a','z');
tokenizer.wordChars('0','9');
tokenizer.wordChars('-','-');
tokenizer.wordChars('_','_');
tokenizer.wordChars('.','.');
tokenizer.wordChars('<','<');
tokenizer.wordChars('>','>');
tokenizer.quoteChar('\'');
tokenizer.quoteChar('"');
tokenizer.whitespaceChars(' ',' ');
tokenizer.whitespaceChars('\t','\t');
tokenizer.whitespaceChars('\n','\n');
tokenizer.whitespaceChars('\r','\r');
tokenizer.eolIsSignificant(false);
return tokenizer;
}
/**
* Extract a Map of named parameters
*/
public static Map parseNamedParameters(String tagValue) {
Map paramMap = new OrderedMap();
StreamTokenizer tokenizer = makeTokenizer(tagValue);
try {
while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) {
String key = tokenizer.sval;
if (tokenizer.nextToken() != '=') {
break;
}
switch (tokenizer.nextToken()) {
case StreamTokenizer.TT_WORD:
case '"':
case '\'':
paramMap.put(key, tokenizer.sval);
default:
break;
}
}
} catch (IOException e) {
// ignore
}
return paramMap;
}
/**
* Extract an array of positional parameters
*/
public static String[] parseWords(String tagValue) {
StreamTokenizer tokenizer = makeTokenizer(tagValue);
ArrayList wordList = new ArrayList();
try {
while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
if (tokenizer.sval == null) {
wordList.add(Character.toString((char)tokenizer.ttype));
} else {
wordList.add(tokenizer.sval);
}
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("error tokenizing tag");
}
String[] wordArray = new String[wordList.size()];
wordList.toArray(wordArray);
return wordArray;
}
/**
* Extract an array of parameters as name or name=value representation
* @since 1.11
*/
public static String[] parseParameters(String tagValue) {
StreamTokenizer tokenizer = makeTokenizer(tagValue);
ArrayList wordList = new ArrayList();
try {
while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
StringBuilder param = new StringBuilder();
if (tokenizer.sval != null) {
param.append( tokenizer.sval );
}
//check for parameterValues
while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
if(tokenizer.sval == null && ('=' == (char)tokenizer.ttype || ','== (char)tokenizer.ttype)){
param.append( Character.toString( (char)tokenizer.ttype ) );
//file was parsed correctly, so this works.
tokenizer.nextToken();
param.append(tokenizer.sval);
}
else {
tokenizer.pushBack(); break;
}
}
wordList.add(param.toString());
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("error tokenizing tag");
}
String[] wordArray = new String[wordList.size()];
wordList.toArray(wordArray);
return wordArray;
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/parser/ 0000775 0000000 0000000 00000000000 12045512336 0023026 5 ustar 00root root 0000000 0000000 qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/parser/Builder.java 0000664 0000000 0000000 00000001762 12045512336 0025265 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.parser;
import com.thoughtworks.qdox.model.Annotation;
import com.thoughtworks.qdox.model.Type;
import com.thoughtworks.qdox.parser.structs.ClassDef;
import com.thoughtworks.qdox.parser.structs.FieldDef;
import com.thoughtworks.qdox.parser.structs.MethodDef;
import com.thoughtworks.qdox.parser.structs.PackageDef;
import com.thoughtworks.qdox.parser.structs.TagDef;
import com.thoughtworks.qdox.parser.structs.TypeDef;
public interface Builder {
void addPackage(PackageDef packageDef);
void addImport(String importName);
void addJavaDoc(String text);
void addJavaDocTag(TagDef def);
void beginClass(ClassDef def);
void endClass();
void beginMethod();
void endMethod(MethodDef def);
void addParameter(FieldDef def);
void addField(FieldDef def);
void addAnnotation(Annotation annotation);
/**
* @deprecated
*/
Type createType(String name, int dimensions);
Type createType(TypeDef name);
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/parser/Lexer.java 0000664 0000000 0000000 00000000344 12045512336 0024751 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.parser;
import java.io.IOException;
public interface Lexer {
int lex() throws IOException;
String text();
int getLine();
int getColumn();
String getCodeBody();
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/parser/ParseException.java 0000664 0000000 0000000 00000001304 12045512336 0026620 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.parser;
/**
* Thrown to indicate an error during parsing
*/
public class ParseException extends RuntimeException {
private int line;
private int column;
private String errorMessage;
public ParseException(String message, int line, int column) {
errorMessage = message + " @[" + line + "," + column + "] in ";
this.line = line;
this.column = column;
}
public int getLine() {
return line;
}
public int getColumn() {
return column;
}
public void setSourceInfo(String sourceInfo) {
errorMessage += sourceInfo;
}
public String getMessage() {
return errorMessage;
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/parser/structs/ 0000775 0000000 0000000 00000000000 12045512336 0024535 5 ustar 00root root 0000000 0000000 qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/parser/structs/AnnoDef.java 0000664 0000000 0000000 00000001745 12045512336 0026721 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.parser.structs;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class AnnoDef extends LocatedDef
{
public String name = "";
public Map args = new HashMap();
public AnnoDef tempAnno = null; // holds an annotation to construct nested values
public boolean equals(Object obj) {
AnnoDef annoDef = (AnnoDef) obj;
return annoDef.name.equals(name) && annoDef.args.equals(args);
}
public int hashCode() {
return name.hashCode() + args.hashCode();
}
public String toString() {
StringBuffer result = new StringBuffer();
result.append('@');
result.append(name);
result.append('(');
if( !args.isEmpty() ) {
for(Iterator i = args.entrySet().iterator(); i.hasNext();) result.append( i.next() + ",");
result.deleteCharAt( result.length()-1 );
}
result.append(')');
return result.toString();
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/parser/structs/ClassDef.java 0000664 0000000 0000000 00000003255 12045512336 0027071 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.parser.structs;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ClassDef extends LocatedDef {
public static final String CLASS = "class";
public static final String INTERFACE = "interface";
public static final String ENUM = "enum";
public static final String ANNOTATION_TYPE = "@interface";
public String name = "";
public Set modifiers = new HashSet();
public List typeParams = new ArrayList(); // Full details can be found in Jira's
Roadmap and
Change Log.
qdox-qdox-1.12.1/src/site/content/download.html 0000664 0000000 0000000 00000003114 12045512336 0021422 0 ustar 00root root 0000000 0000000
Latest stable release - QDox ${project.rel.org.thoughtworks.qdox:qdox}:
binary jar |
sources jar |
javadoc jar |
project tar.bz2 |
project tar.gz |
project zip
The latest snapshot - QDox ${project.dev.org.thoughtworks.qdox:qdox}:
snapshots directory.
The The When using a class, the getSuperClass()
return which class is extended. If this has not been defined in the input source code, When using a class, the getImplements()
returns an array of the interfaces implemented by the class. If none are implemented, an empty array is returned. When
using an interface, this returns an array of interfaces the current interface EXTENDS.
I some cases QDox is used to generate classes for another project with it's own dependencies. This could result in class-collission.
By default the JavadocBuilder will contain the classloader(s) of the current project, but by defining your own classLibrary you can have the required control.
QDox is a high speed, small footprint parser for extracting class/interface/method
definitions from source files complete with JavaDoc @tags. It is designed to be used
by active code generators or documentation tools.
A custom built parser has been built using JFlex
and BYacc/J.
These have been chosen because of their
proven performance and they require no external libraries at runtime.
The parser skims the source files only looking for things of interest such as
class/interface definitions, import statements, JavaDoc and member declarations. The parser ignores things
such as actual method implementations to avoid overhead (while in method blocks, curly brace counting
suffices).
The end result of the parser is a very simple document model containing enough information to be useful.
Copyright 2002-2009 Joe Walnes and QDox Project Team 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 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.
After the source code has been parsed, the content of the files can be navigated using a simple to use and intuitive object model. Represents a complete .java file. This contains a collection of classes. Represents the package of the class. Represents a class or interface. This contains doclet tags, fields and methods. Information about the class
definition is available, such as which classes are extended, which interfaces implemented and modifiers. Represents a field in a class. This has doclet tags, a name and a type. Represents a method in a class. This has doclet tags, a name, return type, parameters and exceptions. Represents a parameter passed to a method. This has a name and a type. Represents a specific instance of a class used by another class (such as return value, superclass, etc).
The value represents the name of the class. Array dimensions are also available. Since 1.8 it's also possible to get the generic value of the Type Represents a JavaDoc tag. Each tag has a name and a value. Optionally, the value can be broken up into
tokens accessed by index or name. The The returned
This section describes what needs to be done when upgrading to QDox 1.10.1.
In some cases the Type.toString() was inconsequent (QDOX-182) so we had to change the implementation.
If you use this in combination with innerClasses you should use Type.getFullyQualifiedName() to get the same result.
This section describes what needs to be done when upgrading to QDox 1.10.
The toString()-method in most of the JavaObjects under com.thoughtworks.qdox.models used to return the corresponding codeblock.
This method has been renamed to getCodeBlock(). The toString() will follow the Java API Specs as described for each equivalent object under the java.lang-package.
Some methods require extra attention, because there's not an exact match. Watch out for differences between Type and JavaClass.
false
, iff there was new input.
*
* @exception java.io.IOException if any I/O-Error occurs
*/
private boolean zzRefill() throws java.io.IOException {
/* first: make room (if you can) */
if (zzStartRead > 0) {
System.arraycopy(zzBuffer, zzStartRead,
zzBuffer, 0,
zzEndRead-zzStartRead);
/* translate stored positions */
zzEndRead-= zzStartRead;
zzCurrentPos-= zzStartRead;
zzMarkedPos-= zzStartRead;
zzStartRead = 0;
}
/* is the buffer big enough? */
if (zzCurrentPos >= zzBuffer.length) {
/* if not: blow it up */
char newBuffer[] = new char[zzCurrentPos*2];
System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);
zzBuffer = newBuffer;
}
/* finally: fill the buffer with new input */
int numRead = zzReader.read(zzBuffer, zzEndRead,
zzBuffer.length-zzEndRead);
if (numRead > 0) {
zzEndRead+= numRead;
return false;
}
// unlikely but not impossible: read 0 characters, but not at end of stream
if (numRead == 0) {
int c = zzReader.read();
if (c == -1) {
return true;
} else {
zzBuffer[zzEndRead++] = (char) c;
return false;
}
}
// numRead < 0)
return true;
}
/**
* Closes the input stream.
*/
public final void yyclose() throws java.io.IOException {
zzAtEOF = true; /* indicate end of file */
zzEndRead = zzStartRead; /* invalidate buffer */
if (zzReader != null)
zzReader.close();
}
/**
* Stores the current input stream on a stack, and
* reads from a new stream. Lexical state, line,
* char, and column counting remain untouched.
*
* The current input stream can be restored with
* yypopstream (usually in an <Example
*
*
* @author Joe Walnes
* @author Aslak Hellesøy
* @author Robert Scholte
*/
public class JavaDocBuilder implements Serializable {
private final JavaClassContext context;
private Set packages = new HashSet();
private List sources = new ArrayList();
private DocletTagFactory docletTagFactory;
private String encoding = System.getProperty("file.encoding");
private boolean debugLexer;
private boolean debugParser;
private ErrorHandler errorHandler = new DefaultErrorHandler();
public static interface ErrorHandler {
void handle(ParseException parseException);
}
public static class DefaultErrorHandler implements ErrorHandler, Serializable {
public void handle(ParseException parseException) {
throw parseException;
}
}
public JavaDocBuilder() {
this(new DefaultDocletTagFactory());
}
public JavaDocBuilder(DocletTagFactory docletTagFactory) {
this.docletTagFactory = docletTagFactory;
ClassLibrary classLibrary = new ClassLibrary();
classLibrary.addDefaultLoader();
this.context = new JavaClassContext(this);
this.context.setClassLibrary(classLibrary);
}
public JavaDocBuilder(ClassLibrary classLibrary) {
this(new DefaultDocletTagFactory(), classLibrary);
}
public JavaDocBuilder(DocletTagFactory docletTagFactory, ClassLibrary classLibrary) {
this.docletTagFactory = docletTagFactory;
this.context = new JavaClassContext(this);
this.context.setClassLibrary(classLibrary);
}
private void addClasses(JavaSource source) {
Set resultSet = new HashSet();
addClassesRecursive(source, resultSet);
JavaClass[] javaClasses = (JavaClass[]) resultSet.toArray(new JavaClass[resultSet.size()]);
for (int classIndex = 0; classIndex < javaClasses.length; classIndex++) {
JavaClass cls = javaClasses[classIndex];
addClass(cls);
}
}
private void addClass(JavaClass cls) {
context.add(cls);
cls.setJavaClassContext(context);
}
public JavaClass getClassByName(String name) {
if (name == null) {
return null;
}
return context.getClassByName(name);
}
protected JavaClass createSourceClass(String name) {
File sourceFile = context.getClassLibrary().getSourceFile( name );
if (sourceFile != null) {
try
{
JavaSource source = addSource( sourceFile );
for (int index = 0; index < source.getClasses().length; index++) {
JavaClass clazz = source.getClasses()[index];
if (name.equals(clazz.getFullyQualifiedName())) {
return clazz;
}
}
return source.getNestedClassByName( name );
}
catch ( FileNotFoundException e )
{
//nop
}
catch ( IOException e )
{
//nop
}
}
return null;
}
protected JavaClass createUnknownClass(String name) {
ModelBuilder unknownBuilder = new ModelBuilder(context, docletTagFactory, new HashMap());
ClassDef classDef = new ClassDef();
classDef.name = name;
unknownBuilder.beginClass(classDef);
unknownBuilder.endClass();
JavaSource unknownSource = unknownBuilder.getSource();
JavaClass result = unknownSource.getClasses()[0];
return result;
}
protected JavaClass createBinaryClass(String name) {
// First see if the class exists at all.
Class clazz = context.getClass(name);
if (clazz == null) {
return null;
} else {
try {
// Create a new builder and mimic the behaviour of the parser.
// We're getting all the information we need via reflection instead.
ModelBuilder binaryBuilder = new ModelBuilder(context, docletTagFactory, new HashMap());
// Set the package name and class name
String packageName = getPackageName(name);
binaryBuilder.addPackage(new PackageDef(packageName));
ClassDef classDef = new ClassDef();
classDef.name = getClassName(name);
// Set the extended class and interfaces.
Class[] interfaces = clazz.getInterfaces();
if (clazz.isInterface()) {
// It's an interface
classDef.type = ClassDef.INTERFACE;
for (int i = 0; i < interfaces.length; i++) {
Class anInterface = interfaces[i];
classDef.extendz.add(new TypeDef(anInterface.getName()));
}
} else {
// It's a class
for (int i = 0; i < interfaces.length; i++) {
Class anInterface = interfaces[i];
classDef.implementz.add(new TypeDef(anInterface.getName()));
}
Class superclass = clazz.getSuperclass();
if (superclass != null) {
classDef.extendz.add(new TypeDef(superclass.getName()));
}
}
addModifiers(classDef.modifiers, clazz.getModifiers());
binaryBuilder.beginClass(classDef);
// add the constructors
//
// This also adds the default constructor if any which is different
// to the source code as that does not create a default constructor
// if no constructor exists.
Constructor[] constructors = clazz.getDeclaredConstructors();
for (int i = 0; i < constructors.length; i++) {
addMethodOrConstructor(constructors[i], binaryBuilder);
}
// add the methods
Method[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
addMethodOrConstructor(methods[i], binaryBuilder);
}
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
addField(fields[i], binaryBuilder);
}
binaryBuilder.endClass();
JavaSource binarySource = binaryBuilder.getSource();
// There is always only one class in a "binary" source.
JavaClass result = binarySource.getClasses()[0];
return result;
} catch (NoClassDefFoundError e) {
return null;
}
}
}
private void addModifiers(Set set, int modifier) {
String modifierString = Modifier.toString(modifier);
for (StringTokenizer stringTokenizer = new StringTokenizer(modifierString); stringTokenizer.hasMoreTokens();) {
set.add(stringTokenizer.nextToken());
}
}
private void addField(Field field, ModelBuilder binaryBuilder) {
FieldDef fieldDef = new FieldDef();
Class fieldType = field.getType();
fieldDef.name = field.getName();
fieldDef.type = getTypeDef(fieldType);
fieldDef.dimensions = getDimension(fieldType);
addModifiers( fieldDef.modifiers, field.getModifiers());
binaryBuilder.addField(fieldDef);
}
private void addMethodOrConstructor(Member member, ModelBuilder binaryBuilder) {
MethodDef methodDef = new MethodDef();
// The name of constructors are qualified. Need to strip it.
// This will work for regular methods too, since -1 + 1 = 0
int lastDot = member.getName().lastIndexOf('.');
methodDef.name = member.getName().substring(lastDot + 1);
addModifiers(methodDef.modifiers, member.getModifiers());
Class[] exceptions;
Class[] parameterTypes;
if (member instanceof Method) {
methodDef.constructor = false;
// For some stupid reason, these methods are not defined in Member,
// but in both Method and Construcotr.
exceptions = ((Method) member).getExceptionTypes();
parameterTypes = ((Method) member).getParameterTypes();
Class returnType = ((Method) member).getReturnType();
methodDef.returnType = getTypeDef(returnType);
methodDef.dimensions = getDimension(returnType);
} else {
methodDef.constructor = true;
exceptions = ((Constructor) member).getExceptionTypes();
parameterTypes = ((Constructor) member).getParameterTypes();
}
for (int j = 0; j < exceptions.length; j++) {
Class exception = exceptions[j];
methodDef.exceptions.add(exception.getName());
}
binaryBuilder.addMethod(methodDef);
for (int j = 0; j < parameterTypes.length; j++) {
FieldDef param = new FieldDef();
Class parameterType = parameterTypes[j];
param.name = "p" + j;
param.type = getTypeDef(parameterType);
param.dimensions = getDimension(parameterType);
binaryBuilder.addParameter( param );
}
}
private static final int getDimension(Class c) {
return c.getName().lastIndexOf('[') + 1;
}
private static String getTypeName(Class c) {
return c.getComponentType() != null ? c.getComponentType().getName() : c.getName();
}
private static TypeDef getTypeDef(Class c) {
return new TypeDef(getTypeName(c));
}
private String getPackageName(String fullClassName) {
int lastDot = fullClassName.lastIndexOf('.');
return lastDot == -1 ? "" : fullClassName.substring(0, lastDot);
}
private String getClassName(String fullClassName) {
int lastDot = fullClassName.lastIndexOf('.');
return lastDot == -1 ? fullClassName : fullClassName.substring(lastDot + 1);
}
public JavaSource addSource(Reader reader) {
return addSource(reader, "UNKNOWN SOURCE");
}
public JavaSource addSource(Reader reader, String sourceInfo) {
ModelBuilder builder = new ModelBuilder(context, docletTagFactory, null);
Lexer lexer = new JFlexLexer(reader);
Parser parser = new Parser(lexer, builder);
parser.setDebugLexer(debugLexer);
parser.setDebugParser(debugParser);
try {
parser.parse();
} catch (ParseException e) {
e.setSourceInfo(sourceInfo);
errorHandler.handle(e);
}
finally {
try {
reader.close();
}
catch (IOException e) {
}
}
JavaSource source = builder.getSource();
sources.add(source);
addClasses(source);
JavaPackage pkg = context.getPackageByName( source.getPackageName() );
if (!packages.contains(pkg)) {
packages.add(pkg);
}
// JavaClass[] classes = source.getClasses();
// for (int i = 0; i < classes.length; i++) {
// if (pkg != null) {
// pkg.addClass(classes[i]);
// }
// }
return source;
}
public JavaSource addSource(File file) throws IOException, FileNotFoundException {
return addSource(file.toURL());
}
public JavaSource addSource(URL url) throws IOException, FileNotFoundException {
JavaSource source = addSource(new InputStreamReader(url.openStream(),encoding), url.toExternalForm());
source.setURL(url);
return source;
}
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
public JavaSource[] getSources() {
return (JavaSource[]) sources.toArray(new JavaSource[sources.size()]);
}
/**
* Returns all the classes found in all the sources, including inner classes
* and "extra" classes (multiple outer classes defined in the same source file).
*
* @return all the classes found in all the sources.
* @since 1.3
*/
public JavaClass[] getClasses() {
Set resultSet = new HashSet();
JavaSource[] javaSources = getSources();
for (int i = 0; i < javaSources.length; i++) {
JavaSource javaSource = javaSources[i];
addClassesRecursive(javaSource, resultSet);
}
JavaClass[] result = (JavaClass[]) resultSet.toArray(new JavaClass[resultSet.size()]);
return result;
}
/**
* Returns all the packages found in all the sources.
*
* @return all the packages found in all the sources.
* @since 1.9
*/
public JavaPackage[] getPackages() {
return (JavaPackage[]) packages.toArray(new JavaPackage[packages.size()]);
}
private void addClassesRecursive(JavaSource javaSource, Set resultSet) {
JavaClass[] classes = javaSource.getClasses();
for (int j = 0; j < classes.length; j++) {
JavaClass javaClass = classes[j];
addClassesRecursive(javaClass, resultSet);
}
}
private void addClassesRecursive(JavaClass javaClass, Set set) {
// Add the class...
set.add(javaClass);
// And recursively all of its inner classes
JavaClass[] innerClasses = javaClass.getNestedClasses();
for (int i = 0; i < innerClasses.length; i++) {
JavaClass innerClass = innerClasses[i];
addClassesRecursive(innerClass, set);
}
}
/**
* Add all files in a directory (and subdirs, recursively).
*
* If a file cannot be read, a RuntimeException shall be thrown.
*/
public void addSourceTree(File file) {
FileVisitor errorHandler = new FileVisitor() {
public void visitFile(File badFile) {
throw new RuntimeException("Cannot read file : " + badFile.getName());
}
};
addSourceTree(file, errorHandler);
}
/**
* Add all files in a directory (and subdirs, recursively).
*
* If a file cannot be read, errorHandler will be notified.
*/
public void addSourceTree(File file, final FileVisitor errorHandler) {
DirectoryScanner scanner = new DirectoryScanner(file);
scanner.addFilter(new SuffixFilter(".java"));
scanner.scan(new FileVisitor() {
public void visitFile(File currentFile) {
try {
addSource(currentFile);
} catch (IOException e) {
errorHandler.visitFile(currentFile);
}
}
});
}
public List search(Searcher searcher) {
List results = new LinkedList();
for (Iterator iterator = context.getClassLibrary().all().iterator(); iterator.hasNext();) {
String clsName = (String) iterator.next();
JavaClass cls = getClassByName(clsName);
if (searcher.eval(cls)) {
results.add(cls);
}
}
return results;
}
public ClassLibrary getClassLibrary() {
return context.getClassLibrary();
}
public void save(File file) throws IOException {
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream out = new ObjectOutputStream(fos);
try {
out.writeObject(this);
} finally {
out.close();
fos.close();
}
}
/**
* Note that after loading JavaDocBuilder classloaders need to be re-added.
*/
public static JavaDocBuilder load(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
ObjectInputStream in = new ObjectInputStream(fis);
JavaDocBuilder builder = null;
try {
builder = (JavaDocBuilder) in.readObject();
} catch (ClassNotFoundException e) {
throw new Error("Couldn't load class : " + e.getMessage());
} finally {
in.close();
fis.close();
}
return builder;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
* Forces QDox to dump tokens returned from lexer to System.err.
*/
public void setDebugLexer(boolean debugLexer) {
this.debugLexer = debugLexer;
}
/**
* Forces QDox to dump parser states to System.out.
*/
public void setDebugParser(boolean debugParser) {
this.debugParser = debugParser;
}
public JavaPackage getPackageByName( String name )
{
if(name != null) {
Iterator iter = packages.iterator();
while(iter.hasNext()) {
JavaPackage pkg = (JavaPackage) iter.next();
if(name.equals( pkg.getName() )) {
return pkg;
}
}
}
return null;
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/Searcher.java 0000664 0000000 0000000 00000000220 12045512336 0024123 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox;
import com.thoughtworks.qdox.model.JavaClass;
public interface Searcher {
boolean eval(JavaClass cls);
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/ant/ 0000775 0000000 0000000 00000000000 12045512336 0022314 5 ustar 00root root 0000000 0000000 qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/ant/AbstractQdoxTask.java 0000664 0000000 0000000 00000006015 12045512336 0026403 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.ant;
import com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaSource;
import com.thoughtworks.qdox.model.DocletTagFactory;
import com.thoughtworks.qdox.model.DefaultDocletTagFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
public abstract class AbstractQdoxTask extends Task {
private Vector filesets = new Vector();
protected HashMap fileMap = new HashMap();
protected ArrayList allSources = new ArrayList();
protected ArrayList allClasses = new ArrayList();
public void addFileset(FileSet set) {
filesets.addElement(set);
}
protected void buildFileMap() {
for (int i = 0; i < filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
String[] srcFiles = ds.getIncludedFiles();
buildFileMap(fs.getDir(getProject()), srcFiles);
}
}
protected void buildFileMap(File directory, String[] sourceFiles) {
for (int i = 0; i < sourceFiles.length; i++) {
File src = new File(directory, sourceFiles[i]);
fileMap.put(src.getAbsolutePath(), src);
}
}
public void execute() throws BuildException {
validateAttributes();
buildFileMap();
JavaDocBuilder builder = new JavaDocBuilder(createDocletTagFactory());
// Add a classloader that has the taskdef's classpath.
builder.getClassLibrary().addClassLoader(getClass().getClassLoader());
mergeBuilderSources(builder);
JavaSource[] sources = builder.getSources();
processSources(sources);
}
protected DocletTagFactory createDocletTagFactory() {
return new DefaultDocletTagFactory();
}
private void mergeBuilderSources(JavaDocBuilder builder) {
for (Iterator iterator = fileMap.keySet().iterator(); iterator.hasNext();) {
String sourceFile = (String) iterator.next();
builder.addSourceTree((File) fileMap.get(sourceFile));
}
}
protected void processSources(JavaSource[] sources) {
for (int i = 0; i < sources.length; i++) {
JavaSource source = sources[i];
allSources.add(source);
JavaClass[] classes = source.getClasses();
processClasses(classes);
}
}
protected void processClasses(JavaClass[] classes) {
for (int j = 0; j < classes.length; j++) {
JavaClass clazz = classes[j];
allClasses.add(clazz);
}
}
protected void validateAttributes() throws BuildException {
if (filesets.size() == 0) {
throw new BuildException("Specify at least one source fileset.");
}
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/directorywalker/ 0000775 0000000 0000000 00000000000 12045512336 0024744 5 ustar 00root root 0000000 0000000 qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/directorywalker/DirectoryScanner.java 0000664 0000000 0000000 00000002750 12045512336 0031071 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.directorywalker;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
public class DirectoryScanner {
private File file;
private Collection filters = new HashSet();
public DirectoryScanner(File file) {
this.file = file;
}
public File[] scan() {
final List results = new ArrayList();
walk(new FileVisitor() {
public void visitFile(File file) {
results.add(file);
}
}, this.file);
File[] resultsArray = new File[results.size()];
results.toArray(resultsArray);
return resultsArray;
}
private void walk(FileVisitor visitor, File current) {
if (current.isDirectory()) {
File[] currentFiles = current.listFiles();
for (int i = 0; i < currentFiles.length; i++) {
walk(visitor, currentFiles[i]);
}
} else {
for (Iterator iterator = this.filters.iterator(); iterator.hasNext();) {
Filter filter = (Filter) iterator.next();
if (!filter.filter(current)) {
return;
}
}
visitor.visitFile(current);
}
}
public void addFilter(Filter filter) {
this.filters.add(filter);
}
public void scan(FileVisitor fileVisitor) {
walk(fileVisitor, this.file);
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/directorywalker/FileVisitor.java 0000664 0000000 0000000 00000000210 12045512336 0030037 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.directorywalker;
import java.io.File;
public interface FileVisitor {
void visitFile(File file);
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/directorywalker/Filter.java 0000664 0000000 0000000 00000000203 12045512336 0027027 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.directorywalker;
import java.io.File;
public interface Filter {
boolean filter(File file);
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/directorywalker/SuffixFilter.java 0000664 0000000 0000000 00000000540 12045512336 0030220 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.directorywalker;
import java.io.File;
public class SuffixFilter implements Filter {
private String suffixFilter;
public SuffixFilter(String suffixFilter) {
this.suffixFilter = suffixFilter;
}
public boolean filter(File file) {
return file.getName().endsWith(this.suffixFilter);
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/junit/ 0000775 0000000 0000000 00000000000 12045512336 0022663 5 ustar 00root root 0000000 0000000 qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/junit/APITestCase.java 0000664 0000000 0000000 00000032477 12045512336 0025610 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.junit;
import com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.model.AbstractBaseJavaEntity;
import com.thoughtworks.qdox.model.AbstractJavaEntity;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaSource;
import junit.framework.TestCase;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.StringTokenizer;
/**
* APITestCase is a JUnit extension that will let you compare two sources
* (typically one kept as a static expected result and a generated one) on the API level.
*
* This class has been ported from XJavaDoc's CodeTestCase, carrying over only the
* parts that compare on the API level. The original CodeTestCase also has comparison
* of Java source AST (Abstract Syntax Trees). This will probably be extracted into
* a ASTTestCase class and hosted as a separate project somewhere else. It should
* probably be based on JavaCC for ease of porting.
*
* @author Aslak Hellesøy
* @author Laurent Etiemble
*/
public abstract class APITestCase extends TestCase {
/*
* Needed to sort JavaClass, JavaField and JavaMethod as they
* don't implement Comparable
*/
private static Comparator ENTITY_COMPARATOR = new Comparator() {
public int compare(Object o1, Object o2) {
AbstractBaseJavaEntity entity1 = (AbstractBaseJavaEntity) o1;
AbstractBaseJavaEntity entity2 = (AbstractBaseJavaEntity) o2;
return entity1.getName().compareTo(entity2.getName());
}
};
public APITestCase() {
super();
}
/**
* Compares API of both sources in the readers.
*
*
* // -- Create JavaDocBuilder
*
* JavaDocBuilder builder = new JavaDocBuilder();
*
* // -- Add some files
*
* // Reading a single source file.
* builder.addSource(new FileReader("MyFile.java"));
*
* // Reading from another kind of input stream.
* builder.addSource(new StringReader("package test; public class Hello {}"));
*
* // Adding all .java files in a source tree (recursively).
* builder.addSourceTree(new File("mysrcdir"));
*
* // -- Retrieve source files
*
* JavaSource[] source = builder.getSources();
*
*
equals
and
* hashCode
methods, the comparison is done by hand.equals
and
* hashCode
methods, the comparison is done by hand.getTagByName(String).getNamedParameter(String)
* that also checks for null tag.
* @since 1.3
*/
public String getNamedParameter(String tagName, String parameterName) {
DocletTag tag = getTagByName(tagName);
if(tag != null) {
return tag.getNamedParameter(parameterName);
} else {
return null;
}
}
void commentHeader(IndentBuffer buffer) {
if (comment == null && (tags == null || tags.length == 0)) {
return;
} else {
buffer.write("/**");
buffer.newline();
if (comment != null && comment.length() > 0) {
buffer.write(" * ");
buffer.write(comment.replaceAll("\n", "\n * "));
buffer.newline();
}
if (tags != null && tags.length > 0) {
if (comment != null && comment.length() > 0) {
buffer.write(" *");
buffer.newline();
}
for (int i = 0; i < tags.length; i++) {
DocletTag docletTag = tags[i];
buffer.write(" * @");
buffer.write(docletTag.getName());
if (docletTag.getValue().length() > 0) {
buffer.write(' ');
buffer.write(docletTag.getValue());
}
buffer.newline();
}
}
buffer.write(" */");
buffer.newline();
}
}
public String getCodeBlock() {
IndentBuffer result = new IndentBuffer();
write(result);
return result.toString();
}
protected void write(IndentBuffer result) {
commentHeader(result);
writeBody(result);
}
protected abstract void writeBody(IndentBuffer result);
public void setModifiers(String[] modifiers) {
this.modifiers = Arrays.asList(modifiers);
}
public void setComment(String comment) {
this.comment = comment;
}
public void setTags(List tagList) {
this.tags = new DocletTag[tagList.size()];
tagList.toArray(this.tags);
}
//helper methods for querying the modifiers
public boolean isAbstract() {
return isModifierPresent("abstract");
}
public boolean isPublic() {
return isModifierPresent("public");
}
public boolean isPrivate() {
return isModifierPresent("private");
}
public boolean isProtected() {
return isModifierPresent("protected");
}
public boolean isStatic() {
return isModifierPresent("static");
}
public boolean isFinal() {
return isModifierPresent("final");
}
public boolean isSynchronized() {
return isModifierPresent("synchronized");
}
public boolean isTransient() {
return isModifierPresent("transient");
}
/**
* @since 1.4
*/
public boolean isVolatile() {
return isModifierPresent("volatile");
}
/**
* @since 1.4
*/
public boolean isNative() {
return isModifierPresent("native");
}
/**
* @since 1.4
*/
public boolean isStrictfp() {
return isModifierPresent("strictfp");
}
private boolean isModifierPresent(String modifier) {
return modifiers.contains(modifier);
}
protected void writeNonAccessibilityModifiers(IndentBuffer result) {
// modifiers (anything else)
for (Iterator iter = modifiers.iterator(); iter.hasNext();) {
String modifier = (String) iter.next();
if (!modifier.startsWith("p")) {
result.write(modifier);
result.write(' ');
}
}
}
protected void writeAccessibilityModifier(IndentBuffer result) {
for (Iterator iter = modifiers.iterator(); iter.hasNext();) {
String modifier = (String) iter.next();
if (modifier.startsWith("p")) {
result.write(modifier);
result.write(' ');
}
}
}
protected void writeAllModifiers(IndentBuffer result) {
for (Iterator iter = modifiers.iterator(); iter.hasNext();) {
String modifier = (String) iter.next();
result.write(modifier);
result.write(' ');
}
}
public JavaSource getSource() {
return parentClass.getParentSource();
}
public void setParentClass( JavaClass parentClass )
{
this.parentClass = parentClass;
}
public JavaClass getParentClass()
{
return parentClass;
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/Annotation.java 0000664 0000000 0000000 00000006543 12045512336 0025617 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.model;
import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.thoughtworks.qdox.model.annotation.AnnotationValue;
import com.thoughtworks.qdox.model.annotation.AnnotationVisitor;
/**
*
* @author Eric Redmond
*/
public class Annotation implements AnnotationValue, Serializable
{
private final Type type;
private final int lineNumber;
/**
* Annotation properties as AnnotationValues
*
*
* ClassLibrary classLibrary = new ClassLibrary();
* classLibrary.addDefaultLoader();
*
*
*
* ClassLibrary classLibrary = new ClassLibrary( ClassLoader.getSystemClassLoader() )
*
*
*
* @todo Static imports are not handled yet
*
* @param typeName
* @return Resolved type name
*/
private String resolveTypeInternal(String typeName) {
String resolvedName = null;
lookup : {
// primitive types
if(PRIMITIVE_TYPES.contains( typeName )) {
resolvedName = typeName;
break lookup;
}
String outerName = typeName;
String nestedName = typeName.replace('.', '$');
int dotpos = typeName.indexOf( '.' );
if(dotpos >= 0) {
outerName = typeName.substring( 0, dotpos );
}
// Check single-type-import with fully qualified name
resolvedName = resolveImportedType( typeName, nestedName, true );
if(resolvedName != null) {
break lookup;
}
// Check single-type-import with outer name
resolvedName = resolveImportedType( outerName, nestedName, false );
if(resolvedName != null) {
break lookup;
}
// check for a class globally
resolvedName = resolveFullyQualifiedType( typeName );
if(resolvedName != null) {
break lookup;
}
if(context.getClassLibrary() != null) {
// check for a class in the same package
resolvedName = resolveFromLibrary( getClassNamePrefix() + nestedName );
if(resolvedName != null) {
break lookup;
}
// try java.lang.*
resolvedName = resolveFromLibrary( "java.lang." + nestedName );
if(resolvedName != null) {
break lookup;
}
}
// Check type-import-on-demand
resolvedName = resolveImportedType( "*", nestedName, false );
if(resolvedName != null) {
break lookup;
}
}
return resolvedName;
}
private String resolveImportedType( String importSpec, String typeName, boolean fullMatch ) {
String[] imports = getImports();
String resolvedName = null;
String dotSuffix = "." + importSpec;
for (int i = 0; i < imports.length && resolvedName == null; i++) {
String imprt = imports[i];
//static imports can refer to inner classes
if(imprt.startsWith( "static " ) ) {
imprt = imprt.substring( 7 );
}
if (imprt.equals(importSpec) || (!fullMatch && imprt.endsWith(dotSuffix))) {
String candidateName = imprt.substring( 0, imprt.length() - importSpec.length()) + typeName;
resolvedName = resolveFullyQualifiedType( candidateName );
if(resolvedName == null && !"*".equals(importSpec)) {
resolvedName = candidateName;
}
}
}
return resolvedName;
}
private String resolveFromLibrary(String typeName) {
return context.getClassLibrary().contains( typeName ) ? typeName : null;
}
private String resolveFullyQualifiedType(String typeName) {
if (context.getClassLibrary() != null) {
int indexOfLastDot = typeName.lastIndexOf('.');
if (indexOfLastDot >= 0) {
String root = typeName.substring(0,indexOfLastDot);
String leaf = typeName.substring(indexOfLastDot+1);
String resolvedTypeName = resolveFullyQualifiedType(root + "$" + leaf);
if(resolvedTypeName != null) {
return resolvedTypeName;
}
}
// check for fully-qualified class
if (context.getClassLibrary().contains(typeName)) {
return typeName;
}
}
return null;
}
public String getClassNamePrefix() {
if (getPackage() == null) return "";
return getPackage().getName() + ".";
}
public JavaSource getParentSource() {
return this;
}
public JavaClass getNestedClassByName(String name) {
JavaClass result = null;
for (ListIterator i = classes.listIterator(); i.hasNext(); ) {
JavaClass candidateClass = (JavaClass) i.next();
if (candidateClass.getName().equals(name)) {
result = candidateClass;
break;
}
}
return result;
}
/**
*
* @return
* @deprecated, use getJavaClassContext().getClassLibrary()
*/
public ClassLibrary getClassLibrary() {
return this.context.getClassLibrary();
}
public String getPackageName()
{
return (packge == null ? "" : packge.getName());
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/Member.java 0000664 0000000 0000000 00000000351 12045512336 0024703 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.model;
/**
* @author Aslak Hellesøy
* @version $Revision$
* @since 1.4
*/
public interface Member {
String getDeclarationSignature(boolean withModifiers);
String getCallSignature();
} qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/ModelBuilder.java 0000664 0000000 0000000 00000026076 12045512336 0026057 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import com.thoughtworks.qdox.JavaClassContext;
import com.thoughtworks.qdox.model.annotation.AnnotationFieldRef;
import com.thoughtworks.qdox.model.annotation.AnnotationVisitor;
import com.thoughtworks.qdox.model.annotation.RecursiveAnnotationVisitor;
import com.thoughtworks.qdox.parser.Builder;
import com.thoughtworks.qdox.parser.structs.ClassDef;
import com.thoughtworks.qdox.parser.structs.FieldDef;
import com.thoughtworks.qdox.parser.structs.MethodDef;
import com.thoughtworks.qdox.parser.structs.PackageDef;
import com.thoughtworks.qdox.parser.structs.TagDef;
import com.thoughtworks.qdox.parser.structs.TypeDef;
import com.thoughtworks.qdox.parser.structs.TypeVariableDef;
/**
* @author Joe Walnes
* @author Robert Scholte
*/
public class ModelBuilder implements Builder {
private final JavaClassContext context;
private final JavaSource source;
private JavaClassParent currentParent;
private JavaClass currentClass;
private JavaMethod currentMethod;
private List currentAnnoDefs;
private String lastComment;
private List lastTagSet;
private DocletTagFactory docletTagFactory;
public ModelBuilder() {
this(new JavaClassContext(new ClassLibrary()), new DefaultDocletTagFactory(), new HashMap());
}
public ModelBuilder(JavaClassContext context, DocletTagFactory docletTagFactory, Map allPackages) {
this.context = context;
this.docletTagFactory = docletTagFactory;
source = new JavaSource(context);
currentParent = source;
currentAnnoDefs = new ArrayList();
}
public void addPackage(PackageDef packageDef) {
JavaPackage jPackage = context.getPackageByName( packageDef.name );;
if (jPackage == null) {
jPackage = new JavaPackage(packageDef.name);
context.add( jPackage );
}
jPackage.setLineNumber(packageDef.lineNumber);
setAnnotations(jPackage);
source.setPackage(jPackage);
}
public void addImport(String importName) {
source.addImport(importName);
}
public void addJavaDoc(String text) {
lastComment = text;
lastTagSet = new LinkedList();
}
public void addJavaDocTag(TagDef tagDef) {
lastTagSet.add(tagDef);
}
public void beginClass(ClassDef def) {
currentClass = new JavaClass();
currentClass.setLineNumber(def.lineNumber);
// basic details
currentClass.setName(def.name);
currentClass.setInterface(ClassDef.INTERFACE.equals(def.type));
currentClass.setEnum(ClassDef.ENUM.equals(def.type));
currentClass.setAnnotation(ClassDef.ANNOTATION_TYPE.equals(def.type));
// superclass
if (currentClass.isInterface()) {
currentClass.setSuperClass(null);
} else if (!currentClass.isEnum()) {
currentClass.setSuperClass(def.extendz.size() > 0 ? createType((TypeDef) def.extendz.toArray()[0], 0) : null);
}
// implements
{
Set implementSet = currentClass.isInterface() ? def.extendz : def.implementz;
Iterator implementIt = implementSet.iterator();
Type[] implementz = new Type[implementSet.size()];
for (int i = 0; i < implementz.length && implementIt.hasNext(); i++) {
implementz[i] = createType((TypeDef) implementIt.next(), 0);
}
currentClass.setImplementz(implementz);
}
// modifiers
{
String[] modifiers = new String[def.modifiers.size()];
def.modifiers.toArray(modifiers);
currentClass.setModifiers(modifiers);
}
// typeParameters
if (def.typeParams != null) {
TypeVariable[] typeParams = new TypeVariable[def.typeParams.size()];
int index = 0;
for(Iterator iterator = def.typeParams.iterator(); iterator.hasNext();) {
TypeVariableDef typeVariableDef = (TypeVariableDef) iterator.next();
typeParams[index++] = createTypeVariable(typeVariableDef);
}
currentClass.setTypeParameters(typeParams);
}
// javadoc
addJavaDoc(currentClass);
// // ignore annotation types (for now)
// if (ClassDef.ANNOTATION_TYPE.equals(def.type)) {
// System.out.println( currentClass.getFullyQualifiedName() );
// return;
// }
// annotations
setAnnotations( currentClass );
currentParent.addClass(currentClass);
currentParent = currentClass;
context.add(currentClass.getFullyQualifiedName());
}
public void endClass() {
currentParent = currentClass.getParent();
if (currentParent instanceof JavaClass) {
currentClass = (JavaClass) currentParent;
} else {
currentClass = null;
}
}
public Type createType( String typeName, int dimensions ) {
if( typeName == null || typeName.equals( "" ) )
return null;
return createType(new TypeDef(typeName), dimensions);
}
public Type createType(TypeDef typeDef) {
return createType(typeDef, 0);
}
/**
* this one is specific for those cases where dimensions can be part of both the type and identifier
* i.e. private String[] matrix[]; //field
* public abstract String[] getMatrix[](); //method
*
* @param typeDef
* @param dimensions
* @return the Type
*/
public Type createType(TypeDef typeDef, int dimensions) {
if(typeDef == null) {
return null;
}
return Type.createUnresolved(typeDef, dimensions, currentClass == null ? currentParent : currentClass);
}
private void addJavaDoc(AbstractJavaEntity entity) {
if (lastComment == null) return;
entity.setComment(lastComment);
Iterator tagDefIterator = lastTagSet.iterator();
List tagList = new ArrayList();
while (tagDefIterator.hasNext()) {
TagDef tagDef = (TagDef) tagDefIterator.next();
tagList.add(
docletTagFactory.createDocletTag(
tagDef.name, tagDef.text,
entity, tagDef.lineNumber
)
);
}
entity.setTags(tagList);
lastComment = null;
}
public void addMethod(MethodDef def) {
beginMethod();
endMethod(def);
}
public void beginMethod() {
currentMethod = new JavaMethod();
setAnnotations(currentMethod);
}
public void endMethod(MethodDef def) {
currentMethod.setParentClass(currentClass);
currentMethod.setLineNumber(def.lineNumber);
// basic details
currentMethod.setName(def.name);
currentMethod.setReturns(createType(def.returnType, def.dimensions));
currentMethod.setConstructor(def.constructor);
// typeParameters
if (def.typeParams != null) {
TypeVariable[] typeParams = new TypeVariable[def.typeParams.size()];
int index = 0;
for(Iterator iterator = def.typeParams.iterator(); iterator.hasNext();) {
TypeVariableDef typeVariableDef = (TypeVariableDef) iterator.next();
typeParams[index++] = createTypeVariable(typeVariableDef);
}
currentMethod.setTypeParameters(typeParams);
}
// exceptions
{
Type[] exceptions = new Type[def.exceptions.size()];
int index = 0;
for (Iterator iter = def.exceptions.iterator(); iter.hasNext();) {
exceptions[index++] = createType((String) iter.next(), 0);
}
currentMethod.setExceptions(exceptions);
}
// modifiers
{
String[] modifiers = new String[def.modifiers.size()];
def.modifiers.toArray(modifiers);
currentMethod.setModifiers(modifiers);
}
currentMethod.setSourceCode(def.body);
// javadoc
addJavaDoc(currentMethod);
currentClass.addMethod(currentMethod);
}
public TypeVariable createTypeVariable(TypeVariableDef typeVariableDef) {
if(typeVariableDef == null) {
return null;
}
return TypeVariable.createUnresolved(typeVariableDef, currentClass == null ? currentParent : currentClass);
}
public TypeVariable createTypeVariable(String name, List typeParams) {
if( name == null || name.equals( "" ) )
return null;
return createTypeVariable(new TypeVariableDef(name, typeParams));
}
public void addField(FieldDef def) {
JavaField currentField = new JavaField();
currentField.setParentClass(currentClass);
currentField.setLineNumber(def.lineNumber);
currentField.setName(def.name);
currentField.setType(createType(def.type, def.dimensions));
// modifiers
{
String[] modifiers = new String[def.modifiers.size()];
def.modifiers.toArray(modifiers);
currentField.setModifiers(modifiers);
}
// code body
currentField.setInitializationExpression(def.body);
// javadoc
addJavaDoc(currentField);
// annotations
setAnnotations( currentField );
currentClass.addField(currentField);
}
public void addParameter(FieldDef fieldDef) {
JavaParameter jParam = new JavaParameter(createType(fieldDef.type, fieldDef.dimensions), fieldDef.name, fieldDef.isVarArgs);
setAnnotations( jParam );
currentMethod.addParameter( jParam );
}
private void setAnnotations( final AbstractBaseJavaEntity entity ) {
if( !currentAnnoDefs.isEmpty() ) {
AnnotationVisitor visitor = new RecursiveAnnotationVisitor() {
public Object visitAnnotation( Annotation annotation ) {
annotation.setContext( entity );
return super.visitAnnotation( annotation );
}
public Object visitAnnotationFieldRef( AnnotationFieldRef fieldRef ) {
fieldRef.setContext( entity );
return super.visitAnnotationFieldRef( fieldRef );
}
};
Annotation[] annotations = new Annotation[currentAnnoDefs.size()];
for( ListIterator iter = currentAnnoDefs.listIterator(); iter.hasNext(); ) {
Annotation annotation = (Annotation) iter.next();
annotation.accept(visitor);
annotations[iter.previousIndex()] = annotation;
}
entity.setAnnotations( annotations );
currentAnnoDefs.clear();
}
}
// Don't resolve until we need it... class hasn't been defined yet.
public void addAnnotation( Annotation annotation ) {
currentAnnoDefs.add( annotation );
}
public JavaSource getSource() {
return source;
}
}
qdox-qdox-1.12.1/src/java/com/thoughtworks/qdox/model/Type.java 0000664 0000000 0000000 00000031244 12045512336 0024422 0 ustar 00root root 0000000 0000000 package com.thoughtworks.qdox.model;
import java.io.Serializable;
import com.thoughtworks.qdox.JavaClassContext;
import com.thoughtworks.qdox.parser.structs.TypeDef;
import com.thoughtworks.qdox.parser.structs.WildcardTypeDef;
public class Type implements Comparable, Serializable {
public static final Type[] EMPTY_ARRAY = new Type[0];
public static final Type VOID = new Type("void");
private String name;
private JavaClassParent context;
private String fullName;
private int dimensions;
private Type[] actualArgumentTypes;
public Type(String fullName, String name, int dimensions, JavaClassParent context) {
this.fullName = fullName;
this.name = name;
this.dimensions = dimensions;
this.context = context;
}
public Type(String fullName, TypeDef typeDef, int dimensions, JavaClassParent context) {
this.fullName = fullName;
this.name = typeDef.name;
this.dimensions = typeDef.dimensions + dimensions; //in some cases dimensions can be spread. Collect them here
if(typeDef.actualArgumentTypes != null && !typeDef.actualArgumentTypes.isEmpty()) {
actualArgumentTypes = new Type[typeDef.actualArgumentTypes.size()];
for(int index = 0; index < typeDef.actualArgumentTypes.size(); index++) {
actualArgumentTypes[index] = createUnresolved((TypeDef) typeDef.actualArgumentTypes.get(index), context);
}
}
this.context = context;
}
public Type(String fullName, int dimensions, JavaClassParent context) {
this(fullName, (String) null, dimensions, context);
}
public Type(String fullName, int dimensions) {
this(fullName, dimensions, null);
}
public Type(String fullName) {
this(fullName, 0);
}
public static Type createUnresolved(String name, int dimensions, JavaClassParent context) {
return new Type(null, name, dimensions, context);
}
public static Type createUnresolved(TypeDef typeDef, int dimensions, JavaClassParent context) {
return new Type(null, typeDef, dimensions, context);
}
public static Type createUnresolved(TypeDef typeDef, JavaClassParent context) {
if(typeDef instanceof WildcardTypeDef) {
return new WildcardType((WildcardTypeDef) typeDef, context);
}
return new Type(null, typeDef, 0, context);
}
public JavaClassParent getJavaClassParent() {
return context;
}
/**
*
* @deprecated instead use getFullyQualifiedName()
*/
public String getFullQualifiedName() {
return getFullyQualifiedName();
}
/**
* Returns the FQN of an Object or the handler of a Type
* If the name of the can't be resolved based on the imports and the classes on the classpath the name will be returned
* InnerClasses will use the $ sign
*
* Some examples how names will be translated
*
* Object > java.lang.Object
* java.util.List > java.util.List
* ? > ?
* T > T
* anypackage.Outer.Inner > anypackage.Outer$Inner
*
*
* @return
*/
public String getFullyQualifiedName() {
return isResolved() ? fullName : name;
}
/**
* The FQN representation of an Object for code usage
* This implementation ignores generics
*
* Some examples how Objects will be translated
*
* Object > java.lang.object
* java.util.List
*
* @return type representation for code usage
*/
public String getValue() {
String fqn = getFullyQualifiedName();
return ( fqn == null ? "" : fqn.replaceAll( "\\$", "." ) );
}
/**
* The FQN representation of an Object for code usage
* This implementation ignores generics
*
* Some examples how Objects will be translated
*
* Object > java.lang.object
* java.util.List
* @since 1.8
* @return generic type representation for code usage
*/
public String getGenericValue() {
StringBuffer result = new StringBuffer(getValue());
if(actualArgumentTypes != null && actualArgumentTypes.length > 0) {
result.append("<");
for(int index = 0;index < actualArgumentTypes.length; index++) {
result.append(actualArgumentTypes[index].getGenericValue());
if(index + 1 != actualArgumentTypes.length) {
result.append(",");
}
}
result.append(">");
}
for (int i = 0; i < dimensions; i++) result.append("[]");
return result.toString();
}
protected String getGenericValue(TypeVariable[] typeVariableList) {
StringBuffer result = new StringBuffer(getResolvedValue(typeVariableList));
if(actualArgumentTypes != null && actualArgumentTypes.length > 0) {
for(int index = 0;index < actualArgumentTypes.length; index++) {
result.append(actualArgumentTypes[index].getResolvedGenericValue(typeVariableList));
if(index + 1 != actualArgumentTypes.length) {
result.append(",");
}
}
}
return result.toString();
}
protected String getResolvedValue(TypeVariable[] typeParameters) {
String result = getValue();
for(int typeIndex=0;typeIndex
* Object > java.lang.Object
* Object[] > java.lang.Object[]
* List
* @return
*/
public String toGenericString() {
if (dimensions == 0) return getGenericValue();
StringBuffer buff = new StringBuffer(getGenericValue());
for (int i = 0; i < dimensions; i++) buff.append("[]");
String result = buff.toString();
return result;
}
public boolean equals(Object obj) {
if (obj == null) return false;
Type t = (Type) obj;
return getValue().equals(t.getValue()) && t.getDimensions() == getDimensions();
}
public int hashCode() {
return getValue().hashCode();
}
public JavaClass getJavaClass() {
JavaClass result = null;
JavaClassParent javaClassParent = getJavaClassParent();
if (javaClassParent != null) {
result = javaClassParent.getNestedClassByName(getFullyQualifiedName());
if(result == null) {
JavaClassContext context = javaClassParent.getJavaClassContext();
if (context.getClassLibrary() != null) {
result = context.getClassByName(getFullyQualifiedName());
}
}
}
return result;
}
/**
* @since 1.3
*/
public boolean isA(Type type) {
if (this.equals(type)) {
return true;
} else {
JavaClass javaClass = getJavaClass();
if (javaClass != null) {
// ask our interfaces
Type[] implementz = javaClass.getImplements();
for (int i = 0; i < implementz.length; i++) {
if (implementz[i].isA(type)) {
return true;
}
}
// ask our superclass
Type supertype = javaClass.getSuperClass();
if (supertype != null) {
if (supertype.isA(type)) {
return true;
}
}
}
}
// We'we walked up the hierarchy and found nothing.
return false;
}
/**
* @since 1.6
*/
public boolean isPrimitive() {
String value = getValue();
if (value == null || value.length() == 0 || value.indexOf('.') > -1) {
return false;
} else {
return "void".equals(value)
|| "boolean".equals(value)
|| "byte".equals(value)
|| "char".equals(value)
|| "short".equals(value)
|| "int".equals(value)
|| "long".equals(value)
|| "float".equals(value)
|| "double".equals(value);
}
}
/**
* @since 1.6
*/
public boolean isVoid() {
return "void".equals(getValue());
}
/**
*
* @param superClass
* @return
* @since 1.12
*/
protected int getTypeVariableIndex( JavaClass superClass ) {
TypeVariable[] typeVariables = superClass.getTypeParameters();
for(int typeIndex=0;typeIndex
Where is the array information stored?
Type
class stores array information
in it. If the array is multidimensional, the dimension depth can be accessed.What's the object type of an interface?
JavaClass
method is used to
represent both classes and interfaces.
The isInterface()
method allows you to distinguish between the two.java.lang.Object
is
returned. When using an interface, this method ALWAYS returns null.Can I have full control over the classloader?
/* new ClassLibrary() will give you an empty classLoader
* Big chance you want at least the system classloader.
*/
ClassLibrary classLibrary = new ClassLibrary( ClassLoader.getSystemClassLoader() );
JavaDocBuilder builder = new JavaDocBuilder(classLibrary);
QDox
In A Nutshell
Getting Started
http://www.apache.org/licenses/LICENSE-2.0JavaSource
Example Input
package com.blah.foo;
import java.awt.*;
import java.util.List;
public class Class1 {
...
}
class Class2 {
}
interface Interface1 {
}
Example Code
JavaDocBuilder builder = new JavaDocBuilder();
builder.addSource(myReader);
JavaSource src = builder.getSources[](0);
JavaPackage pkg = src.getPackage();
String[] imports = src.getImports(); // {"java.awt.*",
// "java.util.List"}
JavaClass class1 = src.getClasses()[0];
JavaClass class2 = src.getClasses()[1];
JavaClass interface1 = src.getClasses()[2];
JavaPackage
Example input
package com.blah.foo;
public class BarClass {
...
}
Example Code
JavaDocBuilder builder = new JavaDocBuilder();
builder.addSource(myReader);
JavaSource src = builder.getSources[](0);
JavaPackage pkg = src.getPackage();
JavaClass[] classes = pkg.getClasses()[0]; // BarClass
String name = pkg.getName(); // "com.blah.foo"
String toString = pkg.toString(); // "package com.blah.foo" conform javaAPI
JavaPackage parent = pkg.getParentPackage(); //
JavaClass
Example Input
package com.blah.foo;
import java.io.*;
import com.custom.*;
import com.base.SubClass;
/**
* @author Joe
*/
public abstract class MyClass extends SubClass
implements Serializable, CustomInterface {
private String name;
public void doStuff() { ... }
private int getNumber() { ... }
}
Example Code
JavaDocBuilder builder = new JavaDocBuilder();
builder.addSource(myReader);
JavaClass cls = builder.getClassByName("com.blah.foo.MyClass");
String pkg = cls.getPackage(); // "com.blah.foo"
String name = cls.getName(); // "MyClass"
String fullName = cls.getFullyQualifiedName(); // "com.blah.foo.MyClass";
boolean isInterface = cls.isInterface(); // false
boolean isPublic = cls.isPublic(); // true
boolean isAbstract = cls.isAbstract(); // true
boolean isFinal = cls.isFinal(); // false
Type superClass = cls.getSuperClass(); // "com.base.SubClass";
Type[] imps = cls.getImplements(); // {"java.io.Serializable",
// "com.custom.CustomInterface"}
String author = cls.getTagsByName("author").getValue(); // "joe"
JavaField nameField = cls.getFields()[0];
JavaMethod doStuff = cls.getMethods()[0];
JavaMethod getNumber = cls.getMethods()[1];
JavaSource javaSource = cls.getParentSource();
JavaField
Example Input
import java.util.Date;
public class MyClass {
/**
* @magic
*/
private String email;
public static Date[][] dates;
}
Example Code
JavaField e = cls.getFields()[0];
Type eType = e.getType(); // "java.lang.String";
String eName = e.getName(); // "email";
DocletTag eTag = e.getTagsByName("magic"); // @magic
boolean eArray = e.getType().isArray(); // false;
JavaField d = cls.getFields()[1];
Type dType = d.getType(); // "java.util.Date";
String dName = d.getName(); // "dates";
DocletTag dTag = d.getTagsByName("magic"); // null
boolean dArray = d.getType().isArray(); // true;
int dDimensions= d.getType().getDimensions(); // 2;
boolean dStatic= d.isStatic(); // true;
JavaClass javaClass = d.getParentClass();
JavaMethod
Example Input
import java.util.Date;
import java.io.*;
public class MyClass {
/**
* @returns Lots of dates
*/
public static Date[] doStuff(int number,
String stuff)
throws RuntimeException, IOException {
...
}
}
Example Code
JavaMethod m = cls.getMethods()[0];
String mName = m.getName(); // "doStuff";
Type mReturns = m.getReturns(); // "java.util.Date";
boolean mArray = m.getReturns().isArray(); // true
boolean mStatic = m.isStatic(); // true
boolean mPublic = m.isPublic(); // true
String doc = m.getTagByName("returns").getValue();
// "Lots of dates"
Type[] exceptions = m.getExceptions();
// {"java.lang.RuntimeException", "java.io.IOException"}
JavaParameter numberParam = m.getParameters()[0];
JavaParameter stuffParam = m.getParameters()[1];
JavaClass javaClass = m.getParentClass();
JavaParameter
Example Input
public class MyClass {
public void stuff(int n, Object[] objects) {
...
}
}
Example Code
JavaMethod m = cls.getMethods()[0];
JavaParameter n = m.getParameters()[0];
String nName = n.getName(); // "n"
Type nType = n.getType(); // "int";
JavaParameter o = m.getParameters()[1];
String oName = o.getName(); // "objects"
Type oType = o.getType(); // "java.lang.Object";
boolean oArray = o.getType().isArray(); // true
JavaMethod javaMethod = o.getParentMethod();
Type
Example Input
import java.util.*;
public class MyClass {
public void stuff(int n, Object[] objects,
Date[][] dates, List
Example Code
JavaMethod m = cls.getMethods()[0];
Type returns = m.getReturns();
returns.getValue(); // "void"
returns.isArray(); // false
returns.getDimensions(); // 0
Type n = m.getParameters()[0].getType();
n.getValue(); // "int"
n.isArray(); // false
n.getDimensions(); // 0
Type objects = m.getParameters()[1].getType();
objects.getValue(); // "java.lang.Object"
objects.isArray(); // true
objects.getDimensions(); // 1
Type dates = m.getParameters()[2].getType();
dates.getValue(); // "java.util.Date"
dates.isArray(); // true
dates.getDimensions(); // 2
Type stringList = m.getParameters()[3].getType();
stringList.getValue(); // "java.util.List"
stringList.getGenericValue(); // "java.util.List
DocletTag
JavaClass
,
JavaField
and
JavaMethod
classes all
support comments and DocletTagsDocletTag
carries
the name, value and methods for breaking up the value into specific parameters.
Example Input
/**
* This method does nothing at all.
*
* @returns A boolean of whether we care or not.
* @param email Someone's email address.
* @param dob Date of birth.
*
* @permission administrator full-access
* @webservice publish=true name=myservice type=rpc
*/
boolean doWeCare(String email, Date dob);
Example Code
JavaMethod mth = cls.getMethods()[0];
// Access the JavaDoc comment
String comment = mth.getComment();
// "This method does nothing at all."
// Access a single doclet tag
DocletTag returns = mth.getTagByName("returns");
returns.getName(); // "returns";
returns.getValue(); // "A boolean of whether we care or not."
// Access multiple doclet tags with the same name
DocletTag[] params = mth.getTagsByName("param");
params[0].getValue(); // "Someone's email address."
params[1].getValue(); // "Date of birth."
// Access specific parameters of a doclet tag by index
DocletTag permission = mth.getTagByName("permission");
permission.getParameter[0]; // "administrator"
permission.getParameter[1]; // "full-access"
// Access specific parameters of a doclet tag by name
DocletTag webservice = mth.getTagByName("webservice");
webservice.getNamedParameter("type"); // "rpc"
webservice.getNamedParameter("name"); // "myservice"
Upgrading to 1.10.1 or above
Things that might break your code
Upgrading to 1.10 or above
Things that might break your code
Java API QDOX ((java.lang.Method) aMethod).getReturnsType().toString() ((com.thoughtworks.qdox.model.JavaMethod) aMethod).getReturns().toString()
com.thoughtworks.qdox.model.Type.getValue() will return the typeName for usage in the code. The new method com.thoughtworks.qdox.model.Type.getFullQualifiedName() will return the FQN as defined by the java specs. Normally they would return the same value, but pay attention when using inner classes.
This section describes what needs to be done when upgrading to QDox 1.9.
In both JavaClass and JavaSource the getPackage() returns an object of type JavaPackage instead of a String. To get the same result as before use getPackage().getName() .
This section describes what needs to be done when upgrading to QDox 1.6. For an extensive list of changes (most of them backwards compatible), please see the Changes Report.
In JavaClass the getInnerClasses() method has been renamed to getNestedClasses(). The old name remains as a (deprecated) synonym.
With support for generic types, we've introduced a bug affecting the use of "<" and ">" in initialisers (see QDOX-71).
This section describes what needs to be done when upgrading to QDox 1.5. For an extensive list of changes (most of them backwards compatible), please see the Changes Report.
The DocletTag interface no longer contains a setContext() method. That information is now provided via DocletTagFactory, where createDocletTag() now requires an additional "context" parameter.
The parser now passes tag-data to Builders using a new TagDef structure.
This section describes what needs to be done when upgrading to QDox 1.3. For an extensive list of changes (most of them backwards compatible), please see the Changes Report.
(Thanks to Peter Donald for contributing this list).
JavaDocBuilder
is the entry point to
QDox. It is responsible for parsing source code, resolving imports and storing
the data.
To create it, all you need to do is call the default constructor.
JavaDocBuilder builder = new JavaDocBuilder();
Java source code can then be added to the
JavaDocBuilder
.
Source can either be read one file at a time (using a java.io.Reader) or an entire source tree
can be added recursively.
// Reading a single source file. builder.addSource(new FileReader("MyFile.java")); // Reading from another kind of input stream. builder.addSource(new StringReader("package test; public class Hello {}")); // Adding all .java files in a source tree (recursively). builder.addSourceTree(new File("mysrcdir"));
In order to resolve classes that have been imported using a wildcard (e.g. import java.util.*;
), the
ClassLibrary
must be aware of other classes used in the project.
ClassLibrary has 4 ways to resolve classes:
All sources and sourcetrees added to the JavaDocBuilder will be parsed. This is often much more than required. To increase efficiency use the ClassLibrary to add sourcefolders. Consider these files as lazy parsed sources.
The current classpath is automaticly set by JavaDocBuilder. In most cases this shall be sufficient, however in some situations you may want resolve the full classes in external libraries.
To resolve classes from different ClassLoaders (e.g. 3rd party Jar files), the
addClassLoader()
method must be called on the ClassLibrary.
// Get the ClassLibrary ClassLibrary lib = builder.getClassLibrary(); // Add a sourcefolder; lib.addSourceFolder( new File( "src/main/java" ) ); lib.addSourceFolder( new File( "target/generated-sources/foobar" ) ); // Add a custom ClassLoader lib.addClassLoader( myCustomClassLoader ); // Ant example : add the <classpath> element's contents lib.addClassLoader( new AntClassLoader( getProject(), classpath ) );
It is important that additional ClassLoaders are added before any source files are parsed.
Now the files have been parsed, move on to navigating the model.
qdox-qdox-1.12.1/src/site/content/website.xml 0000664 0000000 0000000 00000001676 12045512336 0021124 0 ustar 00root root 0000000 0000000Project | Description | How QDox is Used |
---|---|---|
AspectWerkz is an Aspect Oriented Programming (AOP) toolkit for Java that modifies byte-code to weave in interceptors and mixins. | Attributes can be used to associate interceptors and mixins with a specific class. | |
Phoenix was a micro-kernel designed and implemented on top of the Avalon framework. It provided a number of facilities to manage the environment of Server Applications. Apache cancelled the Avalon project 2004 | 'MetaGenerate' is part of the Phoenix toolset and picks up @phoenix prefixed JavaDoc tags to make XML manifests for the components that will be laced together in more XML to make a complete server application. | |
Apache Cocoon is an XML publishing framework that raises the usage of XML and XSLT technologies for server applications to a new level. Designed for performance and scalability around pipelined SAX processing, Cocoon offers a flexible environment based on a separation of concerns between content, logic, and style. | The QDox Block reads in Java source files and fires out SAX events enabling processing by standard XML tools (such as XSLT). | |
Jakarta Commons Attributes provides an API to runtime metadata attributes. Attributes are specified as doclet tags and then compiled into the classpath where they can be accessed at runtime (without requiring the source). The aim is to provide a framework similar to .NET attributes. | QDox is used to extract the JavaDoc tags from the source files. | |
The gwt-maven-plugin provides support for GWT projects, including running the GWT developer tools (the compiler, shell and i18n generation) and performing support operations to help developers make GWT fit more closely in with their standard JEE web application development (debugging, managing the embedded server, running noserver, merging web.xml, generating I18N interfaces, generating Async GWT-RPC interfaces, and more) and environment (Eclipse IDE). | QDox is used to generate the Async GWT-RPC interfaces based on their Service-classes. | |
Ivory provides easy integration between your exiting Java classes, Avalon services, and Axis. It allows easy deployment of soap services with none of the WSDD configuration that Axis normally mandates. | Attributes are used to provide additional hints to Ivory about Java classes that cannot be determined via reflection. | |
The Javadoc Plugin uses the Javadoc tool to generate javadocs for the specified project. |
When developers write code, they could forget to create (or update) the Javadoc comments. The |
|
Maven is a software project management and comprehension tool. | QDox is used for extraction of Javadoc tags from source files to generate plugin descriptors | |
Mock Maker is a tool for automatically generating mock objects from custom classes to aid in testing the untestable. This supports the practises of Test Driven Development and eXtreme Programming. | Mock Maker scans the source repository for any class/interface marked with the @mock JavaDoc tag and automatically creates the Mock Object for this that matches the class definition. | |
Nanning is an Aspect Oriented Programming (AOP) toolkit for Java that does not require a custom compiler. It uses dynamic proxies to weave in interceptors and mixins at runtime. | QDox is used to allow aspects to be applied to classes by specifiying meta-data in doclet tags. | |
Paranamer a mechamism for accessing the parameter names of methods of Java classes compiled into jars | QDox is used to parse the source and generate the parameter names list. | |
A version of Spring that not only has a very small runtime footprint (none), but also is capable of running on small handheld devices, since it does not rely on reflection. | ||
vDoclet is a framework for code-generation using Velocity templates, based on annotated Java source-code. | vDoclet uses QDox to produce input-data for it's templates. | |
Voruta is a data access framework for embedding SQL statements in Java methods using custom JavaDoc tags and dynamic code generation at runtime. | QDox is used to parse metadata and CGLib to generate implementation at runtime. | |
XDoclet2 is a framework for code-generation using Velocity or Jelly templates, based on annotated Java source-code. It is a rewrite of XDoclet. | XDoclet2 uses QDox to produce input-data for it's templates, as well as QDox' APITestCase to validate the generated sources. |