From: <Salvo pelo Windows Internet Explorer 8>
Subject: Learn to Use the New Annotation Feature of Java 5.0
Date: Fri, 17 Jul 2009 19:11:30 -0300
MIME-Version: 1.0
Content-Type: multipart/related;
	type="text/html";
	boundary="----=_NextPart_000_0000_01CA0712.640E8780"
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579

This is a multi-part message in MIME format.

------=_NextPart_000_0000_01CA0712.640E8780
Content-Type: text/html;
	charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://www.devx.com/Java/Article/27235/1954?pf=true

=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" =
"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML><HEAD><TITLE>Learn to Use the New Annotation Feature of Java =
5.0</TITLE><LINK=20
title=3D"Devx: Latest Published Articles" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/devxfeed.xml"><LINK=20
title=3D"DevX: Latest Java Articles" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/javafeed.xml"><LINK=20
title=3D"DevX: Latest .NET Content" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/dotnet.xml"><LINK=20
title=3D"DevX: Latest XML Content" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/xmlfeed.xml"><LINK=20
title=3D"DevX: Latest Database Content" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/databasefeed.xml"><LINK=20
title=3D"DevX: Latest Enterprise Content" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/enterprisefeed.xml"><LINK=20
title=3D"DevX: Latest C++ Content" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/cplusfeed.xml"><LINK=20
title=3D"DevX: Latest Web Development Content" rel=3Dalternate=20
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/webdevfeed.xml"><LINK=20
title=3D"DevX: Latest Wireless Content" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/wirelessfeed.xml"><LINK=20
title=3D"DevX: Recent Tips" rel=3Dalternate type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/recentTipsFeed.xml"><LINK=20
title=3D"DevX: Open Source Articles" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/openSourceFeed.xml"><LINK=20
title=3D"DevX: Premier Club Only Content" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/PCpreviewFeed.xml"><LINK=20
title=3D"DevX: Office Professional Developer" rel=3Dalternate=20
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/officefeed.xml"><LINK=20
title=3D"DevX: Intel Optimizing Center" rel=3Dalternate =
type=3Dapplication/rss+xml=20
href=3D"http://services.devx.com/outgoing/intelOptimizingCenterFeed.xml">=

<META content=3D"text/html; charset=3Dutf-8" http-equiv=3DContent-Type>
<META name=3Dverify-v1 =
content=3D/9rV7xCYeHHdHCIEVkdpwmwtyjgHYKWKu+yeezQHucQ=3D><LINK=20
rel=3Dstylesheet type=3Dtext/css =
href=3D"http://www.devx.com/styles/cps.css"><LINK=20
rel=3Dstylesheet type=3Dtext/css =
href=3D"http://www.devx.com/styles/pf.css">
<META name=3Dkeywords content=3D"">
<META name=3DDescription=20
content=3D"Developers have always struggled to find ways of adding =
semantic data to their Java code. They had to: Java didn't have a native =
metadata facility. But that's all changed with version 5.0 of Java, =
which allows annotations as a typed part of the language.">
<META name=3DTopic=20
content=3D"968 J2SE -- Products and Technologies :: Platforms :: Java :: =
J2SE">
<SCRIPT language=3Djavascript=20
src=3D"http://www.devx.com/scripts/globalFuncs.js"></SCRIPT>

<SCRIPT language=3Djavascript>=0A=
function forgotPassword(email) {=0A=
var theURL =3D "/passwordLookup.cfm?emailAddr=3D" + email;=0A=
popUpWindow(theURL, 300,320);=0A=
}=0A=
</SCRIPT>

<SCRIPT language=3Djavascript>=0A=
document.domain =3D =
document.domain.substring(document.domain.indexOf('.') + 1);=0A=
</SCRIPT>

<META name=3DGENERATOR content=3D"MSHTML 8.00.6001.18783"></HEAD>
<BODY bgColor=3D#fafae6>
<SCRIPT language=3Djavascript>=0A=
function showSupportItem(itemName)=0A=
{=0A=
if( articleSpptItems[itemName] )=0A=
{=0A=
var theURL =3D 'http://www.devx.com/Java/Article/27235/1763';=0A=
theURL +=3D '?supportItem=3D'+articleSpptItems[itemName].number;=0A=
popUpWindow(theURL, articleSpptItems[itemName].width, =
articleSpptItems[itemName].height);=0A=
}=0A=
else=0A=
alert("Sorry, "+itemName+" could not be found.");=0A=
}=0A=
function SupportItem(number, width, height)=0A=
{=0A=
this.number =3D number;=0A=
this.width =3D width;=0A=
this.height =3D height;=0A=
return this;=0A=
}=0A=
articleSpptItems =3D new Object();=0A=
articleSpptItems.listing1 =3D new SupportItem(1,500,500);=0A=
</SCRIPT>

<CENTER>
<DIV=20
style=3D"TEXT-ALIGN: left; LINE-HEIGHT: 18px; WIDTH: 90%; FONT-FAMILY: =
Arial, Helvetica, Sans-Serif; FONT-SIZE: 12px; FONT-WEIGHT: normal"><A=20
href=3D"http://www.devx.com/"><IMG border=3D0 alt=3D"DevX HomePage"=20
src=3D"http://www.devx.com/assets/devx/4055.gif"></A> <BR>
<DIV style=3D"FLOAT: left" class=3DtopPrintHeader><A=20
href=3D"http://www.devx.com/">http://www.devx.com/</A></DIV>
<DIV style=3D"TEXT-ALIGN: right" class=3DtopPrintHeader>Printed from <A=20
href=3D"http://www.devx.com/Java/Article/27235/1954">http://www.devx.com/=
Java/Article/27235/1954</A></DIV><BR>
<DIV class=3DarticleTitle>Learn to Use the New Annotation Feature of =
Java=20
5.0</DIV>
<DIV class=3DarticleDek><BR>Developers have always struggled to find =
ways of=20
adding semantic data to their Java code. They had to: Java didn't have a =
native=20
metadata facility. But that's all changed with version 5.0 of Java, =
which allows=20
annotations as a typed part of the language.</DIV>
<DIV class=3DarticleAuthor>by Javid Jamae </DIV><IMG=20
src=3D"http://www.devx.com/assets/dropcaps/3591.gif">he new Java 2 =
Platform=20
Standard Edition 5.0 (the developer version number is 1.5 and the code =
name is=20
"Tiger") provides many new features, among them is the ability to=20
<I>annotate</I> Java program elements and to create custom <I>annotation =

types</I>. Development and deployment tools can then read annotated data =
(also=20
known as metadata) and process it in some fashion.=20
<P>Previous versions of Java provided a limited and ad-hoc mechanism for =

annotating code through JavaDoc comments and keyword modifiers. Tools =
such as=20
XDoclet provide a slightly more sophisticated, yet non-standard =
annotation=20
syntax, which piggybacks on top of JavaDoc. But now, with Java 1.5, =
annotations=20
are a typed part of the Java language and allow for both runtime and=20
compile-time processing of annotation data.=20
<P><B>What Are Annotations?</B><BR>In short, annotations are metadata or =
<I>data=20
about data</I>. Annotations are said to annotate a Java element. An =
annotation=20
indicates that the declared element should be processed in some special =
way by a=20
compiler, development tool, deployment tool, or during runtime.=20
<P>Older versions of Java have rough-and-ready annotation functionality. =
A good=20
example is the <I>@deprecated</I> JavaDoc tag. The @deprecated tag is =
used for=20
more than sheer documentation purposes. This tag has no effect on the =
code it=20
describes, but causes the compiler to produce warnings if any other code =

references the tagged element. JavaDoc does not seem to be the proper =
place for=20
this type of metadata, but there was no other annotation facility in =
previous=20
versions of Java. With Java 1.5, finally, annotations are a typed part =
of the=20
language and the version even comes with some with pre-built =
annotations, one of=20
which can be used to mark a class as deprecated (I'll cover this later). =

<P>The code below shows how you can declare a method that uses an =
annotation. It=20
is one of Java 1.5's built-in annotation types: <PRE><CODE>
class Child extends Parent {
    @Overrides
    public void doWork() {
        //do something     =20
    }
}
</CODE></PRE>In the code above, note that the annotation starts with an =
"at" (@)=20
sign. This annotation takes no parameters and is merely used to mark a =
method=20
for some purpose. It is therefore called a <I>marker annotation</I>. =
There are=20
also <I>normal annotations</I> and <I>single member annotations</I> =
(more on=20
these later).=20
<P><I>Annotations types</I> are blueprints for annotations, similar to =
how a=20
class is the blueprint for an object. You can create your own custom =
annotations=20
by defining annotation types.=20
<P>The code below shows the declaration of a normal annotation type: =
<PRE><CODE>
public @interface MyAnnotationType {
    int someValue();
    String someOtherValue();
}
</CODE></PRE>Annotations can be analyzed statically before and during =
compile=20
time. Annotations will likely be used before compile time mainly to =
generate=20
supporting classes or configuration files. For example, a code generator =

(XDoclet, for example) can use annotation data in an EJB implementation =
class to=20
generate EJB interfaces and deployment descriptors for you, reducing =
both your=20
effort and the error rate. The average developer will probably not be =
writing=20
code-generation tools, so these annotation types are likely to be used=20
out-of-the-box rather than authored anew.=20
<P></P>
<TABLE=20
style=3D"FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; BACKGROUND: =
white; COLOR: red; FONT-SIZE: small"=20
border=3D1 cellPadding=3D3 width=3D"95%" align=3Dcenter>
  <TBODY>
  <TR>
    <TD>Author's Note:=20
      <UL>
        <LI>For an overview of its new features and a brief guide to =
downloading=20
        and installing Java 5.0, refer to Laurence Moroney's article, =
"<A=20
        href=3D"http://www.devx.com/Java/Article/21810" =
target=3D_blank>Tiger=20
        Stripes: Get Ready to Purr over J2SE 5.0</A>." </LI>
        <LI>The annotations specification was laid out in JSR-175; =
download it=20
        from <A href=3D"http://www.jcp.org/en/jsr/detail?id=3D175"=20
        target=3D_blank>http://www.jcp.org/en/jsr/detail?id=3D175</A>. =
</LI>
        <LI>C# has a similar mechanism for doing annotations called =
custom=20
        attributes. To learn more about C# custom attributes, refer to =
Pierre=20
        Nallet's article, "<A =
href=3D"http://www.devx.com/dotnet/Article/11579"=20
        target=3D_blank>Get Personal with C# Custom=20
  Attributes</A>."</LI></UL></TD></TR></TBODY></TABLE>
<P>Annotations will also be used for compile-time checking such as to =
produce=20
warnings and errors for different failure scenarios. An example of an =
annotation=20
that is used at compile time is the new @Deprecated annotation, which =
acts the=20
same as the old @deprecated JavaDoc tag. Of course, a compiler has to =
know how=20
to interpret annotation data that is meant to produce compile-time =
warnings, so=20
again, annotations that do things at compile time will likely be used=20
frequently, but rarely written by average developers.=20
<P>Annotations can be useful at runtime as well. Using annotations you =
could=20
mark code to behave in a particular way whenever it is called. For =
example, you=20
could mark some methods with a @prelog annotation. Then at runtime, you =
could=20
analyze the methods that you're calling and print a particular log =
message=20
before you begin executing code for that method. One way to achieve this =
would=20
be through the use of the updated Java 1.5 reflection API. The =
reflection API=20
now provides access to runtime-accessible annotation data.=20
<P>&lt; Another way to use annotations at runtime is to use =
Aspect-Oriented=20
Programming (AOP). AOP uses pointcuts=E2=80=94sets of points configured =
to executed=20
aspects. You could define a pointcut that will execute an aspect for an=20
annotated method. My guess is that developers would be more likely to =
write=20
their own runtime annotation types than they would annotation types used =
for=20
code generation and compile-time checking. Still, writing and =
understanding the=20
code that accesses the annotations (the <I>annotation consumer</I>) at =
runtime=20
is fairly advanced.=20
<P>
<P><BR><BR><BR><B>Annotating Code</B><BR>Annotations fall into three =
categories:=20
normal annotations, single member annotations, and marker annotations =
(see Table=20
1). Normal and single member annotations can take <I>member</I> values =
as=20
arguments when you annotate your code.=20
<P></P>
<TABLE border=3D1 cellSpacing=3D0 borderColorLight=3Dblack =
borderColorDark=3Dwhite>
  <TBODY>
  <TR>
    <TD bgColor=3D#99ccff vAlign=3Dtop align=3Dleft>Category </TD>
    <TD bgColor=3D#99ccff vAlign=3Dtop align=3Dleft>Example </TD></TR>
  <TR>
    <TD bgColor=3Dwhite vAlign=3Dtop align=3Dleft>Normal =
Annotations=E2=80=94Annotations=20
      that take multiple arguments. The syntax for these annotations =
provides=20
      the ability to pass in data for all the members defined in an =
annotation=20
      type. </TD>
    <TD bgColor=3Dwhite vAlign=3Dtop =
align=3Dleft>@MyNormalAnnotation(mem1=3D"val1",=20
      mem2=3D"val2") public void someMethod() { ... } </TD></TR>
  <TR>
    <TD bgColor=3Dwhite vAlign=3Dtop align=3Dleft>Single Member =
Annotations=E2=80=94An=20
      annotation that only takes a single argument has a more compact =
syntax.=20
      You don't need to provide the member name. </TD>
    <TD bgColor=3Dwhite vAlign=3Dtop =
align=3Dleft>@MySingleMemberAnnotation("a=20
      single value") public class SomeClass { ... } </TD></TR>
  <TR>
    <TD bgColor=3Dwhite vAlign=3Dtop align=3Dleft>Marker =
Annotations=E2=80=94These=20
      annotations take no parameters. They are used to mark a Java =
element to be=20
      processed in a particular way. </TD>
    <TD bgColor=3Dwhite vAlign=3Dtop align=3Dleft>@Deprecated public =
void doWork() {=20
      ... } </TD></TR></TBODY></TABLE><BR>
<P>Any Java declaration can be marked with an annotation. That is, an =
annotation=20
can be used on a: package, class, interface, field, method, parameter,=20
constructor, enum (newly available in Java 1.5), or local variable. An=20
annotation can even annotate another annotation. Such annotations are =
called=20
<I>meta-annotations</I>.=20
<P>This code below shows an annotated class, constructor, field, and =
method. <PRE><CODE>
@ClassLevelAnnotation(arg1=3D"val1", arg2=3D{"arg2.val1","arg2.val2"})
public class AnnotationExample {

    @FieldLevelAnnotation()
    public String field;   =20

    @CtorLevelAnnotation()
    public AnnotationsTest() {
        // code
    }

    @MethodLevelAnnotationA("val")
    @MethodLevelAnnotationB(arg1=3D"val1",arg2=3D"val2")
    public void someMethod(String string) {
        // code
    }   =20
}
</CODE></PRE>As you can see in the <SPAN =
class=3Dpf>ClassLevelAnnotation</SPAN>,=20
annotations may also take arrays of values. When creating an annotation =
that=20
requires an array you must surround the array of parameters with =
brackets ( { =E2=80=A6=20
} ) and you must comma-separate each array parameter.=20
<P>Annotation types may define default values for some members. Every=20
member-value pair that does not have a default value <I>must</I> be =
supplied=20
when you create an annotation.=20
<P>The annotation-type declaration below uses meta-annotations, which =
provide=20
information on how the annotation type can be used: <PRE><CODE>
@Retention(RUNTIME)=20
@Target(METHOD)
public @interface MyAnnotationType {
    String value;
}
</CODE></PRE>This code shows how to use meta-annotations when declaring =
your own=20
annotation type. I will cover the specifics on declaring annotation =
types and=20
meta-annotation types later, but for now, just know that you can use=20
meta-annotations to annotate other annotations.=20
<P>Packages annotations are also allowed, but because packages are not=20
explicitly declared in Java, package annotations must be declared in a =
source=20
file called <SPAN class=3Dpf>package-info.java</SPAN> in the directory =
containing=20
the source files for the package. This file should contain <I>only</I> a =
package=20
declaration, preceded by any annotations that should apply to the =
package. This=20
java file must not contain an actual class definition (which would be =
illegal=20
anyways, because <SPAN class=3Dpf>package-info</SPAN> is not a legal =
identifier).=20
<P>
<P><BR><BR><BR><B>Built-in Annotations</B><BR>Java 1.5 comes packaged =
with seven=20
pre-built annotations. I will describe these built-in annotations in =
this=20
section, borrowing much of the wording directly from the <A=20
href=3D"http://java.sun.com/j2se/1.5.0/docs/api/index.html" =
target=3D_blank>Java 5=20
documentation</A>.=20
<P><U>java.lang.Override </U><PRE><CODE>
@Target(value=3DMETHOD)
@Retention(value=3DSOURCE)
public @interface Override
</CODE></PRE>This annotation is used to indicate that a method =
declaration is=20
intended to override a method declaration in a superclass. If a method =
is=20
annotated with this annotation type but does not override a superclass =
method,=20
compilers are required to generate an error message.=20
<P>This annotation is useful in avoiding the situation where you think =
you are=20
overriding a method, but you misspell the method name in the child =
class. The=20
code in the method you are trying to override in the parent class will =
be used=20
because the name is misspelled in the child class. This is usually a =
difficult=20
bug to track down because no compiler or runtime error is thrown. But =
marking a=20
method with the Override annotation would help you realize this type of =
problem=20
at compile time rather than through arduous debugging.=20
<P><U>java.lang.Deprecated </U><PRE><CODE>
@Documented
@Retention(value=3DRUNTIME)
public @interface Deprecated
</CODE></PRE>A program element annotated @Deprecated is one that =
programmers are=20
discouraged from using, typically because it is dangerous or because a =
better=20
alternative exists. Using this annotation, compilers warn when a =
deprecated=20
program element is used or overridden in non-deprecated code.=20
<P><U>java.lang.SuppressWarning</U> <PRE><CODE>
@Target(value=3D{TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})=

@Retention(value=3DSOURCE)
public @interface SuppressWarnings
</CODE></PRE>This annotation indicates that the named compiler warnings =
should=20
be suppressed in the annotated element (and in all program elements =
contained in=20
the annotated element). Note that the set of warnings suppressed in a =
given=20
element is a superset of the warnings suppressed in all containing =
elements. For=20
example, if you annotate a class to suppress one warning and annotate a =
method=20
to suppress another, both warnings will be suppressed in the method.=20
<P><U>java.lang.annotation.Documented</U> <PRE><CODE>
@Documented
@Retention(value=3DRUNTIME)
@Target(value=3DANNOTATION_TYPE)
public @interface Documented
</CODE></PRE>Annotations with a type declaration are to be documented by =
javadoc=20
and similar tools by default. It should be used to annotate the =
declarations of=20
types whose annotations affect the use of annotated elements by their =
clients.=20
If a type declaration is annotated with @Documented, its annotations =
become part=20
of the public API of the annotated elements.=20
<P><U>java.lang.annotation.Inherited</U> <PRE><CODE>
@Documented
@Retention(value=3DRUNTIME)
@Target(value=3DANNOTATION_TYPE)
public @interface Inherited
</CODE></PRE>This indicates that an annotation type is automatically =
inherited.=20
If an inherited meta-annotation is present on an annotation type =
declaration,=20
and the user queries the annotation type on a class declaration, and the =
class=20
declaration has no annotation for this type, then the class's superclass =
will=20
automatically be queried for the annotation type. This process will be =
repeated=20
until an annotation for this type is found or the top of the class =
hierarchy=20
(Object) is reached. If no superclass has an annotation for this type, =
then the=20
query will indicate that the class in question has no such annotation.=20
<P>Note that this meta-annotation type has no effect if the annotated =
type is=20
used for anything other than a class. Also, this meta-annotation causes=20
annotations to be inherited only from superclasses; annotations on =
implemented=20
interfaces have no effect.=20
<P><U>java.lang.annotation.Retention</U> <PRE><CODE>
@Documented
@Retention(value=3DRUNTIME)
@Target(value=3DANNOTATION_TYPE)
public @interface Retention
</CODE></PRE>Retention takes a single value of the enumerated type=20
RetentionPolicy, which informs the compiler of its policy for retaining=20
annotations in memory. There are three RetentionPolicy enumerated =
values:=20
<UL>
  <LI><B>SOURCE</B>=E2=80=94Annotations are to be discarded by the =
compiler.</LI>
  <LI><B>CLASS</B>=E2=80=94Annotations are to be recorded in the class =
file by the=20
  compiler but need not be retained by the VM at runtime. This is the =
default=20
  behavior.</LI>
  <LI><B>RUNTIME</B>=E2=80=94Annotations are to be recorded in the class =
file by the=20
  compiler and retained by the VM at runtime, so they may be read=20
  reflectively.</LI></UL>
<P>If no Retention annotation is present on an annotation type =
declaration, the=20
retention policy defaults to <SPAN =
class=3Dpf>RetentionPolicy.CLASS</SPAN>. By=20
default, the annotation data is not available in the JVM in order to =
reduce=20
overhead.=20
<P><U>java.lang.annotation.Target</U> <PRE><CODE>
@Documented
@Retention(value=3DRUNTIME)
@Target(value=3DANNOTATION_TYPE)
public @interface Target
</CODE></PRE>@Target indicates the kinds of program element to which an=20
annotation type is applicable. It takes a single enumerated parameter of =
type=20
<SPAN class=3Dpf>ElementType</SPAN>. The enumerated values are as =
follows:
<UL>
  <LI>TYPE (class, interface or enum declaration)</LI>
  <LI>FIELD (includes enum constants)</LI>
  <LI>METHOD </LI>
  <LI>PARAMETER </LI>
  <LI>CONSTRUCTOR </LI>
  <LI>LOCAL_VARIABLE </LI>
  <LI>ANNOTATION_TYPE </LI>
  <LI>PACKAGE </LI></UL>If a @Target meta-annotation is not present on =
an=20
annotation type declaration, the declared type may be used on any =
program=20
element. If such a meta-annotation is present, the compiler will enforce =
the=20
specified usage restriction.=20
<P>
<P><BR><BR><BR><B>Declaring Annotation Types</B><BR>Now that you've =
learned a=20
little about the annotations that come packaged with Java 1.5, you can =
move on=20
to declaring your own annotation types.=20
<P>Here is a sample annotation type: <PRE><CODE>
public @interface MyAnnotationType {
    int someValue();
    String someOtherValue();
    String yesSomeOtherValue() default "[blank]";

}
</CODE></PRE>As you can see, annotation types are declared similarly to=20
interfaces. In fact they use the <I>interface</I> keyword prepended with =
an @=20
sign. Just like an interface, annotations have method declarations, each =
of=20
which defines a <I>member</I> of the annotation. These methods may not =
have any=20
parameters. As shown in the example, default values are specified after =
the=20
parenthesis on a method declaration.=20
<P>At first, it seems a little odd to specify the members of an =
annotation using=20
method syntax, because when you declare a Java element and annotate it =
(e.g.=20
when you annotate a class), you may pass values into the annotation. But =
you are=20
not the consumer of the annotation at this point; you are merely =
constructing an=20
instance of the annotation. Think of it as calling a constructor on an =
implicit=20
Java class that you didn't have to write.=20
<P>The annotation consumers are the development tools, the compiler, or =
a=20
runtime library that accesses the annotation data you created when you =
annotated=20
your Java code. After you've created the annotation, annotation =
consumers may=20
call the methods on the annotation interface in order to get the =
annotation=20
values. The return types of the methods represent the type of data that =
a=20
consumer of the annotation would get back.=20
<P>There are a few restrictions when defining annotation types.=20
<UL>
  <LI>Annotations cannot extend other annotations, except for the <SPAN=20
  class=3Dpf>java.lang.annotation.Annotation</SPAN> marker interface =
they=20
  inherently extend. </LI>
  <LI>Method return types must be: primitive types, <SPAN=20
  class=3Dpf>String</SPAN>, <SPAN class=3Dpf>Class</SPAN>, enum types, =
annotation=20
  types, or arrays of the preceding types. </LI>
  <LI>Annotations can't have a <SPAN class=3Dpf>throws</SPAN> clause. =
</LI>
  <LI>Self reference is not allowed (e.g. <SPAN =
class=3Dpf>AnnotationA</SPAN>=20
  contains a member of type <SPAN class=3Dpf>AnnotationA</SPAN>), nor =
circular=20
  reference (e.g. <SPAN class=3Dpf>AnnotationA</SPAN> contains a member =
of type=20
  <SPAN class=3Dpf>AnnotationB</SPAN> and vice versa).</LI>
  <LI>Single member annotations must define only a single method called=20
  <I>value</I> in the annotation type. So long as you follow this =
construct, you=20
  can use the condensed single-member syntax when creating an annotation =
of this=20
  type. <BR><BR>A single member annotation can be defined as follows: =
<PRE><CODE>
public @interface Copyright {
    String value();
}
</CODE></PRE></LI></UL>You can also create meta-annotations, as we have =
already=20
seen. A meta-annotation is any annotation that can be used to annotate =
other=20
annotations. For example, all of the build-in annotations utilize=20
meta-annotations and some of them are meta-annotations themselves.=20
<P>Here is the declaration for the @ Inherited meta-annotation type: =
<PRE><CODE>
@Documented
@Retention(value=3DRUNTIME)
@Target(value=3DANNOTATION_TYPE)
public @interface Inherited
</CODE></PRE>The @Inherited annotation uses three other meta-annotations =
and is=20
a meta-annotation itself. What makes it a meta-annotation? Any =
annotation whose=20
@Target annotation member includes <SPAN =
class=3Dpf>ANNOTATION_TYPE</SPAN> can be=20
used as a meta-annotation.=20
<P><B>Reading Annotations</B><BR>Now that you know how to declare your =
own=20
annotation types and annotate Java elements, you need to know how to =
access the=20
annotation data you specified. Annotation consumers are software that =
read=20
annotation data and do something useful with it. Annotation consumers =
fall into=20
three groups:=20
<P><B>General tools</B> are programs that can analyze source code and do =

something useful with it. For example compilers and documentation =
generators are=20
both considered general tools. General tools do not load annotated =
classes or=20
annotation interfaces into the virtual machine.=20
<P><B>Specific tools</B> are also programs that can analyze source code =
without=20
loading annotated classes, but they need to load annotation interfaces =
into the=20
virtual machine. An example of this is a Stub generator.=20
<P><B>Introspectors</B> are programs that can query their own =
annotations (the=20
ones with a <SPAN class=3Dpf>RUNTIME</SPAN> retention policy). =
Introspectors will=20
load both annotated classes and annotation interfaces into the virtual =
machine.=20
<P><A href=3D"javascript:showSupportItem('listing1')">Listing 1</A> is =
an example=20
of how you can access your code during runtime using the reflection API. =

<P>As I mentioned previously, I think that most developers will be users =
of=20
annotations, but few will have to write code that consumes annotations.=20
<P>If you are a general or specific tools developer, you may want to =
look into a=20
few APIs that will help you read annotations from source files in order =
to use=20
them for some type of static preprocessing. The new Doclet API (<SPAN=20
class=3Dpf>com.sun.javadoc</SPAN>) has support for reading annotations. =
It doesn=E2=80=99t=20
currently support all of the features of annotations, but it may suffice =
as a=20
library for writing your tool. Another thing to keep an eye on is the =
newly=20
submitted JSR-269 (Pluggable Annotation Processing API), which will =
provide a=20
generic API that allows developers to read annotation data using general =
and=20
specific tools.=20
<P>If you are developing an introspector, you can use the new reflection =
API to=20
access your annotations, though I would suggest looking into AOP as a =
means to=20
interface with annotated methods. I think there is a lot of room for =
exploration=20
here. The combinations of aspects and annotations can yield a very =
powerful=20
introspection tool.=20
<P>
<P>
<DIV><B>Javid Jamae</B> consults for Valtech, a global consulting group=20
specializing in delivering advanced technology solutions. Valtech =
endeavors to=20
help its customers through its global delivery model to create and/or =
maintain=20
an affordable competitive advantage. </DIV><BR><BR></DIV></CENTER>
<TABLE style=3D"PADDING-TOP: 10px" border=3D0 cellSpacing=3D0 =
cellPadding=3D0=20
width=3D"100%">
  <TBODY>
  <TR>
    <TD class=3DsmallFont align=3Dmiddle>DevX is a division of =
Jupitermedia=20
      Corporation <BR>=C2=A9 Copyright 2007 Jupitermedia Corporation. =
All Rights=20
      Reserved. <A =
href=3D"http://www.internet.com/corporate/legal.html">Legal=20
      Notices</A></TD></TR></TBODY></TABLE></BODY></HTML>

------=_NextPart_000_0000_01CA0712.640E8780
Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-Location: http://www.devx.com/assets/devx/4055.gif

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

------=_NextPart_000_0000_01CA0712.640E8780
Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-Location: http://www.devx.com/assets/dropcaps/3591.gif

R0lGODlhFwAYAMQAAP12F/yVSP19Iv1tCPr03fvRpfyMOvvNoPr13/yqaPyqafydVfvXrvrz2v1u
CvvKm/uxdPuzd/1xDvu1ef1qBPr65v////1oAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA
AAAALAAAAAAXABgAAAWVYCWOyJEYAAUYyYGMMPwEV23bwROPDSTdwJoE0ogRFMFkTUGATZTQyagA
sFmu2KzFBiiIFjet+LaoMAZhcfY2YESgWGiEpowrAwL4FSpw6LdKDn51e4F5hIBJAnRJdkkBb4hy
Z5JJbRVgjYVBZRVUmok3XSNPQY43UiNHpps2TDE9P1AXQ0U7FTNQObcwJScpKy0vMSEAOw==

------=_NextPart_000_0000_01CA0712.640E8780
Content-Type: text/css;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://www.devx.com/styles/cps.css

BODY {
	FONT: 13px Arial, Helvetica, Sans-Serif
}
.error {
	BORDER-BOTTOM: red 2px solid; BORDER-LEFT: red 2px solid; =
PADDING-BOTTOM: 10px; BACKGROUND-COLOR: white; MARGIN: 20px; =
PADDING-LEFT: 10px; PADDING-RIGHT: 10px; FONT: 11px Verdana, Geneva, =
Arial, Helvetica, sans-serif; COLOR: black; BORDER-TOP: red 2px solid; =
BORDER-RIGHT: red 2px solid; PADDING-TOP: 10px
}
.message {
	BORDER-BOTTOM: green 2px solid; BORDER-LEFT: green 2px solid; =
PADDING-BOTTOM: 10px; BACKGROUND-COLOR: white; MARGIN: 20px; =
PADDING-LEFT: 10px; PADDING-RIGHT: 10px; FONT: 11px Verdana, Geneva, =
Arial, Helvetica, sans-serif; COLOR: black; BORDER-TOP: green 2px solid; =
BORDER-RIGHT: green 2px solid; PADDING-TOP: 10px
}
.copyright {
	TEXT-ALIGN: center; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
COLOR: red; FONT-SIZE: 11px; FONT-WEIGHT: bold
}
.formFieldError {
	TEXT-ALIGN: right; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
COLOR: red; FONT-SIZE: 11px; FONT-WEIGHT: bold
}
.billingMessage {
	TEXT-ALIGN: left; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
COLOR: red; FONT-SIZE: 11px; FONT-WEIGHT: bold
}
.imgBtn {
	BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; BORDER-TOP: =
medium none; CURSOR: hand; BORDER-RIGHT: medium none
}
.stageControlBar {
	BORDER-BOTTOM: #6f6c60 2px solid; BORDER-LEFT: white 2px solid; =
BACKGROUND-COLOR: #cdccc5; BORDER-TOP: white 2px solid; BORDER-RIGHT: =
#6f6c60 2px solid
}
.smOptionTag {
	POSITION: relative; LINE-HEIGHT: 14px; FONT-FAMILY: Verdana, Arial, =
Helvetica, sans-serif; FONT-SIZE: 10px; TOP: -2px; FONT-WEIGHT: bold; =
LEFT: 0px
}
.menuItems {
	BORDER-BOTTOM: white 1px solid; MARGIN-LEFT: 3px
}
.taxTypesDiv {
	BORDER-BOTTOM: black solid; POSITION: absolute; TEXT-ALIGN: left; =
BORDER-LEFT: black solid; BACKGROUND-COLOR: #d3d3d3; BORDER-TOP: black =
solid; BORDER-RIGHT: black solid; LEFT: 0px
}
.navBar {
	BORDER-BOTTOM: #e0c189 1px solid; BORDER-LEFT: white 1px solid; =
PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fff5ce; MARGIN-TOP: 2px; =
PADDING-LEFT: 5px; PADDING-RIGHT: 5px; MARGIN-LEFT: 2px; VERTICAL-ALIGN: =
top; BORDER-TOP: white 1px solid; BORDER-RIGHT: #e0c189 1px solid; =
PADDING-TOP: 5px
}
.tabOn {
	BORDER-BOTTOM: silver 2px solid; TEXT-ALIGN: center; BORDER-LEFT: =
#eeeeee 2px solid; PADDING-BOTTOM: 3px; PADDING-LEFT: 5px; =
PADDING-RIGHT: 5px; FONT: bold 11px Verdana, Geneva, Arial, Helvetica, =
sans-serif; BACKGROUND: silver; COLOR: white; BORDER-TOP: #eeeeee 2px =
solid; CURSOR: pointer; BORDER-RIGHT: gray 2px solid; PADDING-TOP: 3px
}
.widgetBox {
	BORDER-BOTTOM: pink 1px solid; BORDER-LEFT: pink 1px solid; MARGIN: =
1px; BORDER-TOP: pink 1px solid; BORDER-RIGHT: pink 1px solid
}
.widgetEdit {
	TEXT-ALIGN: left; WIDTH: 100%; BACKGROUND: silver; HEIGHT: 15px; =
OVERFLOW: hidden
}
.widgetName {
	POSITION: relative; FONT: 9px Verdana, Geneva, Arial, Helvetica, =
sans-serif; LEFT: 0px
}
.tabOff {
	BORDER-BOTTOM: #d3d3d3 2px solid; TEXT-ALIGN: center; BORDER-LEFT: =
#d3d3d3 1px solid; PADDING-BOTTOM: 3px; PADDING-LEFT: 5px; =
PADDING-RIGHT: 5px; FONT: bold 11px Verdana, Geneva, Arial, Helvetica, =
sans-serif; BACKGROUND: darkgray; COLOR: white; BORDER-TOP: #d3d3d3 1px =
solid; CURSOR: hand; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 3px
}
.tabCardBG {
	BORDER-BOTTOM: gray 2px solid; BORDER-LEFT: #eeeeee 2px solid; =
PADDING-BOTTOM: 10px; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; =
BACKGROUND: silver; BORDER-RIGHT: gray 2px solid; PADDING-TOP: 10px
}
.tabCardPosition {
	POSITION: relative; TOP: 0px; LEFT: 0px
}
.tabCardFirst {
	POSITION: absolute; VISIBILITY: visible; OVERFLOW: auto; TOP: 0px; =
LEFT: 0px
}
.tabCard {
	POSITION: absolute; VISIBILITY: hidden; OVERFLOW: auto; TOP: 0px; LEFT: =
0px
}
.pageTitle {
	BORDER-BOTTOM: #3d583e 2px solid; BORDER-LEFT: #6495ed 2px solid; =
PADDING-BOTTOM: 5px; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; FONT: bold =
16px Verdana, Geneva, Arial, Helvetica, sans-serif; BACKGROUND: #aaaaaa; =
COLOR: white; BORDER-TOP: #6495ed 2px solid; BORDER-RIGHT: #3d583e 2px =
solid; PADDING-TOP: 5px
}
.miniPageTitle {
	BORDER-BOTTOM: #3d583e 1px solid; BORDER-LEFT: #6495ed 1px solid; =
PADDING-BOTTOM: 5px; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; FONT: bold =
10px Verdana, Geneva, Arial, Helvetica, sans-serif; MARGIN-BOTTOM: 10px; =
BACKGROUND: #0000cd; COLOR: white; BORDER-TOP: #6495ed 1px solid; =
BORDER-RIGHT: #3d583e 1px solid; PADDING-TOP: 3px
}
.dlgBox {
	BORDER-BOTTOM: black 2px solid; POSITION: absolute; BORDER-LEFT: black =
1px solid; PADDING-BOTTOM: 2px; PADDING-LEFT: 2px; PADDING-RIGHT: 2px; =
BACKGROUND: silver; BORDER-TOP: black 1px solid; RIGHT: 0px; =
BORDER-RIGHT: black 2px solid; PADDING-TOP: 2px; LEFT: 0px
}
.insetBox {
	BORDER-BOTTOM: #d3d3d3 1px solid; BORDER-LEFT: gray 1px solid; =
BORDER-TOP: gray 1px solid; BORDER-RIGHT: #d3d3d3 1px solid
}
TH {
	BORDER-BOTTOM: black 1px solid; BORDER-LEFT: #6495ed 1px solid; =
BACKGROUND-COLOR: #0000cd; FONT: bold 11px Verdana, Geneva, Arial, =
Helvetica, sans-serif; COLOR: #ffffff; BORDER-TOP: #6495ed 1px solid; =
BORDER-RIGHT: black 1px solid
}
TH.subHead {
	BORDER-BOTTOM: black 1px solid; BORDER-LEFT: #f5f5f5 1px solid; =
BACKGROUND-COLOR: #d3d3d3; FONT: 10px Verdana, Geneva, Arial, Helvetica, =
sans-serif; COLOR: black; BORDER-TOP: #f5f5f5 1px solid; BORDER-RIGHT: =
black 1px solid
}
.simpleBox {
	BORDER-BOTTOM: black 1px solid; BORDER-LEFT: black 1px solid; =
BACKGROUND-COLOR: #ffffff; BORDER-TOP: black 1px solid; BORDER-RIGHT: =
black 1px solid
}
.grayLineAbove {
	BORDER-TOP: silver 1px solid
}
.menuDiv {
	BORDER-BOTTOM: #3d583e 1px solid; BORDER-LEFT: #6495ed 1px solid; =
PADDING-BOTTOM: 2px; FONT: bold 11px Verdana, Geneva, Arial, Helvetica, =
sans-serif; BACKGROUND: #0000cd; COLOR: white; BORDER-TOP: #6495ed 1px =
solid; BORDER-RIGHT: #3d583e 1px solid; PADDING-TOP: 2px
}
TH.tableSort {
	BACKGROUND-COLOR: #0000cd; FONT-FAMILY: Verdana, Arial, Helvetica, =
sans-serif; COLOR: white; FONT-SIZE: 8pt; CURSOR: hand; FONT-WEIGHT: =
normal; TEXT-DECORATION: none
}
TH.tableSortOver {
	BORDER-BOTTOM: #c0c0c0 1px solid; BORDER-LEFT: black 1px solid; =
BACKGROUND-COLOR: #b9ceba; FONT-FAMILY: Verdana, Arial, Helvetica, =
sans-serif; COLOR: #000000; FONT-SIZE: 8pt; BORDER-TOP: black 1px solid; =
CURSOR: hand; FONT-WEIGHT: normal; TEXT-DECORATION: none
}
.disabledText {
	OVERFLOW-X: scroll; OVERFLOW-Y: scroll; BACKGROUND-COLOR: #f5f5f5; =
WIDTH: 600px; FONT-FAMILY: monospace; HEIGHT: 230px; FONT-SIZE: 12px; =
WORD-BREAK: normal
}
.fieldLabel {
	TEXT-ALIGN: right; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
FONT-SIZE: 11px; FONT-WEIGHT: bold
}
.fieldLabelLeft {
	TEXT-ALIGN: left; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
FONT-SIZE: 11px; FONT-WEIGHT: bold
}
.fieldEntry {
	FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 11px
}
.smOptionTag {
	POSITION: relative; LINE-HEIGHT: 14px; FONT-FAMILY: Verdana, Arial, =
Helvetica, sans-serif; FONT-SIZE: 10px; TOP: -2px; FONT-WEIGHT: bold; =
LEFT: 0px
}
.smTag {
	FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 10px; =
FONT-WEIGHT: bold; LEFT: 0px
}
A:hover {
	TEXT-DECORATION: underline
}
.navItem {
	FONT: bold 11px Verdana, Geneva, Arial, Helvetica, sans-serif; COLOR: =
blue; TEXT-DECORATION: none
}
.navItemDiv {
	BORDER-BOTTOM: white 1px solid; PADDING-BOTTOM: 1px; MARGIN-LEFT: 3px; =
PADDING-TOP: 1px
}
.mdSans {
	FONT: 11px Verdana, Geneva, Arial, Helvetica, sans-serif
}
.mdBldSans {
	FONT: bold 11px Verdana, Geneva, Arial, Helvetica, sans-serif
}
.smFieldLabel {
	LINE-HEIGHT: 14px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
FONT-SIZE: 10px; FONT-WEIGHT: bold
}
.smBtn {
	FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 10px; =
FONT-WEIGHT: bold
}
TD {
	FONT-FAMILY: Arial, Helvetica, Sans-serif
}
.tinyMessage {
	FONT-FAMILY: Arial, Helvetica, Sans-serif; FONT-SIZE: 8pt
}
.btnBar {
	TEXT-ALIGN: center; MARGIN-TOP: 5px; MARGIN-BOTTOM: 5px
}
.regFeedback {
	COLOR: red; FONT-WEIGHT: bold
}
.surveyQuestion {
	FONT: 11px Verdana, Geneva, Arial, Helvetica, sans-serif; COLOR: black
}
.surveyInstructions {
	BACKGROUND-COLOR: #99ff66; FONT: italic 10px "Tahoma", Geneva, Arial, =
Helvetica, sans-serif
}
.surveyChoice {
	FONT: 10px "Comic Sans MS", Geneva, Arial, Helvetica, sans-serif
}
.surveyRequired {
	COLOR: red
}
.surveyQEHeaderText {
	FONT-FAMILY: Futura, Arial, Helvetica, sans-serif; COLOR: #000000; =
FONT-WEIGHT: normal; TEXT-DECORATION: none
}
.surveyQEFooterText {
	FONT-FAMILY: Futura, Arial, Helvetica, sans-serif; COLOR: #000000; =
FONT-WEIGHT: normal; TEXT-DECORATION: none
}
A {
	COLOR: #003366; TEXT-DECORATION: none
}
A.leftnav {
	COLOR: #ffffff
}
A.rightnav {
	COLOR: #336699
}
A:hover {
	TEXT-DECORATION: underline
}
.smallerfont {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
.smallfont {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-SIZE: 11px
}
.smallfontRight {
	TEXT-ALIGN: right; FONT-FAMILY: Arial, Helvetica, Sans-Serif; =
TEXT-DECORATION: underline
}
.newsletterFont {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; COLOR: #336699
}
.doorFeatureAreaLabel {
	FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.doorFeatureArea {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
.doorFeatureAreaTitle {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-SIZE: 14px
}
.articleTitle {
	FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; COLOR: #336699; =
FONT-SIZE: 16px; FONT-WEIGHT: bolder
}
.articleDek {
	FONT-STYLE: italic; MARGIN-TOP: 0px; FONT-FAMILY: Verdana, Arial, =
Helvetica, Sans-Serif; FONT-SIZE: 12px; FONT-WEIGHT: bolder
}
.articleAuthor {
	FONT-STYLE: normal; MARGIN-TOP: 12px; FONT-FAMILY: Arial, Helvetica, =
Sans-Serif; FONT-SIZE: 10.5px
}
.articleBio {
	FONT-STYLE: italic; FONT-FAMILY: Arial, Helvetica, Sans-Serif; =
FONT-SIZE: 11px
}
A.downloadLink {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bold
}
.downloadMoreLink {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bold
}
A.FeaturedBoxLink {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.downloadText {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
.regFeedback {
	COLOR: red
}
.regTopLabel {
	FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.regLabel {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.downloadTopTitle {
	FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.downloadIntro {
	FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif
}
A.downloadTryIt {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
.downloadTitle {
	FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.smallestText {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
.licenseAgreement {
	FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.licenseDesc {
	FONT-STYLE: italic; FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
A.discMsgNavLink {
=09
}
A.discMsgNavLinkDisabled {
=09
}
A.discTopicLink {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
.discTopOfPageTD {
=09
}
.discTopicsTD {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
.discAuthorTH {
=09
}
.discAuthorTD {
=09
}
.discDatePostedTH {
=09
}
.discDatePostedTD {
=09
}
.discMsgSubjectTH {
=09
}
.discMsgSubjectTD {
=09
}
.discSimpleBox {
=09
}
.discAuthorLabel {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.discAuthorEntry {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
.discDatePostedLabel {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.discDatePostedEntry {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; COLOR: #000000
}
.discSubjectLabel {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; COLOR: #336699; FONT-WEIGHT: =
bolder
}
.discSubjectEntry {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; COLOR: #000000; FONT-WEIGHT: =
bolder
}
.discMsgBody {
	PADDING-BOTTOM: 3px; BACKGROUND-COLOR: #ccffff; PADDING-LEFT: 3px; =
PADDING-RIGHT: 3px; FONT-FAMILY: Arial, Helvetica, Sans-Serif; COLOR: =
#000000; PADDING-TOP: 3px
}
.discRecentMsgsTH {
=09
}
.discRecentMsgsTD {
=09
}
.discRecentAuthorTH {
=09
}
.discRecentAuthorTD {
=09
}
.discRecentDatePostedTH {
=09
}
.discRecentDatePostedTD {
=09
}
.discSubjectTD {
=09
}
.discMessageTitle {
	FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.discMultipage {
=09
}
.discPostAuthorLabel {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.discPostEmailLabel {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.discPostDatePostedLabel {
=09
}
.discPostSubjectLabel {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.discPostParentMsgLabel {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.discPostParentMsg {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif
}
.discPostFieldEntry {
=09
}
.discPostMsgLabel {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; FONT-WEIGHT: bolder
}
.discPostMsgBody {
=09
}
.discFieldLabel {
	TEXT-ALIGN: right; FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; =
FONT-WEIGHT: bolder
}
.discTblHead {
	PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #336699; PADDING-LEFT: 2px; =
PADDING-RIGHT: 2px; FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; =
COLOR: #ffffff; FONT-WEIGHT: bold; PADDING-TOP: 2px
}
.discHeader {
	PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #394d8c; PADDING-LEFT: 2px; =
PADDING-RIGHT: 2px; FONT-FAMILY: Arial, Helvetica, Sans-Serif; COLOR: =
#ffffff; CURSOR: hand; FONT-WEIGHT: bold; PADDING-TOP: 2px
}
.discSortHeader {
	PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #336699; PADDING-LEFT: 2px; =
PADDING-RIGHT: 2px; FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; =
COLOR: #fed980; CURSOR: hand; FONT-WEIGHT: bold; TEXT-DECORATION: =
underline; PADDING-TOP: 2px
}
.discAuthor {
	PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #ccffff; PADDING-LEFT: 2px; =
PADDING-RIGHT: 2px; FONT-FAMILY: Verdana, Arial, Helvetica, Sans-Serif; =
COLOR: #000000; PADDING-TOP: 2px
}
.HeadingStyle {
	FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 16px; =
FONT-WEIGHT: bold
}
.WhiteHeadingStyle {
	FONT-FAMILY: Arial, Helvetica, sans-serif; COLOR: #ffffff; FONT-WEIGHT: =
bold
}
.QuestionStyle {
	FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-WEIGHT: normal
}
.InstructionStyle {
	FONT-STYLE: italic; FONT-FAMILY: Arial, Helvetica, sans-serif; =
FONT-WEIGHT: normal
}
.AnswerStyle {
	FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-WEIGHT: normal
}
.ViewResultsStyle {
	FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-WEIGHT: normal
}
.ScoreStyle {
	FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-WEIGHT: normal
}
.TotalVotesStyle {
	FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-WEIGHT: bold
}
.defaultText {
	FONT-FAMILY: Arial, Helvetica, sans-serif; COLOR: #000000; FONT-SIZE: =
12px; FONT-WEIGHT: normal; TEXT-DECORATION: none
}
CODE {
	FONT-SIZE: 12px
}
.smallwhitefont {
	FONT-FAMILY: Arial, Helvetica, Sans-Serif; COLOR: #ffffff
}

------=_NextPart_000_0000_01CA0712.640E8780
Content-Type: text/css;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://www.devx.com/styles/pf.css

A {
	COLOR: #0000ff; TEXT-DECORATION: underline
}
.articleSubtitle {
	FONT-STYLE: normal; FONT-FAMILY: Arial, Helvetica, Sans-Serif; COLOR: =
#000000; FONT-SIZE: 14px; FONT-WEIGHT: bold
}
.arthead {
	LINE-HEIGHT: 25px; FONT-FAMILY: Verdana, Arial, Geneva; COLOR: black; =
FONT-SIZE: 24px; FONT-WEIGHT: bold
}

------=_NextPart_000_0000_01CA0712.640E8780
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://www.devx.com/scripts/globalFuncs.js

function editWidget(widget_ID, host) {
	var winProps =3D =
"width=3D850,height=3D600,titlebar=3D0,toolbar=3D0,location=3D0,menubar=3D=
0,scrollbars=3D1,resizable=3D1,channelmode=3D0,directories=3D0,status=3D1=
";
	=
window.open("http://"+host+"/cms/popup.cfm?methodId=3D113&popup=3D1&wid=3D=
" + widget_ID, "widgetEditor", winProps, true);
}
function editWidgetProps(widgetType_ID, host) {
	var winProps =3D =
"width=3D850,height=3D600,titlebar=3D0,toolbar=3D0,location=3D0,menubar=3D=
0,scrollbars=3D1,resizable=3D1,channelmode=3D0,directories=3D0,status=3D1=
";
	=
window.open("http://"+host+"/cms/popup.cfm?methodId=3D109&wtId=3D"+widget=
Type_ID+"&popup=3D1", "widgetEditor", winProps, true);
}
function editContent(content_id) {
	var winProps =3D =
"width=3D800,height=3D570,titlebar=3D0,toolbar=3D0,location=3D0,menubar=3D=
0,scrollbars=3D1,resizable=3D1,channelmode=3D0,directories=3D0,status=3D1=
";
	window.open("/cms/popup.cfm?methodId=3D8&popup=3D1&id=3D" + content_id, =
"contentEditor", winProps, true);

}
function popUpWindow(theURL, width, height) {
	var winProps =3D "width=3D" + width + ",height=3D" + height;
	winProps +=3D =
",titlebar=3D0,toolbar=3D0,location=3D0,menubar=3D0,scrollbars=3D1,resiza=
ble=3D1,channelmode=3D0,directories=3D0,status=3D1";
	window.open(theURL,"popUp",winProps,true);
}
function popUpNoResize(theURL, width, height) {
		var winProps =3D "width=3D" + width + ",height=3D" + height;
		winProps +=3D =
",titlebar=3D0,toolbar=3D0,location=3D0,menubar=3D0,scrollbars=3D1,resiza=
ble=3D0,channelmode=3D0,directories=3D0,status=3D1";
		window.open(theURL,"popUp",winProps,true);
}
function popUpNoScroll(theURL, width, height) {
	var winProps =3D "width=3D" + width + ",height=3D" + height;
	winProps +=3D =
",titlebar=3D0,toolbar=3D0,location=3D0,menubar=3D0,scrollbars=3D0,resiza=
ble=3D1,channelmode=3D0,directories=3D0,status=3D1";
	window.open(theURL,"popUp",winProps,true);
}
function emailCheck(emailStr) {
	/*  author: Sandeep V. Tamhankar (stamhankar@hotmail.com) 	*/
	/* conforms closely to RFC 822.                       		*/
=09
	/* The following pattern is used to check if the entered e-mail address =
	*/
	/* fits the user@domain format.  It also is used to separate the =
username 	*/
	/* from the domain. 														*/
	var emailPat=3D/^(.+)@(.+)$/;
	/* The following string represents the pattern for matching all special	=
	*/
	/*  characters.  We don't want to allow special characters in the =
address. 	*/
	/*  These characters include ( ) < > @ , ; : \ " . [ ]    					*/
	var specialChars=3D"\\(\\)<>@,;:\\\\\\\"\\.\\[\\]";
	/* The following string represents the range of characters allowed in a =
	*/
	/* username or domainname.  It really states which chars aren't =
allowed. 	*/
	var validChars=3D"\[^\\s" + specialChars + "\]";
	/* The following pattern applies if the "user" is a quoted string (in	=
*/
	/* which case, there are no rules about which characters are allowed	*/
	/* and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com 	=
*/
	/* is a legal e-mail address. 											*/
	var quotedUser=3D"(\"[^\"]*\")";
	/* The following pattern applies for domains that are IP addresses,  	=
*/
	/* rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal		*/
	/*  e-mail address. NOTE: The square brackets are required. 			*/
	var ipDomainPat=3D/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	/* The following string represents an atom (basically a series of =
non-special characters.) */
	var atom=3DvalidChars + '+';
	/* The following string represents one word in the typical username.*/
	/* For example, in john.doe@somewhere.com, john and doe are words.  */
	/* Basically, a word is either an atom or quoted string. 			*/
	var word=3D"(" + atom + "|" + quotedUser + ")";
	// The following pattern describes the structure of the user
	var userPat=3Dnew RegExp("^" + word + "(\\." + word + ")*$");
	/* The following pattern describes the structure of a normal symbolic =
domain, as opposed to ipDomainPat, shown above. */
	var domainPat=3Dnew RegExp("^" + atom + "(\\." + atom +")*$")	;
	/* Finally, let's start trying to figure out if the supplied address is =
valid. */=09
	/* Begin with the coarse pattern to simply break up user@domain into =
different pieces that are easy to analyze. */
	var matchArray=3DemailStr.match(emailPat);
	if (matchArray=3D=3Dnull) {
	/* Too many/few @'s or something; basically, this address doesn't even =
fit the general mould of a valid e-mail address. */
		alert("Email address seems incorrect (check @ and .'s)");
		return false;
	}
	var user=3DmatchArray[1];
	var domain=3DmatchArray[2];
=09
	// See if "user" is valid=20
	if (user.match(userPat)=3D=3Dnull) {
	    // user is not valid
	    alert("The username doesn't seem to be valid.");
	    return false;
	}
=09
	/* if the e-mail address is at an IP address (as opposed to a symbolic =
host name) make sure the IP address is valid. */
	var IPArray=3Ddomain.match(ipDomainPat);
	if (IPArray!=3Dnull) {
	    // this is an IP address
		  for (var i=3D1;i<=3D4;i++) {
		    if (IPArray[i]>255) {
		        alert("Destination IP address is invalid!");
			return false;
		    }
	    }
	    return true;
	}=09
	// Domain is symbolic name
	var domainArray=3Ddomain.match(domainPat);
	if (domainArray=3D=3Dnull) {
		alert("The domain name doesn't seem to be valid.");
	    return false;
	}=09
	/* domain name seems valid, but now make sure that it ends in a 			*/
	/* three-letter word (like com, edu, gov) or a two-letter word,				*/
	/*  representing country (uk, nl), and that there's a hostname =
preceding  	*/
	/*   the domain or country. 												*/
=09
	/* Now we need to break up the domain to get a count of how many atoms =
it consists of. */
	var atomPat=3Dnew RegExp(atom,"g");
	var domArr=3Ddomain.match(atomPat);
	var len=3DdomArr.length;
	if (domArr[domArr.length-1].length<2 ||=20
	    domArr[domArr.length-1].length>4) {
	   // the address must end in a two, three, or four letter word (four =
letter to support the .name domain)
	   alert("The address must end in a three or four letter domain, or two =
letter country.");
	   return false;
	}
=09
	// Make sure there's a host name preceding the domain.
	if (len<2) {
	   var errStr=3D"This address is missing a hostname!";
	   alert(errStr);
	   return false;
	}
=09
	// If we've gotten this far, everything's valid!
	return true;
}

/*function trackClick(contentID,destURL,userID,trackingKey,title) {
	var xmlhttp =3D false;
	var theURL =3D =
"http://cms.devx.com/RSSLinkTracker/RSSLinkTracker.cfm?contentID=3D" + =
contentID + "&destURL=3D" + destURL + "&userID=3D" + userID + "&trk=3D" =
+ trackingKey + "&title=3D" + title;

    if (!xmlhttp && typeof XMLHttpRequest!=3D'undefined') {
	   try {
		   xmlhttp =3D new XMLHttpRequest();
	   } catch (e) {
		   xmlhttp=3Dfalse;
	   }
    }
	if (!xmlhttp && window.createRequest) {
		try {
			xmlhttp =3D window.createRequest();
		} catch (e) {
			xmlhttp=3Dfalse;
		}
	}
=09
	xmlhttp.open("GET", theURL, true);
=09
	 xmlhttp.send(null)
}
*/

------=_NextPart_000_0000_01CA0712.640E8780--
