<?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>Colabrativ, Inc. &#187; GWT</title>
	<atom:link href="http://www.colabrativ.com/tag/gwt/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.colabrativ.com</link>
	<description>An Experiment Documentation and Electronic Notebook Provider</description>
	<lastBuildDate>Tue, 28 Oct 2014 04:44:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Creating SSL Certificates for Google Web Toolkit Running on Apache HTTPD and Tomcat on Amazon Web Services EC2</title>
		<link>http://www.colabrativ.com/creating-ssl-certificates-for-google-web-toolkit-running-on-apache-httpd-and-tomcat-on-amazon-web-services-ec2/</link>
		<comments>http://www.colabrativ.com/creating-ssl-certificates-for-google-web-toolkit-running-on-apache-httpd-and-tomcat-on-amazon-web-services-ec2/#comments</comments>
		<pubDate>Sat, 31 Aug 2013 16:29:08 +0000</pubDate>
		<dc:creator>Marc Whitlow</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[Elastic Compute Cloud]]></category>
		<category><![CDATA[GWT]]></category>

		<guid isPermaLink="false">http://www.colabrativ.com/?p=737</guid>
		<description><![CDATA[This post is a follow-up article to my August 27, 2012 article on Creating Self-Signed Certificates for Google Web Toolkit Running on Apache HTTPD and Tomcat on Amazon Web Services EC2. Server Configuration Creating and installing a Secure Sockets Layer &#8230; <a href="http://www.colabrativ.com/creating-ssl-certificates-for-google-web-toolkit-running-on-apache-httpd-and-tomcat-on-amazon-web-services-ec2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This post is a follow-up article to my August 27, 2012 article on <a target="_blank" href="http://www.colabrativ.com/self-signed-certificates-gwt-applications-apache-http-tomcat/">Creating Self-Signed Certificates for Google Web Toolkit Running on Apache HTTPD and Tomcat on Amazon Web Services EC2.</a></p>
<h3>Server Configuration</h3>
<p>Creating and installing a <a target="_blank" href="http://en.wikipedia.org/wiki/Secure_Sockets_Layer">Secure Sockets Layer (SSL)</a> certificate on a server should be a relatively simple task.  However, most of the documentation relating to this task is confusing.  Most of the confusion arises from the fact that there are a multitude of different server configurations that utilize the SSL to complete secure transactions over the web.  In order not to add to this confusion, the following tutorial will refer to the following server configuration: </p>
<table style="border:0px solid white;">
<tr>
<td style="border:0px solid white;">Server:</td>
<td style="border:0px solid white;">64 bit Linux server running on <a target="_blank" href="http://aws.amazon.com/">Amazon Web Services</a> <a target="_blank" href="http://aws.amazon.com/ec2/">Elastic Compute Cloud (EC2)</a> server based on AMI ami-3bc9997e</td>
</tr>
<tr>
<td style="border:0px solid white;">Server&nbsp;Software:</td>
<td style="border:0px solid white;"><a target="_blank" href="http://httpd.apache.org/ABOUT_APACHE.html">Apache HTTP Server (HTTPD)</a> and <a target="_blank" href="http://tomcat.apache.org/">Apache Tomcat</a></td>
</tr>
<tr>
<td style="border:0px solid white;">Applications&nbsp;Type:</td>
<td style="border:0px solid white;"><a target="_blank" href="https://developers.google.com/web-toolkit/">Google Web Toolkit</a> and Java servlets</td>
</tr>
</table>
<p>In this post I will describe:</p>
<ol>
<li><a href="#create-keystore">Creating a Java Keystore</a></li>
<li><a href="#CSR-generation">Certificate Signing Request (CSR) Generation</a></li>
<li><a href="#check-CSR">Check the Certificate Signing Request (CSR)</a></li>
<li><a href="#loading-keystore">Loading the Certificates into the Java Keystore</a></li>
<li><a href="#extract-key">Extracting the Key from the Keystore</a></li>
<li><a href="#configure-ssl-conf">Configuring Apache Server (HTTPD) ssl.conf</a></li>
<li><a href="#add-keystore-to-tomcat">Adding Keystore to Tomcat&#8217;s server.xml</a></li>
</ol>
<h3 id="create-keystore">Creating of a Java Keystore</h3>
<p>Here we will use a <a target="_blank" href="http://docs.oracle.com/javase/6/docs/api/java/security/KeyStore.html">Java KeyStore</a> to generate and store the SSL key and certificates.  One of the limitations to this approach is that you must start by creating the KeyStore first.  SSL utilities such as <a target="_blank" href="http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/keytool.html">Java keytool</a> and <a target="_blank" href="http://www.openssl.org/">OpenSSL</a> do not have the ability to create a keystore from an existing certificate and key.  In particular, there is no way to put the key in the keystore. </p>
<div class="codeBox">
<p>First we will create and open to the directory /etc/pki/tls/keystore.  The  <strong>keytool</strong> command that creates the keystore, we need to supply the following: </p>
<ul>
<li><strong>keystore</strong> file name: <span style="color: blue">demo.colabrativ.com.jks</span></li>
<li><strong>key algorythm (keyalg)</strong>: <span style="color: blue">RSA</span></li>
<li><strong>alias</strong>: <span style="color: blue">demo</span></li>
<li><strong>keysize</strong>: <span style="color: blue">2048</span>  As of January 1, 2014 2048-bit or longer keys will be required by <a target="_blank" href="https://www.cabforum.org/Baseline_Requirements_V1.pdf">Certification Authority/Browser Forum</a>.</li>
</ul>
<p>In addition, we need to supply information on the website URL, when the keytool asks for &#8220;What is your first and last name?&#8221;  The key and keystore passwords are optional.  This information and information on our institution have been highlighted in green in the example below.  </p>
<pre>$ sudo mkdir /etc/pki/tls/keystore
$ cd /etc/pki/tls/keystore
$ sudo keytool -genkey -alias <span style="color: blue">demo</span> -keyalg <span style="color: blue">RSA</span> -keystore <span style="color: blue">demo.colabrativ.com.jks</span> -keysize <span style="color: blue">2048</span>
Enter keystore password: <span style="color: #080; font-weight:600;">password</span>
Re-enter new password: <span style="color: #080; font-weight:600;">password</span>
What is your first and last name?
  [Unknown]:  <span style="color: #080; font-weight:600;">demo.colabrativ.com</span>
What is the name of your organizational unit?
  [Unknown]:  <span style="color: #080; font-weight:600;"></span>
What is the name of your organization?
  [Unknown]:  <span style="color: #080; font-weight:600;">Colabrativ, Inc.</span>
What is the name of your City or Locality?
  [Unknown]:  <span style="color: #080; font-weight:600;">Orinda</span>
What is the name of your State or Province?
  [Unknown]:  <span style="color: #080; font-weight:600;">California</span>
What is the two-letter country code for this unit?
  [Unknown]:  <span style="color: #080; font-weight:600;">US</span>
Is CN=demo.colabrativ.com, OU=Developmemt, O=Colabrativ, Inc., L=Orinda, ST=California, C=US correct?
  [no]:  <span style="color: #080; font-weight:600;">yes</span>

Enter key password for <demo>
        (RETURN if same as keystore password):

$ ls -lt
total 4
-rw-r--r-- 1 marc users 2246 Aug 30 08:53 demo.colabrativ.com.jks
</pre>
</div>
<h3 id="CSR-generation">Generating the Certificate Signing Request (CSR)</h3>
<div class="codeBox">
We need to supply the following: </p>
<ul>
<li><strong>alias</strong>: <span style="color: blue">demo</span></li>
<li><strong>keystore</strong> file name: <span style="color: blue">demo.colabrativ.com.jks</span></li>
<li>CSR <strong>file</strong> name: <span style="color: blue">demo.colabrativ.com.csr</span></li>
</ul>
<pre>$ keytool -certreq -alias <span style="color: blue">demo</span> -keystore <span style="color: blue">demo.colabrativ.com.jks</span> -file <span style="color: blue">demo.colabrativ.com.csr</span>
Enter keystore password: <span style="color: #080; font-weight:600;">password</span>

$ ls -lt
total 8
-rw-r--r-- 1 marc users 1039 Aug 30 08:55 demo.colabrativ.com.csr
-rw-r--r-- 1 marc users 2246 Aug 30 08:53 demo.colabrativ.com.jks
</pre>
</div>
<h3 id="check-CSR">Check the Certificate Signing Request (CSR)</h3>
<div class="codeBox">
Symantec Corporation provides a set of SSL tools at <a target="_blank" href="https://ssl-tools.verisign.com/#certChecker?sl=DENJS-0000-04-00">https://ssl-tools.verisign.com/#certChecker?sl=DENJS-0000-04-00</a>, including a CSR Validation.  After pasting your CSR into the window provided and running the validator, then following information on your CCR is shown: </p>
<table style="border:0px solid white;">
<tr>
<td>Common Name</td>
<td>demo.colabrativ.com</td>
</tr>
<tr>
<td>Organization</td>
<td>Colabrativ, Inc.</td>
</tr>
<tr>
<td>Organizational Unit</td>
<td>Unknown</td>
</tr>
<tr>
<td>Locality</td>
<td>Orinda</td>
</tr>
<tr>
<td>State</td>
<td>California</td>
</tr>
<tr>
<td>Country</td>
<td>US</td>
</tr>
<tr>
<td>Signature</td>
<td>Verified</td>
</tr>
<tr>
<td>Signature Algorithm </td>
<td>SHA1</td>
</tr>
<tr>
<td>Key Algorithm</td>
<td>RSA</td>
</tr>
<tr>
<td>Key Length</td>
<td>2048</td>
</tr>
</table>
<p>The signing request (demo.colabrativ.com.csr) can now be sent to the certificate authority.
</p></div>
<h3 id="loading-keystore">Loading the Certificates into the Java Keystore</h3>
<div class="codeBox">
After receiving the certificates from the certificate authority, they need to be loaded in the keystore before exporting the key.  You need both the certificate for your URL and the intermediate certificate from the certificate authority.  This example uses the following certificates and keystore:</p>
<ul>
<li><strong>intermediate certificate</strong> file name: <span style="color: blue">intermediate.crt</span></li>
<li><strong>certificate</strong> file name: <span style="color: blue">demo.colabrativ.com.crt</span></li>
<li><strong>keystore</strong> file name: <span style="color: blue">demo.colabrativ.com.jks</span></li>
</ul>
<p>First the certificate authorities intermediate certificate is loaded using the alias <span style="color: blue">root</span>.</p>
<pre>$ keytool -import -trustcacerts -alias <span style="color: blue">root</span> -file <span style="color: blue">intermediate.crt</span> -keystore <span style="color: blue">demo.colabrativ.com.jks</span>
Enter keystore password: <span style="color: #080; font-weight:600;">password</span>
Certificate was added to keystore
</pre>
<p>Then our certificate, <span style="color: blue">demo.colabrativ.com.crt</span> is loaded in the keystore using the alias <span style="color: blue">demo</span>.</p>
<pre>$ keytool -import -trustcacerts -alias <span style="color: blue">demo</span> -file <span style="color: blue">demo.colabrativ.com.crt</span> -keystore <span style="color: blue">demo.colabrativ.com.jks</span>
Enter keystore password: <span style="color: #080; font-weight:600;">password</span>
Certificate was added to keystore
</pre>
</div>
<h3 id="extract-key">Extracting the Key from the Keystore</a></h3>
<div class="codeBox">
<p>There are three steps in extracting the key from the keystore we created above:</p>
<ol>
<li>Use keytool to create an intermediate <span style="color: blue">PKCS12</span> keystore, <span style="color: blue">demo.colabrativ.com.pkcs12</span>, from the keystore, <span style="color: blue">demo.colabrativ.com.jks</span>.</li>
<li>Use OpenSSL to create a <a target="_blank" href="http://en.wikipedia.org/wiki/Privacy_Enhanced_Mail">Privacy-enhanced Electronic Mail (PEM)</a> formatted file containing both the certificate and the key, <span style="color: blue">demo.colabrativ.com.pem</span>.
<li>Extract the key, <span style="color: blue">demo.colabrativ.com.key</span>, from the PEM file using a text editor.</li>
</ol>
<pre>$ sudo keytool -importkeystore -srckeystore <span style="color: blue">demo.colabrativ.com.jks</span> -destkeystore <span style="color: blue">demo.colabrativ.com.pkcs12</span> -deststoretype PKCS12
Enter destination keystore password: <span style="color: #080; font-weight:600;">password</span>
Re-enter new password: <span style="color: #080; font-weight:600;">password</span>
Enter source keystore password: <span style="color: #080; font-weight:600;">password</span>
Entry for alias tomcat successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

$ sudo openssl pkcs12 -in <span style="color: blue">demo.colabrativ.com.pkcs12</span> -out <span style="color: blue">demo.colabrativ.com.pem</span> -nodes
Enter Import Password: <span style="color: #080; font-weight:600;">password</span>
MAC verified OK

$ sudo cp demo.colabrativ.com.pem demo.colabrativ.com.key
$ sudo vi demo.colabrativ.com.key

$ ls -lt
total 20
-rw-r--r-- 1 marc users 1224 Aug 30 13:57 demo.colabrativ.com.key
-rw-r--r-- 1 marc users  509 Aug 30 13:53 demo.colabrativ.com.pem
-rw-r--r-- 1 marc users  509 Aug 30 13:50 demo.colabrativ.com.pkcs12
-rw-r--r-- 1 marc users 2246 Aug 30 13:48 demo.colabrativ.com.jks
-rw-r--r-- 1 marc users 1039 Aug 30 13:46 demo.colabrativ.com.crt
-rw-r--r-- 1 marc users 1039 Aug 30 13:45 intermediate.crt
-rw-r--r-- 1 marc users 1039 Aug 30 08:55 demo.colabrativ.com.csr
</pre>
<p>After the certificate and key have been prepared, they are moved the /etc/pki/tls/certs/, and /etc/pki/tls/private/ directories, respectively.</p>
<pre>
$ sudo mv intermediate.crt /etc/pki/tls/certs/.
$ sudo mv demo.colabrativ.com.crt /etc/pki/tls/certs/.
$ sudo mv demo.colabrativ.com.key /etc/pki/tls/private/.
</pre>
</div>
<h3 id="configure-ssl-conf">Configuring Apache Server (HTTPD) ssl.conf</h3>
<p>We will place all the SSL information for this server in the ssl.conf file in the /etc/httpd/conf.d directory.  The ssl.conf file is loaded into the Apache Server (HTTPD) from the command &#8220;include conf.d/*.conf&#8221; in httpd.conf in directory /etc/httpd/conf.  You should check to be sure that this command is in your httpd.conf file.</p>
<div class="codeBox">
Shown below are the differences between the original ssl.conf file and the edited version.  It is a bit hard to tell where these changes were made from the file differences, so a copy of a demonstration ssl.conf file can be downloaded at the bottom of the section.</p>
<pre>$ cd /etc/httpd/conf.d
$ sudo cp –p ssl.conf ssl.conf.orig
$ sudo vi ssl.conf
$ sudo diff ssl.conf.orig ssl.conf
19a20,21
&gt; NameVirtualHost *:443
&gt;
74c76,77
&gt; &lt;VirtualHost _default_:443&gt;
---
&gt; #&lt;VirtualHost _default_:443&gt;
&gt; &lt;VirtualHost *:443&gt;
78a82
&gt; ServerName demo.colabrativ.com:443
85a90,100
&gt; #
&gt; # Proxy Server directives. Uncomment the following lines to
&gt; # enable the proxy server:
&gt; #
&gt; ProxyRequests Off
&gt; ProxyPass        /admin   https://demo.colabrativ.com:8443/admin
&gt; ProxyPass        /demoapp https://demo.colabrativ.com:8443/demoapp
&gt;
&gt; SSLProxyEngine on
&gt;
105c120,121
&lt; SSLCertificateFile /etc/pki/tls/certs/localhost.crt
---
&gt; #SSLCertificateFile /etc/pki/tls/certs/localhost.crt
&gt; SSLCertificateFile /etc/pki/tls/certs/<span style="color: blue">demo.colabrativ.com.crt</span>
112c128,129
&lt; SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
---
&gt; #SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
&gt; SSLCertificateKeyFile /etc/pki/tls/private/<span style="color: blue">demo.colabrativ.com.key</span>
143c143
&lt; #SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
---
&gt; SSLCACertificateFile /etc/pki/tls/certs/<span style="color: blue">intermediate.crt</span>
</pre>
<p />
<p><strong>Download: <a target="_blank" href="http://www.colabrativ.com/files/demo_ssl.conf">demo_ssl.conf</a></strong></p>
</div>
<h3 id="add-keystore-to-tomcat">Adding Keystore to Tomcat&#8217;s server.xml</h3>
<div class="codeBox">
We configure Tomcat to support applications and services under the secure https protocol on port 8443.  We do this by editing the server.xml file in /etc/tomcat7.  We need to supply the keystore password in the 8443 Connector we enable.  I have saved the original server.xml, and only show the difference between the two files below. </p>
<pre>$ cd /etc/tomcat7
$ sudo cp -p server.xml server.xml.orig
$ sudo vi server.xml
$ sudo diff server.xml.orig server.xml
84,88c84,92
&lt;     &lt;!--
&lt;     &lt;Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
&lt;                maxThreads="150" scheme="https" secure="true"
&lt;                clientAuth="false" sslProtocol="TLS" /&#038;gt
&lt;     --&gt;
---
&gt;
&gt;     &lt;Connector port="8443"
&gt;                protocol="HTTP/1.1"
&gt;                SSLEnabled="true"
&gt;                maxThreads="150"
&gt;                scheme="https" secure="true"
&gt;                clientAuth="false" sslProtocol="TLS"
&gt;                keystoreFile="<span style="color: blue">/etc/pki/tls/keystore/demo.colabrativ.com.jks</span>"
&gt;                keystorePass="<span style="color: #080; font-weight:600;">password</span>" /&gt;
</pre>
</div>
<h3>Useful Resources</h3>
<ol>
<li>SSL Shopper&#8217;s <a target="_blank" href="http://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html">The Most Common Java Keytool Keystore Commands</a></li>
<li>SSL Shopper&#8217;s <a target="_blank" href="http://www.sslshopper.com/article-most-common-openssl-commands.html">The Most Common OpenSSL Commands</a></li>
<li>Wikipedia&#8217;s page on <a target="_blank" href="http://en.wikipedia.org/wiki/X.509">X.509</a>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.colabrativ.com/creating-ssl-certificates-for-google-web-toolkit-running-on-apache-httpd-and-tomcat-on-amazon-web-services-ec2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Development of Enterprise Clinical Application for The Clearity Foundation</title>
		<link>http://www.colabrativ.com/development-of-enterprise-clinical-application-for-the-clearity-foundation/</link>
		<comments>http://www.colabrativ.com/development-of-enterprise-clinical-application-for-the-clearity-foundation/#comments</comments>
		<pubDate>Tue, 31 Jul 2012 22:21:30 +0000</pubDate>
		<dc:creator>Marc Whitlow</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Clinical]]></category>
		<category><![CDATA[Enterprise]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[patients]]></category>

		<guid isPermaLink="false">http://www.colabrativ.com/?p=488</guid>
		<description><![CDATA[During the 2nd quarter of 2012 we have been developing an enterprise clinical application for The Clearity Foundation. The Clearity Foundation is a non-profit organization dedicated to &#8220;improving treatment options for ovarian cancer patients.&#8221; Patient Information Entry Our initial focus &#8230; <a href="http://www.colabrativ.com/development-of-enterprise-clinical-application-for-the-clearity-foundation/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>During the 2nd quarter of 2012 we have been developing an enterprise clinical application for <a href="http://www.clearityfoundation.org/">The Clearity Foundation</a>.  The Clearity Foundation is a non-profit organization dedicated to &#8220;improving treatment options for ovarian cancer patients.&#8221; </p>
<h3>Patient Information Entry</h3>
<p>Our initial focus is on entry of patient information and test results by the foundation staff, with the initial goal of automating the process as much as possible. The forms in the application are organized as tabs; see Figure 1.  The tabs are organized to match the work flow of entering and analyzing patient information and test results. </p>
<table style="border:0px solid white;">
<tr>
<td style="border:0px solid white;">People:</td>
<td style="border:0px solid white;">The people tab contains Patient Information, Physician Information and the Relationship forms. The Relationship form creates associate between patients and and their physicians.</td>
</tr>
<tr>
<td style="border:0px solid white;">History:</td>
<td style="border:0px solid white;">The patient clinical history is entered under the History tab.  The foundation collects information on disease progress, surgeries, drug treatments, imaging and diagnostic procedures.</td>
</tr>
<tr>
<td style="border:0px solid white;">Specimens:</td>
<td style="border:0px solid white;">The Specimen form collects relevant information on specimens that have been collected from the patient, clinical locations of the specimens, and the physicians associated with the specimens; see Figure 2c.</td>
</tr>
<tr>
<td style="border:0px solid white;">Results:</td>
<td style="border:0px solid white;">Results from testing laboratories can be associated with a specimen and uploaded to the server, where they are processed and returned as test sets.  Each test set is displayed under its own expandable element.  Each result in a test set can be edited; see Figure 3.</td>
</tr>
<tr>
<td style="border:0px solid white;">Analysis:</td>
<td style="border:0px solid white;">The analysis of patient information and test results is initialized and displayed under the Analysis tab.</td>
</tr>
</table>
<table style="border:0px solid white;">
<caption style="font-size: 12pt; padding: 4px;">Figure 1<br />People Tab in the Application</caption>
<tr>
<td style="border:0px solid white; padding: 0px;">
    <img src="http://www.colabrativ.com/images/Clearity_People_tab.png" width="640" alt="The People tab contains the Patient Information, the Physician Information and the Relationship forms.  The Relationship form manages the relationship between patients and and their physicians."/>
  </td>
</tr>
<tr>
<td style="border:1px solid #40BCBF; test-align: center; font-size: 10pt; color: #606060; line-height: 115%;">People tab in The Clearity Foundation application.  All of the personal information displayed in this figure is fictitious and does not represent real individuals.</td>
</tr>
</table>
<table style="border:0px solid white;">
<caption style="font-size: 12pt; padding: 4px;">Figure 2<br />Specimens Tab in The Clearity Foundation Application</caption>
<tr>
<td style="border:0px solid white; padding: 0px;">
    <img src="http://www.colabrativ.com/images/Clearity_Specimens_tab.png" width="640" alt="The Specimen form/tab collects the relevant information on the specimens that were collected from the patient.  The clinical location of the specimen, and the physician associated with the specimen captured in this form."/>
  </td>
</tr>
<tr>
<td style="border:1px solid #40BCBF; test-align: center; font-size: 10pt; color: #606060; line-height: 115%;">Specimens tab in The Clearity Foundation application.  All of the personal information displayed in this figure is fictitious and does not represent real individuals or their specimens.</td>
</tr>
</table>
<table style="border:0px solid white;">
<caption style="font-size: 12pt; padding: 4px;">Figure 3<br />Results Tab in The Clearity Foundation Application</caption>
<tr>
<td style="border:0px solid white; padding: 0px;">
    <img src="http://www.colabrativ.com/images/Clearity_Results_tab.png" width="640" alt="The Specimen form/tab collects the relevant information on the specimens that were collected from the patient.  The clinical location of the specimen, and the physician associated with the specimen captured in this form."/>
  </td>
</tr>
<tr>
<td style="border:1px solid #40BCBF; test-align: center; font-size: 10pt; color: #606060; line-height: 115%;">Results tab in The Clearity Foundation application.  At the top, the Add (upload) section and one of the &#8220;Test-Lab&#8221; test set have been opened.  In the open test set one of the IHC results is being edited.  All of the personal information displayed in this figure is fictitious and does not represent real individuals or their results.</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.colabrativ.com/development-of-enterprise-clinical-application-for-the-clearity-foundation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iExperiment Version 1.1 is Now Available</title>
		<link>http://www.colabrativ.com/iexperiment-enterprise-electronic-notebook-version-1-1/</link>
		<comments>http://www.colabrativ.com/iexperiment-enterprise-electronic-notebook-version-1-1/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 20:43:17 +0000</pubDate>
		<dc:creator>Marc Whitlow</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[electronic notebook]]></category>
		<category><![CDATA[ELN]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[iExperiment]]></category>

		<guid isPermaLink="false">http://www.colabrativ.com/?p=430</guid>
		<description><![CDATA[We are pleased to announce the release of version 1.1 of iExperiment, Colabrativ&#8217;s enterprise electronic notebook. Changes to iExperiment an Enterprise Electronic Notebook The following changes have been made to version 1.1 of iExperiment Enterprise Electronic Notebook (ELN): The options &#8230; <a href="http://www.colabrativ.com/iexperiment-enterprise-electronic-notebook-version-1-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We are pleased to announce the release of version 1.1 of iExperiment, Colabrativ&#8217;s enterprise electronic notebook.  </p>
<h3 style="margin: 0">Changes to iExperiment an Enterprise Electronic Notebook</h3>
<p>The following changes have been made to version 1.1 of iExperiment Enterprise Electronic Notebook (ELN): </p>
<ul>
<li>The options for viewing records under the Select tab have been changed.  There are now four &ldquo;List of Records I Can&rdquo; options: read, edit, delete and download.<br />
<table style="border:0px solid white;">
<caption style="font-size: 11pt; padding: 4px;">Figure 1 <br />New View Record Options under Select Tab</caption>
<tr>
<td style="border:0px solid white; padding: 0px; test-align: center;"><img src="http://www.colabrativ.com/images/view_record_read_option_1.1.png" width="622" alt="Top of Select tab in iExperiment, Colabrativ's enterprise electronic notebook, showing the four new &ldquo;List of Records I Can&rdquo; options: read, edit, delete and download. The read option has been selected."/></td>
</tr>
<tr>
<td style="border:1px solid #606060; test-align: center; font-size: 10pt; color: #606060; line-height: 115%;">Top of Select tab in iExperiment showing the four new &ldquo;List of Records I Can&rdquo; options: read, edit, delete and download.  The read option has been selected.</td>
</tr>
</table style="border:0px solid white;">
  </li>
<li>Copy Record, Download Record Archive and Download PDF Archive buttons have been added to the tops of records.<br />
<table style="border:0px solid white;">
<caption style="font-size: 11pt; padding: 4px;">Figure 2 <br />New Copy Record, Download Record Archive and Download PDF Archive Buttons</caption>
<tr>
<td style="border:0px solid white; padding: 0px; test-align: center;"><img src="http://www.colabrativ.com/images/record_buttons_1.1.png" width="624" alt="Copy Record, Download Record Archive and Download PDF Archive buttons at the top of a record in iExperiment, Colabrativ's enterprise electronic notebook. "/></td>
</tr>
<tr>
<td style="border:1px solid #606060; test-align: center; font-size: 10pt; color: #606060; line-height: 115%;">New Copy Record, Download Record Archive and Download PDF Archive buttons at the top of a record in iExperiment.</td>
</tr>
</table>
</li>
<li>Sponsoring Institution options have been added to the experiment properties file.  The options are:
<ul style="list-style-type: circle;">
<li>admin:  Where the sponsored institution will be the primary administrator (institution key = 1).</li>
<li>author:  Where the institution of the author&#8217;s active research period will be used.</li>
<li>key=:  The sponsoring institution key will be identified by its database key; Example key=23</li>
</ul>
<p>      In this AMI the sponsoring institution option is &#8220;admin&#8221;.</li>
<li>Bug Fix: The material Oracle was failing to add materials that lacked a lot or serial number.</li>
<li>Bug Fix: Sections containing no text, such as a Summary section with only the material produced, were not being displayed from a record archive in a web browser, despite being contained in the record archive.</li>
</ul>
<h3 style="margin: 0">Evaluating iExperiment an Enterprise Electronic Notebook</h3>
<p>It&#8217;s easy for you to evaluate iExperiment through <a target="_blank" href="http://aws.amazon.com">Amazon Web Services</a>.  A <a target="_blank" href="http://www.colabrativ.com/free-61-day-trial-of-iexperiment-enterprise-electronic-notebook/">three-part tutorial</a> is available, under the Free Trial tab in the navigation bar above, to guide you through  i) the creation of an <a target="_blank" href="http://aws.amazon.com/ec2/">Amazon Elastic Compute Cloud</a> instance using the <a target="_blank" href="http://www.colabrativ.com/61-day-iexperiment-v1-1-evaluation-ami-4f5c070a/">iExperiment AMI</a>,  ii) configuration of iExperiment, and iii) adding your first researcher.</p>
<h3 style="margin: 0">Browser Compatibility of iExperiment</h3>
<p>iExperiment is built on <a target="_blank" href="http://code.google.com/webtoolkit/overview.html">Google Web Toolkit</a> and is not compatible with all browsers.  Currently, iExperiment works with <a target="_blank" href="http://www.mozilla.org/en-US/firefox/new/">Mozilla&#8217;s FireFox</a> and <a target="_blank" href="https://www.google.com/chrome">Google&#8217;s Chrome</a>, but does not work with Microsoft&#8217;s Internet Explorer or Apple&#8217;s Safari.  Both Safari and Internet Explorer suffer from the same two problems: </p>
<ol>
<li>The text editor fails to maintain preexisting text.</li>
<li>The file drag-and-drop capability introduces characters into the file names in Safari, and does not work at all in Internet Explorer.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.colabrativ.com/iexperiment-enterprise-electronic-notebook-version-1-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>File Drag and Drop onto a Google Web Toolkit Application</title>
		<link>http://www.colabrativ.com/file-drag-and-drop-onto-a-google-web-toolkit-application/</link>
		<comments>http://www.colabrativ.com/file-drag-and-drop-onto-a-google-web-toolkit-application/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 03:29:31 +0000</pubDate>
		<dc:creator>Marc Whitlow</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[drag & drop]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[iExperiment]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[XMLSttpRequest]]></category>

		<guid isPermaLink="false">http://www.colabrativ.com/?p=316</guid>
		<description><![CDATA[Users increasingly expect to be able to drag and drop objects in applications, including web applications. I would like to show you how we recently added the ability to drop files on to our enterprise electronic notebook iExperiment. iExperiment&#8217;s client &#8230; <a href="http://www.colabrativ.com/file-drag-and-drop-onto-a-google-web-toolkit-application/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Users increasingly expect to be able to drag and drop objects in applications, including web applications.  I would like to show you how we recently added the ability to drop files on to our enterprise electronic notebook iExperiment. iExperiment&#8217;s client side is built on Google Web Toolkit (GWT).  GWT currently does not support file drag and drop. </p>
<p>The work flow for file drag and drop is as follows: </p>
<ol>
<li>The user drops a file on to the client.</li>
<li>The client sends the drop element id and the file to the server in a multipart POST for storage and analysis.</li>
<li>The server sends back the POST response to the client with information on how to display the dropped file.</li>
<li>The client presents the uploaded file&#8217;s information to the user.</li>
</ol>
<p>We are using cutting edge HTML5 APIs in our drag and drop implementation.  Support of these APIs is not available in all browsers. </p>
<ul>
<li>This code works today in recent versions of Chrome and FireFox. </li>
<li>In Safari there is an issue with extra characters being added to the file names, which also complicates the file type assignment. </li>
<li>Internet Explorer does not currently support the required APIs. </li>
</ul>
<p>The file drop event is handled by adding an &#8220;ondrop&#8221; attribute to the HTML elements.  The &#8220;ondrop&#8221; attribute calls the droppedFile JavasScript routine that creates and sends an HTTP POST request to the server.  Note that the first argument in the droppedFile JavaScript call is an &#8220;element-id&#8221;, and the event is the second argument.  The drop element ID allows us to identify where the file was dropped on the page.</p>
<div class="codeBox">
  <strong>Example of &#8220;ondrop&#8221; Attribute in an HTML Table Element</strong></p>
<pre>&lt;table ondrop="event.stopPropagation();
               event.preventDefault();
               droppedFile('element-id', event);"&gt;</pre>
</div>
<p>The &#8220;ondrop&#8221; element is created by the static addOnDrop method in a client side class (DropFileConnector). </p>
<div class="codeBox">
  <strong>addOnDrop Method</strong></p>
<pre>/** Add an ondrop attribute to an element in the DOM, for example:
 * ondrop="event.stopPropagation(); droppedFile('element-id', event);"
 *
 * @param element DOM element
 * @param elementID Element Id to be sent to droppedFile routine.
 */
 public static void addOnDrop(Element element, String elementID) {
     element.setAttribute("ondrop",
         "event.stopPropagation(); droppedFile(\'" + elementID + "\', event);");
 }</pre>
</div>
<p>The droppedFile JavaScript routine creates a FormData element which is transferred to the server using a multipart HTTP POST request.  The first two items appended to the form are the drop element ID (dropElementID) and boundary that is used by the request onreadystatechange function.  Two appends are made to the form for each file that is uploaded; the file length (line 16), and the file itself (line 17) are appended to the form.  On lines 20-24 the information needed for the POST is created, and the upload handlers are attached to the request.  Note that by using a FormData element we are able to eliminate the deprecated FireFox specific methods <code>files[i].getAsBinary()</code>, and replace <code>request.sendAsBinary(postContent)</code> with request.send(formData).  These methods were used in our <a target="_blank" href=""http://www.colabrativ.com/drag-and-drop-onto-a-google-web-toolkit-application-utdated">original post</a> to added the files to the POST, and to send the POST, respectively. </p>
<p>The POST responses are handled by the request.onreadystatechange function on line 26-40, and are sent to the client through <code>window.top.dropFileListener.droppedFile method</code> (calls on lines 34 and 38.)  Initially when the read state is 1 (<code>readyState == 1</code>) the file name and the MIME boundary are sent to GWT client application on lines 28-35.  After succesful completion of the POST (<code>readyState == 4</code>), the POST response is forwarded to the GWT client application.</p>
<div class="codeBox">
  <strong>droppedFile JavaScript Routine</strong></p>
<pre>01  var boundary = null;
02
03  function droppedFile(dropElementID, event) {
04      if (window.File &amp;&amp; window.FileList &amp;&amp; window.top.dropFileListener) {
05          if (event.dataTransfer) {
06              url = secureURL + "upload";
07              boundary = "Colabrativ-" + Math.floor(999999999999999 * Math.random());
08
09              var formData = new FormData();
10              formData.append("drop-element-id", dropElementID);
11              formData.append("boundary", boundary);
12
13              var files = event.dataTransfer.files;
14
15              for (var i = 0; i < files.length; i++) {
16                  formData.append("file-length-" + i, files[i].size);
17                  formData.append("file-"        + i, files[i]);
18              }
19
20              var request = new XMLHttpRequest();
21              request.upload.onprogress = updateProgress;
22              request.upload.onload     = loaded;
23              request.upload.onerror    = loadError;
24              request.open("POST", url, true);
25
26              request.onreadystatechange = function() {
27                  if (this.readyState == 1) {
28                      var filesJSON = '"files":[';
29                      for (var i = 0; i < files.length; i++) {
30                          filesJSON = filesJSON + '"' + files[i].name + '"';
31                          if (i < files.length - 1) filesJSON = filesJSON + ', ';
32                      }
33                      filesJSON = filesJSON + ']'
34                      window.top.dropFileListener.droppedFile( '{' +
35                          '"requestBoundary": "' + boundary + '", ' + filesJSON + '}');
36                  }
37                  if (this.readyState == 4) {
38                     window.top.dropFileListener.droppedFile( request.responseText );
39                  }
40              }
41
42              request.send(formData);
43          }
44          else {
45              alert("Your browser does not support file drag and drop.  " +
46                    "We recommend that you upgrade your browser to one that supports HTML5, " +
47                    "such as Mozilla's FireFox or Google's Chrome.");
48          }
49      }
50      else {
51          alert("window.top.dropFileListener not found!");
52      }
53  }</pre>
</div>
<p>The DropFileConnector class connects the dropFileListener in the JavaScript to the GWT code.  The DropFileConnector class has a ClientSideDropFileSupport interface that defines the droppedFile method in the JavaScript.  The observer (theObserver) is a static ClientSideDropFileSupport incidence that connects to the JavaScript droppedFile method to ClientSideDropFile&#8217;s droppedFile method. </p>
<div class="codeBox">
  <strong>DropFileConnector class</strong></p>
<pre>package com.colabrativ.common.client; 

import com.google.gwt.dom.client.Element; 

public class DropFileConnector {
    /** Used to pass information to the GWT application. Register your implementations with
      *  {@link com.colabrativ.common.client.DropFileConnector#connect( ClientSideDropFileSupport)}
      */
    public interface ClientSideDropFileSupport {
        /** The page calls this method to send dropped file information to application
          *
          * @param json JSON string containing the file name information.
          */
        void droppedFile(String json);
    } 

    /** An observer of drop file events, supplied by the GWT application. */
    static private ClientSideDropFileSupport theObserver; 

    /**
      * Connect the GWT application to the drop file JavaScript. The observer is notified
      * whenever the user drops a file on the application area (id="app-area").
      *
      * @param observer
      */
     public static void connect( ClientSideDropFileSupport observer ) {
         theObserver = observer;
         connectToPanel();
     }

     // These methods are "glue" methods that let the simple JNDI call talk to the observer through its interface.
     @SuppressWarnings("all")
     private static void droppedFile(String s) { theObserver.droppedFile(s); }

     private static native void connectToPanel() /*-{
         var listener = new Object();
         listener.droppedFile = function(json) {
             json = unescape( json );
             @com.colabrativ.common.client.DropFileConnector::droppedFile( Ljava/lang/String;)( json );
         };

         $wnd.top.dropFileListener = listener;
     }-*/; 

     /**
       * Add an ondrop attribute to an element in the DOM, for example:
       * ondrop="event.stopPropagation(); droppedFile('element-id', event);"
       *
       * @param element DOM element
       * @param elementId Element Id to be sent to droppedFile routine.
       */
      public static void addOnDrop(Element element, String elementId) {
          element.setAttribute("ondrop",
              "event.stopPropagation(); droppedFile(\'" + elementId + "\', event);");
      }
} </pre>
</div>
<p>Finally, a <code>DropFileConnector.connect</code> call is made in a client class that handles the POST responses.  Our upload servlet adds either an OKAY or a FAIL to the POST response that the DropFileConnector handles.  In our implementation, the POST responses are encapsulated in JSON.  The upload progress monitoring is also handled by the DropFileConnector.  In our implementation, the MIME boundary is used as an Id for the upload, and the monitoring is managed by the singleton of the UploadManager class. </p>
<div class="codeBox">
  <strong>DropFileConnector Connection</strong></p>
<pre>DropFileConnector.connect(
    new DropFileConnector.ClientSideDropFileSupport() {
        public void droppedFile(String response) {
            if (response.startsWith("OKAY:")) {
                String json = response.substring( response.indexOf(": ") + 2); // Remove OKAY:
                determineWhatToDoWithResponse(json);
            }
            else if (response.startsWith("FAIL:")) {
                // Do Nothing?
            }
            else {
                JSONObject responseJSON = (JSONObject) JSONParser.parseStrict( response );
                JSONString boundaryJSON = (JSONString) responseJSON.get( UploadResponse.requestBoundary);

                if (boundaryJSON != null) {
                    String boundary = boundaryJSON.toString();
                    JSONArray filesJSON = (JSONArray) responseJSON.get( UploadResponse.files);

                    if (filesJSON != null) {
                        UploadManager.getInstance().addProgressDialog( boundary, filesJSON);
                    }
                    else {
                        UploadManager.getInstance().update( boundary, responseJSON);
                    }
                }
            }
        }
    }
); </pre>
</div>
<p>Several resources helped us create our file drag and drop; these included: </p>
<ol>
<li>W3C XMLHttpRequest Level 2 <a target="_blank" href="http://www.w3.org/TR/XMLHttpRequest2/">http://www.w3.org/TR/XMLHttpRequest2/</a></li>
<li>W3C File API <a target="_blank" href="http://www.w3.org/TR/file-upload/">http://www.w3.org/TR/file-upload/</a></li>
<li>Using FormData object in Mozilla&#8217;s Developers Network page on Using XMLHttpRequest at <a target="_blank" href="https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Using_FormData_objects">https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Using_FormData_objects</a></li>
<li>How to Use HTML5 File Drag &amp; Drop by Craig Buckler at <a target="_blank" href="http://www.sitepoint.com/html5-file-drag-and-drop/">http://www.sitepoint.com/html5-file-drag-and-drop/</a></li>
<li>XHR progress and rich file upload feedback by Austin King at <a target="_blank" href="http://hacks.mozilla.org/2009/06/xhr-progress-and-richer-file-uploading-feedback/">http://hacks.mozilla.org/2009/06/xhr-progress-and-richer-file-uploading-feedback/</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.colabrativ.com/file-drag-and-drop-onto-a-google-web-toolkit-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>File Drag and Drop onto a Google Web Toolkit Application &#8211; Outdated</title>
		<link>http://www.colabrativ.com/drag-and-drop-onto-a-google-web-toolkit-application-utdated/</link>
		<comments>http://www.colabrativ.com/drag-and-drop-onto-a-google-web-toolkit-application-utdated/#comments</comments>
		<pubDate>Sat, 30 Apr 2011 22:11:21 +0000</pubDate>
		<dc:creator>Marc Whitlow</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[drag & drop]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[iExperiment]]></category>

		<guid isPermaLink="false">http://www.colabrativ.com/?p=18</guid>
		<description><![CDATA[Users increasingly expect to be able to drag and drop objects in applications, including web applications. I would like to show you how we recently added the ability to drop files on to our enterprise electronic notebook iExperiment. iExperiment&#8217;s client &#8230; <a href="http://www.colabrativ.com/drag-and-drop-onto-a-google-web-toolkit-application-utdated/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Users increasingly expect to be able to drag and drop objects in applications, including web applications.  I would like to show you how we recently added the ability to drop files on to our enterprise electronic notebook iExperiment. iExperiment&#8217;s client side is built on Google Web Toolkit (GWT).  GWT currently does not support file drag and drop. </p>
<p>The work flow for file drag and drop is as follows: </p>
<ol>
<li>The user drops a file on to the client.</li>
<li>The client sends the drop element id and the file to the server in a multipart POST for storage and analysis.</li>
<li>The server sends back the POST response to the client with information on how to display the dropped file.</li>
<li>The client presents the upload file&#8217;s information to the user.</li>
</ol>
<p>The file drop event is handled by adding &#8220;ondrop&#8221; attribute to the HTML elements.  The &#8220;ondrop&#8221; attribute calls the droppedFile Javascript routine that creates and sends an HTTP POST request to the server. Note, that the first argument in the droppedFile Javascript call is an &#8220;element-id&#8221;, and the event as the second argument.  The drop element ID allows us to identify where the file was drop on the page.</p>
<div class="codeBox">
<strong>Example of &#8220;ondrop&#8221; Attribute in an HTML Table Element</strong></p>
<pre>&lt;table ondrop="event.stopPropagation();
               event.preventDefault();
               droppedFile('element-id', event);"&gt;</pre>
</div>
<p>The &#8220;ondrop&#8221; element is created by the static addOnDrop method in a client side class (DropFileConnector). </p>
<div class="codeBox">
<strong>addOnDrop Method</strong></p>
<pre>
/** Add a ondrop attribute to an element in the DOM, example:
 * ondrop="event.stopPropagation(); droppedFile('element-id', event);"
 *
 * @param element DOM element
 * @param elementID Element Id to be sent to droppedFile joutine.
 */
public static void addOnDrop(Element element, String elementID) {
    element.setAttribute("ondrop",
        "event.stopPropagation(); droppedFile(\'" + elementID + "\', event);");
}
</pre>
</div>
<p>The droppedFile Javascript routine creates a multipart HTTP POST request.  On lines 6-9 the information needed for the POST is gathered and created, including the URL, files and boundary.  The XMLHttpRequest is created on line 10 and upload progress monitoring is set up in lines 12-14.  The POST is created on lines 16-35 and sent on line 43.  The first part of the POST contains the element Id (dropElementID) and the subsequent parts (lines 26-33) contain the files that were drop on the page.  Note, that a binary file get <code>.getAsBinary()</code> is used on line 32. </p>
<p>The POST responses are handled by the request.onreadystatechange function on line 37-51, and are sent to the client through <code>window.top.dropFileListener.droppedFile( );</code> calls on lines 45 and 49.  Initially (<code>readyState == 1</code>) the file name being uploaded along with the MIME boundary are sent to the client on lines 39-46.  After succesful completion of the POST (<code>readyState == 4</code>), the POST response is forward to the GWT application.</p>
<div class="codeBox">
<strong>droppedFile Javascript Routine</strong></p>
<pre>
01  var boundary = null;
02
03  function droppedFile(dropElementID, event) {
04      if( window.top.dropFileListener ) {
05          if (event.dataTransfer) {
06              var url = secureURL + "upload";
07              var token = document.cookie.substring( 26, document.cookie.indexOf("userName") - 12);
08              var files = event.dataTransfer.files;
09              boundary = "BoUnDaRy_._-_._-_._" + Math.floor(999999999999999 * Math.random());
10              var request = new XMLHttpRequest();
11
12              request.upload.onprogress = updateProgress;
13              request.upload.onload 	  = loaded;
14              request.upload.onerror 	  = loadError;
15
16              request.open("POST", url, true); // open asynchronous post
17              request.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
18              request.setRequestHeader("Session-Token", token);
19
20              var postContent = "--" + boundary + "\r\n" +
21                  "Content-Disposition: info; name=\"drop-element-id\"\r\n" +
22                  "\r\n" +
23                  dropElementID + "\r\n" +
24                  "--" + boundary;
25
26              for (var i = 0; i &lt; files.length; i++) {
27                  postContent = postContent + &quot;\r\n&quot; +
28                      &quot;Content-Disposition: file; name=\&quot;file\&quot;; filename=\&quot;&quot; + files[i].name + &quot;\&quot;\r\n&quot; +
29                      &quot;Content-Type: application/xml\r\n&quot; +
30                      &quot;File-Length: &quot; + files[i].size + &quot;\r\n&quot; +
31                      &quot;\r\n&quot; +
32                      files[i].getAsBinary() + &quot;\r\n&quot; +
33                      &quot;--&quot; + boundary;
34              }
35              postContent = postContent + &quot;--\r\n&quot;;
36
37              request.onreadystatechange = function() {
38                  if(this.readyState == 1) {
39                      var filesJSON = &#039;&quot;files&quot;:[&#039;;
40                      for (var i = 0; i &lt; files.length; i++) {
41                          filesJSON = filesJSON + &#039;&quot;&#039; + files[i].name + &#039;&quot;&#039;;
42                          if (i &lt; files.length - 1) filesJSON = filesJSON + &#039;, &#039;;
43                      }
44                      filesJSON = filesJSON + &#039;]&#039;
45                      window.top.dropFileListener.droppedFile( &#039;{&#039; +
46                          &#039;&quot;requestBoundary&quot;: &quot;&#039; + boundary + &#039;&quot;, &#039; + filesJSON + &#039;}&#039;);
47                  }
48                  if(this.readyState == 4) {
49                      window.top.dropFileListener.droppedFile( request.responseText );
50                  }
51              }
62
53              request.sendAsBinary(postContent);
54          }
55          else {
56              alert(&quot;Your browser does not support file drag and drop. &quot; +
57                      &quot;We recommend that upgrade your browser to one that support HTML5, &quot; +
58                      &quot;such as Mozella&#039;s FireFox or Apple&#039;s Safari or Google&#039;s Chrome.&quot;);
59          }
60      }
61      else {
62          alert(&quot;window.top.dropFileListener not found!&quot;);
63      }
64  }
</pre>
</div>
<p>The DropFileConnector class connects the dropFileListener in the Javascript to the GWT code. DropFileConnector class has a ClientSideDropFileSupport interface that defines the droppedFile method in the JavaScript.  theObserver is a static ClientSideDropFileSupport incidence that connects to Javascript droppedFile method to ClientSideDropFile&#8217;s droppedFile method. </p>
<div class="codeBox">
<strong>DropFileConnector class</strong></p>
<pre>
package com.colabrativ.common.client; 

import com.google.gwt.dom.client.Element; 

public class DropFileConnector {
    /** Used to pass information to the GWT application. Register your implementations with
     *  {@link com.colabrativ.common.client.DropFileConnector#connect( ClientSideDropFileSupport)}
     */
    public interface ClientSideDropFileSupport {
        /** The page calls this method to send dropped file information to application
         *
         * @param json JSON string containing the file name information.
         */
        void droppedFile(String json);
    } 

    /** An observer of drop file events, supplied by the GWT application. */
    static private ClientSideDropFileSupport theObserver; 

    /**
     * Connect the GWT application to the drop file JavaScript. The observer is notified
     * whenever the user drops a file on the application area (id="app-area").
     *
     * @param observer
     */
    public static void connect( ClientSideDropFileSupport observer ) {
        theObserver = observer;
        connectToPanel();
    }

    // This method are "glue" methods that let the simple JNDI call talk to the observer through its interface.
    @SuppressWarnings("all")
    private static void droppedFile(String s) { theObserver.droppedFile(s); }

    private static native void connectToPanel() /*-{
        var listener = new Object();
        listener.droppedFile = function(json) {
            json = unescape( json );
            @com.colabrativ.common.client.DropFileConnector::droppedFile( Ljava/lang/String;)( json );
        };

        $wnd.top.dropFileListener = listener;
    }-*/; 

    /**
     * Add a ondrop attribute to an element in the DOM, example:
     * ondrop="event.stopPropagation(); droppedFile('element-id', event);"
     *
     * @param element DOM element
     * @param elementId Element Id to be sent to droppedFile routine.
     */
    public static void addOnDrop(Element element, String elementId) {
        element.setAttribute("ondrop",
            "event.stopPropagation(); droppedFile(\'" + elementId + "\', event);");
    }
}
</pre>
</div>
<p>Finally, a <code>DropFileConnector.connect</code> call is made in a client class that handles the POST responses.  Our upload servlet adds either a OKAY or a FAIL to the POST response that the DropFileConnector handles.  In our implementation the POST responces are encapsulated in JSON.  The upload progress monitoring is also handled by the DropFileConnector.  In our implementation the MIME boundary is used as an Id for the upload, and the monitoring is managed by the singleton of the UploadManager class.</p>
<div class="codeBox">
<strong>DropFileConnector Connection</strong></p>
<pre>
DropFileConnector.connect
(
    new DropFileConnector.ClientSideDropFileSupport() {
        public void droppedFile(String response) {
            if (response.startsWith("OKAY:")) {
                String json = response.substring( response.indexOf(": ") + 2); // Remove OKAY:
                determineWhatToDoWithResponse(json);
            }
            else if (response.startsWith("FAIL:")) {
                // Do Nothing?
            }
            else {
            	JSONObject responseJSON = (JSONObject) JSONParser.parseStrict( response );
                JSONString boundaryJSON = (JSONString) responseJSON.get( UploadResponse.requestBoundary);

                if (boundaryJSON != null) {
                    String boundary = boundaryJSON.toString();
                    JSONArray filesJSON = (JSONArray) responseJSON.get( UploadResponse.files);

                    if (filesJSON != null) {
                        UploadManager.getInstance().addProgressDialog( boundary, filesJSON);
                    }
                    else {
                        UploadManager.getInstance().update( boundary, responseJSON);
                    }
                }
            }
        }
    }
);
</pre>
</div>
<p>Several resources helped us create our file drag and drop; these included: </p>
<ol>
<li>Box.net and html5 drag and drop blog by Christopher Blizzasrd at <a href="http://hacks.mozilla.org/2010/06/html5-adoption-stories-box-net-and-html5-drag-and-drop/">http://hacks.mozilla.org/2010/06/html5-adoption-stories-box-net-and-html5-drag-and-drop/</a></li>
<li>Mozilla&#8217;s developers Network page on Using XMLHttpRequest <a href="https://developer.mozilla.org/En/Using_XMLHttpRequest">https://developer.mozilla.org/En/Using_XMLHttpRequest</a></li>
<li>XHR progress and rich file upload feedback by Austin King at <a href="http://hacks.mozilla.org/2009/06/xhr-progress-and-richer-file-uploading-feedback/">http://hacks.mozilla.org/2009/06/xhr-progress-and-richer-file-uploading-feedback/</a>	</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.colabrativ.com/drag-and-drop-onto-a-google-web-toolkit-application-utdated/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
