admin@glassfish.java.net

how to document properties for _at_Configured items (PROPOSAL)

From: Lloyd Chambers <Lloyd.Chambers_at_Sun.COM>
Date: Fri, 17 Oct 2008 16:42:40 -0700

Team,

I just finished going through "Sun GlassFish Enterprise Server v3
Prelude Administration Reference". It took a lot of "eyeball work"
going through every page, and each and every interface--this is error
prone and hard to maintain.

Many properties and system properties are documented in the reference,
yet none of them are documented in the @Configured interfaces--at
all. This stands in stark contrast to attributes and elements, which
are naturally javadoc'd.

Several other issues come to mind for properties (eg <property> and
<system-property>):
- no formal mechanism to document the legal properties (except free-
form javadoc comments, none there as yet);
- impossible to validate property names or values;
- cannot warn the user if an unknown or mis-spelled property is being
used (eg "readerThreads" instead of "reader-threads");
- documentation for public API is not possible; there is nothing to
generate it from;
- no way for dependent interfaces (eg AMX) to validate or provide
metadata.

--- PROPOSAL ---

1) Add annotations to describe the legal properties and system
properties;
2) Add these annotations on all the @Configured interfaces which have
properties;
3) Encourage developers to maintain the annotations.

Below is an example of how this would work for @Configured
HttpListener. One alternative would be to define a "sidecar" class
that has "public static final String" variables for each property, and
annotate each of those individually.

Note that because there cannot be more than one annotation of a given
type, a grouping annotation is used to allow annotations for every
property. See annotation classes further below.

@PropertiesDesc({
     @PropertyDesc(name="recycle-objects", defaultValue="true",
dataType=Boolean.class),
     @PropertyDesc(name="reader-threads", defaultValue="0",
dataType=NonNegativeInteger.class),
     @PropertyDesc(name="acceptor-queue-length", defaultValue="4096",
dataType=NonNegativeInteger.class),
     @PropertyDesc(name="reader-queue-length", defaultValue="4096",
dataType=NonNegativeInteger.class),
     @PropertyDesc(name="use-nio-direct-bytebuffer",
defaultValue="false", dataType=Boolean.class),
     @PropertyDesc(name="authPassthroughEnabled",
defaultValue="false", dataType=Boolean.class),
     @PropertyDesc(name="proxyHandler",
defaultValue="com.sun.enterprise.web.ProxyHandlerImpl"),
     @PropertyDesc(name="proxiedProtocol", values={"ws/tcp", "http",
"https", "tls"}),
     @PropertyDesc(name="bufferSize", defaultValue="4096",
dataType=NonNegativeInteger.class),
     @PropertyDesc(name="connectionTimeout", defaultValue="30",
dataType=NonNegativeInteger.class),
     @PropertyDesc(name="maxKeepAliveRequests", defaultValue="250",
dataType=NonNegativeInteger.class),
     @PropertyDesc(name="traceEnabled", defaultValue="true",
dataType=Boolean.class),
     @PropertyDesc(name="cometSupport", defaultValue="false",
dataType=Boolean.class),
     @PropertyDesc(name="jkEnabled", defaultValue="false",
dataType=Boolean.class),
     @PropertyDesc(name="compression", defaultValue="off",
values={"off","on","force"}),
     @PropertyDesc(name="compressableMimeType", defaultValue="text/
html, text/xml, text/plain"),
     @PropertyDesc(name="noCompressionUserAgents", defaultValue=""),
     @PropertyDesc(name="compressionSize",
dataType=NonNegativeInteger.class),
     @PropertyDesc(name="minCompressionSize",
dataType=NonNegativeInteger.class),
     @PropertyDesc(name="crlFile"),
     @PropertyDesc(name="trustAlgorithm", values="PKIX"),
     @PropertyDesc(name="trustMaxCertLength", defaultValue="5",
dataType=Integer.class),
     @PropertyDesc(name="disableUploadTimeout", defaultValue="true",
dataType=Boolean.class),
     @PropertyDesc(name="connectionUploadTimeout", defaultValue="5",
dataType=NonNegativeInteger.class),
     @PropertyDesc(name="uriEncoding", defaultValue="UTF-8",
values={"UTF-8"})
})

@AMXConfigInfo
( amxInterfaceName
="com.sun.appserv.management.config.HTTPListenerConfig")
@Configured
public interface HttpListener extends ConfigBeanProxy, Injectable,
PropertyBag {

    ...
}

---
/**
  * Describes properties or system properties that might exist as sub- 
elements.
  */
@Retention(RUNTIME)
@Target({TYPE})
public @interface PropertyDesc {
     /** name of the property */
     String name();
     /** default value of the property */
     String defaultValue()  default "\u0000";
     /** freeform description */
     String description()  default "\u0000";
     /** Indicates that this property is required (rare) */
     boolean required() default false;
     /** the DataType class, can be Class<? extends {_at_link DataType}>  
or String.class */
     Class  dataType()  default String.class;
     /** Possible values, might not be a complete list and/or there  
could be other alternatives
        such as specific numbers, variables, etc.
      */
     String[] values();
}
/**
  * Annotation that holds an array of {_at_link PropertyDesc} for system  
properties eg {_at_link SystemProperty}.
  * Needed because it's not otherwise possible to have more than one  
annotation of the same type.
  */
@Retention(RUNTIME)
@Target({TYPE,METHOD})
public @interface SystemPropertiesDesc {
     /** name of the property */
     PropertyDesc[] value();
}
/**
  * Annotation that holds an array of {_at_link PropertyDesc} for  
properties eg {_at_link Property}.
  * Needed because it's not otherwise possible to have more than one  
annotation of the same type.
  */
@Retention(RUNTIME)
@Target({TYPE,METHOD})
public @interface PropertiesDesc {
     /** name of the property */
     PropertyDesc[] value();
}
..............................................
Lloyd Chambers
lloyd.chambers_at_sun.com
GlassFish team, LSARC member