<?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; Codegenerierung</title>
	<atom:link href="http://www.agimatec.de/blog/tag/codegenerierung/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>Influencing AJAX-GUIs With Metadata</title>
		<link>http://www.agimatec.de/blog/2009/04/influencing-ajax-guis-with-metadata/</link>
		<comments>http://www.agimatec.de/blog/2009/04/influencing-ajax-guis-with-metadata/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 16:13:43 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[Codegenerierung]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[Portlet]]></category>
		<category><![CDATA[Validierung]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=606</guid>
		<description><![CDATA[This article explains how to create metadata that we use for scaffolding flexible AJAX GUIs . I keep the text as short as possible by providing a step-by-step cookbook based on code examples. What you should know: Metadata for scaffoling your GUI (described here). What you need to compile/run the examples: java1.5 or newer opensource [...]]]></description>
			<content:encoded><![CDATA[<p>This article explains how to create metadata that we use for scaffolding flexible AJAX GUIs . I keep the text as short as possible by providing a step-by-step cookbook based on code examples.</p>
<p>What you should know:</p>
<ul>
<li>Metadata for scaffoling your GUI (described <a title="Generate Your UI Using Metadata " href="http://www.agimatec.de/blog/2009/03/generate-your-ui-using-metadata/">here</a>).<span id="more-606"></span></li>
</ul>
<p>What you need to compile/run the examples:</p>
<ul>
<li>java1.5 or newer</li>
<li><a href="http://code.google.com/p/agimatec-validation/">opensource framework: agimatec-validation</a> : download agimatec-validation.jar</li>
<li>optional: javax.servlet.jar (servlet-api)</li>
<li>optional: <a href="http://code.google.com/p/agimatec-tools/">opensource frameworks/tools: agimatec-tools</a> : download annomark-dist.zip and annogen.jar</li>
</ul>
<p><strong>1. Create model classes</strong></p>
<p>We start with a plain java class, our model, used to transport attributes from the server to the GUI. (You can use <a title="Direct Web Remoting" href="http://directwebremoting.org/">DWR</a> for marshaling object instances between Java and JavaScript/JDOM).</p>
<p><strong>Example class &#8220;Business&#8221;:</strong></p>
<blockquote><p>import javax.persistence.*;</p></blockquote>
<blockquote><p>public class Business {<br />
@Id<br />
@Column(name=&#8221;business_id&#8221;, nullable=false, unique=true)<br />
Long businessId;<br />
@Column(name=&#8221;name&#8221;, nullable=false, unique=true, length=200)<br />
String name;<br />
@Column(name=&#8221;active&#8221;, nullable=false)<br />
boolean active;<br />
// getters, setters follow&#8230;<br />
}</p></blockquote>
<p><strong>2. Write or generate xml meta data</strong></p>
<p>You can write the xml meta data manually, or &#8211; if your classes have javax.persistence.* annotations &#8211; you can generate them using agimatec-tools/annomark.jar (described <a title="annomark explained" href="http://code.google.com/p/agimatec-tools/wiki/annomark">here</a>):</p>
<blockquote><p>&lt;bean id=&#8221;com.agimatec.Business&#8221; impl=&#8221;com.agimatec.Business&#8221;&gt;<br />
&lt;feature key=&#8221;mainKey&#8221;&gt;<br />
&lt;value class=&#8221;string&#8221;&gt;businessId&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;property name=&#8221;businessId&#8221;&gt;<br />
&lt;feature key=&#8221;uniqueKey&#8221;&gt;<br />
&lt;value class=&#8221;boolean&#8221;&gt;true&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;/property&gt;<br />
&lt;property name=&#8221;name&#8221; mandatory=&#8221;true&#8221; maxLength=&#8221;200&#8243;&gt;<br />
&lt;feature key=&#8221;uniqueKey&#8221;&gt;<br />
&lt;value class=&#8221;boolean&#8221;&gt;true&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;/property&gt;<br />
&lt;property name=&#8221;active&#8221; mandatory=&#8221;true&#8221;/&gt;<br />
&lt;/bean&gt;</p></blockquote>
<p>Store the file as &#8220;beaninfos-default.xml&#8221; in the classpath.</p>
<p><strong>2. Access the MetaBean</strong></p>
<p>This requires agimatec-validation.jar to compile:</p>
<blockquote><p>import com.agimatec.validation.MetaBeanManagerFactory;<br />
import com.agimatec.validation.model.MetaBean;</p>
<p>MetaBeanManagerFactory.getRegistry().<br />
addResourceLoader(&#8220;beaninfos-default.xml&#8221;);</p>
<p>MetaBean metabean = MetaBeanManagerFactory.getFinder().findForClass(Business.class);</p></blockquote>
<p><strong>3. Generate JSon for metabean(s)</strong></p>
<p>We want to use the meta data in the AJAX layer, to have information about the properties, their types and additional features (mandatory, max-length, &#8230;) as a JSON formatted string. agimatec-validation offers a JSONGenerator, based on a freemarker template:</p>
<blockquote><p>import com.agimatec.validation.json.JSONGenerator;</p>
<p>JSONGenerator generator = new JSONGenerator();<br />
String json = generator.toJSON(metabean);<br />
System.out.println(json);</p></blockquote>
<p>This prints this JSON string:</p>
<blockquote><p>agimatec.namespace(&#8220;agimatec.metadata&#8221;);</p>
<p>(function(){</p>
<p>var metaBean0 = {<br />
&#8220;id&#8221; : &#8220;com.agimatec.Business&#8221;,<br />
&#8220;beanClass&#8221; : &#8220;com.agimatec.Business&#8221;,<br />
&#8220;name&#8221; : &#8220;Business&#8221;,<br />
&#8220;features&#8221; :{   &#8220;mainKey&#8221; : &#8220;businessId&#8221;},<br />
&#8220;properties&#8221; :{<br />
&#8220;active&#8221;:{<br />
&#8220;name&#8221; : &#8220;active&#8221;,<br />
&#8220;type&#8221; : &#8220;boolean&#8221;,<br />
&#8220;features&#8221; : {       &#8220;mandatory&#8221; : true       }},<br />
&#8220;businessId&#8221;:{<br />
&#8220;name&#8221; : &#8220;businessId&#8221;,<br />
&#8220;type&#8221; : &#8220;long&#8221;,<br />
&#8220;features&#8221; : {       &#8220;uniqueKey&#8221; : true       }},<br />
&#8220;name&#8221;:{<br />
&#8220;name&#8221; : &#8220;name&#8221;,<br />
&#8220;type&#8221; : &#8220;java.lang.String&#8221;,<br />
&#8220;features&#8221; : {       &#8220;maxLen&#8221; : 200,       &#8220;mandatory&#8221; : true,       &#8220;uniqueKey&#8221; : true       }},<br />
&#8220;version&#8221;:{<br />
&#8220;name&#8221; : &#8220;version&#8221;,<br />
&#8220;type&#8221; : &#8220;int&#8221;,<br />
&#8220;features&#8221; : {       }}}};</p>
<p>agimatec.metadata.metaBeans = {&#8220;com.agimatec.Business&#8221; : metaBean0};})();</p></blockquote>
<p><strong>4. Write a servlet to deliver JSON for the AJAX GUI</strong></p>
<p>The java code for the servlet should not be a surprise, for it consists of what we have seen so far:</p>
<blockquote><p>public void init() throws ServletException {<br />
super.init();<br />
MetaBeanManagerFactory.getRegistry().addResourceLoader(&#8220;beaninfos-default.xml&#8221;);<br />
}</p>
<p>public void service(HttpServletRequest servletRequest, HttpServletResponse res)<br />
throws ServletException, IOException {<br />
Map&lt;String, MetaBean&gt; metaBeans = MetaBeanManagerFactory.getFinder().findAll();<br />
// output JSON:<br />
res.setContentType(&#8220;text/javascript&#8221;);<br />
PrintWriter writer = res.getWriter();<br />
String json = new JSONGenerator().toJSON(metaBeans.values());<br />
writer.write(json);<br />
}</p></blockquote>
<p>Thats basically all! With this infrastructure your AJAX GUIs have access to meta information about the model classes.</p>
<p><strong>5. Enrich meta data with information for the GUI-layer</strong></p>
<p>You can enrich the xml meta data with additional hints (field sequence, formats, &#8230;) &#8211; whatever your GUI needs. If hhe additional information cannot be generated automatically, you should keep them in a separate xml-file:</p>
<blockquote><p>&lt;bean id=&#8221;com.agimatec.Business&#8221;&gt;<br />
&lt;feature key=&#8221;DESCRIPTION&#8221;&gt;<br />
&lt;value class=&#8221;string&#8221;&gt;{name}&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;feature key=&#8221;SORTING&#8221;&gt;<br />
&lt;value class=&#8221;list&#8221;&gt;<br />
&lt;string&gt;name&lt;/string&gt;<br />
&lt;string&gt;active&lt;/string&gt;<br />
&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;!&#8211;Visualisation as table&#8211;&gt;<br />
&lt;feature key=&#8221;TABLE_COLUMNS&#8221;&gt;<br />
&lt;value class=&#8221;list&#8221;&gt;<br />
&lt;string&gt;name&lt;/string&gt;<br />
&lt;string&gt;active&lt;/string&gt;<br />
&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;/bean&gt;</p></blockquote>
<p>Save this as &#8220;beaninfos-gui.xml &#8221; in the classpath and register the file in the init() method of the servlet, too:</p>
<blockquote><p>MetaBeanManagerFactory.getRegistry().addResourceLoader(&#8220;beaninfos-gui.xml&#8221;);</p></blockquote>
<p>You see, that the JSON code will contain the additional information as well, because the MetaBeanManager merges them.</p>
<p>So far, we have the infrastructure to support meta data that allows us to build generic AJAX GUIs. The JSON string can be cached, because it will never change while the application is running.</p>
<p><strong>6. User-specific meta data</strong></p>
<p>We can go one step further: We can also support user-specific meta data! A usual requirement in a web application is, that &#8211; depending on the role of a user that is logged in &#8211; field-level permissions must be supported:<br />
User A is allowed to change the &#8220;active&#8221;-state of our &#8220;Business&#8221; entity, while User B has read-only access to the field and the field is hidden for User C, &#8230;</p>
<p>This could also be useful, when a user can customize its GUI (disable fields) by himself or when the application is used by different companies with different settings for their users&#8230;.</p>
<p>How does it work? &#8211; Use additional xml files and merge them in the JSON servlet. (You can also generate the meta beans during runtime programmatically).</p>
<p>beaninfos-role1.xml:</p>
<blockquote><p>&lt;bean id=&#8221;com.agimatec.Business&#8221;&gt;<br />
&lt;property name=&#8221;active&#8221;&gt;<br />
&lt;feature key=&#8221;readonly&#8221;&gt;<br />
&lt;value class=&#8221;boolean&#8221;&gt;true&lt;/value&gt;<br />
&lt;/feature&gt;<br />
&lt;/property&gt;<br />
&lt;/bean&gt;</p></blockquote>
<p>Extension of the servlet:</p>
<blockquote><p>String customInfos = &#8220;beaninfos-role1.xml&#8221;; // determine this from session or request dynamically!<br />
XMLMetaBeanInfos xmlInfos =<br />
new XMLMetaBeanURLLoader(getClass().getResource(customInfos)).load();<br />
Map&lt;String, MetaBean&gt; metaBeans =<br />
MetaBeanManagerFactory.getEnricher().enrichCopies(xmlInfos);</p></blockquote>
<p>The statements after &#8220;// output JSON&#8221; stay the same (see previous code fragment).</p>
<p><strong>More information?</strong></p>
<p>We already got some more posts in German about metadata and code generation, explaining the concepts and giving examples:</p>
<ul>
<li><strong></strong><strong><a title="TransferObjects generieren" href="http://www.agimatec.de/blog/2008/05/transferobjects-generieren/">TransferObjects generieren</a></strong></li>
<li><strong></strong><strong><a title="agimatec-tools als OpenSource auf google.code released!" href="http://www.agimatec.de/blog/2008/06/agimatec-tools-als-opensource-auf-googlecode-released/">agimatec-tools als OpenSource auf google.code released!</a></strong></li>
<li><strong></strong><strong><a title="Statt Modellieren: Annotieren und generieren" href="http://www.agimatec.de/blog/2008/04/statt-modellieren-annotieren-und-generieren/">Statt Modellieren: Annotieren und generieren</a></strong></li>
<li> <strong><a title="Klassen mit Mehrwert: Validierung und Metadaten" href="http://www.agimatec.de/blog/2008/04/klassen-mit-mehrwert-validierung-und-metadaten/">Klassen mit Mehrwert: Validierung und Metadaten</a></strong></li>
</ul>
<p>The open-source frameworks have a WIKI and additional examples or junit testcases, that help you.</p>
<p>If you have questions, do not hesitate to contact us!</p>
<p><span style="color: #333333;"><strong>This is the fifth article in our mini-series about developing highly ajaxified portlets. Other articles are:</strong></span></p>
<ul>
<li><strong><a href="http://www.agimatec.de/blog/2009/03/generate-your-ui-using-metadata/">Generate Your UI Using Metadata </a></strong></li>
<li><strong><a href="http://www.agimatec.de/blog/2009/02/client-side-inter-portlet-communication-done-right/">Inter Portlet Communication</a></strong></li>
<li><strong><a href="http://www.agimatec.de/blog/2009/01/using-yui-to-load-your-javascript-modules/">Using YUI loader for your own javascript modules</a></strong></li>
<li><strong><a href="http://www.agimatec.de/blog/2008/10/advanced_javascript_namespaces_for_portlets/">Portlet namespaces and javascript</a></strong></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2009/04/influencing-ajax-guis-with-metadata/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>agimatec-tools als OpenSource auf google.code released!</title>
		<link>http://www.agimatec.de/blog/2008/06/agimatec-tools-als-opensource-auf-googlecode-released/</link>
		<comments>http://www.agimatec.de/blog/2008/06/agimatec-tools-als-opensource-auf-googlecode-released/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 11:25:31 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[Codegenerierung]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=167</guid>
		<description><![CDATA[Unsere agimatec-tools sind nun als OpenSource Projekt auf google.code veröffentlicht. Wir setzen diese Tools und Frameworks bereits seit über einem Jahr produktiv in unseren Produkten ein. Drei Tools verbergen sich bisher hinter &#8220;agimatec-tools&#8221;: 1. Ein Database-Migration Tool zum setup/alter/check von Datenbanken. Projekte, die eine oder mehrere Datenbanken (oder Datenbanken unterschiedlicher Hersteller) pflegen und weiterentwicklen, können [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.agimatec.de/blog/wp-content/uploads/2008/06/schema.png"><img class="alignnone size-medium wp-image-166" title="agimatec-tools" src="http://www.agimatec.de/blog/wp-content/uploads/2008/06/schema.png" alt="agimatec-tools" width="300" height="254" /></a></p>
<p>Unsere <a href="http://code.google.com/p/agimatec-tools/">agimatec-tools sind nun als OpenSource Projekt auf google.code</a> veröffentlicht.  Wir setzen diese Tools und Frameworks bereits seit über einem Jahr produktiv in unseren Produkten ein.</p>
<p>Drei Tools verbergen sich bisher hinter &#8220;agimatec-tools&#8221;:<span id="more-167"></span></p>
<p>1. Ein Database-Migration Tool zum setup/alter/check von Datenbanken. Projekte, die eine oder mehrere Datenbanken (oder Datenbanken unterschiedlicher Hersteller) pflegen und weiterentwicklen, können mit diesem Werkzeug das Deployment/Upgrade ihrer Datenbanken durchführen und prüfen, ob das Schema vollständig und korrekt ist. (Beispielprojekt anbei)</p>
<p>Das Tool erlaubt auch die Verarbeitung (Parsen, Transformation, Code-Generierung) von SQL-Scripten.</p>
<p>2. Ein Framework zum Datenimport, das es vor allem mit einem Groovy-Script einfach macht, CSV-Dateien, XML-Dateien und andere Textformate zu importieren. (Wir setzen es z.B. gemeinsam mit dem Datenbank-Migration-Tool ein um einen initialen Datenimport aus vom Kunden gelieferten Dateien durchzuführen.)</p>
<p>3. Das Tool &#8220;annomark&#8221; (annnogen+freemarker) zur Generierung von Code durch Annotationen, wie bereits in einem früheren Beitrag angekündigt: &#8220;<a href="http://www.agimatec.de/blog/2008/05/transferobjects-generieren/">TransferObjects generieren</a>&#8220;. Mit Annomark lassen sich flexible Verarbeitungen, nicht nur die Generierung von TransferObjekten, realisieren. (Ein Beispielprojekt demonstriert weitere Möglichkeiten.)</p>
<p>Die Veröffentlichung beinhaltet nicht nur Source und Binaries, sondern bietet auch Beispielprojekte und -templates, die für eigene Maven-Projekte verwendet werden können und umfassend die Verwendung der APIs demonstrieren.  Auf google.code sind die Frameworks jeweils ausführlich im Wiki auf Englisch dokumentiert.</p>
<p>Jetzt sind wir gespannt auf Rückmeldungen und Anregungen und freuen uns, wenn diese Tools dem einen oder anderen weiterhelfen können!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/06/agimatec-tools-als-opensource-auf-googlecode-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>TransferObjects generieren</title>
		<link>http://www.agimatec.de/blog/2008/05/transferobjects-generieren/</link>
		<comments>http://www.agimatec.de/blog/2008/05/transferobjects-generieren/#comments</comments>
		<pubDate>Fri, 16 May 2008 09:09:41 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[Codegenerierung]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=117</guid>
		<description><![CDATA[Für persistente Objekte (Hibernate-POJOs oder Entity-Beans) gilt: über Remote-Schnittstellen werden an Clients nur sogenannte TransferObjects weitergegeben. (J2EE-Pattern hierzu corej2eepatterns/TransferObject) Komisch nur, dass man bei Anwendung dieses Pattern, welches zweifellos wichtig und richtig ist, massiv gegen ein anderes, grundlegendes Softwareentwicklungs-Gebot verstößt: DRY &#8211; don&#8217;t repeat yourself. Oft wird das persistente Modell quasi verdoppelt als TransferObject-Modell. Die [...]]]></description>
			<content:encoded><![CDATA[<p>Für persistente Objekte (Hibernate-POJOs oder Entity-Beans)  gilt: über Remote-Schnittstellen werden an Clients nur sogenannte TransferObjects weitergegeben. (J2EE-Pattern hierzu <a title="Transfer Object" href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html">corej2eepatterns/TransferObject)</a></p>
<p>Komisch nur, dass man bei Anwendung dieses Pattern, welches zweifellos wichtig und richtig ist, massiv gegen ein anderes, grundlegendes Softwareentwicklungs-Gebot verstößt: <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> &#8211; don&#8217;t repeat yourself. Oft wird das persistente Modell quasi verdoppelt als TransferObject-Modell. Die TransferObjekte besitzen allenfalls einige Attribute weniger, bestehen nur aus Getter-Setter-Methoden, implementieren keine Businesslogik und weniger Relationen untereinander.</p>
<p>Wir wollen TransferObjects nutzen ohne DRY zu verletzen, daher bietet es sich an, die TransferObjects durch Codegenerierung zu erzeugen. Wie geht das auf einfache Weise?</p>
<p><span id="more-117"></span></p>
<p>- mit dem kleinen agimatec-Framework &#8220;annomark&#8221;. (siehe auch <a href="http://www.agimatec.de/blog/2008/04/statt-modellieren-annotieren-und-generieren/">Annotieren und Generieren</a>)</p>
<p>In der Praxis finden sich natürlich Alternativen, z.B. durch die Verwendung von Codegeneratoren (<a href="http://de.wikipedia.org/wiki/Modellgetriebene_Softwareentwicklung">MDSD</a>).</p>
<p>Nehmen wir jedoch an, es gibt kein UML-Modell der Klassen.</p>
<p>Nehmen wir auch an, wir wollen die TransferObjekte flexibel abwandeln, z.B.</p>
<ul>
<li>andere Attributtypen als beim persistenten Objekt</li>
<li>Umbenennung von Attributen</li>
<li>Konvertierung zwischen Transfermodell und persistenter Klasse (in beide Richtungen), flexibel konfigurierbar</li>
<li>Wahlweises Weglassen einzelner Relationen und Attributen</li>
<li>&#8220;Flachklopfen&#8221;, d.h. Attribute von Childobjekten in ein flaches Transferobjekt hochziehen</li>
<li>Splitten von Attributen (d.h. das Gegenteil von &#8220;Flachklopfen&#8221;)</li>
<li>unterschiedliche Transferobjekte aus einer Klasse generieren (je nach Use-Case, z.B. Anzeigeobjekt, Bearbeitungsobjekt, &#8230;)</li>
<li>Aus Getter-Methods des persistenten Objekts Attribute im Transferobjekt erzeugen</li>
</ul>
<p>Dazu einige Beispiele, wie annomark dies ermöglicht. Wer hier eigenen Bedarf sieht, kann sich gerne melden, denn wir würden das Framework, das sich leicht in ant und maven Projekte integrieren läßt, dann als OpenSource Projekt veröffentlichen. Jetzt aber mal ein paar kurze Beispiele:</p>
<pre name="code" class="java">/** persistent class PostOffice **/
@DTOs({@DTO(usage = "edit"), @DTO(usage = "view")})
public class PostOffice {
    @DTOAttribute(type="Long", property="postOfficeId")
    private long id;
    private int version;
    /** Bezeichnung der Filiale **/
    @DTOAttribute
    private String name;
    @DTOAttribute(usage="edit")
    private String description;
    @DTOAttribute
    private Address address;

    // Getters and Setters ...
}
</pre>
<p>Wie wird sich das generierte TransferObjekt von class PostOffice unterscheiden?</p>
<ul>
<li>der Typ des &#8220;id&#8221; Attributes wird von primitive &#8220;long&#8221; auf die Wrapper-Class &#8220;Long&#8221; geändert (und kann damit null sein)</li>
<li>der Name des &#8220;id&#8221; Attributes wird &#8220;postOfficeId&#8221; sein
<li>das Attribut &#8220;version&#8221; wird im TransferObjekt nicht enthalten sein, da es nicht annotiert ist</li>
<li>das Attribut &#8220;description&#8221; wird nur im TransferObjekt für Bearbeitung enthalten sein. Zur reinen Anzeige kann eine andere Transferklasse erzeugt werden, in der &#8220;description&#8221; fehlt.</li>
<li>die Beziehung zum &#8220;Address&#8221; Objekt wird in eine Beziehung zum TransferObjekt für Address gewandelt (sofern für Address ein eigenes Transferobjekt erzeugt wird)</li>
<li>Java-Doc Kommentare werden übernommen und zusätzliche generiert.
</ul>
<p>Was kommt heraus? (Beispiel: Bearbeitungs-Transferobjekt)</p>
<pre name="code" class="java">
public class TransferPostOffice {
  /**
  * source: id
  **/
  private Long postOfficeId;
  /**
  * source: name
  * Bezeichnung der Filiale
  **/
  private String name;
  /**
  * source: description
  **/
  private String description;
  /**
  * source: address
  **/
  private TransferAddress address;

  // Getters and Setters aus Platzgründen weggelassen...
}
</pre>
<p>Weitere Möglichkeiten lassen sich am Source der @DTOAttribute-Annotation erahnen:</p>
<pre name="code" class="java">
@Retention(RetentionPolicy.SOURCE)
@Target(value = {ElementType.FIELD, ElementType.METHOD})
public @interface DTOAttribute {
    // reference to DTO.usage (when multiple DTO annotations exist per class)
    String usage() default "";
    // Reflector.path to take the attribute of the pojo FROM
    String path() default "";
    // name of the pojo.property to write the value TO
    String property() default "";
    // for dozer-mapping: name of a Converter class
    String converter() default "";
    // for dozer-mapping: true when call-by-reference
    boolean copyByReference() default false;
    // for dozer-mapping: true when one-way
    boolean oneWay() default false;
    // the type of the property, default is the same type as origin's
    String type() default "";
    // iterate-type setter method
    String addMethod() default "";
}
</pre>
<p>Alles, was nicht über die Annotation eingestellt wird, kann direkt im freemarker-Template (30 Zeilen groß) geändert werden, welches die eigentliche Codegenerierung durchführt.</p>
<p>Aber, wie sieht der Aufruf aus (z.B. aus Maven2 heraus)?</p>
<pre name="code" class="xml">
<java classname="org.codehaus.gram.Gram" fork="true">
  <classpath refid="maven.test.classpath"/>
  <arg value="${basedir}/src/main/java"></arg>
  <arg value="src/main/groovy/Launcher.groovy"></arg>
</java>
</pre>
<p>Anstelle vieler Parameter ruft das Groovyscript &#8220;Launcher.groovy&#8221; die Generierung auf und gibt dabei weitere Parameter an:</p>
<pre name="code" class="java">
import java.util.*;
import com.agimatec.annotations.jam.*;
import com.agimatec.annotations.*;
def dtoClasses = new HashSet();
dtoClasses.addAll(classes.findAll { it.getAnnotation(DTO.class) != null });
dtoClasses.addAll(classes.findAll { it.getAnnotation(DTOs.class) != null });
generator = new JAMDtoGenerator();
generator.setTemplateDir("annomark/templates");
generator.addInstruction("java-pojo", "target/generated-src", null)
    .setUsageQualifier("edit")
    .setPrefix("Transfer")
    .setSuffix(".java")
    .setDefaultPackage("com.agimatec.model.transfer");
</pre>
<p>Die Konvertierung zwischen Transferobjekt und Sourceobjekt erledigt Dozer. Die Konfiguration für Dozer generiert ein weiteres Template.</p>
<pre name="code" class="java">
generator.addInstruction("dozer-mapping", "target/generated-resources", "dozerMapping-generated.xml")
    .setUsageQualifier("edit")
    .setPrefix("Transfer")
    .setSuffix(".xml")
    .setDefaultPackage("com.agimatec.model.transfer");
</pre>
<p>Unsere Metadaten zur Validierung sowie die View-Transferklassen generieren wir mit weiteren Template.</p>
<p>Über Meinungen hierzu freuen wir uns!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/05/transferobjects-generieren/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Statt Modellieren: Annotieren und generieren</title>
		<link>http://www.agimatec.de/blog/2008/04/statt-modellieren-annotieren-und-generieren/</link>
		<comments>http://www.agimatec.de/blog/2008/04/statt-modellieren-annotieren-und-generieren/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 14:49:58 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[Codegenerierung]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/blog/?p=59</guid>
		<description><![CDATA[Viele Projekte modellieren die Domain-Klassen mit einem UML-Tool. Im Idealfall ist das Tool so mächtig, dass auch die Tabellen der Datenbank daraus generiert werden können &#8211; mit allen Eigenschaften (Tablespaces, Berechtigungen, Sequences etc.). Diesen Idealfall habe ich aber bisher kaum erlebt. Meist werden die SQL-Scripte noch manuell angepaßt oder ergänzt, wenn das UML-Tool nicht alle [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.agimatec.de/blog/wp-content/uploads/2008/04/istock_000005025824xsmall.jpg"><img class="alignleft size-medium wp-image-61" style="float: left;" title="istock_000005025824xsmall" src="http://www.agimatec.de/blog/wp-content/uploads/2008/04/istock_000005025824xsmall.jpg" alt="" width="220" height="300" /></a>Viele Projekte modellieren die Domain-Klassen mit einem UML-Tool. Im Idealfall ist das Tool so mächtig, dass auch die Tabellen der Datenbank daraus generiert werden können &#8211; mit allen Eigenschaften (Tablespaces, Berechtigungen, Sequences etc.). Diesen Idealfall habe ich aber bisher kaum erlebt. Meist werden die SQL-Scripte noch manuell angepaßt oder ergänzt, wenn das UML-Tool nicht alle SQL-Features der genutzten Datenbank direkt ausspuckt. Genauso oft wird umgekehrt verfahren: Die Datenbank wird mit einem ER-Tool modelliert und die SQL-Scripte generiert. Dann müssen die Hibernate-Mappings oder Entity-Klassen samt EJB3- und Hibernate-Annotations dazu passend manuell erstellt werden. Erzähle mir jetzt bitte keiner, dass die von Hibernate generierten Domain-Klassen fehlerfrei und ohne Änderungen genutzt werden können (&#8230; für Anpassungen ist der Hibernate Codegenerator nicht gut ausgelegt).</p>
<p>OK, alternativ kann eine MDA-Plattform (z.B. <a href="http://www.openarchitectureware.org/">openArchitectureWare</a>) genutzt und die Templates den speziellen Bedürfnissen anpasst werden. Da unser Projekt eben kein MDA-Projekt ist und wir auch keinen Schwenk in diese Richtung geplant haben, fiel diese Möglichkeit weg.</p>
<p>Wir generieren dennoch eine Menge (Java, XML, Scripts etc.) und fahren gut damit. Dadurch bleiben große Teile des Systems automatisch konsistent. Anfangs wurde im Projekt wenig generiert, vieles redundant gepflegt. So nach und nach haben wir geeignete Kandidaten erkannt und durch generierte Artefakte ersetzt &#8211; schrittweise. Über die Erfahrungen und Tools, die dabei entstanden sind, möchte ich berichten.<span id="more-59"></span></p>
<p>Zunächst ein grober Überblick, was wir derzeit generieren:</p>
<p><a href="http://www.agimatec.de/blog/wp-content/uploads/2008/04/code_gen_overview.jpg"><img class="aligncenter size-full wp-image-60" src="http://www.agimatec.de/blog/wp-content/uploads/2008/04/code_gen_overview.jpg" alt="Übersicht Codegenerierung" width="576" height="582" /></a></p>
<ul>
<li>Die Datenbank modellieren wir für Postgres mit dem netten kleinen Tool <a href="http://www.datanamic.com/dezign/index.html" target="_blank">DeZign.</a><br />
Leider speichert es das ER-Model nur im proprietären Format (kein XMI) oder generiert SQL-Scripte.</li>
<li>Wir parsen mit unserem &#8220;dbtool&#8221; die SQL-Scripte und generieren mit Freemarker-Templates:
<ul>
<li>SQL-Scripte für Oracle (d.h. wir führen eine Transformation der Datentypen etc. durch)</li>
<li>SQL-Scripte für Tabellen mit historischen Daten und zugehörige Trigger (unterschiedlich für Oracle und Postgres)</li>
<li>Java-Klassen, annotiert als EJB3 Entities für Hibernate. Diese werden jedoch später manuell angepaßt!</li>
</ul>
</li>
<li>Aus den angepaßten EJB3-Klassen generieren wir:
<ul>
<li>Data-Transfer-Klassen (Value-Objects) zur Bearbeitung der Daten (&#8220;CRUD&#8221;)</li>
<li>Abgespeckte Data-Transfer-Klassen zur reinen Anzeige (&#8220;Light&#8221;)</li>
<li>XML-Dateien mit <a href="http://www.agimatec.de/blog/2008/04/klassen-mit-mehrwert-validierung-und-metadaten/">Metadaten </a>(&#8220;mandatory&#8221;, &#8220;maxLength&#8221;, &#8220;default value&#8221;, &#8220;readonly&#8221;, &#8220;unique&#8221;, &#8230;)</li>
<li>XML-Dateien für den <a href="http://dozer.sourceforge.net/">Dozer-Mapper</a>, der zwischen Entities und DTO-Instanzen mappen/kopiert.</li>
</ul>
</li>
</ul>
<p>Für unsere Clients sind nur die DTO-Klassen sichtbar, nicht die Entities. Zur Generierung verwenden wir nur <a href="http://www.freemarker.org/" target="_blank">Freemarker</a>-Templates, da diese bereits vielen Entwicklern verständlich waren. Wenn weitere Artefakte generiert werden sollen, kann dies ohne Änderung der Generator-Frameworks erfolgen.</p>
<p>Zwei &#8220;Tricks&#8221; sind es, die hierbei die Arbeit erheblich erleichtern und die weitere Blog-Posts wert sind:</p>
<ol>
<li>Um vom ER-Tool unabhängig zu sein, verarbeiten wir die SQL-Scripte von DeZign als Input für die Generierung. Wir brauchen daher etwas Ähnliches wie einen SQL-Parser und ein Modell, um die Struktur der Datenbank abzubilden. Dieses Modell geht in die Freemarker-Templates ein und liefert die Informationen für die Generierung. Also mußte ein Framework dafür her: &#8220;<strong>dbtool</strong>&#8221; &#8211; auch bald OpenSource, sobald ich dazu komme. (Bei Interesse gerne nachfragen, dann geht es schneller. :-) )</li>
<li>Für die EJB3-Klassen haben wir &#8211; außer dem Java-Source, den wir um eigene Annotations &#8220;aufhübschen&#8221; &#8211; kein (UML-)Modell. Wir parsen daher die Klassen und nutzen die Annotations, um daraus ein Modell zu erzeugen, was mit Freemarker verarbeitet wird. Dieses Framework &#8211; auch als OpenSource geplant (s.o.) &#8211; nannten wir &#8220;<strong>annomark</strong>&#8220;, da es i.W. (neben Freemarker) auf <a href="http://docs.codehaus.org/display/GROOVY/Gram" target="_blank">Gram (Groovy+JAM)</a> und <a href="http://annogen.codehaus.org/" target="_blank">Annogen</a> basiert. Diese Projekte sollte man sich einmal anschauen, obwohl es hier leider schon länger keine neuen Releases gegeben hat.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/04/statt-modellieren-annotieren-und-generieren/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Klassen mit Mehrwert: Validierung und Metadaten</title>
		<link>http://www.agimatec.de/blog/2008/04/klassen-mit-mehrwert-validierung-und-metadaten/</link>
		<comments>http://www.agimatec.de/blog/2008/04/klassen-mit-mehrwert-validierung-und-metadaten/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 17:30:32 +0000</pubDate>
		<dc:creator>roman.stumm</dc:creator>
				<category><![CDATA[Deutsch]]></category>
		<category><![CDATA[Codegenerierung]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Validierung]]></category>

		<guid isPermaLink="false">http://www.agimatec.de/wordpress/?p=42</guid>
		<description><![CDATA[In einer mehrschichtigen Anwendung gibt es &#8211; bei aller Entkopplung der einzelnen Layer &#8211; immer Informationen, die den Objekten mit auf den Weg gegeben werden können von ganz &#8220;unten&#8221; (Datenbank) bis nach &#8220;oben&#8221; (GUI): z.B. Feldlänge, Pflichtfelder, Eindeutigkeit, Formattierungsvorschriften u.v.m. Diese zusätzliche Semantik der Klassen kann für diverse Verwendungszwecke als Metadaten abgelegt werden, aber wie [...]]]></description>
			<content:encoded><![CDATA[<p style="0cm;">In einer mehrschichtigen Anwendung gibt es &#8211; bei aller Entkopplung der einzelnen Layer &#8211;  immer  Informationen, die den Objekten mit auf den Weg gegeben werden können von ganz &#8220;unten&#8221; (Datenbank) bis nach &#8220;oben&#8221; (GUI): z.B. Feldlänge, Pflichtfelder, Eindeutigkeit, Formattierungsvorschriften u.v.m.</p>
<p style="0cm;">Diese zusätzliche Semantik der Klassen kann für diverse Verwendungszwecke als Metadaten abgelegt werden, aber wie und wozu?</p>
<p style="0cm;">Die bekannten Ansätze fokussieren meist ausschließlich auf die Validierung von Objekten (z.B. das altgediente commons-validator, das seine Struts-Wurzeln nie leugnen konnte, der Hibernate-Validator, aus dessen Ecke nun die JSR 303 (bean-validation) entsprungen ist und andere Exoten).</p>
<p style="0cm;">Gleich vorweg: mit JSR 303 wird endlich eine Lücke für einen Standard zur Definition von Constraints mit Hilfe von Annotations geschlossen.</p>
<p style="0cm;">Wir, ansonsten fleißige <a title="Open Source Wilderer" href="http://www.agimatec.de/wordpress/?p=6" target="_self">Open Source Nutzer</a>, haben uns vor über einem Jahr entschlossen, ein neues Validation-Framework zu entwicklen, um Metadaten flexibel definieren zu können. Nebenbei implementiert es bereits jetzt als vollständiges bean-validation framework die als Draft vorhandene JSR 303.</p>
<p style="0cm;"><span id="more-42"></span></p>
<p style="0cm;">
<p style="0cm;"><strong>Wie hätten Sie Ihre Metadaten denn gerne&#8230;</strong></p>
<p style="0cm;">
<p style="0cm;"><strong>a) als Annotations an den POJO-Klassen?</strong></p>
<p style="0cm;">So standardisiert es JSR 303. Beispiele erübrigen sich hier, ausführliche Erläuterungen gibt es z.B. bei <a title="Bloggers/BeanValidationSneakPeekPartIIIGroupsAndPartialValidation" href="http://in.relation.to/Bloggers/BeanValidationSneakPeekPartIIIGroupsAndPartialValidation" target="_blank">Bloggers/BeanValidationSneakPeekPartIIIGroupsAndPartialValidation</a></p>
<p style="0cm;">
<p style="0cm;"><strong>b) als XML-Dateien oder aus der Datenbank?</strong></p>
<p style="0cm;">Das hat den Vorteil, dass an den Klassen nichts geändert werden braucht (z.B. wenn diese generiert werden) und dass die Metadaten einer Klasse aus mehreren XML-Files zusammengesetzt werden (Dekoration). Sie können auch zur Laufzeit geändert werden.</p>
<p style="0cm;"><strong>c) dynamisch angefragt von einem Webservice?</strong></p>
<p style="0cm;">Dadurch können die Metadaten im Server gepflegt und benutzerspezifisch zurückgegeben werden, was z.B. zur Folge hat, dass manche Felder nach einem Benutzerwechsel readonly werden, ausgeblendet werden, usw.</p>
<p style="0cm;"><strong>d) eine Kombination aus a-c &#8230;</strong></p>
<p style="0cm;">&#8230; gewürzt mit neuen Ideen?</p>
<p style="0cm;">
<p style="0cm;"><strong>Jetzt noch schnell ein Crashkurs mit Source-Beispielen:</strong></p>
<p style="0cm;">Wer mehr sehen will, kann sich der Test-Sourcen oder des Wikis bedienen (siehe <a href="http://code.google.com/p/agimatec-validation/">agimatec-validation</a>).</p>
<p style="0cm;">
<p style="0cm;"><strong>Wir geben ein paar Metadaten für Klasse &#8220;com.sample.Customer&#8221; an:</strong></p>
<pre>&lt;beanInfos&gt;
&lt;bean id="com.sample.Customer"&gt;
&lt;feature key="tooltip"&gt;&lt;value class="string"&gt;König Kunde&lt;/value&gt;&lt;/feature&gt;
&lt;property name="firstName" maxLength="40"/&gt;
&lt;property name="identification"&gt;
&lt;feature key="readonly"&gt;&lt;value class="boolean"&gt;true&lt;/value&gt;&lt;/feature&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/beanInfos&gt;</pre>
<p style="0cm;">Fener besteht die Möglichkeit mit &lt;relationship/&gt; auch ganze Objektnetze zu definieren. Die üblichen Constraints (maxLength, mandatory) sind vordefinierte Attribute. Frei  wählbar sind  weitere &#8220;Features&#8221;, die an der Klasse oder einer Property hängen können.</p>
<p style="0cm;">
<p style="0cm;">Gerade die Standardconstraints können z.B. schon in den javax.persistence-Annotations (@Column) etc. bei den EJB3-Entites definiert worden sein. Wir schreiben Code ungern doppelt, daher generieren wir die XML der &lt;beanInfos&gt; mit diesen Informationen automatisch (aber zu Codegenerierung ein andermal mehr).</p>
<p style="0cm;">
<p style="0cm;"><strong>Wie verwendet man Metainformationen?</strong></p>
<p style="0cm;">
<p style="0cm;"><strong>Initialisierung</strong></p>
<p style="0cm;">Angenommen, die XML-Datei liegt als &#8220;beanInfos.xml&#8221; im Classpath, dann können die darin enthaltenen Definitionen so registiert werden:</p>
<pre>MetaBeanManagerFactory.getRegistry().addResourceLoader("beanInfos.xml");</pre>
<p style="0cm;">In der Reihenfolge der Registierung werden die Informationen verarbeitet. Mehrere XML-Dateien können dabei nacheinander das gleiche Bean (gleiche &lt;bean id=&#8221;"/&gt;) ergänzen &#8211; der Letzte gewinnt.</p>
<p style="0cm;">
<p style="0cm;"><strong>Verwendung</strong></p>
<p style="0cm;">Nur einige Beispiele&#8230;</p>
<p style="0cm;">
<p>1. Zugriff auf die Metadaten ohne Validierung</p>
<pre>MetaBeanFinder finder = MetaBeanManagerFactory.getFinder();
MetaBean metaBean = finder.findForId("com.sample.Customer");
String tooltip = metaBean.getFeature("tooltip");</pre>
<p style="0cm;">2. Überprüfung, ob eine Instanz den Constraints entspricht (klassische Validierung):</p>
<pre>Customer object = //... von woher auch immer;
BeanValidator validator = new BeanValidator();

ValidationResults results = validator.validate(object, metaBean);
if(!results.isEmpty()) { // Fehler gefunden }</pre>
<p style="0cm;">
<p style="0cm;">3. Validierung der Parameter eines Methodenaufrufs bei Aufruf eines Webservice:</p>
<p style="0cm;">Das Interface:</p>
<pre>import com.agimatec.utility.validation.integration.Validate;

@javax.jws.WebService
interface MyWebservice {
@Validate void saveCustomer(@Validate Customer customer);
}</pre>
<p>Die Validierung:</p>
<pre>Method m = // saveCustomer
Object[] params =  // Array Parametern</pre>
<p>ValidationResults results = validator.validateCall(m, params);</p>
<p>4. Aus den Metadaten einen JSON String für eine AJAX GUI erzeugen</p>
<pre>JSONGenerator jsonGenerator = new JSONGenerator();
String jsonString = jsonGenerator.toJSON(MetaBean metaBean);
String jsonStringAll = jsonGenerator.toJSON(finder.findAll().values());</pre>
<p>In einem Servlet kann für einzelne oder alle Beans so die Metainformation ausgegeben werden.</p>
<p>Seitdem wir erst einmal diese Grundlagen im Griff hatten, sind uns noch mehr Einsatzmöglichkeiten für Metainformationen eingefallen, die zur Steigerung unserer Produktivität, besserem Abstraktionsniveau in der Software und Schrumpfung in den Sourcen geführt haben.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agimatec.de/blog/2008/04/klassen-mit-mehrwert-validierung-und-metadaten/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
