Download ToDo List Example

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Xdoclet Introduction
Ross Sponholtz
[email protected]
Agenda
•
•
•
•
•
•
XDoclet Overview
Todo List
EJB File Generation
Servlet File Generation
Hibernate File Generation
Custom File Generation
What is Xdoclet
•
•
•
•
Code generation framework
Attribute based (@ doclet tags)
Popular (95,000 downloads in 2003)
Originated as EJBDoclet to generate EJB artifacts
(interfaces, deployment descriptors, etc.)
• Evolved to generate even more stuff (Hibernate
mapping files, web.xml, TLD files, etc.)
• Built in support for many leading tools (Jboss,
WebLogic, WebSphere, Castor, Hibernate, Struts,
etc.)
ToDo List Example
Usage of todo tag
/**
* This is a customer bean. It is an example of how to use the XDoclet tags.
*
* ...
*
* @todo This too should not appear in CMP class
*/
public abstract class CustomerBean
extends PersonBean {
private EntityContext ctx;
Ant task
•
•
•
•
•
<taskdef name="documentdoclet"
classname="xdoclet.modules.doc.DocumentDocletTask"
classpathref="samples.class.path"
/>
•
•
•
•
<target name="todo" depends="prepare">
<echo>+-----------------------------------------+</echo>
<echo>| R U N N I N G
T O D O
|</echo>
<echo>+-----------------------------------------+</echo>
•
•
•
•
•
•
•
•
<mkdir dir="${samples.todo.dir}"/>
<documentdoclet destdir="${samples.todo.dir}" >
<fileset dir="${samples.java.dir}">
<include name="**/*.java"/>
</fileset>
<info tag="todo"/>
</documentdoclet>
</target>
Generation of EJB Artifacts
Session
Bean
XDoclet Process
Home
Interface
Remote
Interface
Value
Object
Ejb-jar.xml
Jboss.xml
Session Bean Example
• /**
•
* This is a teller bean. *
•
* @ejb.bean
name="Teller"
•
*
description="Teller example bean"
•
*
jndi-name="ejb/bank/Teller"
•
*
type="Stateless"
•
*
• */
• public abstract class TellerBean extends BaseTellerBean
implements SessionBean {
• …
• }
Session Bean Details
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
/**
* This is a teller bean. It is an example of how to use the XDoclet tags.
*
* @ejb.bean
name="Teller"
*
description="Teller example bean"
*
jndi-name="ejb/bank/Teller"
*
type="Stateless"
*
* @ejb.ejb-ref
ejb-name="Account"
*
ref-name="ejb/bank/Account"
*
* @ejb.ejb-ref
ejb-name="Customer"
*
* @ejb.security-role-ref role-link="Administrator"
*
role-name="admin"
*
* @ejb.permission role-name="Teller"
* @ejb.permission role-name="Administrator"
*
* @ejb.transaction type="Required"
* @ejb.transaction-type type="Container"
*
* @ejb.resource-ref res-auth="Container"
*
res-name="jdbc/DBPool"
*
res-type="javax.sql.DataSource"
*
* @soap.service urn="TellerService"
*
* @jboss.resource-ref res-ref-name="jdbc/DBPool"
*
resource-name="MyDataSourceManager"
*
* @jboss.container-configuration name="Standard Stateless
SessionBean"
*
* @jboss.ejb-ref-jndi jndi-name="ejb/bank/Account"
*
ref-name="bank/Account"
*
* @weblogic.pool
initial-beans-in-free-pool="1"
*
max-beans-in-free-pool="3"
*
* @weblogic.stateless-clustering stateless-bean-call-router-classname="Whatever"
*
stateless-bean-is-clusterable="True"
*
stateless-bean-load-algorithm="Whazzup"
*
stateless-bean-methods-are-idempotent="Sure"
*/
Session Bean Method
•
•
•
•
•
•
/**
* Transfer money between accounts.
*
* @ejb.interface-method view-type="remote"
*/
public void transfer(Account from, Account to,
float amount) {
•
•
•
•
•
•
•
•
try {
from.withdraw(amount);
to.deposit(amount);
}
catch (java.rmi.RemoteException e) {
throw new EJBException(e);
}
}
Ant Task
<target name="ejbdoclet" depends="prepare">
<ejbdoclet
destdir="${samples.gen-src.dir}"
mergedir="parent-fake-to-debug"
excludedtags="@version,@author,@todo"
addedtags="@xdoclet-generated at ${TODAY},@copyright The XDoclet Team,@author
XDoclet,@version ${version}"
ejbspec="2.0"
force="${samples.xdoclet.force}"
verbose="false"
>
<fileset dir="${samples.java.dir}">
<include name="test/ejb/*Bean.java"/>
<include name="test/ejb/cmr/*Bean.java"/>
<include name="test/ejb/jdo/*.java"/>
<exclude name="test/ejb/Base*.java"/>
<exclude name="test/ejb/SecurityOfficerBean.java"/>
</fileset>
<packageSubstitution packages="ejb" substituteWith="interfaces"/>
<remoteinterface/>
<localinterface/>
<homeinterface/>
<localhomeinterface/>
<dataobject/>
<valueobject/>
<entitypk/>
<entitycmp/>
<entitybmp/>
<session/>
Ant Task (cont.)
<deploymentdescriptor
destdir="${samples.meta-inf.dir}"
validatexml="true"
mergedir="fake-to-debug"
description="bæbæ"
>
<configParam name="clientjar" value="blah.jar"/>
</deploymentdescriptor>
<jboss
version="3.2"
unauthenticatedPrincipal="nobody"
xmlencoding="UTF-8"
destdir="${samples.meta-inf.dir}"
validatexml="true"
preferredrelationmapping="relation-table"
/>
</ejbdoclet>
</target>
Generated EJB Descriptor
<session >
<description><![CDATA[Teller example
bean]]></description>
<ejb-name>Teller</ejb-name>
<home>test.interfaces.TellerHome</home>
<remote>test.interfaces.Teller</remote>
<local-home>
test.interfaces.TellerLocalHome</local-home>
<local>test.interfaces.TellerLocal</local>
<ejb-class>test.ejb.TellerSession</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
Generated EJB Descriptor
<ejb-ref >
<ejb-ref-name>ejb/bank/Account</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>test.interfaces.AccountHome</home>
<remote>test.interfaces.Account</remote>
<ejb-link>Account</ejb-link>
</ejb-ref>
<ejb-ref >
<ejb-ref-name>ejb/Customer</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>test.interfaces.CustomerHome</home>
<remote>test.interfaces.Customer</remote>
<ejb-link>Customer</ejb-link>
</ejb-ref>
Generated EJB Descriptor
<security-role-ref>
<role-name>admin</role-name>
<role-link>Administrator</role-link>
</security-role-ref>
<resource-ref >
<res-ref-name>jdbc/DBPool</res-ref-name>
<res-type>
javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</session>
JBoss Descriptor
<session>
<ejb-name>Teller</ejb-name>
<jndi-name>ejb/bank/Teller</jndi-name>
<local-jndi-name>TellerLocal</local-jndi-name>
<configuration-name>
Standard Stateless SessionBean</configuration-name>
<ejb-ref>
<ejb-ref-name>ejb/bank/Account</ejb-ref-name>
<jndi-name>ejb/bank/Account</jndi-name>
</ejb-ref>
<resource-ref>
<res-ref-name>jdbc/DBPool</res-ref-name>
<resource-name>MyDataSourceManager</resource-name>
</resource-ref>
<method-attributes>
</method-attributes>
</session>
WebLogic Descriptor
<weblogic-enterprise-bean>
<ejb-name>Teller</ejb-name>
<stateless-session-descriptor>
<pool>
<max-beans-in-free-pool>3
</max-beans-in-free-pool>
<initial-beans-in-free-pool>1
</initial-beans-in-free-pool>
</pool>
</stateless-session-descriptor>
<reference-descriptor>
</reference-descriptor>
<jndi-name>ejb/bank/Teller</jndi-name>
<local-jndi-name>TellerLocal</local-jndi-name>
</weblogic-enterprise-bean>
Home Interface
/*
* Generated by XDoclet - Do not edit!
*/
package test.interfaces;
/**
* Home interface for Teller.
* @xdoclet-generated at 9-06-04
* @copyright The XDoclet Team
* @author XDoclet
* @version ${version}
*/
public interface TellerHome
extends javax.ejb.EJBHome
{
public static final String COMP_NAME="java:comp/env/ejb/Teller";
public static final String JNDI_NAME="ejb/bank/Teller";
public test.interfaces.Teller create()
throws javax.ejb.CreateException,java.rmi.RemoteException;
}
EJB Summary
• Write bean class
– Everything is in one place
• Generate:
– Descriptors
– Interfaces
• Support for many app servers:
– JBoss, BEA WebLogic, IBM WebSphere, Oracle IAS,
Orion, Borland, MacroMedia JRun, Jonas, Pramati,
Sybase EAServer and many more
• Entity & Message driven beans also
– CMRs
– Value Objects
Servlet
/**
* Simple Servlet.
* @web.servlet
*
display-name="Simple Servlet"
*
load-on-startup="1"
*
name="SimpleServlet"
*
* @web.servlet-init-param
*
name="param1"
*
value="value1"
*
* @web.servlet-init-param
*
name="param2"
*
value="value2"
*
* @web.servlet-mapping
*
url-pattern="/simple/*"
*/
public class SimpleServlet extends VelocityServlet {
/**
* Called by the server (via the service method) to allow a
*
servlet to handle a POST request.
*/
public void doPost(HttpServletRequest request, HttpServletResponse
response)
throws IOException, ServletException {
// just print Hi!
response.getWriter().println("Hi!");
}
}
Servlet web.xml descriptor
<servlet>
<servlet-name>SimpleServlet</servlet-name>
<display-name>Simple Servlet</display-name>
<servlet-class>test.web.SimpleServlet</servlet-class>
<init-param>
<param-name>param1</param-name>
<param-value>value1</param-value>
</init-param>
<init-param>
<param-name>param2</param-name>
<param-value>value2</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SimpleServlet</servlet-name>
<url-pattern>/simple/*</url-pattern>
</servlet-mapping>
Servlet Filter
/**
*
* @web.filter
*
display-name="Timer Filter"
*
name="TimerFilter"
*
* @web.filter-init-param
*
name="param1"
*
value="value1"
*
* @web.filter-mapping
*
url-pattern="*.xml"
*
*/
public class TimerFilter implements Filter {
...
}
Filter Descriptor
<filter>
<filter-name>TimerFilter</filter-name>
<display-name>Timer Filter</display-name>
<filter-class>test.web.TimerFilter</filter-class>
<init-param>
<param-name>param1</param-name>
<param-value>value1</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>TimerFilter</filter-name>
<url-pattern>*.xml</url-pattern>
</filter-mapping>
Hibernate
package test.hibernate;
import java.util.Set;
/**
* @author Administrator
*
* @hibernate.class
* table="ANIMALS"
* dynamic-update="true"
*/
public class Animal extends Persistent {
private Set prey;
private char sex;
/**
* Constructor for Animal.
*/
public Animal() {
super();
}
Hibernate (cont)
/**
* @hibernate.set
* lazy="true"
* table="PREDATOR_PREY"
* order-by="PREY_ID"
* @hibernate.collection-key
* column="PREDATOR_ID"
* @hibernate.collection-many-to-many
* column="PREY_ID"
* @return Set
*/
public Set getPrey() {
return prey;
}
/**
* @hibernate.property
* not-null="true"
* Returns the sex.
* @return char
*/
public char getSex() {
return sex;
}
}
Custom Generation
• Write your own templates for the standard
subtask
• Use the <template> task
• Write tag handlers / subtasks in Java
Example of custom template
•
•
•
•
/*
* <XDtI18n:getString bundle="xdoclet.ejb.Messages" resource="do_not_edit"/>
*/
package <XDtPackage:packageOf><XDtClass:fullClassName/></XDtPackage:packageOf>;
•
<XDtClass:importedList currentClass="<XDtClass:fullClassName/>"/>
•
•
import java.sql.*;
import org.apache.log4j.Logger;
•
•
•
•
•
/**
<XDtClass:forAllClassTags superclasses="false">
<XDtClass:ifTagNameEquals value="@ejb:bean">
* @ejb:bean
<XDtClass:ifHasClassTag tagName="ejb:bean" paramName="type"> * type="<XDtClass:classTagValue tagName="ejb:bean" paramName="type"
/>"</XDtClass:ifHasClassTag>
<XDtClass:ifHasClassTag tagName="ejb:bean" paramName="cmp-version"> * cmp-version="<XDtClass:classTagValue tagName="ejb:bean" paramName="cmpversion" />"</XDtClass:ifHasClassTag>
<XDtClass:ifHasClassTag tagName="ejb:bean" paramName="name"> * name="<XDtClass:classTagValue tagName="ejb:bean" paramName="name"
/>"</XDtClass:ifHasClassTag>
<XDtClass:ifHasClassTag tagName="ejb:bean" paramName="jndi-name"> * jndi-name="<XDtClass:classTagValue tagName="ejb:bean" paramName="jndi-name"
/>"</XDtClass:ifHasClassTag>
<XDtClass:ifHasClassTag tagName="ejb:bean" paramName="local-jndi-name"> * local-jndi-name="<XDtClass:classTagValue tagName="ejb:bean" paramName="localjndi-name" />"</XDtClass:ifHasClassTag>
<XDtClass:ifHasClassTag tagName="ejb:bean" paramName="view-type"> * view-type="<XDtClass:classTagValue tagName="ejb:bean" paramName="view-type"
/>"</XDtClass:ifHasClassTag>
<XDtClass:ifHasClassTag tagName="ejb:bean" paramName="primkey-field"> * primkey-field="<XDtClass:classTagValue tagName="ejb:bean" paramName="primkeyfield" />Impl"</XDtClass:ifHasClassTag>
* generate="true"
*
</XDtClass:ifTagNameEquals>
<XDtClass:ifTagNameEquals value="@ejb:pk">
</XDtClass:ifTagNameEquals>
<XDtClass:ifTagNameNotEquals value="@ejb:bean">
<XDtClass:ifTagNameNotEquals value="@ejb:interface">
<XDtClass:ifTagNameNotEquals value="@ejb:pk">
* <XDtClass:getTag/> </XDtClass:ifTagNameNotEquals></XDtClass:ifTagNameNotEquals></XDtClass:ifTagNameNotEquals>
</XDtClass:forAllClassTags>
*/
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Lessons Learned
• Errors may be difficult to track down
– Error reporting is bad to non-existant
– Get the tags Exactly right
• Don’t do source control on generated files!
What’s wrong with XDoclet 1.2?
• Based on JavaDoc (limited to Java).
• Difficult and fixed template language
(XDT).
• LARGE codebase (largely made up of
unmaintained modules).
• Tightly coupled with Ant.
• No unit-tests.
• No tag validation.
Future Developments
• Velocity Templating
• XDoclet2 development in progress
• JBoss-IDE support for XDoclet tags
– Didn’t work for me
Conclusion
• Q&A
• Demos?
Related documents