Sebastien Dionne's Blog
Sebastien Dionne graduated from university in Software Engineering. He started his career making rich client applications for telecommunications companies using Swing. Now he is focussing on J2EE applications in banking companies. His job is mainly to provide real-time applications web based and gateways for the stock market.
Enhance DisplayTag
Posted by survivant on May 04, 2009 at 08:17 AM | Permalink
| Comments (0)
I did some enhancements to DisplayTag. You can start by reading my previous post on DisplayTag.
There were some features that I needed and Displaytag didn't have them. I took the source code and I did it.
The enchancements are not in Displaytag trunk, you will have to take my build or add it your self to the trunk.
I didn't see recent activities on DisplayTag, but I would like to see them sometime to the repository.
Now.. what are theses enhancements :)
- i18n for the export links
- remember to sort order on a refresh (via session's variable lookup)
- add TableHeaderTop to customize table header
The source code and the build are provided at the end :)
Let's take a look at the picture.
The first section is a table that keep the sort order on a refresh and had a nice custom header. The export link is also i18n.
The second section is a table that doesn't have the enhancements except the i18n export.
Here the modifications to the code.
Add i18n support for export
First, you need to modify the file : displaytag.properties and activate theses lines
resource.provider=org.displaytag.localization.I18nStrutsAdapter
locale.provider=org.displaytag.localization.I18nStrutsAdapter
You will have to modify your Struts Bundle Resources to include this line.
export.links.label=<div class="exportlinks">Export displayed rows : {0}</div>
After that it's in the code, edit this file : org.displaytag.render.HtmlTableWriter
At the end of private void writeExportLinks()
String[] exportOptions = {buffer.toString()};
// handle title i18n
String evalTitle = this.properties.geResourceProvider().getResource(
"export.links.label",
TableProperties.PROPERTY_STRING_EXPORTBANNER,
null,
this.tableModel.getPageContext());
//write(MessageFormat.format(this.properties.getExportBanner(), exportOptions));
write(MessageFormat.format(evalTitle, exportOptions));
Variable lookup for sort order
In DisplayTag 1.3 there is a way to keep the sort order. You will have to add keepStatus=true to the tables.
What I didn't like about that is when you use the same tables for multiple displays (tiles) sometime you don't want to keep the order
when the page refresh, like after a new search.
Instead of a harcoded value in the value, I prefer to add a lookup session's variable.
I added the property : keepStatusProperty="variable name"
Like that you could change to value in the session and not in the JSP.
You will need to modify the java class: org.displaytag.tags.TableTag
/**
* Preserve the current page and sort.
*/
private String keepStatusProperty;
/**
* Preserve the current page and sort across session?
* @param keepStatus <code>true</code> to preserve paging and sorting
*/
public void setKeepStatus(boolean keepStatus)
{
this.keepStatus = keepStatus;
}
public void setKeepStatusProperty(String keepStatusProperty)
{
this.keepStatusProperty = keepStatusProperty;
}
In the method private void initParameters() throws JspTagException, FactoryInstantiationException
add this
initHref(requestHelper);
if(keepStatusProperty!=null && keepStatusProperty.trim().length()>0){
Boolean keepStatusEnabled = (Boolean)request.getSession().getAttribute(keepStatusProperty);
if(keepStatusEnabled==null){
keepStatus = false;
} else {
keepStatus = keepStatusEnabled.booleanValue();
}
}
Integer pageNumberParameter = getFromRequestOrSession(request, requestHelper, TableTagParameters.PARAMETER_PAGE);
this.pageNumber = (pageNumberParameter == null) ? 1 : pageNumberParameter.intValue();
In the class : org.displaytag.tags.TableTagBeanInfo
add this :
proplist.add(new PropertyDescriptor("keepStatusProperty", //$NON-NLS-1$
TableTag.class, null, "setKeepStatusProperty")); //$NON-NLS-1$
and don't forgot the TLD : displaytag.tld
after the block keepStatus add this (the same as keepStatus)
<attribute>
<name>keepStatusProperty</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
Preserve the current paging/sort status across session. The default is false (do not use sessions). Note that
for this to work properly you need to assign to each table in your application a different id.
</description>
</attribute>
The custom header with TableHeaderTop
We need to add a block in the TLD : displaytag.tld
<tag>
<name>tableHeaderTop</name>
<tag-class>org.displaytag.tags.TableHeaderTopTag</tag-class>
<body-content>JSP</body-content>
<display-name>column</display-name>
<description>
Displays a property of a row object inside a table. MUST be nested inside of a Table tag. The value displayed will
be the results of a decorator (if any); else the property named by the 'property' attribute; or if the 'property'
attribute is null, then the results of evaluating the JSP body of the tag.
</description>
<attribute>
<name>property</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
name of the property in the bean specified in the parent table tag (via the "name" attribute) mapped to this
column
</description>
</attribute>
<attribute>
<name>sortProperty</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
name of the property in the bean specified in the parent table tag (via the "name" attribute) which will be used
to sort values in the column. This can be used when the column body is filled or a decorator is used and column
should sort on undecorated values.
</description>
</attribute>
<attribute>
<name>title</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>title of the column (text for the th cell)</description>
</attribute>
<attribute>
<name>comparator</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
The classname of comparator to use when sorting this column, or the comparator itself. Defaults to the
DefaultComparator.
</description>
</attribute>
<attribute>
<name>titleKey</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>
Resource key used to lookup the title value. Only works if "title" is not defined. Works together with a
configured I18nResourceProvider, specified via the displaytag.properties file. By default, if JSTL is available,
the JSTL provider is used, which makes this attribute work the same as fmt:message's key property.
</description>
</attribute>
<attribute>
<name>nulls</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>
By default, null values don't appear in the list. By setting 'nulls' to 'true', then null values will appear as
"null" in the list (mostly useful for debugging). Defaults to 'false'.
</description>
</attribute>
<attribute>
<name>total</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>
If true, will total the contents of this column. This value is available via the Map named in varTotals for the
table. Column values need to Numbers.
</description>
</attribute>
<attribute>
<name>sortable</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>Set to 'true' to make the column sortable. Defaults to 'false'.</description>
</attribute>
<attribute>
<name>defaultorder</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
The default sort order for this column. Valid values are "ascending" (default) or "descending"
</description>
</attribute>
<attribute>
<name>autolink</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>
Automatically hyperlink URLs and email addresses that appear in the column. Defaults to 'false'.
</description>
</attribute>
<attribute>
<name>format</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
A MessageFormat patter that will be used to decorate objects in the column. Can be used as a "shortcut" for
simple column decorations. @since 1.1
</description>
</attribute>
<attribute>
<name>escapeXml</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>
Set it to true to escape special characters in html and xml output. Defaults to 'false'. @since 1.1
</description>
</attribute>
<attribute>
<name>media</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
Use this attribute to keep a column from being output during an export. The column will only render for the
named media type(s) - it won't be added to the table if the current request media is not supported. Can be any
space separated combination of 'html', 'csv', 'xml', 'all', or 'excel'. Defaults to 'all'. See the export page
in the example webapp for more details.
</description>
</attribute>
<attribute>
<name>href</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
<![CDATA[
The base URL used to construct the dynamic link. If this attribute is provided, then the data that is shown for
this column is wrapped inside a <a href=""> tag with the url provided through this attribute. Typically you
would use this attribute along with one of the struts-like param attributes (param*) to create a dynamic link so
that each row creates a different URL based on the data that is being viewed. An empty href value will generate
a link to the current page, preserving parameters just like for paging links.]]>
</description>
</attribute>
<attribute>
<name>url</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
The base URL used to construct the dynamic link. This attribute has the same functionality as the href
attribute, but it pre-pends the contextPath.
</description>
</attribute>
<attribute>
<name>paramId</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
The name of the request parameter that will be dynamically added to the generated href URL. The corresponding
value is defined by the paramProperty and (optional) paramName attributes, optionally scoped by the paramScope
attribute.
</description>
</attribute>
<attribute>
<name>paramName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
The name of a JSP bean that is a String containing the value for the request parameter named by paramId (if
paramProperty is not specified), or a JSP bean whose property getter is called to return a String (if
paramProperty is specified). The JSP bean is constrained to the bean scope specified by the paramScope property,
if it is specified. If paramName is omitted, then it is assumed that the current object being iterated on is the
target bean.
</description>
</attribute>
<attribute>
<name>paramProperty</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
The name of a property of the current object being iterated on, whose return value will be used as the value of
the parameter (named by the paramId attribute) that will be dynamically added to this href URL. If paramName is
also specified the property will not be fetched from the object being iterated on, but from the bean specified
by paramName. The support of paramProperty in conjunction with paramName will be probably removed in future: use
paramProperty only if you need a property in the iterated object, elsewhere use only paramName (you can select a
property using an expression name.property).
</description>
</attribute>
<attribute>
<name>paramScope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
@deprecated - use Expressions in paramName. The scope within which to search for the bean specified by the
paramName attribute. If not specified, all scopes are searched. If paramName is not provided, then the current
object being iterated on is assumed to be the target bean.
</description>
</attribute>
<attribute>
<name>maxLength</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>int</type>
<description>
If this attribute is provided, then the column's displayed is limited to this number of characters. An elipse
(...) is appended to the end if this column is linked, and the user can mouseover the elipse to get the full
text. Be careful on using this attribute for String which can contain html tags or entities, or together with
the autolink attribute turned on: displaytag will do its best trying to avoid leaving unclosed tags or broken
entities in the output, but a complex or bad input could lead to unattended results.
</description>
</attribute>
<attribute>
<name>maxWords</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>int</type>
<description>
If this attribute is provided, then the column's displayed is limited to this number of words. An elipse (...)
is appended to the end if this column is linked, and the user can mouseover the elipse to get the full text. Be
careful on using this attribute for String which can contain html tags or entities, or together with the
autolink attribute turned on: displaytag will do its best trying to avoid leaving unclosed tags or broken
entities in the output, but a complex or bad input could lead to unattended results.
</description>
</attribute>
<attribute>
<name>class</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
html pass through attribute; use this instead of directly coding presentational atttributes.
</description>
</attribute>
<attribute>
<name>headerClass</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>"class" html attribute added only for header cells.</description>
</attribute>
<attribute>
<name>style</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>html pass through attribute.</description>
</attribute>
<attribute>
<name>group</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>int</type>
<description>
The grouping level (starting at 1 and incrementing) of this column (indicates if successive contain the same
values, then they should not be displayed). The level indicates that if a lower level no longer matches, then
the matching for this higher level should start over as well. If this attribute is not included, then no
grouping is performed.
</description>
</attribute>
<attribute>
<name>decorator</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
Whitespace separated list of column decorators to apply to the current column. A table decorator name can be the
name of an object in page, request, session or application scope or a fully qualified class name of a class
implementing the org.displaytag.decorator.DisplaytagColumnDecorator interface. If a decorator is specified for
the entire table, then this decorator will decorate that decorator.
</description>
</attribute>
<attribute>
<name>sortName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>
Used with sort="external", the name that should be given to the server to sort this column. IE if
sortName="buzz", then the href for this column to sort will have a parameter d-(encodedId)-s=buzz. If sortName
is ommitted the value for the sort param will default to the column number.
</description>
</attribute>
<attribute>
<name>headerScope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>"scope" html attribute added only for header cells.</description>
</attribute>
<attribute>
<name>scope</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>"scope" html attribute.</description>
</attribute>
<attribute>
<name>value</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.Object</type>
<description>
Static value to be used for the column. It has the same meaning of setting a value in the tag body, but values
set using this attribute will not be coerced to Strings. You may need to use the value attribute instead of a
scriptlet in the tag body if you need to calculate totals on numeric values.
</description>
</attribute>
</tag>
In the java class : org.displaytag.model.TableModel
/**
* Table header.
*/
private String tableHeaderTop;
/**
* Obtain this table's row header.
* @return This table's caption.
*/
public String getTableHeaderTop()
{
return this.tableHeaderTop;
}
/**
* Set this table's caption.
* @param caption This table's caption.
*/
public void setTableHeaderTop(String tableHeaderTop)
{
this.tableHeaderTop = tableHeaderTop;
}
In the java class : org.displaytag.render.HtmlTableWriter
We need to change the constructor and add few methods
private TableHeaderTopTag tableHeaderTopTag;
/**
* This table writer uses a <code>TableTag</code> and a <code>JspWriter</code> to do its work.
* @param tableTag <code>TableTag</code> instance called back by this writer.
* @param out The output destination.
*/
public HtmlTableWriter(
TableModel tableModel,
TableProperties tableProperties,
Href baseHref,
boolean export,
JspWriter out,
TableHeaderTopTag tableHeaderTopTag,
CaptionTag captionTag,
PaginatedList paginatedList,
SmartListHelper listHelper,
int pagesize,
HtmlAttributeMap attributeMap,
String uid)
{
this.tableModel = tableModel;
this.properties = tableProperties;
this.baseHref = baseHref;
this.export = export;
this.out = out;
this.tableHeaderTopTag = tableHeaderTopTag;
this.captionTag = captionTag;
this.paginatedList = paginatedList;
this.listHelper = listHelper;
this.pagesize = pagesize;
this.attributeMap = attributeMap;
this.uid = uid;
}
protected void writeTableHeaderTop(TableModel model)
{
this.write(tableHeaderTopTag.getOpenTag() + model.getTableHeaderTop() + tableHeaderTopTag.getCloseTag());
}
In the method protected void writeTableHeader(TableModel model)
// open thead
write(TagConstants.TAG_THEAD_OPEN);
// render header rows
if (model.getTableHeaderTop() != null)
{
writeTableHeaderTop(model);
}
// open tr
write(TagConstants.TAG_TR_OPEN);
In the java class : org.displaytag.render.ItextTableWriter
/**
* Write the table's caption to a iText document.
* @see org.displaytag.render.TableWriterTemplate#writeCaption(org.displaytag.model.TableModel)
*/
protected void writeTableHeaderTop(TableModel model) throws Exception
{
//nothing
}
In the java class : org.displaytag.render.TableWriterTemplate
/**
* Called by writeTable to write the table's caption.
* @param model The table model for which the content is written.
* @throws Exception if it encounters an error while writing.
*/
protected abstract void writeTableHeaderTop(TableModel model) throws Exception;
In the java class : org.displaytag.tags.TableTag
/**
* Static caption added using the footer tag.
*/
private String tableHeaderTop;
/**
* Child header tag.
*/
private TableHeaderTopTag tableHeaderTopTag;
/**
* Set the child caption tag.
* @param captionTag Child caption tag
*/
public void setTableHeaderTopTag(TableHeaderTopTag tableHeaderTopTag)
{
this.tableHeaderTopTag = tableHeaderTopTag;
}
public void setTableHeaderTop(String string)
{
this.tableHeaderTop = string;
this.tableModel.setTableHeaderTop(this.tableHeaderTop);
}
/**
* Obtain the child caption tag.
* @return The child caption tag
*/
public TableHeaderTopTag getTableHeaderTopTag()
{
return this.tableHeaderTopTag;
}
In the method : protected void writeHTMLData() throws JspException
// use HtmlTableWriter to write table
new HtmlTableWriter(
this.tableModel,
this.properties,
this.baseHref,
this.export,
out,
getTableHeaderTopTag(),
getCaptionTag(),
this.paginatedList,
this.listHelper,
this.pagesize,
getAttributeMap(),
this.uid).writeTable(this.tableModel, this.getUid());
/code>
And finally two new classes : org.displaytag.tags.TableHeaderTopTag and org.displaytag.tags.TableHeaderTopTagBeanInfo
You can download the modify source code and a demo at my kenai repository
Grizzly http-deployer moved to module in Release 1.9.11
Posted by survivant on April 08, 2009 at 11:28 AM | Permalink
| Comments (0)
The little baby : Grizzly http-deployer just moved from contrib to modules since release 1.9.11.
Grizzly Http-Deployer evolve since my previous post
New Grizzly enhancement : Servlet AutoDeployer.
There are few new options. Let's describe the new command line params.
Support multiple paths for application deployment
-a warfile1;warfile2 or --application=warfile1;warfile2 ";" is File.pathSeparator
Support multiple library paths to add to the classpath
--libraryPath=libpath1/;libpath2 ";" is File.pathSeparator
Force context for a servlet
-c newcontext/ or --context=newcontext/
Only work if you use it with a web.xml as application. Like : -a path/servlet/web.xml
Comet support
--cometEnabled
Force war file deployment over expanded folder
--forceWarDeployment
if you have a folder that contains a war file and expanded war file, the default is to load the expanded folder and skip the war file.
With this, you can force to deploy the war file instead.
Don't start GrizzlyWebServer
--dontstart=true
With this option GrizzlyWebServer won't be started unless the user call start();
There are lot more options that will be available in the next releases.
Scoop :
- WarAdapter
- Jsp support
- Jmx support
- ... :)
Follow us on twitter.com/project_grizzly
type="text/javascript">
New Grizzly enhancement : Servlet AutoDeployer
Posted by survivant on April 01, 2009 at 07:43 PM | Permalink
| Comments (4)
We got something really cool for Grizzly. It's a Servlet AutoDeployer for GrizzlyWebServer.
Now that it said.. let's talk more about that.
When you have servlets, you will need a AppServer or a WebServer to deploy your applications. Nothing new there.. it's a been like that for years. Mostly you had to create a web.xml, put that in a war and deploy it.
There are others alternatives, like using GrizzlyWebServer, but you will have to put your web.xml into code.
GrizzlyWebServer ws = new GrizzlyWebServer(80);
try {
ServletAdapter sa = new ServletAdapter();
sa.setContextPath("/");
// need to load JspRuntimeContext
Class.forName("org.apache.jasper.compiler.JspRuntimeContext");
Servlet servlet = (Servlet)ClassLoaderUtil.load("ca.sebastiendionne.welcome_jsp");
sa.setServletInstance(servlet);
ws.addGrizzlyAdapter(sa, new String[]{});
ws.start();
} catch (Exception e){
s_logger.error("Error Launching GrizzlyWebServer",e);
}
What's wrong with that ?
In my point of view.. it's not efficient. I don't want to use a WebServer to deploy a simple servlet and I don't want code what I could simply extract from a config file.
That why a servlet autodeployer could be useful. Yes a WebServer or AppServer do that already, but like I said.. you can skip it and go for a smaller and faster solution.
The GrizzlyServletDeployer (or the super fast and super easy thing for GrizzlyWebServer) will do everything for you.
In one simple command line you can deploy multiple applications.
Let's take a look at the command line first.
java -jar grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar [options]
where options are :
-p : the port [default 8080]
-a : applications to deploy (everything is done from that)
You can deploy many things from the option "-a" (servlets, war, multiple wars, expanded wars). Let's decribe what can be done.
Syntax examples :
# 1 : Deploy a war
java -jar grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar -a c:/temp/hudson.war
That will deploy the war file. The same way a WebServer will deploy it. The web.xml will be read and the servlets will be deployed.
The context will be the war file. In this example : http://localhost:8080/hudson/
#2 - Deploy a expanded war.
java -jar grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar -a c:/temp/hudson
Your application could be a expanded war, or have the same hierarchy.
That will give the same result as #1
#3 Deploy servlets
java -classpath myservlet.jar;.;grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar com.sun.grizzly.http.servlet.deployer.GrizzlyWebServerDeployer -a web.xml
You can skip the step to create a war file if you want. Simply declare a web.xml and put the jars into the classpath (in this case the servlet is in myservlet.jar)
The context will be the default "/"
http://localhost:8080/
#4 - Deploy multiples war in the same time.
This one is more advanced. It will deploy all the war files or expanded wars that are in a root folder.
java -jar grizzly-servlet-deployer-1.9.11-SNAPSHOT.jar -a /MultipleWarFolder
(yes it's the same syntax as #2)
Example :
Here what the folders will look like
...../MultipleWarFolder/
/freemarker
/WEB-INF
/classes/
/lib/
/templates/
/web.xml
hudson.war
struts2-showcase-2.0.12.war
cometd-demo.war
sebastiendionne-is-the-man.war
The folder /MultipleWarFolder contains 4 war files and 1 expanded folder.
Serlvet-Deployer will check all the folders in the root (/MultipleWarFolder) and check if it can apply #1 or #2.
If it find one that contains /WEB-INF/web.xml it will consider it as #2 (expanded war) and if it find a .war it will do #1 (war file).
The context for each application will be the folder name (freemarker) or the war file.
If you want to can use it in a testcase easily.
GrizzlyWebServerDeployer gws = new GrizzlyWebServerDeployer();
try {
args = new String[]{"-a","./web.xml"};
// ready to launch
gws.init(args);
gws.launch();
... launch your tests...
} catch (Exception e){
e.printStackTrace();
}
I think when you will start using that, you will love it :)
This Servlet AudoDeployer support web.xml version 2.2 to 3.0
GrizzlyWebServer is really powerful and so small. It's a Asynchronous IO server that support multiples protocols : HTTP(s), Comet, PHP, JSP, Freemarker, AJP protocol (mod_jk) and more check (https://grizzly.dev.java.net/).
Read web.xml with one line of code Part 2
Posted by survivant on March 25, 2009 at 08:49 AM | Permalink
| Comments (2)
I did a previous post about how to do it with XMLBean or JABX, but it was more an example how to do it. This time is the real deal.
I used JABX to generate the java classes from the schemas and use that to parse the web.xml.
The result is a simple class : WebAppLoader that will load the web.xml.
Here a example :
WebappLoader webappLoader = new WebappLoader();
WebApp webapp = webappLoader.load("/web-2.2.xml");
The object WebApp contains all the infos extracted from the web.xml. The representation is based on webapp 3.0.
you can get the source code from my repository : http://kenai.com/projects/sebastiendionne/sources/repository/show/dtd-schemas-generator
JAXB : web.xml : dtd and xsd classes generator
Posted by survivant on March 22, 2009 at 05:39 PM | Permalink
| Comments (0)
I created a little demo to show how easy it can be to create a kit of classes from DTD and XSD using Maven and JAXB.
To generate from XSD schemas
In your pom.xml, you will have to add this.
<dependencies>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!-- if you want to put DTD somewhere else
<schemaDirectory>src/main/jaxb</schemaDirectory>
-->
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2-commons</groupId>
<artifactId>property-listener-injector</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
The important thing to know is that you have to generate your classes with one schema each time. If you put webapp schemas 2.2 and 2.3 in the same time,
you will obtain errors. Be sure to include all the files related to your webapp schema to generate your java classes.
Example : webapp 2.4 need
web-app_2_4.xsd
j2ee_1_4.xsd
jsp_2_0.xsd
You can even do some customization with a config file named : domain.jaxb (/src/main/resources).
To generate from DTD
In your pom.xml, you will have to add this.
<dependencies>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!-- if you want to put DTD somewhere else
<schemaDirectory>src/main/jaxb</schemaDirectory>
-->
<extension>true</extension>
<schemaLanguage>DTD</schemaLanguage>
<schemaIncludes>
<schemaInclude>*.dtd</schemaInclude>
</schemaIncludes>
<bindingIncludes>
<bindingInclude>*.jaxb</bindingInclude>
</bindingIncludes>
<args>
<arg>-Xinject-listener-code</arg>
</args>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2-commons</groupId>
<artifactId>property-listener-injector</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
The DTD generation is the same pattern as XSD. The principal differences are in the pom.xml
You can download a complete project that use webapp xsd and dtd to parse any web.xml. It could be useful when you want to keep it simple :)
You can browse the code from : my Kenai repository
How to configure proxy on Glassfish v3
Posted by survivant on March 17, 2009 at 07:18 PM | Permalink
| Comments (2)
If you are behind a proxy maybe you will want to set the proxy in Glassfish.
There are few different ways to do that.
#1 - You could use the admin web page.
You can add the proxy settings : host and port with the admin. Into the admin web page, go to the Application Server at your left. After that on your right select : JVM Settings / JVM Options.
Just add theses settings :
http.proxyHost=myproxy.mydomain
http.proxyPort=myproxy.port

Click here to enlarge
#2 - You could use the command line
Go into your Glassfish installation /bin and enter theses commands :
asadmin create-jvm-options "-Dhttp.proxyHost=myproxy.mydomain"
asadmin create-jvm-options "-Dhttp.proxyPort=myproxy.port"
#3 - The last option is to edit manually domain.xml
You add the settings in the "<java-config>" element.
<java-config ...>
<jvm-options>-Dhttp.proxyHost=myproxy.mydomain</jvm-options>
<jvm-options>-Dhttp.proxyPort=myproxy.port</jvm-options>
...
Slowly move to Kenai
Posted by survivant on March 14, 2009 at 05:04 PM | Permalink
| Comments (0)
After that my hard drive crash two weeks ago, I deceived to host my demos on a hosting repository. I just got my Kenai repository last week, and I start to move my stuff there one by one.
I'll update all my previous posts to point to the new download path.
My Kenai page is : http://kenai.com/projects/sebastiendionne
 |