<?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/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>Building Blocks &#187; lcds</title>
	<atom:link href="http://joelhooks.com/category/lcds/feed/" rel="self" type="application/rss+xml" />
	<link>http://joelhooks.com</link>
	<description>if there's one thing I know about me and my thoughts: given enough time I'm always wrong</description>
	<lastBuildDate>Tue, 29 Jun 2010 18:45:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/us/</creativeCommons:license>
		<item>
		<title>Custom JDBC (MySQL) Realm Authentication with Livecycle Data Services (or BlazeDS)</title>
		<link>http://joelhooks.com/2008/08/27/custom-jdbc-mysql-realm-authentication-with-livecycle-data-services-or-blazeds/</link>
		<comments>http://joelhooks.com/2008/08/27/custom-jdbc-mysql-realm-authentication-with-livecycle-data-services-or-blazeds/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 01:44:31 +0000</pubDate>
		<dc:creator>Joel</dc:creator>
				<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[lcds]]></category>

		<guid isPermaLink="false">http://joelhooks.com/?p=73</guid>
		<description><![CDATA[LCDS ships with the default Tomcat roles based security ready to go. You simply add some users to the tomcat-users.xml and there you go. This is probably fine for some, but for my needs I want to be able to authenticate against a MySQL database. I addition, I want to use strong encryption to protect [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter size-full wp-image-80" title="lcds" src="http://69.164.207.135/wp-content/uploads/2008/08/images.jpg" alt="" width="104" height="104" /></p>
<p>LCDS ships with the default Tomcat roles based security ready to go. You simply add some users to the tomcat-users.xml and there you go. This is probably fine for some, but for my needs I want to be able to authenticate against a MySQL database. I addition, I want to use strong encryption to protect my users personal information, as well as potentially sensitive business data. In this article I am going to explain how to configure Tomcat and Livecycle Data Services to do just that. It is actually fairly painless, once you get all the pieces put together. Hopefully this will be an area of the LCDS documentation that will get some attention in the future.</p>
<p>There are many robust frameworks available to Java that provide authentication functionality. In addition to that, they provide a level of complexity that I want to avoid. My primary purpose is creating enterprise Flex/AIR applications with a strong service layer provided by LCDS. I simply don't want to learn the intrict workings of Spring, JBoss Websphere, or any of the other fine solutions that might solve this particular problem. What I want is a simple solution that provides the functionality I need without a host of extra features I won't ever use. My finite capacity for new information needs all the filtering it can get.</p>
<p><span id="more-73"></span></p>
<p><em>The following assumes you are using the turnkey Tomcat LCDS installation.</em></p>
<h3><strong>Setting up the MySQL Database</strong></h3>
<p>Any JDBC connectable database solution should work, so long as the proper tables are in place. MySQL is used in this example simply for convenience.</p>
<p>Tomcat's <a href="http://linux-sxs.org/internet_serving/c619.html">realms</a> (discussed below) require some specific tables in your database. It needs a User table that identifies the users and their passwords. In addition, there needs to be a user_roles table that corresponds to each user and their role(s) in the application.</p>

<div class="wp_codebox"><table><tr id="p7310"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code" id="p73code10"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">create</span> <span style="color: #993333; font-weight: bold;">table</span> users <span style="color: #66cc66;">&#40;</span>
  username         varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">not</span> <span style="color: #993333; font-weight: bold;">null</span> <span style="color: #993333; font-weight: bold;">primary</span> <span style="color: #993333; font-weight: bold;">key</span><span style="color: #66cc66;">,</span>
  password         varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">not</span> <span style="color: #993333; font-weight: bold;">null</span>
<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">create</span> <span style="color: #993333; font-weight: bold;">table</span> user_roles <span style="color: #66cc66;">&#40;</span>
  username          varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">not</span> <span style="color: #993333; font-weight: bold;">null</span><span style="color: #66cc66;">,</span>
  role              varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">not</span> <span style="color: #993333; font-weight: bold;">null</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">primary</span> <span style="color: #993333; font-weight: bold;">key</span> <span style="color: #66cc66;">&#40;</span>username<span style="color: #66cc66;">,</span> role<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>);</p>
<p>The above would be the be sufficient to provide JDBCRealm the information it needs for authentication. While I'm sure it would be possible to extend the JDBC realm further than I do in this walk-through</p>
<h3><strong>Configuring the Realm</strong></h3>
<p>Tomcat implements realms for security. At its simplest form we have the <a href="http://tomcat.apache.org/tomcat-5.5-doc/catalina/docs/api/org/apache/catalina/realm/RealmBase.html">RealmBase</a> class. This provides the functionality to parse simple XML files for users, passwords, and roles. In addition, there is a realm class <a href="http://tomcat.apache.org/tomcat-5.5-doc/catalina/docs/api/org/apache/catalina/realm/JDBCRealm.html">JDBCRealm</a>. This realm is a lot closer to what we actually need, and would probably be sufficient in many cases. While the JDBCRealm provides for the digesting of passwords into encrypted hashes for storage in the databse, I want to use a more robust encryption solution. <a href="http://www.jasypt.org/">Jasypt (Java Simplified Encryption)</a> provides this, as well as transparent integration with Hibernate. This lets me put user's passwords in the database with salted hashes, and also provides the flexibility to encrypt virtually any other field in my data model.</p>
<p>To facilitate this addition, we need to extend the JDBCRealm, overriding the authenticate method to remove the default digest calls and replace them with the Jasypt StrongPasswordEncryptor.</p>

<div class="wp_codebox"><table><tr id="p7311"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
</pre></td><td class="code" id="p73code11"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">realm</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.catalina.realm.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.commons.logging.Log</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.commons.logging.LogFactory</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.security.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.Connection</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.ArrayList</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.jasypt.util.password.StrongPasswordEncryptor</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MyRealm <span style="color: #000000; font-weight: bold;">extends</span> JDBCRealm <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> Log containerLog <span style="color: #339933;">=</span> LogFactory.<span style="color: #006633;">getLog</span><span style="color: #009900;">&#40;</span>SAIRealm.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      StrongPasswordEncryptor passwordEncryptor <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> StrongPasswordEncryptor<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      @Override
      <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">synchronized</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aprincipal+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Principal</span></a> authenticate<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aconnection+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Connection</span></a> dbConnection,
                                                 <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> username,
                                                 <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> credentials<span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>username <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                  <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
            <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> dbCredentials <span style="color: #339933;">=</span> getPassword<span style="color: #009900;">&#40;</span>username<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000066; font-weight: bold;">boolean</span> validated <span style="color: #339933;">=</span> passwordEncryptor.<span style="color: #006633;">checkPassword</span><span style="color: #009900;">&#40;</span>credentials, dbCredentials<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>validated<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>containerLog.<span style="color: #006633;">isTraceEnabled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                       containerLog.<span style="color: #006633;">trace</span><span style="color: #009900;">&#40;</span>sm.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jdbcRealm.authenticateSuccess&quot;</span>,
                       username<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>containerLog.<span style="color: #006633;">isTraceEnabled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                       containerLog.<span style="color: #006633;">trace</span><span style="color: #009900;">&#40;</span>sm.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jdbcRealm.authenticateFailure&quot;</span>,
                       username<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                  <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
            ArrayList<span style="color: #339933;">&lt;</span>string<span style="color: #339933;">&gt;</span> roles <span style="color: #339933;">=</span> getRoles<span style="color: #009900;">&#40;</span>username<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> GenericPrincipal<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>, username, credentials, roles<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>This class needs to be compiled and placed into a Jar (FlexBuilder/Exlipse makes this easy through the file>export menu). The compiled class can now be added to the {lcds}/tomcat/lib folder so that it will be available to the server.</p>
<p>Now that we've added our custom realm to the server, we need to add it to the configuration files so that it is recognized.</p>
<p>In {lcds}\tomcat\conf\server.xml find the existing realm, and remove it (this might be something you can configure, multiple realms, but I didn't figure it out and don't need the stock XML database so I just killed it):</p>

<div class="wp_codebox"><table><tr id="p7312"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p73code12"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;engine</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Catalina&quot;</span> <span style="color: #000066;">defaultHost</span>=<span style="color: #ff0000;">&quot;localhost&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      ...
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;realm</span> <span style="color: #000066;">className</span>=<span style="color: #ff0000;">&quot;realm.MyRealm&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">debug</span>=<span style="color: #ff0000;">&quot;99&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">driverName</span>=<span style="color: #ff0000;">&quot;com.mysql.jdbc.Driver&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">connectionURL</span>=<span style="color: #ff0000;">&quot;jdbc:mysql://localhost/mydatabase?user=dbUsername&amp;amp;password=dbPassword&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">userTable</span>=<span style="color: #ff0000;">&quot;user&quot;</span> <span style="color: #000066;">userNameCol</span>=<span style="color: #ff0000;">&quot;username&quot;</span> <span style="color: #000066;">userCredCol</span>=<span style="color: #ff0000;">&quot;password&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">userRoleTable</span>=<span style="color: #ff0000;">&quot;user_roles&quot;</span> <span style="color: #000066;">roleNameCol</span>=<span style="color: #ff0000;">&quot;role&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      ...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/engine<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>In addition, your application's context file needs to supply information about the realm:</p>
<p>{lcds}/tomcat/conf/Catalina/localhost/{application_context}.xml</p>

<div class="wp_codebox"><table><tr id="p7313"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p73code13"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;realm</span> <span style="color: #000066;">className</span>=<span style="color: #ff0000;">&quot;realm.MyRealm&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">debug</span>=<span style="color: #ff0000;">&quot;99&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">driverName</span>=<span style="color: #ff0000;">&quot;com.mysql.jdbc.Driver&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">connectionURL</span>=<span style="color: #ff0000;">&quot;jdbc:mysql://localhost/mydatabase?user=dbUsername&amp;amp;password=dbPassword&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">userTable</span>=<span style="color: #ff0000;">&quot;user&quot;</span> <span style="color: #000066;">userNameCol</span>=<span style="color: #ff0000;">&quot;username&quot;</span> <span style="color: #000066;">userCredCol</span>=<span style="color: #ff0000;">&quot;password&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">userRoleTable</span>=<span style="color: #ff0000;">&quot;user_roles&quot;</span> <span style="color: #000066;">roleNameCol</span>=<span style="color: #ff0000;">&quot;role&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;valve</span> <span style="color: #000066;">className</span>=<span style="color: #ff0000;">&quot;flex.messaging.security.TomcatValve&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></td></tr></table></div>

<p>I don't know if the additional database information is actually neccessary here, but it doesn't hurt anything, so there it is. This is also the place to define the Tomcat Valce so that Flex/LCDS can communicate with our custom realm. Note that it is important to FULLY qualify your classname for both the custom realm and the database connector classes.</p>
<h3><strong>Configuring the Services</strong></h3>

<div class="wp_codebox"><table><tr id="p7314"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p73code14"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;security<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;login-command</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;flex.messaging.security.TomcatLoginCommand&quot;</span> <span style="color: #000066;">server</span>=<span style="color: #ff0000;">&quot;Tomcat&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;per-client-authentication<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>false<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/per-client-authentication<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/login-command<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;security-constraint</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;jdbc-auth&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;auth-method<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Custom<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/auth-method<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;roles<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;role<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>super<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/role<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;role<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>admin<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/role<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;role<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>user<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/role<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;role<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>client<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/role<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/roles<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/security-constraint<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/security<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>This is the basic configuration. Now you simply need to add the security tag to your destinations to enable.</p>

<div class="wp_codebox"><table><tr id="p7315"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p73code15"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;destination</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;SecurePojo1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        ...
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;security<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;security-constraint</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;jdbc-auth&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/security<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/destination<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>You can also apply the constraint globally.</p>

<div class="wp_codebox"><table><tr id="p7316"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p73code16"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;service<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
     ...
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;default-security-constraint</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;jdbc-auth&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/service<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>or to individual methods</p>

<div class="wp_codebox"><table><tr id="p7317"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p73code17"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;destination</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;sampleIncludeMethods&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;properties<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;source<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>my.company.SampleService<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/source<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;include-methods<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;method</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;fooMethod&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;method</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;barMethod&quot;</span> <span style="color: #000066;">security-constraint</span>=<span style="color: #ff0000;">&quot;jdbc-auth&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/include-methods<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/properties<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;security<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;security-constraint</span> <span style="color: #000066;">ref</span>=<span style="color: #ff0000;">&quot;jdbc-auth&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/security<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/destination<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<h3><strong>The Client</strong></h3>
<p>All of the complex bits are now taken care of. When you try to access a tagged destination you are flatly denied. To authenticate from Flex, your ChannelSet will need to login to the service. I use AIR, so I define my ChannelSets in the application, but Flex apps will automagically configure this for you and they are 'hidden'. To get at your ChannelSet in flex you need to use the ServerConfig class:</p>

<div class="wp_codebox"><table><tr id="p7318"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p73code18"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">import</span> mx.<span style="color: #006600;">messaging</span>.<span style="color: #006600;">config</span>.<span style="color: #006600;">ServerConfig</span>;
...
<span style="color: #006600;">myChannelSet</span>=ServerConfig.<span style="color: #006600;">getChannelSet</span><span style="color: #66cc66;">&#40;</span>remoteObject.<span style="color: #006600;">destination</span><span style="color: #66cc66;">&#41;</span>;
myChannelSet.<span style="color: #006600;">login</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;username&quot;</span>,<span style="color: #ff0000;">&quot;password&quot;</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>If you have place <mx:TraceTarget/> in the main mxml file of your application and stare at the LCDS/Tomcat console, you should see a successful login. If not, I apologize for failing you up to this point ;(</p>
<p>One thing that the realm does NOT provide is a way to add new users or manipulate the database. I plan on getting into this in future articles, so stay tuned.</p>
<p>These files need to be added to the {lcds}/tomcat/lib folder:<br />
<strong>icu4j-4_0.jar<br />
jasypt-1.5.jar<br />
commons-codec-1.1.jar<br />
commons-lang-2.1.jar<br />
mysql-connector-java-5.1.6-bin.jar<br />
myrealm.jar</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://joelhooks.com/2008/08/27/custom-jdbc-mysql-realm-authentication-with-livecycle-data-services-or-blazeds/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>Integrating Adobe AIR, Cairngorm, PureMVC, LiveCycle Data Services (LCDS), MySQL and Hibernate</title>
		<link>http://joelhooks.com/2008/08/17/integrating-adobe-air-cairngormpuremvc-livecycle-data-services-lcds-mysql-and-hibernate/</link>
		<comments>http://joelhooks.com/2008/08/17/integrating-adobe-air-cairngormpuremvc-livecycle-data-services-lcds-mysql-and-hibernate/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 01:47:51 +0000</pubDate>
		<dc:creator>Joel</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[lcds]]></category>

		<guid isPermaLink="false">http://joelhooks.com/?p=68</guid>
		<description><![CDATA[This post is going to cover the use of Adobe AIR, PureMVC, cairngorm, MySQL, LiveCycle Data Services (LCDS), and Hibernate. It utilizes these tools to create a simple image management system. The focus is on the configuration of the server to integrate Hibernate with LCDS and access that configuration from an AIR client. The Tools:Flex [...]]]></description>
			<content:encoded><![CDATA[<p>This post is going to cover the use of Adobe AIR, PureMVC, cairngorm, MySQL, LiveCycle Data Services (LCDS), and Hibernate. It utilizes these tools to create a simple image management system. The focus is on the configuration of the server to integrate Hibernate with LCDS and access that configuration from an AIR client.<br id="h2h60" /></p>
<p><span id="more-68"></span></p>
<p><br id="w1qj" /><strong>The Tools:</strong><br id="tj9y" /><br id="tj9y0" /><a id="f60-" title="Flex Builder 3" href="http://www.adobe.com/products/flex/">Flex Builder 3</a> <br id="oqc1" /><br id="oqc10" />You can use any IDE that you prefer, but I will be using Flex Builder 3 (with Java Development Tools installed).<br id="w2fl0" /><br id="w2fl1" /><a id="ukgw" title="LiveCycle Data Services" href="http://www.adobe.com/products/livecycle/dataservices/">LiveCycle Data Services</a> [<a id="wmag" title="Download" href="http://www.adobe.com/go/trylivecycle_dataservices">Download</a>]<br id="w2fl2" /><br id="w2fl3" />For the purposes of demonstration, and many production needs that don't require the additional processing power, the free version of LCDS with the single CPU limitation is more than adequate. Why not use BlazeDS? Well, BlazeDS doesn't have the RTMP support or the Hibernate adapters that are included with its big brother LCDS. My primary goal is to get Hibernate functioning with Flex/AIR, and LCDS is the shortest (easiest?) route that I am currently aware of. There are several ongoing projects to bring a hibernate adapter to BlazeDS, and it will be interesting to follow what comes about from those efforts.<br id="h2h61" /><br id="w1qj4" /><a id="luj." title="Cairngorm Enterprise 2.2.1" href="http://opensource.adobe.com/wiki/display/cairngorm/Cairngorm">Cairngorm Enterprise 2.2.1</a> <br id="h2h62" /><br id="h2h63" />Cairngorm is a versatile, lightweight MVC framework updated and maintained by Adobe. It is an open-source project, and extremely useful in a wide variety of use cases. That said, it doesn't provide me with the full feature set I desire in my MVC solution. It does, however, provide a most excellent service locator pattern that works extremely well with LCDS. The service locator is the only aspect of Cairngorm I am going to use in this exercise.<br id="zm1q" /><br id="zm1q0" /><a id="sdvb" title="PureMVC 2.0.1" href="http://www.puremvc.org/">PureMVC Multicore 1.0.5</a> <br id="daf70" /><br id="daf71" />PureMVC is a robust open source MVC solution. It is a weightier than cairngorm in its approach, but that extra weight provides useful patterns for approaching view-centric RIA development. Simply put, I can't live without the Mediator's control over my view components. The Proxy pattern provides a highly controlled method for accessing, sorting, and maintaining my data. The Command is essentially the same as the system found in Cairngorm, but for the purposes of this project I will be using mostly PureMVC with cairngorm's EnterpriseServiceLocator providing the connectivity with LCDS on the backend.<br id="x0.w2" /><br id="eue0" /><a id="al-2" title="Hibernate" href="http://www.hibernate.org/344.html">Hibernate</a><br id="eue01" /> <br id="xuri0" />Hibernate is an Object/Relational Management framework for Java. It provides seemingly magical functionality in this capacity. It isn't really magic, as digging through its open source will demonstrate, but it is highly configurable and generally easy to use. It abstract painful CRUD operations and solves the majority of the problems you encounter when combining relational databases with object oriented software systems.<br id="y9xq" /><br id="y9xq0" /><a id="zdkq" title="Hibernate Tools" href="http://www.hibernate.org/255.html">Hibernate Tools</a> <br id="y9xq1" /><br id="y9xq2" />Hibernate tools is an Eclipse (Flex Builder) plugin that will reverse engineer Java objects and Hibernate config files from your database.<br id="ofra0" /><br id="ofra1" /><a id="o8m9" title="MySQL" href="http://dev.mysql.com/">MySQL</a> <br id="ofra2" /><br id="ofra3" />MySQL is the relational database of choice for this series. It should be relatively painless to utilize your preferred relational database, but for the sake of simplicity, and my lack of experience with other systems, that is what I will be utilizing here.<br id="vl2q" /><br id="vl2q0" />This is a lot of ground to cover. It is a daunting task, but the results are worth the effort. Once you have a level of comfort with the tools, the resulting systems provide a maintainable structure that provides your users with a rich visual experience. Data is maintained and updated across all clients accessing the system. LCDS allows for users to interact with one another, provides offline synchronization capabilities, as well as a robust persistence framework via the LCDS Hibernate adapter. Flex provides a consistent cross-platform user experience and applications are easily brought to the desktop with the AIR runtime.<br id="w1qj6" /><br id="r8.s" /><strong>The Project:</strong><br id="r8.s6" /><br id="r8.s7" />This project is a simple image gallery that stores images in albums.<br id="m7dp" /><br id="m7dp0" /><strong>The Setup:</strong><br id="m7dp7" /><br id="m7dp8" />It is assumed that you can download and install all of the above tools, so I am not going to detail that process. There are some details in the process that I will cover here. These are annomolies, or frustrating problems that took some measure of significant time searching down solutions for.<br id="e2q1" /><br id="e2q10" /><strong>MySQL</strong><br id="qhxk0" /></p>
<div id="p92h" style="margin-left: 40px;">DROP TABLE IF EXISTS `album`;<br id="qhxk1" style="color: #073763;" />CREATE TABLE `album` (<br id="qhxk2" style="color: #073763;" /> `id` int(11) NOT NULL auto_increment,<br id="qhxk3" style="color: #073763;" /> `name` varchar(256) default NULL,<br id="qhxk4" style="color: #073763;" /> `description` varchar(1024) default NULL,<br id="qhxk5" style="color: #073763;" /> `is_active` tinyint(1) default NULL,<br id="qhxk6" style="color: #073763;" /> `display_order` int(11) NOT NULL default '0',<br id="qhxk7" style="color: #073763;" /> `updated_on` datetime default NULL,<br id="qhxk8" style="color: #073763;" /> `created_on` datetime default NULL,<br id="qhxk10" style="color: #073763;" /> `mp3_url` varchar(256) default NULL,<br id="qhxk11" style="color: #073763;" /> PRIMARY KEY  (`id`)<br id="qhxk14" style="color: #073763;" />) ENGINE=InnoDB DEFAULT CHARSET=utf8;<br id="qhxk15" style="color: #073763;" /><br id="qhxk16" style="color: #073763;" />--<br id="qhxk17" style="color: #073763;" />-- Table structure for table `image`<br id="qhxk18" style="color: #073763;" />--<br id="qhxk19" style="color: #073763;" /><br id="qhxk20" style="color: #073763;" />DROP TABLE IF EXISTS `image`;<br id="qhxk21" style="color: #073763;" />CREATE TABLE `image` (<br id="qhxk22" style="color: #073763;" /> `id` int(11) NOT NULL auto_increment,<br id="qhxk23" style="color: #073763;" /> `image` longblob NOT NULL,<br id="qhxk24" style="color: #073763;" /> `album_id` int(11) NOT NULL,<br id="qhxk25" style="color: #073763;" /> `sequence` int(11) NOT NULL,<br id="qhxk26" style="color: #073763;" /> PRIMARY KEY  (`id`),<br id="qhxk27" style="color: #073763;" /> KEY `album_id` (`album_id`),<br id="qhxk28" style="color: #073763;" /> CONSTRAINT `image_ibfk_1` FOREIGN KEY (`album_id`) REFERENCES `album` (`id`)<br id="qhxk29" style="color: #073763;" />) ENGINE=InnoDB DEFAULT CHARSET=utf8;</div>
<p>This is the database schema that will be used in the project. It is a simple two table structure. Note that we are using the <a id="gf29" title="INNOdb" href="http://en.wikipedia.org/wiki/InnoDB">INNOdb</a> engine for the tables. I use <a id="rksr" title="XAMPP" href="http://www.apachefriends.org/en/xampp.html">XAMPP</a> for my localhost configuration, and INNOdb is actually disabled by default. It is important to use INNOdb, as it supports foreign key constraints. These constraints will be used by the Hibernate Tools reverse engineering scripts to determine relationships across our object classes. While it isn't strictly necessary to use these tools, it saves a lot of initial typing.<br id="p58p" /><br id="p58p0" />This database structure is simple on purpose. You could add many other tables/fields to make this a more robust system. For the purposes of demonstration we will be applying KISS principles. Some ideas for expantion would be user accounts, thumbnails, slideshows, tagging, rating, or any other features that you might find in a photo album.<br id="lovt" /><br id="lovt0" />Create a database called 'slideshow' and apply the above SQL to create the two tables we will use for this demonstration.<br id="isk9" /><br id="isk90" /><strong>LCDS</strong><br id="isk91" /><br id="isk92" />The default installation of LCDS contains some sample projects as well as a template project called LCDS. Because of limitations with the free single-cpu license, you are not able to run multiple applications. I move the default samples project out and rename the lcds project to slideshow (or better yet, move the lcds folder out and place a renamed copy of it back in the webapps folder.) You will also need to rename the context file that initializes the transaction manager utilized by Hibernate located in the {lcds-root}/tomcat/conf/Catalina/localhost folder. I removed the lcds-samples.xml, as well as the lcds.xml files after first making a copy of lcds.xml and renaming it slideshow.xml to match our application.<br id="x8au" /><br id="e7ev" />NOTE: If you are using Flex Builder, you will need to install the Java Development Tools. If you are using Eclipse, you will need to install the Flex Builder plugin. In this demonstration, I am using Flex Builder 3 with the Java Development Tools added on.<br id="e7ev0" /><br id="x8au0" />In Flex Builder create a new Java Project named Slideshow. Select the Create project from existing source option and navigate to {lcds-root}/tomcat/webapps/slideshow/WEB-INF. Choose next, and ensure that the Default output path is set to Slideshow/classes. By default, this might be set to bin-debug, and this is not appropriate for an LCDS application. The server will not know where to look for the compiled classes! Click Finish.<br id="mi9i" /><br id="mi9i0" /></p>
<div id="bgp7" style="padding: 1em 0pt; text-align: center;"><img id="pu8x" style="width: 443px; height: 365px;" src="http://docs.google.com/File?id=dfnsxvcr_4c2dhthpz_b" alt="" /><br id="pu8x0" />Initial Slideshow project structure<br id="et6l0" /><br id="et6l1" /></div>
<div id="d8nz" style="padding: 1em 0pt; text-align: center;">
<div id="et6l2" style="text-align: left;">Open the Hibernate perspective in Flex Builder. In the Hibernate Configurations tab, right-click and select Add Configuration... to open the configuration dialog. Name the configuration slideshow-hibernate, select your project, hit Setup... for your property file and select Create new... and place it in the root of your project. Click Setup... for your configuration file and select Create new... to create an initial hibernate.cfg.xml that we will use to connect to our database for reverse engineering of the tables into Java POJOs and Hibernate mapping files. Select MySQL 5(InnoDB) as the database dialect, org.gjt.mm.mysql.Driver as the Driver class, jdbc:mysql://localhost/slideshow as your connection URL, and enter your database username/password before clicking finish. The configuration should now be available in the Hibernate Configurations tab. Open the Database, and you should see your database and the tables contained within:<br id="hx87" /><br id="hx870" /></p>
<div id="r_op" style="padding: 1em 0pt; text-align: center;"><img id="lxk8" style="width: 350px; height: 417px;" src="http://docs.google.com/File?id=dfnsxvcr_5dptm6dcp_b" alt="" /><br id="lxk80" />Hibernate Configuration Wizard results<br id="lxk82" /><br id="lxk83" /></p>
<div id="lxk84" style="text-align: left;"><br id="lxk85" /></div>
</div>
<div id="zdfg" style="margin-left: 40px;">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br id="zdfg1" style="color: #0b5394;" />&lt;!DOCTYPE hibernate-configuration PUBLIC<br id="zdfg3" style="color: #0b5394;" /> "-//Hibernate/Hibernate Configuration DTD 3.0//EN"<br id="zdfg5" style="color: #0b5394;" /> "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"&gt;<br id="zdfg7" style="color: #0b5394;" />&lt;hibernate-configuration&gt;<br id="zdfg9" style="color: #0b5394;" /> &lt;session-factory&gt;<br id="zdfg11" style="color: #0b5394;" /> &lt;property name="hibernate.connection.driver_class"&gt;org.gjt.mm.mysql.Driver&lt;/property&gt;<br id="zdfg13" style="color: #0b5394;" /> &lt;property name="hibernate.connection.password"&gt;mypassword&lt;/property&gt;<br id="zdfg15" style="color: #0b5394;" /> &lt;property name="hibernate.connection.url"&gt;jdbc:mysql://localhost/slideshow&lt;/property&gt;<br id="zdfg17" style="color: #0b5394;" /> &lt;property name="hibernate.connection.username"&gt;root&lt;/property&gt;<br id="zdfg19" style="color: #0b5394;" /> &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.MySQL5InnoDBDialect&lt;/property&gt;<br id="zdfg21" style="color: #0b5394;" /> &lt;/session-factory&gt;<br id="zdfg23" style="color: #0b5394;" />&lt;/hibernate-configuration&gt;<br id="zdfg25" /><br id="zdfg26" /></div>
<p>The resulting hibernate.cfg.xml should look like the above.<br id="yb70" /><br id="yb700" />From the Run menu, select Hibernate Code Generation, and select Open Hibernate Code Generation Dialog... to create a reverse engineering configuration to generate our POJOs and Hibernate mapping files. Click the "New launch configuration" icon and rename the configuration "slideshow-configuration". In the Console configuration dialog select our slidwshow-hibernate configuration that we created in the previous step. Brows to the src directory of our project in the Output directory selection. Click the "Reverse engineer from JDBC Connection" checkbox. Enter "slideshow.data" in the package text input area. Click the setup button for reveng.xml and choose "Create new..." and place the file in the root of our project. Move to the "Exporters Tab" and choose Domain code (.java), Hibernate XML Mappings (.hbm.xml), and Hibernate XML Configuration (.cfg.xml). Didn't we already create a hibernate.cfg.xml? Yes, but this generated version will be placed in the src directory, and will contain the appropriate references to our mapping files. The first configuration is simply to tell the generator where to connect to our database. Switch to the Refresh tab and select "Refresh resources upon completion." so that our project structure will be refreshed after we click Run. Click Run.<br id="mu7g" /><br id="mu7g0" />From the Package Explorer tab, you will see that our .java classes have been generated, as well as their appropriate sidecar .hbm.xml files. The album class containes a Set called images, and the Image class contains an Album property. Take a look at the .hbm.xml files and take note of the defined relationships. The Hibernate reverse engineering has successfully traversed our database structure and created the appropriate relationsips!<br id="g8l4" /><br id="g8l40" />It is worth noting that the Hibernate reverse engineering tools could concievably take care of the following steps. This is on my list of things to explore, but for now we will define our LCDS destinations and Actionscript value objects the old fashioned way. By hand. Yick.<br id="pyn6" /><br id="pyn60" />As a final step we will add cascading and a retrieve all query to our album.hbm.xml like this:<br id="d8nz0" /><br id="d8nz1" /></p>
<div id="d8nz2" style="margin-left: 40px; color: #0b5394;">&lt;?xml version="1.0"?&gt;<br id="d8nz3" />&lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"<br id="d8nz4" />"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt;<br id="d8nz5" />&lt;!-- Generated Aug 17, 2008 1:02:52 PM by Hibernate Tools 3.2.2.GA --&gt;<br id="d8nz6" />&lt;hibernate-mapping&gt;<br id="d8nz7" /> &lt;class name="slideshow.data.Album" table="album" catalog="slideshow"&gt;<br id="d8nz8" /> &lt;id name="id" type="java.lang.Integer"&gt;<br id="d8nz9" /> &lt;column name="id" /&gt;<br id="d8nz10" /> &lt;generator class="identity" /&gt;<br id="d8nz11" /> &lt;/id&gt;<br id="d8nz12" /> &lt;property name="name" type="string"&gt;<br id="d8nz13" /> &lt;column name="name" length="256" /&gt;<br id="d8nz14" /> &lt;/property&gt;<br id="d8nz15" /> &lt;property name="description" type="string"&gt;<br id="d8nz16" /> &lt;column name="description" length="1024" /&gt;<br id="d8nz17" /> &lt;/property&gt;<br id="d8nz18" /> &lt;property name="isActive" type="java.lang.Boolean"&gt;<br id="d8nz19" /> &lt;column name="is_active" /&gt;<br id="d8nz20" /> &lt;/property&gt;<br id="d8nz21" /> &lt;property name="displayOrder" type="int"&gt;<br id="d8nz22" /> &lt;column name="display_order" not-null="true" /&gt;<br id="d8nz23" /> &lt;/property&gt;<br id="d8nz24" /> &lt;property name="updatedOn" type="timestamp"&gt;<br id="d8nz25" /> &lt;column name="updated_on" length="19" /&gt;<br id="d8nz26" /> &lt;/property&gt;<br id="d8nz27" /> &lt;property name="createdOn" type="timestamp"&gt;<br id="d8nz28" /> &lt;column name="created_on" length="19" /&gt;<br id="d8nz29" /> &lt;/property&gt;<br id="d8nz30" /> &lt;property name="mp3Url" type="string"&gt;<br id="d8nz31" /> &lt;column name="mp3_url" length="256" /&gt;<br id="d8nz32" /> &lt;/property&gt;<br id="d8nz33" /> &lt;set name="images" inverse="true" cascade="all"&gt;<br id="d8nz34" /> &lt;key&gt;<br id="d8nz35" /> &lt;column name="album_id" not-null="true" /&gt;<br id="d8nz36" /> &lt;/key&gt;<br id="d8nz37" /> &lt;one-to-many class="slideshow.data.Image" /&gt;<br id="d8nz38" /> &lt;/set&gt;<br id="d8nz39" /> &lt;/class&gt;<br id="d8nz40" /> &lt;query name="all.albums"&gt;from Album&lt;/query&gt;<br id="d8nz41" />&lt;/hibernate-mapping&gt;</div>
<p><br id="vkzx1" />These two changes are the only changes neccessary. The generator has taken care of everything else.<br id="vkzx2" /><br id="s08i0" /><strong>Defining the LCDS Destinations</strong><br id="s08i2" /><br id="s08i3" />Now that we have set up the server side Java application, it is neccessary to create destinations for our client to communicate with. In the flex directory of our project, there are a number of xml configuration files. The default configuration will be sufficient in all cases except for the data-management-config.xml. This is the file that will contain our destinations.<br id="dp:8" /><br id="dp:80" />This is the basic configuration for our destinations defining the relationships between our objects:<br id="et6l3" /></div>
</div>
<div id="dp:81" style="margin-left: 40px;">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br id="dp:83" style="color: #3d85c6;" />&lt;service id="data-service" <br id="dp:85" style="color: #3d85c6;" /> class="flex.data.DataService"&gt;<br id="dp:87" style="color: #3d85c6;" /><br id="dp:88" style="color: #3d85c6;" /> &lt;adapters&gt;<br id="dp:810" style="color: #3d85c6;" /> &lt;adapter-definition id="actionscript" class="flex.data.adapters.ASObjectAdapter" default="true"/&gt;<br id="dp:812" style="color: #3d85c6;" /> &lt;adapter-definition id="java-dao" class="flex.data.adapters.JavaAdapter"/&gt;<br id="dp:814" style="color: #3d85c6;" /> &lt;/adapters&gt;<br id="dp:816" style="color: #3d85c6;" /><br id="dp:817" style="color: #3d85c6;" /> &lt;default-channels&gt;<br id="dp:819" style="color: #3d85c6;" /> &lt;channel ref="my-rtmp"/&gt;<br id="dp:821" style="color: #3d85c6;" /> &lt;/default-channels&gt;<br id="dp:823" style="color: #3d85c6;" /> <br id="dp:825" style="color: #3d85c6;" /> &lt;destination id="AlbumHibernate"&gt;<br id="dp:827" style="color: #3d85c6;" /> &lt;adapter ref="java-dao" /&gt;<br id="dp:829" style="color: #3d85c6;" /> &lt;properties&gt;<br id="dp:831" style="color: #3d85c6;" /> &lt;use-transactions&gt;true&lt;/use-transactions&gt;<br id="dp:833" style="color: #3d85c6;" /> &lt;source&gt;flex.data.assemblers.HibernateAssembler&lt;/source&gt;<br id="dp:835" style="color: #3d85c6;" /> &lt;scope&gt;application&lt;/scope&gt;<br id="dp:837" style="color: #3d85c6;" /> &lt;metadata&gt;<br id="dp:839" style="color: #3d85c6;" /> &lt;!--This is the unique identifier from the hibernate-entity bean --&gt;<br id="dp:841" style="color: #3d85c6;" /> &lt;identity property="id"/&gt;<br id="dp:843" style="color: #3d85c6;" /> &lt;one-to-many property="images" destination="ImageHibernate" lazy="true" /&gt;    <br id="dp:845" style="color: #3d85c6;" /> &lt;/metadata&gt;<br id="dp:847" style="color: #3d85c6;" /> &lt;network&gt;<br id="dp:849" style="color: #3d85c6;" /> &lt;session-timeout&gt;0&lt;/session-timeout&gt;<br id="dp:851" style="color: #3d85c6;" /> &lt;/network&gt;<br id="dp:853" style="color: #3d85c6;" /> &lt;server&gt;<br id="dp:855" style="color: #3d85c6;" /> &lt;hibernate-entity&gt;slideshow.data.Album&lt;/hibernate-entity&gt;<br id="dp:857" style="color: #3d85c6;" /> &lt;fill-method&gt;<br id="dp:859" style="color: #3d85c6;" /> &lt;name&gt;fill&lt;/name&gt;<br id="dp:861" style="color: #3d85c6;" /> &lt;params&gt;java.util.List&lt;/params&gt;<br id="dp:863" style="color: #3d85c6;" /> &lt;/fill-method&gt;<br id="dp:865" style="color: #3d85c6;" /> &lt;fill-configuration&gt;<br id="dp:867" style="color: #3d85c6;" /> &lt;use-query-cache&gt;false&lt;/use-query-cache&gt;<br id="dp:869" style="color: #3d85c6;" /> &lt;allow-hql-queries&gt;true&lt;/allow-hql-queries&gt;<br id="dp:871" style="color: #3d85c6;" /> &lt;/fill-configuration&gt;<br id="dp:873" style="color: #3d85c6;" /> &lt;/server&gt;<br id="dp:875" style="color: #3d85c6;" /> &lt;/properties&gt;<br id="dp:877" style="color: #3d85c6;" /> &lt;/destination&gt;  <br id="dp:879" style="color: #3d85c6;" /><br id="dp:880" style="color: #3d85c6;" /> &lt;destination id="ImageHibernate"&gt;<br id="dp:882" style="color: #3d85c6;" /> &lt;adapter ref="java-dao" /&gt;<br id="dp:884" style="color: #3d85c6;" /> &lt;properties&gt;<br id="dp:886" style="color: #3d85c6;" /> &lt;use-transactions&gt;true&lt;/use-transactions&gt;<br id="dp:888" style="color: #3d85c6;" /> &lt;source&gt;flex.data.assemblers.HibernateAssembler&lt;/source&gt;<br id="dp:890" style="color: #3d85c6;" /> &lt;scope&gt;application&lt;/scope&gt;<br id="dp:892" style="color: #3d85c6;" /> &lt;metadata&gt;<br id="dp:894" style="color: #3d85c6;" /> &lt;!--This is the unique identifier from the hibernate-entity bean --&gt;<br id="dp:896" style="color: #3d85c6;" /> &lt;identity property="id"/&gt;<br id="dp:898" style="color: #3d85c6;" /> &lt;many-to-one property="album"  destination="AlbumHibernate" lazy="true" /&gt;<br id="dp:8100" style="color: #3d85c6;" /> &lt;/metadata&gt;<br id="dp:8102" style="color: #3d85c6;" /> &lt;network&gt;<br id="dp:8104" style="color: #3d85c6;" /> &lt;session-timeout&gt;0&lt;/session-timeout&gt;<br id="dp:8106" style="color: #3d85c6;" /> &lt;/network&gt;<br id="dp:8108" style="color: #3d85c6;" /> &lt;server&gt;<br id="dp:8110" style="color: #3d85c6;" /> &lt;hibernate-entity&gt;slideshow.data.Image&lt;/hibernate-entity&gt;<br id="dp:8112" style="color: #3d85c6;" /> &lt;fill-method&gt;<br id="dp:8114" style="color: #3d85c6;" /> &lt;name&gt;fill&lt;/name&gt;<br id="dp:8116" style="color: #3d85c6;" /> &lt;params&gt;java.util.List&lt;/params&gt;<br id="dp:8118" style="color: #3d85c6;" /> &lt;/fill-method&gt;<br id="dp:8120" style="color: #3d85c6;" /> &lt;fill-configuration&gt;<br id="dp:8122" style="color: #3d85c6;" /> &lt;use-query-cache&gt;false&lt;/use-query-cache&gt;<br id="dp:8124" style="color: #3d85c6;" /> &lt;allow-hql-queries&gt;true&lt;/allow-hql-queries&gt;<br id="dp:8126" style="color: #3d85c6;" /> &lt;/fill-configuration&gt;<br id="dp:8128" style="color: #3d85c6;" /> &lt;/server&gt;<br id="dp:8130" style="color: #3d85c6;" /> &lt;/properties&gt;<br id="dp:8132" style="color: #3d85c6;" /> &lt;/destination&gt;              <br id="dp:8134" style="color: #3d85c6;" />&lt;/service&gt;<br id="orhv" /></div>
<div id="orhv0"><br id="fegk0" /><br id="fegk1" /><br id="orhv1" /><strong>The Client</strong><br id="orhv3" /><br id="orhv4" />The client will be an Adobe AIR client. Why AIR? Well, for this particular demonstration, an image gallery, it is neccesary to pull images from the users harddrive and upload them as bytearrays to the server for storage in the database. With the current Flash Player Runtime (9 at the time of this writing) you cannot do this due to security sandbox restrictions. The good news is that this particular restriction is being relaxed in Flash Player 10, but for now it is not possible outside of AIR, or with roundtrip trickery via a web service.<br id="vp3g" /><br id="vp3g0" />"But wait, I thought we were applying KISS principles? Cairngorm AND PureMVC? What's up with that?"<br id="fdxw" /><br id="fdxw0" />Cairngorm is a nice framework, but PureMVC provides robust control over your view layer that Cairngorm lacks. Cairngorm's ServiceLocator (or EnterpriseServiceLocator in this case) is extremely convenient and provides easy access to our data services. In the context of this application, the ServiceLocator is the only piece of Cairngorm we are going to use. When I originally built this application, it was actually as a means to learn about the Cairngorm framework, but I found myself missing PureMVC the entire time I was working with it. So I am taking this opportunity to demonstrate the combination of these two frameworks as a means to create a robust MVC driven LCDS connected application.<br id="x.28" /><br id="x.280" /></p>
<div id="oid5" style="padding: 1em 0pt; text-align: center;">
<div id="io4z" style="padding: 1em 0pt; text-align: center;"><img id="ct.:" style="width: 339px; height: 761px;" src="http://docs.google.com/File?id=dfnsxvcr_7gvk8m2gs_b" alt="" /><br id="ct.:0" /> Flex Project Structure<br id="g2eb2" /></div>
</div>
<p>The project structure is typical PureMVC, with model, view and controller folders added under the slideshow package. The focus of this tutorial is the server side configuration. I'm not going to go into detail about constructing the client application, but I am going to summarize what the classes do:<br id="h.dv" /> <br id="h.dv0" /> <strong>Slideshow.mxml</strong><br id="h.dv2" /> This is our main application window. It calls a reference to the SlideshowServiceLocator component to initialize the EnterpriseServiceLocator singleton class. It also contains references to our two Value Object classes. This is neccesary to send typed objects back and forth over the wire. Until the VOs are called, they will be transfered as generic objects. Slideshow.mxml also initializes the PureMVC ApplicationFacade. <br id="i:s60" /> <br id="i:s61" /> <strong>SlideshowServiceLocator.mxml</strong><br id="i:s62" /> This component is an extension of the Cairngorm Enterpriese EnterpriseServiceLocator class. This is the place where you define your channels and services to facilitate communication with the LCDS rtmp end-point. If you want to change the end-point from localhost to reflect your personal configuration or a remote server, this is the place to do it.<br id="n63n0" /> <br id="n63n1" /> <strong>*Command.as</strong><br id="n63n3" /> These classes initialize the PureMVC proxy and view components.<br id="djdo" /> <br id="djdo0" /> <strong>*Events.as</strong><br id="djdo2" /> These are custom events. They are very simple extensions of the Event class, but they carry references to value objects to make life easier.<br id="er.p" /> <br id="er.p0" /> <strong>*VO.as</strong><br id="er.p2" /> The value objects mirror the POJO objects on our server side. They are [Managed], meaning they are monitored for changes by LCDS. Managed classes are [Bindable] by default. There is also additional metadata referencing the remote class so that our objects will be stongly typed over the wire.<br id="g-g5" /> <br id="kt.2" /> <strong>ApplicationMediator.as</strong><br id="kt.20" /> This is the mediator for the main application window. It registers the mediators that monitor and control the sub-components of the application.<br id="kt.21" /> <br id="gt_i" /> <strong>*Mediator.as</strong><br id="gt_i0" /> The mediators monitor for changes in our view components and respond to notifications from commands, proxies, and other mediators. In this application, there are not many notifications being sent around, but I left the methods in place for future expansion.<br id="gt_i1" /> <strong><br id="g-g50" /> AlbumListProxy.as</strong><br id="g-g51" /> This proxy is where we grab the list of albums from the server. This proxy grabs an instance of the EnterpriseServiceLocator and calls the "albums.all" query to fill the data property of the proxy. When the list of albums is retrieved, we assign each album an individual proxy to lord over it.<br id="g-g52" /> <br id="g-g53" /> <strong>AlbumProxy.as</strong><br id="g-g54" /> AlbumProxy contains methods to manipulate albums. Add images, delete images, delete the album, etc. While it is wholly possible to place these methods inside the actual view components (ServiceLocator makes it very easy), it is better form to seperate the manipulation of our data model from our view layer. View components should be stupid, ignorant of anything outside of displaying the data passed to them. With this application, I actually did data manipulation in the view components, but then refactored to follow the proxied data methodology. This is how I approach these things a lot of the times. Create a monolithic view component, break it into smaller components, mediate those deserving of such treatment, and finally proxy the data manipulation methods contained in the objects. I've found that as I gain experience, I am able to plan the broader structure without having to use this approach, but "make it work, then make it work better" is still a valid approach.</div>
<div id="x4ef2" class="Section1" style="font-family: Verdana;">
<p id="x4ef131" class="MsoNormal"><strong>In Conclusion:</strong></p>
<p id="cyxy" class="MsoNormal">This application is possibly too simple for this elaborate setup. I chose this particular project because it is actually a piece of a larger image management system that I have planned. You might also notice, that while I call it 'Slideshow", we never actually run a slideshow! It could, with some simple additions, and lists of images are only interesting when they move and have music thumping behind them. This technology stack is very exciting, and presents many possibilities for a wide variety of application development. For small scale development, the single cpu LCDS license is probably sufficient. One thing I have not done is stress test LCDS to see exactly what it can handle on a single CPU.<br id="cyxy1" /></p>
<p id="j:qy" class="MsoNormal">Below is the exported web application archive. It can be extraced to your {lcds-root}/tomcat/webapps/ folder and contains all of the Java libraries, as well as the SWCs that I used on the Flex side. The Flex project, AIR rather, is contained in the flex-src folder of the java project. To get these projects into Flex Builder, follow these steps:<br id="j:qy0" /></p>
<p id="f0wt0" class="MsoNormal">In the Flex Development perspective choose Import&gt;Flex Project and select Project folder. Navigate to the {lcds-root}/tomcat/webapps/slideshow/WEB-INF/flex-src/slideshow-tutorial folder, select it, and then hit finish.<br id="f0wt1" /></p>
<p id="u:hz" class="MsoNormal">In the Java perspective, choose file&gt;new&gt;Java Project and choose "Create project from existing source." Navigate to {lcds-root}/tomcat/webapps/slideshow/WEB-INF and select this folder.<br id="u:hz0" /></p>
<p id="u:hz2" class="MsoNormal">Both the Flex and Java projects should now be properly imported.<br id="u:hz3" /></p>
<p>If you find glaring errors, omissions, or any other problems with this project, please let me know so that I can improve upon it for others.</p>
<p><a href="http://joelhooks.com/slideshow.zip">slideshow.zip (22.7mb)</a></p>
<p>[The zip is large. This is because of the JAR libs in the java project. Specifically those related to Acrobat. <a href="http://joelhooks.com/slideshow_small.zip">Here (1.7mb)</a> is a version with no JARs.]</div>
]]></content:encoded>
			<wfw:commentRss>http://joelhooks.com/2008/08/17/integrating-adobe-air-cairngormpuremvc-livecycle-data-services-lcds-mysql-and-hibernate/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/us/</creativeCommons:license>
	</item>
	</channel>
</rss>
