<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>agimatec &#187; Java</title>
	<atom:link href="http://www.agimatec.de/blog/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.agimatec.de/blog</link>
	<description>Clash of realities</description>
	<lastBuildDate>Tue, 22 Dec 2009 16:50:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Auditing and entity versioning based on triggers and hibernate</title>
		<link>http://www.agimatec.de/blog/2009/07/auditing-and-entity-versioning-based-on-triggers-and-hibernate/</link>
		<comments>http://www.agimatec.de/blog/2009/07/auditing-and-entity-versioning-based-on-triggers-and-hibernate/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 13:11:20 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=644</guid>
		<description><![CDATA[If you are looking for a framework for auditing the versions and changes of your hibernate objects, you might probably be satisfied with Envers (http://www.jboss.org/envers/), a solution based on hibernate. In this blog entry I want to give you an impression of an alternative solution by agimatec, that is slightly different. It is the solution [...]]]></description>
			<content:encoded><![CDATA[<p>If you are looking for a framework for auditing the versions and changes of your hibernate objects, you might probably be satisfied with <em><strong>Envers</strong></em> (http://www.jboss.org/envers/), a solution based on hibernate.</p>
<p>In this blog entry I want to give you an impression of an <strong><em>alternative solution</em><em> by agimatec</em></strong>, that is slightly different. It is the solution we are using in our products for more than two years and with which we are satisfied. It would be interesting to hear your options on this.</p>
<p><strong>The concept</strong></p>
<p><em>Database:</em><strong><br />
</strong></p>
<p>We generate history tables for each table for which we need auditing. We generate database triggers (oracle or postgres) to automatically insert data in the history tables when entities are stored/deleted.</p>
<p>We do not store duplicate data, which means that our history tables contain only OLD data. All current data is ONLY stored in the application&#8217;s tables (usually mapped by hibernate/Ejb3).</p>
<p><em>Configuration:</em></p>
<p>We have a XML configuration, that contains the table names for which we want to enable our history solution. This configuration lets you specify:</p>
<ul>
<li>name of history table (or a default name will be used)</li>
<li>which columns to exclude from history (default is that all columns are historised)</li>
<li>optionally you can turn off history for insert and/or update, change trigger names etc.</li>
</ul>
<p>The XML configuration controls the tables and triggers generated by freemarker templates.</p>
<p><em>Features:</em></p>
<p>It is not only important to version the changes, but also to store, the timestamp of a change and some context information about the change (e.g. who is the actor, which application, from which sessionID etc.). Any context information can be associated with a version record by storing a contextID in the history table&#8217;s rows.</p>
<p>This is also a way to separate changes from user-specific data, which might be a judical requirement. An extended Hibernate event handler stores the contextID into the database session by calling a stored procedure, so that the history triggers and access the contextID to store it together with the history data.</p>
<p>Each history table has additional columns:</p>
<ul>
<li>HIST_TIME (timestamp of change)</li>
<li>HIST_CONTEXTID (ID of context providing additional information)</li>
<li>HIST_TYPE (to distinguish INSERT, UPDATE and DELETION)</li>
</ul>
<p>A simple java API exists to query historical data. It returns the same classes as you use for your hibernate entities, but it materializes the objects itself. Hibernate does not know anything about the history tables or mappings.</p>
<p><strong>The benefits</strong></p>
<p>There are some differences between the solution provided by Envers and agimatec:</p>
<ul>
<li>Envers needs a global _revision table, agimatec&#8217;s history rows are identified by the primary key and a version number (@Version) incremented from 1 for each entity/no global _revision</li>
<li>You can change data with any SQL tool.Historisation does not rely on hibernate as the only API to change the database.</li>
<li>Whenever you increment a row&#8217;s version, the history triggers will automatically write historical data. By this way, you can use migration scripts that can control whether history data will be stored.</li>
<li>Envers stores current data in history tables, which makes it a bit easier to query the data, but with means redundancy (and potential data inconsistencies).</li>
<li>Both framework are integrated with Hibernate by extending the Hibernate Events (to provide context information).</li>
</ul>
<p><strong>Examples</strong></p>
<p><em>History configuration</em><br />
<code><br />
&lt;historyConfig&gt;<br />
&lt;tableConfig&gt;<br />
&lt;tableName&gt;booking&lt;/tableName&gt;<br />
&lt;/tableConfig&gt;<br />
&lt;tableConfig&gt;<br />
&lt;tableName&gt;customer&lt;/tableName&gt;<br />
&lt;historyTable&gt;h_cust&lt;/historyTable&gt;<br />
&lt;insertTrigger&gt;TR_I_cust&lt;/insertTrigger&gt;<br />
&lt;updateTrigger&gt;TR_U_cust&lt;/updateTrigger&gt;<br />
&lt;/tableConfig&gt;<br />
</code></p>
<p><em>Generated tables</em><br />
<code><br />
CREATE TABLE H_JOURNAL (<br />
ID INTEGER NOT NULL,<br />
HIST_TABLE VARCHAR(50) NOT NULL,<br />
HIST_TIME TIMESTAMP NOT NULL,<br />
HIST_CONTEXTID VARCHAR(40),<br />
CONSTRAINT H_JOURNAL_PK PRIMARY KEY (ID, HIST_TABLE)<br />
);</code></p>
<p><code>CREATE TABLE H_booking (<br />
VERSION INTEGER NOT NULL,<br />
booking_id INTEGER NOT NULL,<br />
price NUMBER,<br />
HIST_TIME TIMESTAMP NOT NULL,<br />
HIST_CONTEXTID VARCHAR(40),<br />
HIST_TYPE CHAR(1) NOT NULL,<br />
CONSTRAINT H_booking_PK PRIMARY KEY (VERSION, booking_id)<br />
);<br />
CREATE TABLE H_cust (<br />
VERSION INTEGER NOT NULL,<br />
cust_id INTEGER NOT NULL,<br />
first_name VARCHAR2(40),<br />
last_name VARCHAR2(40),<br />
HIST_TIME TIMESTAMP NOT NULL,<br />
HIST_CONTEXTID VARCHAR(40),<br />
HIST_TYPE CHAR(1) NOT NULL,<br />
CONSTRAINT H_cust_PK PRIMARY KEY (VERSION, card_id)<br />
);</code></p>
<p><em>Generated triggers</em><br />
<code><br />
CREATE OR REPLACE TRIGGER TR_I_cust<br />
AFTER INSERT ON customer<br />
REFERENCING NEW AS NEW<br />
FOR EACH ROW<br />
BEGIN<br />
setTATime();<br />
INSERT INTO H_JOURNAL (ID,  HIST_TIME, HIST_CONTEXTID, HIST_TABLE)<br />
select :NEW.card_id, h.ts, h_session.getContextId, 'customer' from h_tatime h;<br />
END;<br />
/</code><br />
<code><br />
CREATE OR REPLACE TRIGGER TR_U_cust<br />
AFTER DELETE OR UPDATE<br />
ON customer<br />
REFERENCING NEW AS NEW OLD AS OLD<br />
FOR EACH ROW<br />
BEGIN<br />
IF(DELETING) THEN<br />
setTATime();<br />
INSERT INTO H_cust (<br />
cust_id,<br />
version,<br />
first_name,<br />
last_name,<br />
HIST_TIME, HIST_CONTEXTID, HIST_TYPE)<br />
select<br />
:OLD.cust_id,<br />
:OLD.version,<br />
:OLD.first_name,<br />
:OLD.last_name,<br />
h.ts, h_session.getContextId, 'D' from h_tatime h;<br />
ELSIF (UPDATING AND :OLD.VERSION != :NEW.VERSION) THEN<br />
setTATime();<br />
INSERT INTO H_cust (<br />
cust_id,<br />
version,<br />
first_name,<br />
last_name,<br />
HIST_TIME, HIST_CONTEXTID, HIST_TYPE)<br />
select<br />
:OLD.cust_id,<br />
:OLD.version,<br />
:OLD.first_name,<br />
:OLD.last_name,<br />
h.ts, h_session.getContextId, 'U' from h_tatime h;<br />
END IF;<br />
END;<br />
/</code></p>
<p><strong>Java API</strong></p>
<p>The implementation of class <strong><em>HibernateHistoryReader</em></strong> was rather complex, because of the need to resolve the relationships through the current tables and the history tables. All changes done inside a single transaction are joined together by using a timestamp in HIST_TIME that is unique inside the running database transaction.</p>
<p>Here is interface <strong><em>HistoryReader</em></strong>:</p>
<p><code>interface HistoryReader {</code><br />
<code><br />
void open(EntityManager entityManager);<br />
void close();</code><br />
<code><br />
List&lt;EntityRevision&gt; getRevisions(Class entityClass, Object primaryKey, Timeframe timeframe);<br />
EntityRevision getRevision(Class entityClass, Object primaryKey, int version);</code></p>
<p><code>Map&lt;Object, List&lt;EntityRevision&gt;&gt; getChildrenRevisions(Class parentEntityClass,EntityRevision parentRevision,String relationship);</code></p>
<p><code>&lt;E&gt; HistoryEntity&lt;E&gt; loadEntity(Class&lt;E&gt; entityClass, Object primaryKey,Timestamp time);<br />
&lt;E&gt; List&lt;HistoryEntity&lt;E&gt;&gt; loadChildren(Class parentEntityClass, String relationship,<br />
Object parentPrimaryKey, Timestamp time);</code></p>
<p><code>}</code></p>
<p>Where class HistoryEntity contains the entity instance for a given point of time and some additional information, such as the contextID and the foreignKey values to load some to-one-references.</p>
<p>If you are interested in more details contact us.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/07/auditing-and-entity-versioning-based-on-triggers-and-hibernate/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Dependency Management in Maven done right</title>
		<link>http://www.agimatec.de/blog/2009/02/dependency-management-in-maven-done-right/</link>
		<comments>http://www.agimatec.de/blog/2009/02/dependency-management-in-maven-done-right/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 12:23:15 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=552</guid>
		<description><![CDATA[Despair, anger, perplexity, pain &#8211; I think we all know this moments when dealing with large Maven projects. I have seen a lot of posts in the lasts months who use some of this words. After years with Maven we learned how to deal with it. Not the pain, I mean to deal with Maven. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.agimatec.de/blog/2009/02/dependency-management-in-maven-done-right/what/" rel="attachment wp-att-553"><img src="http://www.agimatec.de/blog/wp-content/uploads/2009/02/what.jpg" alt="what" title="what" width="424" height="283" class="alignleft size-full wp-image-553" /></a>Despair, anger, perplexity, pain &#8211; I think we all know this moments when dealing with large Maven projects. I have seen a lot of posts in the lasts months who use some of this words. After years with Maven we learned how to deal with it. Not the pain, I mean to deal with Maven. I want to share a way to avoid some pitfalls or give you some advices if you are in trouble.</p>
<p>Maven is a good tool to handle your dependencies. You shouldn&#8217;t copy the necessary artifacts by hand in your lib folder. It is the beginning of the end for your project. Transitive dependencies could ease the management of your dependencies and Maven is the right tool for this. But sometimes it is to much magic behind the scenes. There could be a lot of transitive dependencies and there could be conflicts. Even more if your projects gets larger and uses more and more open source frameworks. We had problems with two actions:</p>
<ul>
<li>Change the version of a dependency</li>
<li>Update the version of Maven</li>
</ul>
<p><span id="more-552"></span></p>
<p><strong>Change the version of a dependency</strong></p>
<p>If you update the version of a dependency this could cause completely different transitive dependencies to be fetched. Normally no big deal, but you need to clean your artifacts. Often you just use <em>mvn install</em> to install your artifact. But without the <em>clean</em> target, the old dependencies are still in your target folder. Remember to use <em>mvn clean install</em> when changing the version of a dependency. But there is also another place, where old dependencies can survive. If you hot deploy your artifacts to your server, you should also delete the old artifacts and extracted folders. After that you are in a really clean condition.</p>
<p><strong>Update the version of Maven</strong></p>
<p>We had problems with transitive dependencies when changing the version of Maven. Make sure that every team member and build server uses the same version. Then you can still have problems, but there are no different transitive resolutions on different computers. Can be very confusing if one person in the team has version A and another one has version B. I think the Maven team tries to reduce this, but if there are changes in the dependency resolution, it could happen that conflicts are solved in a different way.</p>
<h2>What about real trouble?</h2>
<p>If you have a lot open source dependencies, there are much more transitive dependencies. Maven tries to resolve conflicts, but you will often find a situation, where dependencies A and B needs the same transitive dependency but in a different version. This can produce situations, described in the post: <a href="http://agilesoftwaredevelopment.com/blog/pbielicki/maven-supports-jar-hell">Maven supports JAR hell</a>. Something is wrong and you have a lot of unwanted dependencies in your library folder. The next step is to find out, where they come from. This can be complicated, because transitive dependencies also have own transitive dependencies.</p>
<h2>Find out where the dependencies come from</h2>
<p>There are different solutions for this and Maven has improved the detection of dependencies for users. Most of the time I use the Maven site. It is always a good idea to use this feature, because it can give you a nice overview of your project. Take the time and configure your site, it is very helpful for the team.</p>
<p>To generate the Maven site just use: <em>mvn site</em></p>
<p>This will generate a linked web site, where you can use a lot plugins. There is also the section dependencies, where you can have a look what dependencies exist and watch the transitive dependencies tree.</p>
<p>But there are also command line options. First of all the <a href="http://maven.apache.org/plugins/maven-dependency-plugin/">Maven Dependency Plugin</a>. To get the transitive dependencies tree just type: <em>mvn dependency:tree</em></p>
<p>It will display where the dependencies come from. It is also possible to <a href="http://maven.apache.org/plugins/maven-dependency-plugin/examples/filtering-the-dependency-tree.html">filter the output</a> or <a href="http://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html">find conflicts</a>.</p>
<p>We also use the concept of parent POMs with a deeper hierarchy. Sometimes you need to know, how your effective POM in the sub-project looks like. To get this information use: <em>mvn help:effective-pom</em></p>
<p>You should have a look at the <a href="http://maven.apache.org/plugins/maven-help-plugin/index.html">Maven Help Plugin</a>, because there are some interesting other options.</p>
<h2>Start your own dependency management</h2>
<p>That doesn&#8217;t mean that you don&#8217;t use Maven. But most of the time you know your artifacts and their actual version. And you want a specific version to be included. You also want to have a consistent version of an artifact used through all sub-projects, then you can use declarative dependency management in Maven. That can avoid classpath issues. It is also very easy to upgrade a version, because the child-POMs don&#8217;t have a version included. They use the version defined in the parent POM.</p>
<p>We manage our dependencies in our master parent POM. There is a section in the XML called dependencyManagement. There you can list your dependencies and add the group, the artifactId and very important: the version. Now every time Maven tries to resolve a dependency it is using this specified version. Easy, isn&#8217;t it? Yes, the dependency management list is getting larger, but in a large project you are very pleased to find always the correct version of your dependencies.</p>
<p>Read more about this in the <a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management">Maven documentation</a>.</p>
<p>For us it was a great time saver, because we had less problems with Maven. You don&#8217;t need your own dependency management, but if you run in trouble think about using it.</p>
<p>If you want the know about the best Maven plugins, check out the <a href="http://www.agimatec.de/blog/2008/08/top-10-maven-plugins/">Top 10 Maven plugins on our blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/02/dependency-management-in-maven-done-right/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring Security in the wild with Maven</title>
		<link>http://www.agimatec.de/blog/2009/01/spring-security-in-the-wild-with-maven/</link>
		<comments>http://www.agimatec.de/blog/2009/01/spring-security-in-the-wild-with-maven/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 08:11:50 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Struts2]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=459</guid>
		<description><![CDATA[Security is always important when you need protected or user specific areas in your application. The easiest way for a basic security is the configuration of a security constraint in your web.xml file. If you are using Tomcat all you need is a Realm. This works well for static users in a file or if [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.agimatec.de/blog/wp-content/uploads/2009/01/security.png" alt="security" title="security" width="425" height="282" class="alignleft size-full wp-image-466" /><br />
Security is always important when you need protected or user specific areas in your application. The easiest way for a basic security is the configuration of a security constraint in your web.xml file. If you are using Tomcat all you need is a <a href="http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html">Realm</a>. This works well for static users in a file or if you are beginning your application with the standard database layout for the Tomcat JDBC Realm. If you have a look at the database layout this won&#8217;t fit well for most of the applications. You need more options, but Tomcat is very limited in this point.</p>
<p>If you need more options you should have a look at <a href="http://www.acegisecurity.org/">Spring Security</a> (formerly known as Acegi Security). There are a lot of options in Spring Security, but I will give you an example, not a list of features copied from the documentation.</p>
<p><span id="more-459"></span></p>
<h2>Requirements</h2>
<ul>
<li>easy configuration</li>
<li>working together with Struts2</li>
<li>URL based</li>
<li>getting user details from a web service</li>
</ul>
<p>When I started using Spring Security I found a lot of examples. There is also a good documentation available, but you need some hours to sort everything. Because I couldn&#8217;t find an example for exactly my problem, I will share my solution.</p>
<h2>Before we start</h2>
<p>At the beginning of your application you should plan which areas need a security layer. You don&#8217;t need to include it from the beginning, but please take the time to think about it. This will reduce the configuration time afterwards. If you know that some services will be secured, create a special namespace for this (e.g. /secure/*). For your URL based security you just need to include the namespace. It is a waste of time to create a lot of actions in a base folder and write 100 lines of suspect security configuration. If you forget an action, it could be very dangerous. If you need a more fine grained security you can use a good URL layout as a starting point and reduce the configuration overhead.</p>
<h2>Let&#8217;s get real</h2>
<h3>Maven configuration</h3>
<pre name="code" class="xml">
&lt;project&gt;

  ...

  &lt;dependencies&gt;
    &lt;!--  Struts 2 --&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.apache.struts&lt;/groupId&gt;
      &lt;artifactId&gt;struts2-core&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.apache.struts&lt;/groupId&gt;
      &lt;artifactId&gt;struts2-sitemesh-plugin&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.apache.struts&lt;/groupId&gt;
      &lt;artifactId&gt;struts2-spring-plugin&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;!-- Security --&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
      &lt;artifactId&gt;spring-security-core&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
      &lt;artifactId&gt;spring-security-core-tiger&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
      &lt;artifactId&gt;spring-security-acl&lt;/artifactId&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
      &lt;artifactId&gt;spring-security-taglibs&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;!-- Servlet &#038; Jsp --&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
      &lt;version&gt;2.4&lt;/version&gt;
      &lt;scope&gt;provided&lt;/scope&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;jsp-api&lt;/artifactId&gt;
      &lt;version&gt;2.0&lt;/version&gt;
      &lt;scope&gt;provided&lt;/scope&gt;
    &lt;/dependency&gt;
&lt;/project&gt;
</pre>
<h3>web.xml</h3>
<pre name="code" class="xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
      http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4"&gt;
  &lt;display-name&gt;Name&lt;/display-name&gt;

  &lt;!-- path of applicationContexts used by spring --&gt;
  &lt;context-param&gt;
    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
    &lt;param-value&gt;
      /WEB-INF/applicationContext.xml
      /WEB-INF/applicationContext-security.xml
    &lt;/param-value&gt;
  &lt;/context-param&gt;

  &lt;filter&gt;
    &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
    &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt;
  &lt;/filter&gt;
  &lt;filter&gt;
    &lt;filter-name&gt;action2-cleanup&lt;/filter-name&gt;
    &lt;filter-class&gt;org.apache.struts2.dispatcher.ActionContextCleanUp&lt;/filter-class&gt;
  &lt;/filter&gt;
  &lt;filter&gt;
    &lt;filter-name&gt;sitemesh&lt;/filter-name&gt;
    &lt;filter-class&gt;com.opensymphony.module.sitemesh.filter.PageFilter&lt;/filter-class&gt;
  &lt;/filter&gt;
  &lt;filter&gt;
    &lt;filter-name&gt;action2&lt;/filter-name&gt;
    &lt;filter-class&gt;org.apache.struts2.dispatcher.FilterDispatcher&lt;/filter-class&gt;
  &lt;/filter&gt;

  &lt;filter-mapping&gt;
    &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
    &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  &lt;/filter-mapping&gt;
  &lt;filter-mapping&gt;
    &lt;filter-name&gt;action2-cleanup&lt;/filter-name&gt;
    &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  &lt;/filter-mapping&gt;
  &lt;filter-mapping&gt;
    &lt;filter-name&gt;sitemesh&lt;/filter-name&gt;
    &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  &lt;/filter-mapping&gt;
  &lt;filter-mapping&gt;
    &lt;filter-name&gt;action2&lt;/filter-name&gt;
    &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  &lt;/filter-mapping&gt;

  &lt;!-- Listeners --&gt;
  &lt;listener&gt;
    &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
  &lt;/listener&gt;

  &lt;!-- Welcome file lists --&gt;
  &lt;welcome-file-list&gt;
    &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;
  &lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</pre>
<h3>applicationContext.xml</h3>
<pre name="code" class="xml">
&lt;beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="

http://www.springframework.org/schema/beans

           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" default-autowire="autodetect"&gt;

  &lt;!-- UserService for Spring Security --&gt;
  &lt;bean id="customUserService" class="com.agimatec.ostium.security.CustomUserDetailsService"/&gt;
&lt;/beans&gt;
</pre>
<h3>applicationContext-security.xml</h3>
<pre name="code" class="xml">
&lt;!--
- Spring namespace-based configuration
--&gt;
&lt;beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/security

http://www.springframework.org/schema/security/spring-security-2.0.1.xsd"&gt;

  &lt;!--
  - Secure the page per the URL pattern
  --&gt;
  &lt;http auto-config="true"&gt;
    &lt;!-- we need a ROLE_ prefix in here --&gt;
    &lt;intercept-url pattern="/update/**" access="ROLE_OSTIUM-User"/&gt;

    &lt;!-- use own login page rather than the default one --&gt;
    &lt;form-login login-page="/login/login.jsp"/&gt;
  &lt;/http&gt;

  &lt;!--
    Use with DummyDAO
  --&gt;
  &lt;!--&lt;authentication-provider&gt;
    &lt;user-service&gt;
      &lt;user name="12345" password="12345" authorities="ROLE_USER"/&gt;
      &lt;user name="12346" password="12346" authorities="ROLE_USER"/&gt;
    &lt;/user-service&gt;
  &lt;/authentication-provider&gt; --&gt;

  &lt;!--
    Use with JDBC
  --&gt;
  &lt;!--&lt;authentication-provider&gt;
    &lt;jdbc-user-service
        data-source-ref="dataSource"
        users-by-username-query="SELECT ...;"
        authorities-by-username-query="SELECT ..."/&gt;
  &lt;/authentication-provider&gt; --&gt;

  &lt;authentication-provider user-service-ref="customUserService"/&gt;
&lt;/beans:beans&gt;
</pre>
<h3>CustomUserDetailsService.java</h3>
<pre name="code" class="java">
package com.agimatec.ostium.security;

import com.agimatec.connecta.model.XFireUser;
import com.agimatec.connecta.xfire.WebXFireDAO;
import com.agimatec.nucleus.exceptions.CodedException;
import com.agimatec.nucleus.common.model.UserState;
import com.agimatec.usermanagement.service.XFireUserManagement;
import org.springframework.dao.DataAccessException;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.security.userdetails.User;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;

public class CustomUserDetailsService extends WebXFireDAO<XFireUserManagement> implements UserDetailsService {
    public CustomUserDetailsService() {
        super(XFireUserManagement.class);
    }

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
        try {
            // get the user from the XFire webservice
            XFireUser user = this.getService().getUserByIdentification(username);

            // extract all important parts
            String password = user.getPassword();
            String role = user.getRole();
            boolean enabled = user.isEnabled();

            // create a new Spring Security User
            return new User(username,password,enabled,true,true,true,new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_"+role)});
        } catch (CodedException e) {
            e.printStackTrace();
        }
        return null;
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/01/spring-security-in-the-wild-with-maven/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bean Validation (JSR-303) &#8211; 3/3 Ausblicke</title>
		<link>http://www.agimatec.de/blog/2008/12/bean-validation-jsr-303-33-ausblicke/</link>
		<comments>http://www.agimatec.de/blog/2008/12/bean-validation-jsr-303-33-ausblicke/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 10:01:24 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Validierung]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=435</guid>
		<description><![CDATA[Im letzten Teil der Blog-Einträge zur JSR-303 möchte ich einige Ideen für Integrationsmöglichkeiten vorstellen, die sich durch die Verwendung von Metadaten ergeben sowie einen Ausblick auf die kommende erste offizielle Referenzimplementierung geben. Beispiel 1: Verwendung im AJAX-Layer Um auf die Metadaten außerhalb von Java im JavaScript einer AJAX-GUI zugreifen zu können, wird aus den MetaBeans [...]]]></description>
			<content:encoded><![CDATA[<p>Im letzten Teil der Blog-Einträge zur JSR-303 möchte ich einige Ideen für Integrationsmöglichkeiten vorstellen, die sich durch die Verwendung von Metadaten ergeben sowie einen Ausblick auf die kommende erste offizielle Referenzimplementierung geben.<span id="more-435"></span></p>
<p><strong>Beispiel 1: Verwendung im AJAX-Layer</strong></p>
<p>Um auf die Metadaten außerhalb von Java im JavaScript einer AJAX-GUI zugreifen zu können, wird aus den MetaBeans ein JSON-String erzeugt, den ein Servlet zurückgeben kann:</p>
<p><code>public void service(  HttpServletRequest req,  HttpServletResponse res)<br />
throws ServletException, IOException {<br />
res.setContentType("text/javascript");<br />
JSONGenerator jsonGenerator =    new JSONGenerator();<br />
PrintWriter writer = res.getWriter();<br />
try {<br />
String output = jsonGenerator.toJSON(manager.findAll().values());<br />
writer.write(output);<br />
} catch (Exception e) {<br />
throw new ServletException("error creating JSON for metaBeans", e);<br />
}<br />
}<br />
</code></p>
<p>Dabei werden auch die Typinformationen von Java nach JSON übertragen, da diese ansonsten verloren gingen. Die Beans selbst überträgt das AJAX-Framework <a href="http://getahead.org/dwr/ ">DWR</a>, was nicht Gegenstand dieses Eintrages ist.</p>
<p><strong>Beispiel 2: Verwendung im Webservice-Layer</strong></p>
<p>Eine weitere Einsatzmöglichkeit stellt sich bei  Validierung eingehender Objekte eines Webservice. Am Beispiel der Webservice Frameworks <a href="http://xfire.codehaus.org/ ">XFire oder CXF</a> kann eine eigene Invoker-Implementierung konfiguriert werden, welche die eingehenden Beans validiert. Die zu validierenden Methoden und Parameter werden durch die Annotation @Validate gekennzeichnet.</p>
<p>Auszug aus einem Webservice-Interface:<br />
<code>@Validate<br />
void save(@Validate  Address address)  throws ValidationException;<br />
</code><br />
Entdeckte ConstraintViolations können der Exception mitgegeben werden.</p>
<p>Im Invoker wird das Validierungsframework aufgerufen (Beispiel für XFire):</p>
<p><code>public Object invoke(Method m, Object[] params, MessageContext context) throws XFireFault {<br />
BeanValidator validator =     new BeanValidator();<br />
ValidationResults results =    validator.validateCall( m, params);<br />
if (results != null &amp;&amp;   !results.isEmpty()) {<br />
throw new XFireFault(new  ValidationException(results),   XFireFault.RECEIVER);<br />
}<br />
return super.invoke(  m, params, context);<br />
}<br />
</code></p>
<p>Die zugehörige Konfiguration für XFire sieht dabei so aus:<br />
<code>&lt;beans&gt;<br />
&lt;bean id="TxInvoker" class="com.example.xfire.TransactionalInvoker"<br />
scope="prototype"/&gt;<br />
</code><br />
<code><br />
&lt;service xmlns="http://xfire.codehaus.org/config/1.0"&gt;<br />
&lt;name&gt;ExampleService&lt;/name&gt;<br />
&lt;serviceClass&gt;com.example.service.ExampleService&lt;/serviceClass&gt;<br />
&lt;implementationClass&gt;com.example.service.ExampleServiceImpl&lt;/implementationClass&gt;<br />
&lt;serviceFactory&gt;jsr181&lt;/serviceFactory&gt;<br />
&lt;invoker&gt;#TxInvoker&lt;/invoker&gt;<br />
&lt;/service&gt;<br />
&lt;/beans&gt;</code></p>
<p>Weitere Anwendungsmöglichkeiten sind die Visualisierung der Pflichtfelder und Validierungsfehler in Swing-GUIs oder einem Webformular.</p>
<p><strong>Ausblick</strong></p>
<p>Seit Oktober 2008 entsteht eine <a href="http://anonsvn.jboss.org/repos/hibernate/validator/trunk/">Referenzimplementierung</a>, die sich an Hibernate-Validator orientiert. Von der  veröffentlichten <a href="http://jcp.org/aboutJava/communityprocess/edr/jsr303/">Draft-Spec des JSR-303</a><br />
wurde dabei in den letzten Monaten mehrfach massiv abgewichen, um neue Features und Anregungen, die von der Java-Community eingegangen sind, einzubeziehen. Das agimatec-validation framework implementiert den jeweils aktuellen Stand der APIs möglichst zeitnah und vollständig. Wir gehen davon aus, dass sich bis zum offiziellen 1.0 Release des Standards noch mehrfach einiges ändern wird, da die Referenzimplementierung noch unvollständig ist.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/12/bean-validation-jsr-303-33-ausblicke/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bean Validation (JSR-303) &#8211; 2/3 Implementierung</title>
		<link>http://www.agimatec.de/blog/2008/12/bean-validation-jsr-303-23-implementierung-agimatec-validation/</link>
		<comments>http://www.agimatec.de/blog/2008/12/bean-validation-jsr-303-23-implementierung-agimatec-validation/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 09:46:39 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Validierung]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=424</guid>
		<description><![CDATA[agimatec-validation framework Constraints in Annotations oder mit XML-Deskriptoren sind Metadaten, die den Domainklassen zusätzliche Semantik verleihen, die für diverse Verwendungszwecke mit der Constraint-Metadata-API ausgewertet werden kann. Diese Anforderung bestand auch schon vor Zeiten der JSR-303 und hat die agimatec GmbH dazu veranlasst, das Framework „agimatec-validation“ im Frühjahr 2007 zu entwickeln. Das Framework ist seither als [...]]]></description>
			<content:encoded><![CDATA[<p><strong>agimatec-validation framework<br />
</strong></p>
<p>Constraints in Annotations oder mit XML-Deskriptoren sind Metadaten, die den Domainklassen zusätzliche Semantik verleihen, die für diverse Verwendungszwecke mit der Constraint-Metadata-API ausgewertet werden kann.</p>
<p>Diese Anforderung bestand auch schon vor Zeiten der JSR-303 und hat die agimatec GmbH dazu veranlasst, das Framework „agimatec-validation“ im Frühjahr 2007 zu entwickeln. Das Framework ist seither als Basis zur Erzeugung dynamischer AJAX Oberflächen für Portlets und zur Validierung in Webservices produktiv im Einsatz.</p>
<p>Durch die konzeptionelle Nähe war es bei Erscheinen der JSR-303 möglich, das <a href="http://code.google.com/p/agimatec-validation/">agimatec-validation Framework</a> so zu erweitern, dass damit rasch die erste und bislang  vollständigste Implementierung des Specification-Draft als OpenSource veröffentlicht wurde.<span id="more-424"></span></p>
<p>Zusätzliche Anforderungen waren dabei, dass</p>
<ul>
<li>eine möglichst automatische Generierung der Metadaten als XML-Dateien erfolgt,</li>
<li>eine Klasse zur Laufzeit unterschiedliche Metadaten und Validierungsregeln besitzen kann (z.B. für rechteabhängige Validierung),</li>
<li>die „höheren“ Schichten (hier: die GUI-Schicht) die Metadaten erweitern oder selektiv überschreiben können und</li>
<li> die Metadaten den AJAX GUIs in Form von <a href="http://www.json.org/ ">JSON (JavaScript Object Notation)</a> zur Verfügung stehen sollen.</li>
</ul>
<p><strong>Generierung aus Datenbankinformationen</strong></p>
<p>Die häufigsten Metainformationen betreffen  Pflichtfelder und Feldlängen. Diese sind im Datenbankschema definiert oder durch  Annotationen der Package javax.persistence<br />
<code>@Column(nullable, length, unique) oder<br />
@JoinColumn(...)</code><br />
an den Entity-Klassen definiert. Um aus dem Datenbankschema oder den Annotationen entsprechendes XML zu generieren bieten sich die als OpenSource verfügbaren <a href="http://code.google.com/p/agimatec-tools/">agimatec-tools</a> an (oder eine MDA-Lösung).</p>
<p>Das hier gezeigte XML folgt dem agimatec-validation Framework, da die JSR-303 bislang noch keine Aussage über XML-Tags getroffen hat:</p>
<p><code>&lt;beanInfos&gt;<br />
&lt;bean id=“Address“<br />
impl=“test.jsr303.Address“&gt;<br />
&lt;property name=“line1“<br />
mandatory=“true“<br />
maxLength=“30“/&gt;<br />
&lt;property name=“line2“<br />
maxLength=“30“/&gt;<br />
&lt;property name=“zipCode“<br />
mandatory=“true“<br />
maxLength=“5“/&gt;<br />
...<br />
&lt;/bean&gt;<br />
...<br />
&lt;/beanInfos&gt;<br />
</code></p>
<p><strong>Features und Validators per XML</strong></p>
<p>Häufige Eigenschaften sind direkt als Attribut deklarierbar, sonstige Informationen werden mit &lt;feature&gt;-Tags abgelegt:</p>
<p><code><br />
&lt;feature key="readonly"&gt;<br />
&lt;value class="boolean"&gt;true&lt;/value&gt;<br />
&lt;/feature&gt;<br />
</code></p>
<p>Eigene Validator-Implementierungen werden über das &lt;validator&gt;-Tag konfiguriert:</p>
<p><code><br />
&lt;beanInfos&gt;<br />
&lt;validator id="email"<br />
java="my.own.EMailValidation"/&gt;<br />
&lt;bean id=“Customer“&gt;<br />
&lt;property name=“emailAddress“&gt;<br />
&lt;validator refId="email"/&gt;<br />
&lt;/property&gt;<br />
&lt;/bean&gt;<br />
&lt;/beanInfos&gt;<br />
</code></p>
<p>Nicht alle Metadaten sind zur Validierung relevant, sondern können für andere Zwecke z.B. zur Erzeugung einer Oberfläche genutzt werden. So können z.B. Feldreihenfolgen im Eingabeformular, Felder zur Darstellung in einer Tabelle oder die Properties zur Anzeige einer Beschreibung eines Objekts aus den Metadaten hervorgehen. Hier sind der Phantasie der GUI-Entwickler kaum Grenzen gesetzt.</p>
<p>Da die Metadaten aus diversen Quellen (Annotations, unterschiedlichen XML-Dateien und/oder den JDK-BeanInfos) zusammengestellt werden, können Zusatzinformationen beispielsweise in gesonderten XML-Dateien gehalten werden, während andere Informationen per Generierung zustande kommen.</p>
<p>Jede XML-Datei mit Metadaten muss  registriert werden:</p>
<p><code>MetaBeanManager manager =  new MetaBeanManager();<br />
manager.addResourceLoader("beanInfos.xml");</code></p>
<p>Auf die Metadaten einer Domainklasse kann alternativ zur Metadata-API des JSR-303 direkt über den MetaBeanManager zugegriffen werden:</p>
<p><code>MetaBean metabean =  manager.findForClass(Address.class);<br />
// oder<br />
metaBean =  manager.findForId(„Address“);<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/12/bean-validation-jsr-303-23-implementierung-agimatec-validation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bean Validation (JSR-303) &#8211; 1/3 Standard</title>
		<link>http://www.agimatec.de/blog/2008/12/bean-validation-jsr-303-13-standard/</link>
		<comments>http://www.agimatec.de/blog/2008/12/bean-validation-jsr-303-13-standard/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 09:33:21 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Validierung]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=409</guid>
		<description><![CDATA[Die Modellschicht ist das Kernstück der meisten Anwendungen und beeinflusst Schnittstellen, Datenbankdesign und Oberflächen. Validierungsregeln und Metadaten, die über die Typinformationen von Java hinausgehen, können mit Hilfe von Annotations oder XML, deklariert werden. Daraus ergeben sich Chancen zur Verbesserung der Konsistenzprüfungen und Verarbeitung der Modellschicht in unterschiedlichen Anwendungslayern. Neben den seit Jahren bekannten proprietären Validierungsframeworks [...]]]></description>
			<content:encoded><![CDATA[<p>Die Modellschicht ist das Kernstück der meisten Anwendungen und beeinflusst Schnittstellen, Datenbankdesign und Oberflächen. Validierungsregeln und Metadaten, die über die Typinformationen von Java hinausgehen, können mit Hilfe von Annotations oder XML, deklariert werden. Daraus ergeben sich Chancen zur Verbesserung der  Konsistenzprüfungen und Verarbeitung der Modellschicht in unterschiedlichen Anwendungslayern.</p>
<p>Neben den seit Jahren bekannten proprietären Validierungsframeworks liegt seit März 2008 mit der JSR-303 ein Spezifikationsvorschlag für eine Java API für JavaBeans vor, der zukünftige Tools und Standards beeinflussen wird.</p>
<p>In den folgenden drei Einträgen stelle ich</p>
<p>a) Grundkonzepte der JSR-303<br />
b) eine erste Implementierung des Standards<br />
und<br />
c) Beispiele für Integrationsmöglichkeiten und die Referenzimplementierung<br />
vor.<br />
<span id="more-409"></span><br />
Datenvalidierung ist eine allgemeine Aufgabe, die leider über die meisten Schichten einer Anwendung verteilt ist und dabei oftmals die Implementierung gleicher oder ähnlicher Regeln in jeder Schicht zur Folge hat. Dies führt zu doppeltem Code und Fehleranfälligkeit.</p>
<p>Für die Konsistenzprüfung umfangreicher Modelle von Businessentitäten müssen Validierungsregeln deklariert oder programmiert werden. Zu diesem Zweck gibt es seit Jahren bereits eine Vielzahl an proprietären Frameworks, einige Beispiele:</p>
<ul>
<li>
<p style="margin-bottom: 0cm; font-style: normal;" align="left"><a href="http://commons.apache.org/validator/ "><span style="font-family: Times New Roman,serif;"><span style="font-size: small;">Apache 	Common-Validator </span></span></a></p>
</li>
<li>
<p style="margin-bottom: 0cm; font-style: normal;" align="left"><a href="http://struts.apache.org/1.2.4/userGuide/dev_validator.html "><span style="font-family: Times New Roman,serif;"><span style="font-size: small;">Struts-Validation 	für Webclients und JavaScript</span></span></a></p>
</li>
<li>
<p style="margin-bottom: 0cm; font-style: normal;" align="left"><a href="http://validator.hibernate.org "><span style="font-family: Times New Roman,serif;"><span style="font-size: small;">Hibernate-Validator 	(mit JBoss Seam Integration) </span></span></a></p>
</li>
<li>
<p style="margin-bottom: 0cm; font-style: normal;" align="left"><a href="http://www.opensymphony.com/xwork/wikidocs/Validation%20Framework.html "><span style="font-family: Times New Roman,serif;"><span style="font-size: small;">WebWork mit XWork 	Validation Framework</span></span></a></p>
</li>
</ul>
<p>Diese sind jedoch meist darauf ausgelegt, die Validierung in einer bestimmten Schicht der Anwendung abzusichern und sind sich allenfalls konzeptionell ähnlich. Einen Java-Standard für Deklaration und Prüfung von Validierungs-Constraints gab es bislang nicht.<br />
Seit März 2008 liegt mit der „JSR-303: Bean Validation“ ein erster Vorschlag für einen allgemeinen Validierungsstandard im Javaumfeld vor, der zukünftig Einfluß auf Tools, Produkte und darauf aufbauende Standards haben soll. Ziel der Spezifikation ist es, als Erweiterung des Java-Beans Objektmodells in Java EE und SE eine einheitliche API für alle Schichten, sei es die Persistence Schicht, die Web Schicht und andere GUI-Schichten (z.B. Swing), zu bieten.</p>
<p style="margin-bottom: 0cm; font-style: normal;" align="left"><span style="font-family: Times New Roman,serif;"><span style="font-size: small;"><strong>Grundkonzepte der Spezifikation</strong></span></span></p>
<p>Als Metamodell zur Deklaration von Constraints schlägt der <a href="http://jcp.org/aboutJava/communityprocess/edr/jsr303/">Draft der JSR-303</a> Annotationen für JavaBeans vor. Ferner wird in Aussicht gestellt, dass auch XML-Deployment-Descriptoren unterstützt werden sollen, was zum Zeitpunkt der Erstellung dieses Artikels aber noch nicht spezifiziert wurde. Alle Klassen der Spezifikation selbst werden sich im Package „javax.validation“ befinden.</p>
<p style="margin-bottom: 0cm;" align="left"><span style="font-family: Times New Roman,serif;"><span style="font-size: small;"><em><strong>Annotation der Domainklassen</strong></em></span></span></p>
<p>Um für die Domainklasse „Address“ festzulegen, dass die Felder „line1“ und „zipCode“ Pflichtfelder sind und die Werte eine  maximale Anzahl Zeichen nicht überschreiten dürfen, schreibt man:<br />
<code>public class Address {<br />
@NotEmpty @Length(max = 30)<br />
private String line1;<br />
@Length(max = 30)<br />
private String line2;<br />
@NotEmpty @Length(max = 5)<br />
private String zipCode;<br />
...<br />
}</code></p>
<p>Folgende Sprachkonstrukte dürfen hierzu mit Annotationen versehen werden:</p>
<ul>
<li> Instanzvariablen (field validation)</li>
<li> Getter-Methoden (method validation)</li>
<li> die Klasse selbst (bean-level constraints)</li>
<li> Superklassen und</li>
<li> Interfaces.</li>
</ul>
<p>Es ist daher auch möglich, die Klasse „Customer“ durch Annotation ihres Interfaces „Person“ mit Constraints zu versehen:</p>
<p><code>public interface Person {<br />
@NotEmpty<br />
String getFirstName();<br />
String getMiddleName();<br />
@NotEmpty<br />
String getLastName();<br />
}</code></p>
<p><code><br />
public class Customer implements Person {<br />
private String firstName;<br />
private String middleName;<br />
private String lastName;<br />
@Password(robustness = 5)<br />
private String password;<br />
...<br />
}<br />
</code></p>
<p>Alle Constraints aus Oberklassen und Interfaces werden stets vererbt. Neben den Annotationen, welche die Implementierung der Spezifikation mitbringen wird, können beliebige eigene genutzt werden.</p>
<p><strong>Eigene Constraints definieren</strong><br />
Zur Implementierung neuer Constraints müssen die entsprechende Annotation und ein  ConstraintValidator erstellt werden.<br />
Die Annotation wird im Domainmodell wie bereits dargestellt verwendet. Aufgerufen wird die Implementierung von einem Validator,  welcher darüber entscheidet ob der Constraint erfüllt ist oder nicht.</p>
<p>Dazu folgt ein Beispiel für die Annotation „Pattern“:</p>
<p><code>@Documented<br />
@Target({METHOD, FIELD})<br />
@Retention(RUNTIME)<br />
@ConstraintValidator(<br />
PatternValidator.class)</code><br />
<code><br />
public @interface Pattern {<br />
String regex();<br />
String message()<br />
default "{beancheck.pattern}";<br />
String[] groups() default {};<br />
}</code></p>
<p>Die Implementierung „PatternValidator“ soll den Wert der annotierten Property gegen den angegebenen regulären Ausdruck aus „regex“ prüfen. Der ConstraintValidator PatternValidator muss das Interface „javax.validation.Constraint“ implementieren, das die Methode<br />
<code>boolean isValid(Object value, ConstraintContext constraintContext);</code><br />
beinhaltet.</p>
<p><strong>Mehrfache Zuweisung von Constraints gleichen Typs</strong></p>
<p>Um mehrere gleiche Constraints mit unterschiedlichen Parametern für das gleiche Feld verwenden zu können, unterstützt die Spezifikation sogenannte „multi-valued constraints“.  Eine Annotation darf hierbei die eigentlichen Constraint-Annotations als Array im Feld „value“ beinhalten:</p>
<p><code>@Documented<br />
@Target({ElementType.METHOD, FIELD})<br />
@Retention(RUNTIME)<br />
public @interface Patterns {<br />
Pattern[] value();<br />
}<br />
</code></p>
<p>In der Verwendung liest sich dies dadurch folgendermaßen:<br />
<code><br />
public class Engine {<br />
@Patterns({<br />
@Pattern(regex = "^[A-Z0-9-]+$"),<br />
@Pattern(regex = "^....-....$")<br />
})<br />
protected String serialNumber;<br />
...<br />
}<br />
</code></p>
<p>Das Beispiel zeigt die Constraint-Definitionen zweier @Pattern für das Feld „serialNumber“ in einer Domainklasse namens „Engine“.</p>
<p>Für die eigentliche Validierung sieht die Spezifikation das Interface „Validator“ vor. Es definiert diverse validate*() Methoden für Objekte oder einzelne Properties, welche bei Verstoß gegen die festgelegten Validierungsregeln die Menge der entsprechenden ConstraintViolation Objekte zurückgeben:<br />
<code><br />
Validator validator = ... ;<br />
Set&lt;ConstraintViolation&lt;Address&gt;&gt;<br />
errors = validator.validate(address);</code></p>
<p><code><br />
for(ConstraintViolation each :  errors) {<br />
printInvalidContraint(<br />
each.getPropertyPath(),<br />
each.getInterpolatedMessage());<br />
}</code></p>
<p>An welcher Stelle die Validierung in eine Anwendung integriert werden kann oder sollte ist nicht Bestandteil der Spezifikation.</p>
<p>Dieser Eintrag ist sowieso schon zu lang, aber alle Features im Detail zu zeigen, würde den Rahmen endgültig springen, daher hier einige weitere Features der JSR-303 stichpunktartig:</p>
<p><strong>Validierung von Objektgraphen</strong><br />
Durch die Annotation „@Valid“ können auch referenzierte Objekte in die Validierung ihres Parent-Objects einbezogen werden. Auf diese Weise ist es möglich,  mit einem Aufruf der Validierungs-API ganze Objektgraphen zu validieren.</p>
<p><strong>Mehrsprachige Meldungen</strong><br />
Ein Constraint kann eine eigene Fehlermeldung im Annotation-Element „message“ festlegen. Die Spezifikation beschreibt die Möglichkeit, die Meldungen mehrsprachig in ein  ResourceBundle auszulagern und in den Annotationen nur die sprachunabhängigen Schlüssel zu referenzieren.</p>
<p>Mit <strong>Class-Level Constraints</strong> können ganze Objekte anstatt einzelner Properties validiert werden. Als Anwendungsbeispiel kann man sich einen Validator vorstellen, der überprüft, ob die angegebene Stadt in einer Adresse zu Land und Postleitzahl passt.</p>
<p><strong>Validierungsgruppen</strong> ermöglichen eine teilweise Validierung und werden von der Community noch diskutiert, wobei die Expert Group nach Möglichkeiten sucht, dies verständlich und gleichzeitig flexibel zu gestalten.<br />
Eine Reihenfolge der Validierungen festzulegen ermöglicht die Annotation @GroupSequence.<br />
Mit Hilfe der Gruppen und Reihenfolge ist es möglich, dass in einer Anwendungsschicht nur bestimmte Validierungen durchgeführt werden („Wizzard-Style“) um auch bereits unvollständig initialisierte Objekte prüfen zu können oder die Validierung so gestaltet wird, dass zeitaufwändige Verarbeitungen nachgelagert werden („Short-Circuit“).</p>
<p>Mit der <strong>Constraint-Metadata API </strong>wird eine Schnittstelle definiert, die Auskunft über die Constraints einer Klasse oder einzelner Properties gibt. Auch diese API steht noch nicht abschließend fest, dürfte aber für Toolhersteller von besonderem Interesse sein.</p>
<p>Wer mehr über die Spezifikation erfahren möchte, sei auf den <a href="http://blog.emmanuelbernard.com/2008/05/jsr-303-interviews.html ">Blog des Lead-Autors</a> der JSR-303 verwiesen, der für alle Features auch Beispiele vorstellt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/12/bean-validation-jsr-303-13-standard/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Selenium-Flex-Tests with Maven</title>
		<link>http://www.agimatec.de/blog/2008/11/selenium-flex-tests-with-maven/</link>
		<comments>http://www.agimatec.de/blog/2008/11/selenium-flex-tests-with-maven/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 19:05:05 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[TeamCity]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=385</guid>
		<description><![CDATA[I wanted to integrate our Flex application with tests into our Maven build. A few days ago I moved the app to Flex 3 and changed the Maven Plugin from the Maven2 Flex Plugin to Flex-mojos. Now the artifacts are in the repository and you don&#8217;t need to install the Flex SDK to build the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.agimatec.de/blog/wp-content/uploads/2008/11/img_2340.jpg" alt="" title="london" width="300" height="225" class="alignleft size-medium wp-image-390" />I wanted to integrate our Flex application with tests into our Maven build. A few days ago I moved the app to Flex 3 and changed the Maven Plugin from the <a href="http://www.israfil.net/projects/mojo/maven-flex2-plugin/">Maven2 Flex Plugin</a> to <a href="http://blog.flex-mojos.info">Flex-mojos</a>. Now the artifacts are in the repository and you don&#8217;t need to install the Flex SDK to build the application.</p>
<p>We have written the application as a demo in the first place and now wanting to test it in the wild. Because we use Cairngorm the application is well structured and contains as view layer only minimal parts of logic. Yes, we could include unit tests, but integration tests are far more interesting (from my point of view). In a large code base it could happen, that because of refactoring some things are broken. No deal, if you have tests and a CI system. But in the Flex app there are just tiny parts which I could test in a normal unit test.</p>
<p>Okay, so it should be integration test. Sounds good and not too complicated. There should exist a lot of frameworks because a lot of people start to use BlazeDS and other stuff in Java environments. Just something to start the app, run some tests and get the result back in the CI system.</p>
<p>I started to search on google and was surprised. Most of the blog posts I have found on that topic are just two month old. And there are not so many posts about that topic. With the combination of those posts I figured out, how to solve that problem. What problem?</p>
<ul>
<li>Integration tests of our Flex app</li>
<li>Integrated in Maven</li>
<li>Should work together with Cairngorm (would be more complicated with some unit tests frameworks)</li>
<li>Could be Selenium (to start the app and run tests)</li>
<li>Should be integrated in our continuous integration server TeamCity</li>
<li>Could be written in Java</li>
</ul>
<p><span id="more-385"></span></p>
<p>First thanks to the <a href="http://www.blackpepper.co.uk/black-pepper-blog/Flex-acceptance-testing-and-continuous-integration.html">blog post of Julia at Blackpepper</a>. She opened my eyes how to work with Java and Flex in combination. It is the combination of the SeleniumFlexAPI, which integrates as Flex to Javascript bridge in your Flex application and FlashSelenium.</p>
<p><a href="http://sourceforge.net/projects/seleniumflexapi/">SeleniumFlexApi</a> is in one part a Flex library which needs to be included in your app and on the other part an extension to the Selenium IDE. I like the Flex part, because it makes it easy to dive over Javascript into the details of your Flex app. What I don&#8217;t really like is the Javascript extension. Yes, it is not only a Selenium IDE part and you can include it into the start of the Selenium Server, but it is far away from Java and Maven.</p>
<p><a href="http://code.google.com/p/flash-selenium/">FlashSelenium</a> is a piece of code which let&#8217;s you talk from Java over Selenium with your Flex app. The Java part is very handy, but you need to code into Flex, which methods you could call over your bridge. So I need to write special code, which opens the bridge. The SeleniumFlexAPI is much better in this part.</p>
<p>I liked the solution of the blog post and started to implement it.</p>
<p>First the pom.xml where you need to include the SeleniumFlexAPI (the scope cost me some time):</p>
<pre class="xml" name="code">&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&gt;

   &lt;parent&gt;
        &lt;groupId&gt;agimatec&lt;/groupId&gt;
        &lt;artifactId&gt;assessor&lt;/artifactId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
        &lt;relativePath&gt;../pom.xml&lt;/relativePath&gt;
    &lt;/parent&gt;

  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;agimatec&lt;/groupId&gt;
  &lt;artifactId&gt;assessor-flexapp&lt;/artifactId&gt;
  &lt;packaging&gt;swf&lt;/packaging&gt;
  &lt;version&gt;${agimatec-assessor-version}&lt;/version&gt;
  &lt;name&gt;Assessor Flex Application&lt;/name&gt;
  &lt;url&gt;http://www.agimatec.de&lt;/url&gt;

  &lt;dependencies&gt;
    		 &lt;!--Flex SDK dependencies--&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;playerglobal&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;flex&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;framework&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;framework&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;resource-bundle&lt;/type&gt;
			&lt;classifier&gt;en_US&lt;/classifier&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;rpc&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;rpc&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;resource-bundle&lt;/type&gt;
			&lt;classifier&gt;en_US&lt;/classifier&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;com.adobe.flex.sdk&lt;/groupId&gt;
			&lt;artifactId&gt;utilities&lt;/artifactId&gt;
			&lt;version&gt;3.0.0.477&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
		&lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;com.adobe.cairngorm&lt;/groupId&gt;
      &lt;artifactId&gt;cairngorm-bin&lt;/artifactId&gt;
      &lt;version&gt;2.2.1&lt;/version&gt;
      &lt;type&gt;swc&lt;/type&gt;
    &lt;/dependency&gt;

      &lt;dependency&gt;
        &lt;groupId&gt;org.openqa.selenium&lt;/groupId&gt;
        &lt;artifactId&gt;flex-api&lt;/artifactId&gt;
        &lt;version&gt;0.22&lt;/version&gt;
        &lt;type&gt;swc&lt;/type&gt;
          &lt;scope&gt;internal&lt;/scope&gt;
      &lt;/dependency&gt;

		 &lt;!--FlexUnit dependencies--&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;flexunit&lt;/groupId&gt;
			&lt;artifactId&gt;flexunit&lt;/artifactId&gt;
			&lt;version&gt;0.85&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;flexunit.junit&lt;/groupId&gt;
			&lt;artifactId&gt;flexunit-optional&lt;/artifactId&gt;
			&lt;version&gt;0.85&lt;/version&gt;
			&lt;type&gt;swc&lt;/type&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
  &lt;/dependencies&gt;

  &lt;build&gt;
    &lt;sourceDirectory&gt;src/main/flex&lt;/sourceDirectory&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;info.rvin.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;flex-compiler-mojo&lt;/artifactId&gt;
        &lt;extensions&gt;true&lt;/extensions&gt;
        &lt;configuration&gt;
          &lt;includeSources&gt;
            &lt;param&gt;${project.build.sourceDirectory}&lt;/param&gt;
          &lt;/includeSources&gt;
          &lt;locales&gt;
            &lt;param&gt;en_US&lt;/param&gt;
            &lt;param&gt;de_DE&lt;/param&gt;
          &lt;/locales&gt;
          &lt;debug&gt;true&lt;/debug&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;info.rvin.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;asdoc&lt;/artifactId&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;
&lt;/project&gt;</pre>
<p>To get the Flex application compile with Maven you need to download the SeleniumFlexAPI and include the swc-file into your Maven repository, because it is (not yet) available on public repositories.</p>
<p>After compiling you can start the Selenium IDE and load the extension or go directly to FireBug and try to call the methods. Be aware, that the args-parameter is normally optional, but needs to be filled for the Javascript-Flex bridge (also cost me some time).</p>
<p>To call a method of your running application in Firefox fire up in FireBug&#8217;s console:</p>
<pre class="html" name="code">window.document['AppName'].getFlexExists('NameOfAnElement','');</pre>
<p>To test your application you need to know, what the name of your application is (can be found in the HTML calling the Flash file) and you need to give ids to your elements, because there is just an id locator at the moment.</p>
<p>If you are at this point we can now switch to the Java part with Selenium. Selenium is just Javascript when you are in the browser. So all you do is to call the Javascript function which you called before over Firebug. FlashSelenium is a good wrapper for that call which means that you don&#8217;t have to write normal strings into your Selenium commands. I like a little bit more comfort and wanted to wrap the SeleniumFlexAPI a little bit closer. Also there are some methods in the FlashSelenium you don&#8217;t need with this solution. So I started to implement my own little wrapper. Maybe it is also interesting for the SeleniumFlexAPI (if completed with all methods).</p>
<p>Here is the beginning of the code:</p>
<pre class="java" name="code">package com.agimatec.assessor.selenium;

import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;

public class FlexSelenium {
    Selenium selenium;
    String flexApp;

    public FlexSelenium(String ip, int port, String browser, String url, String flexApp) {
        selenium = new DefaultSelenium(ip, port, browser, url);
        this.flexApp = flexApp;
    }

    public void start() {
        selenium.start();
    }

    public void open(String url) {
        selenium.open(url);
    }

    public void stop() {
        selenium.stop();
    }

    public String doFlexClick(String id) {
        return callFlexBridge("doFlexClick",id);
    }

    public boolean getFlexExists(String id) {
        return callFlexBridge("getFlexExists",id).equals("true");
    }

    private String callFlexBridge(String method, String id) {
        return callFlexBridge(method, id, null);
    }

    private String callFlexBridge(String method, String id, String args) {
        if(args == null || args.trim().equals("")) {
            args = "''";
        }
        return selenium.getEval("window.document['"+flexApp+"']."+method+"('"+id+"',"+args+");");
    }
}</pre>
<p>And now the test case is the only thing which is missing. I used TestNG because it can be easier configured in a Selenium environment (when it started to become more complicated with several browsers, plattforms, test suites, test groups &#8230;):</p>
<pre class="java" name="code">package com.agimatec.assessor.selenium;

import org.testng.annotations.Test;

public class AssessorTest {
    private final static String URL = "http://192.168.1.175:8080/assessor-webapp";
    FlexSelenium selenium;

    @Test
    public void setUp() throws InterruptedException {
        selenium = new FlexSelenium("192.168.1.254", 4444, "*firefox", URL, "Terminal");
        selenium.start();
        selenium.open(URL);
        while(!selenium.getFlexExists("videoPlayer")) {
            Thread.sleep(1000);
        }

        selenium.doFlexClick("videoPlayer");
        Thread.sleep(300);
        selenium.doFlexClick("enterUserModeButton");
        selenium.stop();
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/11/selenium-flex-tests-with-maven/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Perfect Selenium Setup</title>
		<link>http://www.agimatec.de/blog/2008/10/perfect-selenium-setup/</link>
		<comments>http://www.agimatec.de/blog/2008/10/perfect-selenium-setup/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 14:15:45 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[TeamCity]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=369</guid>
		<description><![CDATA[It takes some time, but I&#8217;m now nearly happy with our Selenium setup. In this series I want to explain what goals existed and how we get a larger suite of Selenium tests running. You can find some posts around Selenium in this blog, but I want to get in more detail. Also there are [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.agimatec.de/blog/wp-content/uploads/2008/10/fotolia_1476264_xs.jpg"><img class="alignleft size-medium wp-image-371" title="crash test dummy" src="http://www.agimatec.de/blog/wp-content/uploads/2008/10/fotolia_1476264_xs.jpg" alt="" width="300" height="195" /></a>It takes some time, but I&#8217;m now nearly happy with our Selenium setup. In this series I want to explain what goals existed and how we get a larger suite of Selenium tests running.</p>
<p>You can find some posts around Selenium in this blog, but I want to get in more detail. Also there are some improvements to the solutions which could be really interesting if you start with Selenium or get an idea, how others deal with larger Selenium test suites. I will try to publish a new part every week, because there is so much to say, which wouldn&#8217;t fit into one single post.</p>
<p>Goals:</p>
<ul>
<li>Continuous integration of web application tests</li>
<li>Tests in different browsers</li>
<li>TestNG Setup</li>
<li>Integration in Maven2</li>
<li>Faster Selenium tests</li>
</ul>
<p>Tests:</p>
<ul>
<li>Running use cases of the web application</li>
<li>Running Javascript Unit Tests in different browsers</li>
<li>Take screenshots of the application</li>
</ul>
<p>I&#8217;m a web developer and no full-time tester, that&#8217;s why you should see the posts as support in an agile environment. There are different solutions and methods to test a web application, but I feel very comfortable with coding my tests and provide solutions which helps in the day-to-day work.</p>
<p>Until I will continue with the series, you can have a look at the previous posts:</p>
<ul>
<li><a href="http://www.agimatec.de/blog/2008/04/web20-oberflachen-testen/">Testing of Web 2.0 interfaces</a> (in german, but you will understand the code part)</li>
<li><a href="http://www.agimatec.de/blog/2008/07/robust-portlet-testing/">Robust portlet testing</a></li>
<li><a href="http://www.agimatec.de/blog/2008/07/selenium-ci-tests-with-teamcity/">Selenium CI tests with TeamCity</a></li>
<li><a href="http://www.agimatec.de/blog/2008/08/selenium-testing-of-massive-ajax-apps/">Selenium testing of massive Ajax Apps</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/10/perfect-selenium-setup/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Marshal-arts in XStream</title>
		<link>http://www.agimatec.de/blog/2008/09/marshal-arts-in-xstream/</link>
		<comments>http://www.agimatec.de/blog/2008/09/marshal-arts-in-xstream/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 09:32:16 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=313</guid>
		<description><![CDATA[You might already know various ways to process XML with java objects or to transform XML into different formats. XML transformation with XSLT can be quite difficult to implement because its concept differs from usual programming approaches. I like the framework XStream to parse and generate XML because of its simple but flexible API. You [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.agimatec.de/blog/wp-content/uploads/2008/09/marshalarts.jpg"><img class="size-full wp-image-344 alignnone" title="marshalarts" src="http://www.agimatec.de/blog/wp-content/uploads/2008/09/marshalarts.jpg" alt="" width="424" height="283" /></a></p>
<p>You might already know various ways to process XML with java objects or to transform XML into different formats. XML transformation with XSLT can be quite difficult to implement because its concept differs from usual programming approaches.</p>
<p>I like the framework <a href="http://xstream.codehaus.org/" target="_blank">XStream </a>to parse and generate XML because of its simple but flexible API. You can configure the XML with annotations on plain java classes, no XML schema or DTD is required. XStream&#8217;s documentation shows you in <a href="http://xstream.codehaus.org/tutorial.html" target="_blank">two minutes</a> how to use it.</p>
<p>We are using XStream to process XML-messages asynchronously between clients and a server, where some clients might use an older XML dialect than others. This leads to the requirement that the server must support various versions of XML messages for both receiving and sending with its clients. We use XStream not only to process the messages but for transformation as well.<span id="more-313"></span></p>
<p><strong>In short terms, the concept:</strong><br />
<span style="color: #0000ff;"><strong><br />
current version: classes and annotations </strong></span></p>
<p><span style="color: #0000ff;"><strong>former versions: classes, different configuration and converters</strong></span></p>
<p>XML is marshaled into POJOs and back. The POJOs and their annotations fit to the current version of the XML dialect of the server.</p>
<p><strong>Example for a class &#8220;Box&#8221;:</strong></p>
<pre class="java" name="code">@XStreamAlias("Box")
public class Box {
  Long number;
  boolean defect;
  boolean soiled;
  // getters and setters...
}</pre>
<p>The corresponding XML is:</p>
<pre class="xml" name="code">&lt;Box&gt;
  &lt;number&gt;1&lt;/number&gt;
  &lt;defect&gt;false&lt;/defect&gt;
  &lt;soiled&gt;false&lt;/soiled&gt;
&lt;/Box&gt;</pre>
<p>Various aspects on the XML can change during evolution of the schema. I adjust the annotations and classes, but how to provide backward compatibility?</p>
<p>I use the same classes with a different XStream configuration. For each version I need to support, I implement the interface XStreamConfigurator. This is the interface I created to initialize an instance of XStream.</p>
<pre class="java" name="code">public interface XStreamConfigurator {
    void configure(XStream xstream);
}</pre>
<p>The current version, based on annotations just lists the classes that participate in XML marshaling:</p>
<pre class="java" name="code">xstream.processAnnotations(Box.class); // ... for each class</pre>
<p>To provide XML marshaling/unmarshaling for other versions with the same class, I implement XStreamConfigurator differently:</p>
<p><strong>Example 1: changed tags</strong></p>
<p>e.g. &#8220;Pocket&#8221; instead of &#8220;Box&#8221;, &#8220;id&#8221; instead of &#8220;number&#8221;</p>
<pre class="java" name="code">xstream.alias("Pocket", Box.class);
xstream.aliasField("id", Box.class, "number");</pre>
<p>This overrules the annotations.</p>
<p><strong>Example 2: attribute instead of element</strong></p>
<p>e.g. &#8220;defect&#8221; as attribute instead of element</p>
<pre class="java" name="code">xstream.useAttributeFor("defect", Box.class);</pre>
<p><strong>Example 3: new fields</strong></p>
<p>When the current version has additional fields, you can tell XStream to omit them.</p>
<pre class="java" name="code">xstream.omitField(Box.class, "soiled");</pre>
<p><strong>Example 4: custom converter</strong></p>
<p>Some classes could change so heavily, that you need to implement a converter to marshal and unmarshal XML from old version into your classes. The example supports the additional xml element &#8220;active&#8221;, that does not appear in class Box.</p>
<pre class="java" name="code">xstream.registerConverter(new BoxConverter_v1());
...
public class BoxConverter_v1 implements Converter {
 public void marshal(Object source, HierarchicalStreamWriter writer,
                     MarshallingContext context) {
        Box box = (Box) source;
        writeNode(writer, "id", box.getNumber(), context);

        writeNode(writer, "defect", box.isDefect(), context);
        writeNode(writer, "active", true, context); // additional xml element "active"
    }

 public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        Box box = new Box();
        while (reader.hasMoreChildren()) {
            reader.moveDown();
            String nn = reader.getNodeName();
            if ("id".equals(nn)) {
                box.setNumber((Long) context.convertAnother(box, Long.class));
            } else if ("defect".equals(nn)) {
                box.setDefect(Boolean.parseBoolean(reader.getValue()));
            } else if ("active".equals(nn)) {
                // ignore, always "true"
            }
            reader.moveUp();
        }
        return box;
    }

    public boolean canConvert(Class type) {
        return type.equals(Box.class);
    }

    protected void writeNode(HierarchicalStreamWriter writer, String nodeName, Object value,
                             MarshallingContext context) {
        if (value != null) {
            writer.startNode(nodeName);
            context.convertAnother(value);
            writer.endNode();
        }
    }
}</pre>
<p><strong>Example 5: changed nested parts and new classes<br />
</strong></p>
<p>Finally I assume that the current version wraps the &#8220;Box&#8221; element under an &#8220;Action&#8221; element, so that class &#8220;Action&#8221; contains the &#8220;Box&#8221;.</p>
<pre class="java" name="code">@XStreamAlias("Action")
public class Action {
  private Box box;
  // getter and setters...
}</pre>
<p>XML looks like:</p>
<pre class="java" name="code">&lt;Action&gt;
  &lt;box&gt;
    &lt;number&gt;1&lt;/number&gt;
    &lt;defect&gt;false&lt;/defect&gt;
    &lt;soiled&gt;false&lt;/soiled&gt;
  &lt;/box&gt;
&lt;/Action&gt;</pre>
<p>To configure the instance of XStream that supports the former version, I write:</p>
<pre class="java" name="code">  xstream.registerConverter(new BoxConverter_v1());
  xstream.registerConverter(new ActionConverter_v1());
// Whenever XStream encounters an instance of this type,
// it will use the default implementation instead.
  xstream.addDefaultImplementation(Action.class,  Box.class);</pre>
<p>The ActionConverter is just a delegate to BoxConverter:</p>
<pre class="java" name="code">public class ActionConverter_v1 extends BoxConverter_v1 {

    public void marshal(Object source, HierarchicalStreamWriter writer,
                        MarshallingContext context) {
        Box box = ((Action) source).getBox();
        super.marshal(box, writer, context);
    }

    public boolean canConvert(Class type) {
        return type.equals(Action.class);
    }
}</pre>
<p>So when you generate XML for an instance of Action, you call</p>
<pre class="java" name="code">xstream.toXML(action);</pre>
<p>but you still get</p>
<pre class="java" name="code">&lt;Pocket&gt;
  &lt;id&gt;1&lt;/id&gt;
  ...
  &lt;active&gt;true&lt;/active&gt;
&lt;/Pocket&gt;</pre>
<p>These examples show some possibilities for transformation with XStream. To transform old XML into current XML you unmarshal with one XStream instance and marshal with another. XStream is not restricted to generate XML, you can also generate JSON or build your own formats.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/09/marshal-arts-in-xstream/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Top 10 Maven Plugins</title>
		<link>http://www.agimatec.de/blog/2008/08/top-10-maven-plugins/</link>
		<comments>http://www.agimatec.de/blog/2008/08/top-10-maven-plugins/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 07:53:30 +0000</pubDate>
		<dc:creator>Simon Tiffert</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Maven]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=285</guid>
		<description><![CDATA[Whenever you start to build your project with Maven you are using plugins. There are different kinds of plugins: core plugins, packaging types or tool, reporting plugins, tools and plugins to generate IDE configurations. Some of this plugins like clean, compile, install and others you are using everday. Maybe without to know that these are [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-286" href="http://www.agimatec.de/blog/2008/08/top-10-maven-plugins/hot/"><img class="alignleft size-medium wp-image-286" title="hot" src="http://www.agimatec.de/blog/wp-content/uploads/2008/08/hot.jpg" alt="" width="300" height="201" /></a>Whenever you start to build your project with Maven you are using plugins. There are different kinds of plugins: core plugins, packaging types or tool, reporting plugins, tools and plugins to generate IDE configurations.</p>
<p>Some of this plugins like clean, compile, install and others you are using everday. Maybe without to know that these are plugins.</p>
<p>Most of the plugins are highly configurable which helps you in the most situations. Most of the plugins are well documented on their own websites.</p>
<p>In this post I will present our 10 most valuable Maven plugins.</p>
<p><span id="more-285"></span></p>
<p><strong>1.  Maven AntRun Plugin</strong></p>
<p>The <a href="http://maven.apache.org/plugins/maven-antrun-plugin/">Maven AntRun Plugin</a> is the plugin we use whenever we want to do little tasks. Maven is great in solving dependencies, but Ant is very helpful in a lot of situations. Maybe you want to copy files or integrate existing Ant tasks. Yes, you can sit down and write your own Maven plugin in this situations, but then you have to deploy the plugin to all team members and have a lot of overhead in implementing your own plugin. In most situations it is easier to write a few lines of ant configuration in your pom.xml</p>
<p><strong>2. Maven Surefire Plugin</strong></p>
<p>The <a href="http://maven.apache.org/plugins/maven-surefire-plugin/">Maven Surefire Plugin</a> is normally used, when you start the command <em>mvn test</em> or when you are executing a goal which includes the test goal (read more about this in <a href="http://www.agimatec.de/blog/2008/07/maven2-build-livecycle/">Maven2 Build Lifecycle</a>). If you are using the <a href="http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html">standard directory layout</a> of Maven your tests can be found at <em>src/test/java</em>. If there are tests in this directory the Maven Surefire Plugin will automatically run these tests and generate reports including the results in the directory <em>target/surefire-reports</em>. Opposite to the documentation on the plugin page, the Maven Surefire Plugin will run JUnit 3/4 tests as well as <a href="http://maven.apache.org/plugins/maven-surefire-plugin/examples/testng.html">TestNG tests</a>.</p>
<p><strong>3. Maven Site Plugin</strong></p>
<p>The <a href="http://maven.apache.org/plugins/maven-site-plugin/">Maven Site Plugin</a> is used more frequently but maybe not known to everybody. With the Maven Site Plugin you can generate a complete website for your project. All you need to do is to call <em>mvn site</em> and wait for the site to appear in the <em>target </em>directory. If you are developing a public available project, it is maybe all you need to generate your own website. A lot of information is taken from your configuration but you can easily include your own pages and content. We use it to include reports about our code: test results, test coverage, resolved dependencies and many more. For more information about the available reports have a look at the report plugin section on <a href="http://maven.apache.org/plugins/index.html">this page</a>.</p>
<p><strong>4. Maven Archetype Plugin</strong></p>
<p>With the <a href="http://maven.apache.org/plugins/maven-archetype-plugin/">Maven Archetype Plugin</a> you can easily generate a scaffolding of a project. You need a <a href="http://struts.apache.org/2.1.2/docs/struts-maven-archetypes.html">Struts2</a> application? Try out the following code:</p>
<pre class="java" name="code">mvn archetype:create   -DgroupId=tutorial \
                       -DartifactId=tutorial \
                       -DarchetypeGroupId=org.apache.struts \
                       -DarchetypeArtifactId=struts2-archetype-starter \
                       -DarchetypeVersion=2.0.5-SNAPSHOT \
                       -DremoteRepositories=http://people.apache.org/repo/m2-snapshot-repository</pre>
<p>There are archetypes for a lot of project types and you can also build your own project template. We use it to generate a stub for a portlet module with our full technology stack.</p>
<p><strong>5. Maven IDEA Plugin</strong></p>
<p>It can be a pain to configure the IDE with all the required libraries and settings for a project. With the <a href="http://maven.apache.org/plugins/maven-idea-plugin/">Maven IDEA Plugin</a> or the <a href="http://maven.apache.org/plugins/maven-eclipse-plugin/">Maven Eclipse Plugin</a> you can generate <em>ready to start</em> project settings files. It was important until Jetbrains had improved the Maven Support in version 7 of IntelliJ. Maybe it is still helpful for you.</p>
<p><strong>6. Maven Jetty Plugin</strong></p>
<p>When developing Java web applications you often find yourself configuring Tomcat, deploying WAR-files and restarting your Tomcat. With the <a href="http://mojo.codehaus.org/jetty-maven-plugin/usage.html">Maven Jetty Plugin</a> all you need to do is to call <em>mvn jetty:run</em>. It was never so easy to start and develop your Java web projects, because this server is running on the actual files. No copying, no deploying while your are developing. I really like it, because this one is speeding up your daily work.</p>
<p><strong>7. Maven Cargo Plugin</strong></p>
<p>The <a href="http://cargo.codehaus.org/Maven2+plugin">Maven Cargo Plugin</a> is great for getting a container with your artifacts running. You need a JBoss? This plugin can download and start a JBoss. You need to deploy your artifacts and check until the server is started, you can use this plugin. The configuration can be a little tricky and especially when you are using features like container managed security.</p>
<p><strong>8. Maven Dependency Plugin</strong></p>
<p>Most problems with Maven occur in resolving the right dependencies. Often you don&#8217;t know, where the version of a library comes from or why the library is included in your artifact. With the <a href="http://maven.apache.org/plugins/maven-dependency-plugin/">Maven Dependency Plugin</a> you can get all the infos you need:</p>
<ul>
<li>mvn dependency:tree will give you a tree view of the resolved dependencies</li>
<li>mvn dependency:analyze-dep-mgt will find mismatches in your dependencyManagement section</li>
</ul>
<p><strong>9. Maven Javadoc Plugin</strong></p>
<p>The <a href="http://maven.apache.org/plugins/maven-javadoc-plugin/">Maven javadoc Plugin</a> is a reporting plugin and will generate the Javadoc of your project and will include it into the site. Your Maven site can be a central point for your team members to get information about your project. The Javadoc could be one part and it is often very helpful to deploy the Maven site on a central server with your CI builds. If you are developing parts in Javascript there is also a JsDoc plugin available.</p>
<p><strong>10. Maven WAR Plugin</strong></p>
<p>The <a href="http://maven.apache.org/plugins/maven-war-plugin/">Maven WAR Plugin</a> is a of the type packaging and will generate a <em>ready to run</em> WAR file.  If you are using the standard directory layout all you need to do is to declare the type of your project as WAR and call <em>mvn install</em>. You can copy this WAR file into your Java web container (eventually with the Maven AntRun Plugin) and get your application running. Very helpful is the filtering feature of Maven which also works with the WAR plugin. It is very important in this case, because you can&#8217;t change or patch anything, after the WAR file is packaged.</p>
<p><strong>Our plugins</strong></p>
<p>Because we are facing situations where no plugin for a problem is available, we have written some plugin and <a href="http://code.google.com/p/agimatec-maven-plugins/">released it as open source</a>.</p>
<p><a href="http://code.google.com/p/agimatec-maven-plugins/wiki/MavenSizewatchPlugin">Maven Sizewatch Plugin</a>: Include the plugin in the maven &#8220;verify&#8221; or &#8220;install&#8221; phase to check, that an artifact does not exceed a predefined size. This plugin can be useful to check the size of .war archives, that might contain more libs than expected when some transient dependencies have changed.</p>
<p><a href="http://code.google.com/p/agimatec-maven-plugins/wiki/MavenWaitPlugin">Maven Wait Plugin</a>: We&#8217;re doing automated integration tests via Xen containers, so we didn&#8217;t need a full blown cargo installation &#8211; instead we&#8217;ve a full blown JBoss installation with database fresh and ready for tests. The wait plugin just makes sure that tests are started as soon as the server is up and running.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/08/top-10-maven-plugins/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
