<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
  <title>concena.com</title>
  <link rel="alternate" href="" />
  <subtitle>concena.com</subtitle>
  <entry>
    <title>Looking for Contract Nuxeo Developers</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15689" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15689</id>
    <updated>2013-04-12T16:11:14Z</updated>
    <published>2013-04-12T16:02:45Z</published>
    <summary type="html">&lt;p&gt;
	We are currently looking for a few contract Nuxeo DM and DAM developers to help out on a number of client and internal projects. Experience with IDE-based Nuxeo plugin development is a must. Experience with Google Web Toolkit would be beneficial but is not required. If you are interested, please submit your resume, rate expectations and contact information to bruce@concena.com.&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2013-04-12T16:02:45Z</dc:date>
  </entry>
  <entry>
    <title>Great resource for Nuxeo developers...</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15629" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15629</id>
    <updated>2013-03-13T14:11:38Z</updated>
    <published>2013-03-13T14:06:38Z</published>
    <summary type="html">&lt;p&gt;
	Whether you are starting out as a Nuxeo Developer or been working at it for years, the Nuxeo &lt;a href="http://www.nuxeo.com/en/developers"&gt;For Developers&lt;/a&gt; page is a great launch pad. Heck, even if you&amp;#39;re not a Nuxeo developer, the resources for Maven and Git usage serve as great topical examples!&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2013-03-13T14:06:38Z</dc:date>
  </entry>
  <entry>
    <title>Comment on Nuxeo Tech Report 4 - DAM</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15622" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15622</id>
    <updated>2013-03-11T14:59:22Z</updated>
    <published>2013-03-11T14:45:06Z</published>
    <summary type="html">&lt;p&gt;
	Studio and UI configurability enhancements in Nuxeo DAM are welcome improvements. Making more of the interface more easily configurable with help more quickly meet customer requirements.&lt;/p&gt;
&lt;p&gt;
	Unfortunately, I think Nuxeo has missed the mark when it comes to DAM performance. While DM has certain performance requirements, they pale in comparison to DAM. The average Nuxeo DM document (with attachments) is orders of magnitude smaller than a typically DAM asset. In this case I am talking about the use of DAM for high resolution images, graphics, and video.&lt;/p&gt;
&lt;p&gt;
	There are challenges storing, rendering, and presenting all of these large files. Hardware (RAM, disk speed, CPU) is an extremely important part of the equation, but equally so are the underlying libraries that extract metadata, render lower resolution images, and stream video. Nuxeo&amp;#39;s own code, wrapped around these libraries is also an important (and sometimes limiting) factor.&lt;/p&gt;
&lt;p&gt;
	I believe that for Nuxeo DAM to be useful (in a marketing firm for example) there needs to be significant work on performance and scalability of DAM.&lt;/p&gt;
&lt;p&gt;
	That&amp;#39;s my two cents, albeit based though on real life experience with DAM. Anybody else have similar experience with DAM and handling of large digital assets?&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2013-03-11T14:45:06Z</dc:date>
  </entry>
  <entry>
    <title>Integrating GWT Applications with Nuxeo</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15608" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15608</id>
    <updated>2013-03-02T17:50:00Z</updated>
    <published>2013-03-01T17:38:36Z</published>
    <summary type="html">&lt;p&gt;
	While support for GWT is baked into Nuxeo, this native approach doesn&amp;#39;t offer the flexibility I&amp;#39;m after to create composite applications where Nuxeo is just one source/sink of content. In previous applications, I have used a rest-client based approach using the &amp;nbsp;&lt;a href="http://restlet.org/"&gt;RESTLET framework&lt;/a&gt;. However, I couldn&amp;#39;t find any reasonable way to get the GWT datagrid control to play nicely using the restlet apporach. So, I switched gears, and returned to an HttpClient RPC approach for integrating GWT datagrids with Nuxeo.&lt;/p&gt;
&lt;p&gt;
	What I do is bind the DataGrid to an AsyncDataProvider. The provider is set up in the corresponding presenter.&lt;/p&gt;
&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
	// Create a data provider.&lt;/div&gt;
&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
	dataProviderAsync = new LaborProfileAsyncDataProvider(SharedConstants.API_ACTION_LIST, eventBus);&lt;/div&gt;
&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
	dataProviderAsync.addDataDisplay(getView().getDataGrid());&lt;/div&gt;
&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
	addColumnSortAsyncHandling();&lt;/div&gt;
&lt;div&gt;
	&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
	The provider&amp;#39;s onRangeChanged method then contains the applicable RPC server call. Data is reflected into the datagrid control in the onSuccess method (updateRowData and updateRowCount). OnSuccess also fires an event that has a listener update on screen statistics.&lt;/div&gt;
&lt;div&gt;
	&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
	&lt;div style="margin-left: 40px;"&gt;
		// RPC Call&lt;/div&gt;
	&lt;div style="margin-left: 40px;"&gt;
		rpcService.getLaborProfileList(action, CurrentUser.getInstance().getUserName(),&amp;nbsp;&lt;/div&gt;
	&lt;div style="margin-left: 40px;"&gt;
		&amp;nbsp; CurrentSession.getInstance().getSessionId(),&amp;nbsp;&lt;/div&gt;
	&lt;div style="margin-left: 40px;"&gt;
		&amp;nbsp; CurrentUser.getInstance().getOwnerId(), searchFilter, &amp;nbsp;&lt;/div&gt;
	&lt;div style="margin-left: 40px;"&gt;
		&amp;nbsp; new AsyncCallback&amp;lt;ArrayList&amp;lt;LaborProfileRowFlat&amp;gt;&amp;gt;() {&lt;/div&gt;
	&lt;div style="margin-left: 80px;"&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div style="margin-left: 80px;"&gt;
		@Override&lt;/div&gt;
	&lt;div style="margin-left: 80px;"&gt;
		public void onSuccess(ArrayList&amp;lt;LaborProfileRowFlat&amp;gt; result) {&lt;/div&gt;
	&lt;div style="margin-left: 120px;"&gt;
		if (result != null) {&lt;/div&gt;
	&lt;div style="margin-left: 160px;"&gt;
		filteredRowCount = result.size();&lt;/div&gt;
	&lt;div style="margin-left: 160px;"&gt;
		if (&amp;quot;&amp;quot;.equals(searchFilter)) {&lt;/div&gt;
	&lt;div style="margin-left: 200px;"&gt;
		totalRowCount = filteredRowCount;&lt;/div&gt;
	&lt;div style="margin-left: 160px;"&gt;
		}&lt;/div&gt;
	&lt;div style="margin-left: 160px;"&gt;
		updateRowData(0, result);&lt;/div&gt;
	&lt;div style="margin-left: 160px;"&gt;
		updateRowCount(filteredRowCount, true);&lt;/div&gt;
	&lt;div style="margin-left: 160px;"&gt;
		&lt;span style="line-height: 1.4;"&gt;eventBus.fireEvent(new UpdateLaborProfileStatsEvent());&lt;/span&gt;&lt;/div&gt;
	&lt;div style="margin-left: 120px;"&gt;
		}&lt;/div&gt;
	&lt;div style="margin-left: 80px;"&gt;
		}&lt;/div&gt;
	&lt;div style="margin-left: 40px;"&gt;
		});&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
	&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
	The rpcService class prepares the command url (in url) and the Nuxeo transaction (in jsonString), and then handles the resulting JSON. The URL corresponds to a defined URL restlet pattern in Nuxeo (still using restlets on the Nuxeo side), from example the pattern &amp;lt;urlPattern&amp;gt;/laborprofile/{action}&amp;lt;/urlPattern&amp;gt; is mapped to the Nuxeo restlet class that handles laborprofile transactions. The URL is the glue between the GWT caller and Nuxeo.&lt;/div&gt;
&lt;div&gt;
	&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
	&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
		// MAKE THE CALL and PROCESS THE RESULT...&lt;/div&gt;
	&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
		HttpEntity resEntity = HttpClientCall.execute(url, jsonString);&lt;/div&gt;
	&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
		String resSource = &amp;quot;&amp;quot;;&lt;/div&gt;
	&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
		JsonNode rootNode = null;&lt;/div&gt;
	&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
		JsonNode dataNode = null;&lt;/div&gt;
	&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
		&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/div&gt;
	&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
		if (resEntity != null) {&lt;/div&gt;
	&lt;div style="margin-left: 40px;"&gt;
		...&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		The actual HttpClient call requires a bit more packaging (call to set-up security is removed) but is relatively trivial.&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			// MAKE THE CALL&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			DefaultHttpClient client = new DefaultHttpClient();&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			...&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			HttpPost postMethod = new HttpPost(url);&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			StringEntity reqEntity = null;&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			&amp;nbsp;&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			try {&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			reqEntity = new StringEntity(jsonString, &amp;quot;application/json&amp;quot;, &amp;quot;UTF-8&amp;quot;);&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			} catch (UnsupportedEncodingException e1) {&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			System.out.println(&amp;quot;Error parsing jsonString&amp;quot;);&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			}&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			&amp;nbsp;&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			if (reqEntity != null) {&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			reqEntity.setChunked(false);&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			postMethod.setEntity(reqEntity);&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			postMethod.setHeader(&amp;quot;Connection&amp;quot;, &amp;quot;close&amp;quot;);&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			&amp;nbsp;&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			HttpResponse response = null;&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			try {&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 120px;"&gt;
			response = client.execute(postMethod);&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			} catch (ClientProtocolException e) {&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 120px;"&gt;
			e.printStackTrace();&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			} catch (IOException e) {&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 120px;"&gt;
			e.printStackTrace();&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			}&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			&amp;nbsp;&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			// PROCESS THE RESULT...&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			HttpEntity resEntity = response.getEntity();&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 80px;"&gt;
			return resEntity;&lt;/div&gt;
		&lt;div id="cke_pastebin" style="margin-left: 40px;"&gt;
			}&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
	&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
	Straighforward enough once you have worked out all the details.&lt;/div&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2013-03-01T17:38:36Z</dc:date>
  </entry>
  <entry>
    <title>Wearable Computers and the MYO #getmyo @thalmic</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15601" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15601</id>
    <updated>2013-03-02T17:50:55Z</updated>
    <published>2013-02-26T16:32:24Z</published>
    <summary type="html">&lt;p&gt;
	Wearable, guesture-based computing is a little off-topic from my normal blogging, but very cool and relevant (to me at least). Yesterday, Thalmic Labs, a Waterloo-based tech startup opened up pre-ordering for the MYO (&lt;a href="https://getmyo.com"&gt;getmyo.com&lt;/a&gt;). All the big tech blogs and publications covered the release and there are numerous articles about the MYO (&lt;a href="http://techcrunch.com/2013/02/25/thalmic-labs-myo/"&gt;Techcrunch&lt;/a&gt;, &lt;a href="http://www.wired.com/business/2013/02/thalmic-labs/"&gt;Wired&lt;/a&gt;, &lt;a href="http://business.financialpost.com/2013/02/25/waterloos-thalmic-labs-announces-myo-the-motion-tracking-armband/"&gt;Financial Post&lt;/a&gt;).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	The MYO represents a big step into the future - guesture-based control without the need for cameras. The applications of the MYO are limitless.&lt;/p&gt;
&lt;p&gt;
	For those that think this isn't real - think again. The science behind the MYO is real, the product is real, and those backing the company are very real (and experienced). I suppose I may be a little biased given that my son Aaron is one of the co-founders, however, I believe this technology has the potential to take wearable computers to the mainstream.&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2013-02-26T16:32:24Z</dc:date>
  </entry>
  <entry>
    <title>Nuxeo Upgrade 5.3.2 to 5.6</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15501" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15501</id>
    <updated>2013-02-05T16:32:23Z</updated>
    <published>2013-02-05T15:10:32Z</published>
    <summary type="html">&lt;p&gt;
	Once again I am impressed at the job Nuxeo has done to make the core migration process as painless as possible. Moving from 5.3.2 to 5.6 (through 5.4.1, 5.4.2, 5.5) is time-consuming but it produces a very predictable result. I think I read somewhere on the Nuxeo that this is the preferred approach, and it does make sense (at least to me). I create a bare-bones customization (schemas, doc types, UI, and a few other contributions) to enable me to load Nuxeo after each upgrade step and see that my data is preserved/available as expected.&lt;/p&gt;
&lt;p&gt;
	Of course, that is not to say there isn't effort required in such a migration, especially when you've created extensive add-ons that rely on certain architecture/features/fields within Nuxeo. However, even that migration effort can be fairly easily scoped and understood.&lt;/p&gt;
&lt;p&gt;
	My only real criticism of the process is migration documentation that explicitly spells out significant changes to the architecture or data model. Sorry, but trolling through java docs, changesets, or the like just doesn't cut it!&lt;/p&gt;
&lt;p&gt;
	By way of example. From 5.4.1 to 5.4.2 the lock field (in the locks table) was removed and split into two separate fields (owner and created date). As part of the upgrade process Nuxeo is smart enough to split the existing field into the two new fields - unless of course it hits something unexepected and the process fails (so no lock information is preserved). Understanding what was happening and why took some time, which could have been avoided with a detailed change guide!&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2013-02-05T15:10:32Z</dc:date>
  </entry>
  <entry>
    <title>Time for NuxeoWorld North America</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15455" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15455</id>
    <updated>2012-10-29T14:13:53Z</updated>
    <published>2012-10-29T14:13:10Z</published>
    <summary type="html">&lt;p&gt;
	A number of &amp;nbsp;realizations got me to thinking that it's high time for a NuxeoWorld North America. Consider the following...&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Recent Nuxeo press release about 40 percent growth in business in North America&lt;/li&gt;
	&lt;li&gt;
		Nuxeo CEO resides in the US&lt;/li&gt;
	&lt;li&gt;
		There are three offices in the US (and only one in Europe)&lt;/li&gt;
	&lt;li&gt;
		For what is effectively a one-day conference (not including the Dev day) the time and monetary costs are too high for many outside Europe to attend &amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	If Nuxeo is serious about growth, serious about feeding the community, serious about listening to customers, and wants to effectively compete with Alfresco and others then I think it's time to add NuxeoWorld part deux. Other vendors do exactly the same thing because they realize the importance of bringing clients, developments and vendors together face-to-face. Conferences help create and strengthen relationships, provide a forum for direct dissemination of important information, as well as gathering first hand real-world feedback.&lt;/p&gt;
&lt;p&gt;
	I know there is a certain critical mass required before such an event can be considered, but certainly that point must be here (or at least very close).&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-10-29T14:13:10Z</dc:date>
  </entry>
  <entry>
    <title>Nuxeo Studio as a separately priced SAAS?</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15413" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15413</id>
    <updated>2012-10-26T11:49:01Z</updated>
    <published>2012-10-24T13:33:52Z</published>
    <summary type="html">&lt;p&gt;
	It&amp;#39;s been a while since I have had any breathing room. I wish I had the cycles to attend NuxeoWorld in Paris, but I simply don&amp;#39;t. However, when NuxeoWorld comes around it does get me to thinking about things Nuxeo could do better.&lt;/p&gt;
&lt;p&gt;
	While I do most of my Nuxeo development in the IDE there are some tasks that are simply far more efficient in Studio (e.g., basic schema and document prototyping). The tool has definite value. Problem is, there isn&amp;#39;t a separate offering just to use Studio - you have to buy a full support package (yes, there is Connect Base but that still has Nuxeo Maintenance wrapped in). As a developer and integrator this just doesn&amp;#39;t make sense since I do not need or require technical support (that is included in the support package).&lt;/p&gt;
&lt;p&gt;
	I would like to see Nuxeo sell Studio as a separately priced Software as a Service (SAAS) offering, much like Jira and many others. I think this approach would increase adoption and drive up customer support revenues.&lt;/p&gt;
&lt;p&gt;
	I suspect many Nuxeo developers would be willing to pay a monthly usage fee -- especially if they have bought into the SAAS model.&lt;/p&gt;
&lt;p&gt;
	Maybe this will be announced at NuxeoWorld, although that&amp;#39;s probably just my hopeful thinking.&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-10-24T13:33:52Z</dc:date>
  </entry>
  <entry>
    <title>Great GWTP resources...</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15301" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15301</id>
    <updated>2012-08-20T21:35:17Z</updated>
    <published>2012-08-20T20:58:55Z</published>
    <summary type="html">&lt;p&gt;
	I can&amp;#39;t remember how I came upon GWTP, but I am sure glad I did. GWTP provides an additional level of structure, abstraction, and code generation that makes it much more enjoyable to build GWT interfaces and (more importantly) connect to back-end service/data providers.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	But like any framework there is a learning curve. I learn best by example, so over the last months, I have been searching for practicals tutorials and examples. The two best resources I have found to date:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		Dani&amp;#39;s YouTube video series on GWTP&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=Gm-RO-cmsEQ"&gt;http://www.youtube.com/watch?v=Gm-RO-cmsEQ&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
		Uptick tutorial and working application&amp;nbsp;&lt;a href="http://uptick.com.au/content/gwt-login-security"&gt;http://uptick.com.au/content/gwt-login-security&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	There are many more great resources for GWTP (including the &lt;a href="http://code.google.com/p/gwt-platform/"&gt;project site&lt;/a&gt;), but I found these the best at getting started and then diving deep into the inner workings of a real application. Many thanks to the authors of GWTP, Dani, and the folks at Uptick!&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-08-20T20:58:55Z</dc:date>
  </entry>
  <entry>
    <title>Nuxeo 5.6 - One Time Event Trigger example</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15219" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15219</id>
    <updated>2012-08-08T22:40:52Z</updated>
    <published>2012-08-08T22:23:59Z</published>
    <summary type="html">&lt;p&gt;
	Four parts to creating and using a one-time event (leveraging the Nuxeo SchedulerService):&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;1. Register a &amp;#39;scheduled&amp;#39; event - in this case the event will fire in 10 minutes time.&amp;nbsp; &lt;/strong&gt;The event that fires is called myNuxeoEvent in this sample.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public class FireInTenMinutes {&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public void task() {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SchedulerService service;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;try {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;service = Framework.getService(SchedulerService.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;} catch (Exception e) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;e.printStackTrace();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScheduleImpl schedule = new ScheduleImpl();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; schedule.cronExpression = &amp;quot;0 0/10 * * * ?&amp;quot;;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; schedule.id = &amp;quot;test1&amp;quot;;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; schedule.username = &amp;quot;Administrator&amp;quot;;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; schedule.eventId = &amp;quot;myNuxeoEvent&amp;quot;;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; schedule.eventCategory = &amp;quot;default&amp;quot;;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service.registerSchedule(schedule);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
	&lt;br /&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;2. Create a listener to respond the event created above. &lt;/strong&gt;In this example all I am doing is wirting to the log when the event fires. Since we want this to be a one-time event, I unregister it (again using the SchedulerService) once the event is handled.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; public void handleEvent(Event event) throws ClientException {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (!(&amp;quot;myNuxeoEvent&amp;quot;.equals(event.getName()))) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;log.info(&amp;quot;*** Fired in 10 minutes! ***&amp;quot;);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// remove the one-time event after it fires&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SchedulerService service;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;try {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;service = Framework.getService(SchedulerService.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;} catch (Exception e) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;e.printStackTrace();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service.unregisterSchedule(&amp;quot;test1&amp;quot;);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;3. I have to register the listener in a contribution file.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension target=&amp;quot;org.nuxeo.ecm.core.event.EventServiceComponent&amp;quot; point=&amp;quot;listener&amp;quot;&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;listener name=&amp;quot;test1&amp;quot; async=&amp;quot;false&amp;quot; postCommit=&amp;quot;false&amp;quot;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;class=&amp;quot;com.concena.mckellar.coreapp.delete.TenMinuteListener&amp;quot; priority=&amp;quot;135&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;event&amp;gt;myNuxeoEvent&amp;lt;/event&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/listener&amp;gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; etc...&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;4. And finally, you&amp;#39;ll need to initiate the event from your existing code.&lt;/strong&gt; In my example I add two lines to an existing event handler.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void handleTrashCompactorEvent(Event event) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;RepositoryManager repoMgr = Framework.getService(RepositoryManager.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;Repository repo = repoMgr.getDefaultRepository();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;RemoveDocuments removeDocs = new RemoveDocuments(repo.getName());&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;removeDocs.runUnrestricted();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;} catch (Exception e) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;log.error(&amp;quot;*** Error removing documents in trash *** error: &amp;quot; + e.getMessage());&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// fire test event in 10 minutes&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;FireInTenMinutes fireInTen = new FireInTenMinutes();&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;fireInTen.task();&lt;/p&gt;
&lt;p&gt;
	That&amp;#39;s all there is to it!&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-08-08T22:23:59Z</dc:date>
  </entry>
  <entry>
    <title>Nuxeo Event Trigger - firing a simple one-time event</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15208" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15208</id>
    <updated>2012-08-08T13:39:56Z</updated>
    <published>2012-08-08T13:21:18Z</published>
    <summary type="html">&lt;p&gt;
	I see that in Nuxeo 5.6 the SchedulerService has moved packages and undertaken some renaming. I disovered this after looking further into a question on Nuxeo Answers.&lt;/p&gt;
&lt;p&gt;
	In order to use the Scheduler Service effectively it would be extremely helpful if the underlying SchedulerServiceImpl registerSchedule method could handle the case where a CRON expression (in the schedule object) is null. When the CRON expression is null then a SimpleTrigger could be created that could be run 1 .. n times.&lt;/p&gt;
&lt;p&gt;
	Something like...&lt;/p&gt;
&lt;p&gt;
	if(cronexpression==null)&lt;br /&gt;
	&amp;nbsp; use SimpleTrigger&lt;br /&gt;
	else&lt;br /&gt;
	&amp;nbsp; use CronTrigger&lt;br /&gt;
	}&lt;/p&gt;
&lt;p&gt;
	This would nicely support one-time events created in code without having to use a CRON expression. Would be even nicer if there was a way to automatically remove the one-time scheduled service on firing to avoid having to manually unregister. Maybe there's an easier way?&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-08-08T13:21:18Z</dc:date>
  </entry>
  <entry>
    <title>First Impressions - Nuxeo 5.6</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15101" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15101</id>
    <updated>2012-06-27T11:46:01Z</updated>
    <published>2012-06-27T00:30:17Z</published>
    <summary type="html">&lt;p&gt;
	Last week I downloaded a Nuxeo 5.6 build. After downloading, it took me only a few minutes to get the instance up and running - pure vanilla with the exception of using Postgresql 9.1 as the database. I have only had a bit of time to play with the release and explore some of the changes but I have to say that my first impressions are very favourable.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Running Nuxeo 5.6 on the same server as I run 5.5 using the same components (DM, Collab, and DAM) the 5.6 server started slightly faster (this was not a scientific comparison but the results seem consistent); the start time on the server went from 21 sec (5.5) to about 19 sec (5.6); server spec - see below&lt;/li&gt;
	&lt;li&gt;
		I felt the responsiveness (performance of the UI) was improved significantly (again this is my out of the box impression -- I may be crazy). I did find that the default navigation tree jumped a little (like a pixel shift) and that was a bit disconcerting. However, remember I am not looking at released code and so there is probably much last minute testing and tweaking underway in the Nuxeo development bunker&lt;/li&gt;
	&lt;li&gt;
		The UI takes on a much more polished look than its predecessors. This is reflected in updated graphics and in Action menus that just look more professional (it&amp;#39;s too bad this new look doesn&amp;#39;t seem to extend to sub-actions - at least out of the box - although I haven&amp;#39;t dug under the covers and maybe this is easily configured)&lt;/li&gt;
	&lt;li&gt;
		Reorganization of the default DM UI makes for (in my opinion) better use of available space - some of that&amp;#39;s achieved with icons and some is achieved through a combination of better contrast and better presentation of simple data (like current document state and contributors)&lt;/li&gt;
	&lt;li&gt;
		Every time I visit the Admin Center there is cool (and more importantly useful) functionality exposed - I only sped breifly through this section - enough time to see a number of new tabs, functions and the same UI improvements as DM&lt;/li&gt;
	&lt;li&gt;
		I didn&amp;#39;t, however, see any outward facing improvements in the DAM interface (anybody help here - am I missing something?)&lt;/li&gt;
	&lt;li&gt;
		The cookie trail seems to have shrunk in size, which personally I like, because I always like to see the entire path up there, but it may be too small for some&lt;/li&gt;
	&lt;li&gt;
		One part of the UI I would really like to see streamlined is security administration. This is one part of the UI that has been with the product for as long as I have been using it, and in my opinion it&amp;#39;s just clunky - needs to be more intuitive and easier to manage. Not simple I know, but given the other UI improvements hopefully somebody will turn their attentions to this area of the UI in an upcoming release&lt;/li&gt;
	&lt;li&gt;
		Really like the new icons although it will take a bit to remember which one is which (this isn&amp;#39;t a complaint, rather an observation)&lt;/li&gt;
	&lt;li&gt;
		Just haven&amp;#39;t had time to make it through Social Collaboration in any detail but the new dashboard looks great and although it may seem trivial, I really like the idea of a built-in voting system&lt;/li&gt;
	&lt;li&gt;
		I know there are numerous internal improvements (some obviously reflected in ui and load speed) to look forward to, but not this time around&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	The pre-release code seems extremely stable - out of the box, running in less than 15 minutes, and no crashes! Spending a few hours looking at 5.6 scratched the surface but was well worth the investment in time.&lt;/p&gt;
&lt;p&gt;
	Server Spec: i7, 8 cores, 32GB RAM, SSD Boot/App disk, 7200RPM SATA for data, running CentOS 6.2 64 bit.&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-06-27T00:30:17Z</dc:date>
  </entry>
  <entry>
    <title>Nuxeo Roadmap</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=15001" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=15001</id>
    <updated>2012-06-07T19:57:58Z</updated>
    <published>2012-06-07T19:07:27Z</published>
    <summary type="html">&lt;p&gt;
	I had signed up to attend, but ended up missing, the &lt;a href="http://www.nuxeo.com/resource-center/Videos/Webinars/Nuxeo-Roadmap-June-2012" target="_blank"&gt;Nuxeo roadmap session&lt;/a&gt;. But my customers come first and I had to take of a few time-sensitive issues. C&amp;#39;est la vie. The&lt;a href="http://www.nuxeo.com/resource-center/Videos/Webinars/Nuxeo-Roadmap-June-2012" target="_blank"&gt; session&lt;/a&gt; is up on the site so at least I could watch after-the-fact. Apart from what I have previously written about with respect to DAM, I had some more general questions about the future of Nuxeo that I would have liked to ask. At least one was answered during the webinar and another touched on briefly.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		There are many third party libraries that are part of Nuxeo. Some of these libraries are fairly old (in technology terms) and I think they need to be updated much more frequently. Libaries for PDF, image manipulation, metadata extraction, and more need regular updates. I would like to know when/if these will become part of the regular hotifx / release cycle.&lt;/li&gt;
	&lt;li&gt;
		Integration of Studio and IDE with full two-way engineering. The ability to move back and forth between the environments would have great value. It looks as though 5.6 will start down the path but I will have to wait and see whether there is value in the initial offering.&lt;/li&gt;
	&lt;li&gt;
		Whether on premise or in the cloud, performance is of critical concern - especially with huge digital assets. I would like to know specifics on plans to improve overall imaging and asset management performance.&lt;/li&gt;
	&lt;li&gt;
		Nothing specific in mind, but I would like to see fewer error pages popping up in the application. And when they do it would be nice to have a way to return to the context prior to the application cacking. Just wondering if there is any work under way to tighten up and improve error handling.&lt;/li&gt;
	&lt;li&gt;
		More into the future - any thoughts or plans to support any NoSQL database variants?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	I was glad to see more work in the mobile space as this is critical in my opinion to delivering focused, effective content applications to users regardless of where they are!&lt;/p&gt;
&lt;p&gt;
	Hopefully I get a chance to attend the next roadmap session.&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-06-07T19:07:27Z</dc:date>
  </entry>
  <entry>
    <title>Beyond Nuxeo 5.6</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=14901" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=14901</id>
    <updated>2012-05-28T18:00:19Z</updated>
    <published>2012-05-17T17:55:58Z</published>
    <summary type="html">&lt;p&gt;
	Looks like the 5.6 release of Nuxeo has some promising ui/usability improvements. No doubt there will be improvements in other areas as well. Hopefully I will have some time in the not too distant future to investigate.&lt;/p&gt;
&lt;p&gt;
	I&amp;#39;m looking beyond 5.6, specifically with my new DAM goggles on. There is demand for industrial strength DAM across most verticals. In some verticals, digital asset management underpins the business itself, and in these situations industrial strength DAM is critical. I would like to see a stronger focus on improving the DAM product (and underlying CAP/imaging components).&lt;/p&gt;
&lt;p&gt;
	I think it&amp;#39;s time for Nuxeo to step up efforts to improve DAM over and under the covers - to get it on a level playing field with commercially available DAM solutions.&lt;/p&gt;
&lt;p&gt;
	What do i think are the most important areas on which to focus?&lt;/p&gt;
&lt;p&gt;
	1. Format agnosticism.&lt;/p&gt;
&lt;p&gt;
	Whether it&amp;#39;s a raw image from a Nikon camera, a multi-layer PSD, or one of a myriad of other formats the DAM solution needs to be able to handle it,&lt;/p&gt;
&lt;p&gt;
	2. Size agnosticism.&lt;/p&gt;
&lt;p&gt;
	Industrial strength DAM products must handle 1.5GB Tiff files just as eloquently as they handle a 5MB Jpeg. While processors, RAM, and disk speed will determine overall performance, the solution should have workarounds for any reasonably sized hardware or virtual machine. This also means finding and eradicating all software-based limitations for handling files &amp;gt; 2GB in size.&lt;/p&gt;
&lt;p&gt;
	3. Metadata - all of it.&lt;/p&gt;
&lt;p&gt;
	Filtering and finding images is one of the most important functions (in my opinion) of a digital asset system. Using image metadata for searching and filtering requires efficient automated extraction. And, it means that every type of common metadata must be easily extracted from supported image types. This includes, but is not limited to, XMP, IPTC, and EXIF.&lt;/p&gt;
&lt;p&gt;
	4. Performance Profiling data and Sizing Charts&lt;/p&gt;
&lt;p&gt;
	The challenges with moving and processing multi-GB files are much different than those of smaller files (where transaction times - even aggregrated - or not all that significant). It would be extremely useful if Nuxeo published recommended configurations for all Nuxeo applications, but DAM specifically. The recommendations could include JVM sizing, Database configuration, OS configuration, Imaging component tweaks, RAM, disk usage, etc. This is a big complex area, but some base level of recommendations would be helpful as a starting point.&lt;/p&gt;
&lt;p&gt;
	5. Speed, Speed, Speed&lt;/p&gt;
&lt;p&gt;
	With big images, and lots of them, processing speed is critical. I have seen a number of opportunities in the core Nuxeo imaging code to improve overall transaction speed. One of the biggest areas for possible improvement is the imaging library - especially when spinning off multiple Jpeg versions of the original image. Lots of opportunity here.&lt;/p&gt;
&lt;p&gt;
	6. Third party Library Updates - More Frequent/Alternates/Plugins&lt;/p&gt;
&lt;p&gt;
	Libraries that support third party image processing (ImageMagick, metadata-extractor, etc.) have to be kept up-to-date, preferably as part of point releases. This ensures that newer image formats can be handled with minimal fuss. Maybe it&amp;#39;s time to look at alternatives to some of the image processing components. Is Google&amp;#39;s OiiO a possible alternative to ImageMagick? Is there a way to abstract the third party image library in such a way that OSX users could take advantage of the CoreImage library for image processing (which is far faster than ImageMagick equivlents)?&lt;/p&gt;
&lt;p&gt;
	[Added May 28 2012:&lt;/p&gt;
&lt;p&gt;
	7. Parameter driven functionality&lt;/p&gt;
&lt;p&gt;
	An example... When an asset is ingested into the DAM repository three images are generated - an original size JPEG, a Medium size JPEG, and a thumbnail. The number of images generated and their sizes are hard-coded in the application. It would be nice if the configuration of this functionality were exposed in a configuration document, allowing additional renditions, lower resolution renditions, different formats, etc. In my opinion this would greatly improve the flexiblity and applicability of DAM.]&lt;/p&gt;
&lt;p&gt;
	What else can Nuxeo improve in the current DAM product to make it more industrial strength?&lt;/p&gt;
&lt;p&gt;
	Cheers,&lt;/p&gt;
&lt;p&gt;
	Bruce.&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-05-17T17:55:58Z</dc:date>
  </entry>
  <entry>
    <title>Nuxeo, DAM, ImageMagick and really big files</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=14814" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=14814</id>
    <updated>2012-04-29T20:57:54Z</updated>
    <published>2012-04-29T17:54:04Z</published>
    <summary type="html">&lt;p&gt;
	Dam frustrating is a good way to describe my last three days.&amp;nbsp;I have been working to tune the Nuxeo DAM import for very large images &amp;hellip; frustrating because there are many pieces, moving big images takes time, and debugging/document the whole process introduces a natural latency.&lt;/p&gt;
&lt;p&gt;
	Nuxeo import relies on ImageMagick for image-related tasks (e.g. resizing and cropping) - during import ImageMagick is used heavily and is by far the most time-consuming element of the import process. If ImageMagick slows then so does your import.&lt;/p&gt;
&lt;p&gt;
	Nuxeo DAM, for that matter the core imaging code, works really well with most images. &amp;quot;Works really well&amp;quot; extends to the integration with ImageMagick. But take a step into the world of very large/complex image files and the works well fantasy world takes a halting step into reality.&lt;/p&gt;
&lt;p&gt;
	What do I mean by very large image (or complex) files? Three possible interpretations:&lt;/p&gt;
&lt;p&gt;
	In absolute terms, any image file over 2GB is very large (well, technically anything over 2^31-1, which is the limit of an int value in Java). This limit is important because any code that uses int values for file size or related processing will be limited to 2GB files. There are still some limitations within Nuxeo when it comes to uploading very large files (not just images) - e.g., in DAM I can import a 3.5GB video file through the importer but the same import fails when attempted through the UI.&amp;nbsp; I do know that Nuxeo developers have been working actively to remove these barriers.&lt;/p&gt;
&lt;p&gt;
	In relative terms, very large can be any image that is big enough (or the requested operation complex enough) to require more physical memory during image processing than your OS can make available. For example, images in the 1GB range can be a problem on a Windows box with 4GB of RAM (assuming Nuxeo server is also running). ImageMagick runs fastest when the entire pixel map can be loaded into RAM.&amp;nbsp; If the entire pixel map can&amp;#39;t be loaded into memory then image processing slows dramatically &amp;ndash; that&amp;rsquo;s because ImageMagick will page parts of the image in/out of memory to complete the requested task.&lt;/p&gt;
&lt;p&gt;
	Complexity of the image file itself can exacerbate the situation. For example, multi-layered PSD images require far more processing time than a single layer file of the same size. To the ImageMagick &lt;strong&gt;&lt;em&gt;identify&lt;/em&gt;&lt;/strong&gt; command each layer is effectively an image of its own, with its own metadata. So it takes ImageMagick much longer to troll through multiple images to extract the required information.&lt;/p&gt;
&lt;p&gt;
	Add to this complexity the differences in memory allocation/reservation of different operating systems and it makes it challenging to tune Nuxeo DAM and ImageMagick.&lt;/p&gt;
&lt;p&gt;
	I have spent the last three days running through numerous configurations, file sizes, limits, memory allocations, etc. trying to better understand the issues in order to move forward. What I found is...&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		So long as you&amp;#39;re running VCS then Postgres tuning is not really important for image processing (of course it is very important for other reasons)&lt;/li&gt;
	&lt;li&gt;
		Technically, the amount of RAM you set aside for Nuxeo will not limit the size of images you can import, but practically speaking, if you don&amp;#39;t allocate enough RAM to reflect the size and volume of images imported, displayed, etc. in your system then your DAM solution will be less than useful. The RAM required is dependent on numerous other factors so it&amp;#39;s difficult to be entirely prescriptive&lt;/li&gt;
	&lt;li&gt;
		The amount of physical RAM available to ImageMagick is absolutely critical to timely image processing. Not enough RAM and ImageMagick will page to disk, run times will increase dramatically and it&amp;#39;s likely your Nuxeo transaction will timeout. The end result &amp;hellip; nothing will be imported (the transaction will be rolled back). You might want to set upper limits on the resources available to ImageMagick (using environment variable) so all available RAM isn&amp;#39;t gobbled up&lt;/li&gt;
	&lt;li&gt;
		The speed of your disk is also important. Slow disk = slower image processing. Longer to read, longer to write, longer to create any interim temp files. If your disk is on the network then make sure it&amp;#39;s on a high speed connection. You might want to consider a solid state drive for ImageMagick temporary files.&lt;/li&gt;
	&lt;li&gt;
		CPU speed, number of cores, and number of threads allocated (for ImageMagick) must also be considered - especially from a global perspective, since multiple image commands can be running simultaneously.&lt;/li&gt;
	&lt;li&gt;
		The location of ImageMagick temp files is important. ImageMagick commands produce temp files, the location of which can be controlled with the MAGICK_TEMPORARY_PATH environment variable. Set the path variable to a disk with lots of free space, preferably not the same disk as your OS and Nuxeo are on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Each case is difference, but the end result for Nuxeo-ImageMagick import tuning: expect to spend extra time understanding your requirements, get ready to buy more memory, and be prepared to put in some effort to get everything running quickly!&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-04-29T17:54:04Z</dc:date>
  </entry>
  <entry>
    <title>Nuxeo Community Survey - Any Interest?</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=14605" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=14605</id>
    <updated>2012-03-30T14:18:09Z</updated>
    <published>2012-03-30T13:58:35Z</published>
    <summary type="html">&lt;p&gt;
	I have been kicking about the idea of running a community driven survey on Nuxeo (the product suite and the company). Is anyone else interested in understanding how Nuxeo is being used, which versions are being used, what software has been integrated with/to Nuxeo, what people like/don't like about Nuxeo, suggestions to improve, etc.&lt;/p&gt;
&lt;p&gt;
	My thinking is as follows:&lt;/p&gt;
&lt;p&gt;
	1. Gather some basic demographics (products, versions, number of users, geography, etc.)&lt;/p&gt;
&lt;p&gt;
	2. Gather feedback on how Nuxeo is going as a company (quality, responsiveness, etc.).&lt;/p&gt;
&lt;p&gt;
	3. Gather feedback on individual products (likes, dislikes, ideas to improve, etc.)&lt;/p&gt;
&lt;p&gt;
	4. Gather information on how products are being used (purpose, integrations, etc.)&lt;/p&gt;
&lt;p&gt;
	5. And free format feedback.&lt;/p&gt;
&lt;p&gt;
	Once collected I will generate summary report. The report will be shared with Nuxeo as formal community feedback, and a copy of the report will be emailed to all who participated in the survey. I will also post the survey on my site for those who don't provide contact information. Published results will be completely anonymous.&lt;/p&gt;
&lt;p&gt;
	This will take some effort on my part but I think it will help the community, those considering Nuxeo, and it can help guide the future of the product?&lt;/p&gt;
&lt;p&gt;
	Am I crazy (I probably am) or would this have some value? Also, let me know if you have suggestions for specific questions or areas of interest to include in the survey.&lt;/p&gt;
&lt;p&gt;
	Thanks.&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-03-30T13:58:35Z</dc:date>
  </entry>
  <entry>
    <title>Nuxeo Hotfixes - An Idea</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=14418" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=14418</id>
    <updated>2012-03-22T19:17:17Z</updated>
    <published>2012-03-22T18:59:51Z</published>
    <summary type="html">&lt;p&gt;
	Today on Nuxeo answers a user asked about the availability of the latest hotfix package for 5.5 (&lt;a href="http://answers.nuxeo.com/questions/2046/how-to-get-version-550-hf05" target="_blank"&gt;link to Nuxeo answers question&lt;/a&gt;). The reply, as I expected, was that packaged hotfixes are for paying customers only. Absolutely understandable, for although Nuxeo is open source, Nuxeo the company is a business and needs to make money to stay in business and flourish. Hopefully everyone who has invested time and energy in Nuxeo can appreciate this.&lt;/p&gt;
&lt;p&gt;
	But this got me to thinking, maybe there is an additional subscription model for small businesses and individuals, where there is no additional support provided, but hotfixes are sold as-is for a fixed price (via credit card or paypal). To Nuxeo this becomes a transaction requiring no additional labor or cost. Incremental revenue, happier users, and a chance at growing the customer base when users reach a certain size where they feel a more formal support arrangement is warranted.&lt;/p&gt;
&lt;p&gt;
	In my mind, if the cost of a hotfix were set reasonably it would far outbalance the cost of having to build from source and then deploy on one or more servers (and having to deal with any resulting issues). Would $150 per hot fix be reasonable?&lt;/p&gt;
&lt;p&gt;
	I can see the downside to this of course - create more hotfixes to generate more revenue... that would be evil :-)&lt;/p&gt;
&lt;p&gt;
	Ok, so what about an annual hotfix only subscription. Look at the last few releases and the number of hotfixes per year on average and let's say $1500 per year for hotfixes only - but no technical support (other than that provided in forums and answers).&lt;/p&gt;
&lt;p&gt;
	Thoughts?&lt;/p&gt;
&lt;p&gt;
	Cheers, Bruce.&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-03-22T18:59:51Z</dc:date>
  </entry>
  <entry>
    <title>Leveraging ImageMagick with Nuxeo</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=14201" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=14201</id>
    <updated>2012-03-14T05:06:46Z</updated>
    <published>2012-03-13T19:52:36Z</published>
    <summary type="html">&lt;p&gt;
	Until recently I never really appreciated the value and power of ImageMagick. This is one slick piece of software (or collection of image transformation tools).&lt;/p&gt;
&lt;p&gt;
	The base integration with Nuxeo is good, but there is still plenty of opportunity to improve. The need for speed (and flexibility) becomes very evident when dealing with 250MB images, TIF images, IPTC/EXIF/XMP metadata, and with images that have a CMYK color space.&lt;/p&gt;
&lt;p&gt;
	&lt;b&gt;Quick Fix...&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;
	ImageMagick is integrated with Nuxeo, or more accurately loosely bound to, via a series of command line calls that perform the image-related magic.&amp;nbsp; Nuxeo expects to find the ImageMagick tools on the system path, while the loose binding comes by way of a contribution that associates Nuxeo command names with ImageMagick commands and parameters. Part of the default Nuxeo contribution is shown below…&lt;/p&gt;
&lt;p&gt;
	&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;
	&amp;lt;component name="org.nuxeo.ecm.platform.picture.commandline.imagemagick"&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;require&amp;gt;org.nuxeo.ecm.platform.commandline.executor.service.defaultContrib&amp;lt;/require&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;extension target="org.nuxeo.ecm.platform.commandline.executor.service.CommandLineExecutorComponent”&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; point="command"&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;command name="identify" enabled="true"&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;commandLine&amp;gt;identify&amp;lt;/commandLine&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;parameterString&amp;gt; -ping -format '%m %w %h %z' #{inputFilePath}&amp;lt;/parameterString&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;winParameterString&amp;gt; -ping -format "%m %w %h %z" #{inputFilePath}&amp;lt;/winParameterString&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;installationDirective&amp;gt;You need to install ImageMagic.&amp;lt;/installationDirective&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/command&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;command name="resizer" enabled="true"&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;commandLine&amp;gt;convert&amp;lt;/commandLine&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;parameterString&amp;gt;-flatten -resize #{targetWidth}x#{targetHeight} -depth #{targetDepth} #{inputFilePath}[0]&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; #{outputFilePath}&amp;lt;/parameterString&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;installationDirective&amp;gt;You need to install ImageMagic.&amp;lt;/installationDirective&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/command&amp;gt;&lt;br /&gt;
	Etc.&lt;/p&gt;
&lt;p&gt;
	I included this chunk of code because it demonstrates an issue with ImageMagick and the flexibility of Nuxeo (and ImageMagick) to address the issue.&lt;/p&gt;
&lt;p&gt;
	In the example, the Nuxeo “resizer” command gets tied to the ImageMagick “convert” command. If the input picture is a TIF file then resizer will convert the image to a JPG and resize as required. This causes a problem when the TIF image has layers/masks. Unfortunately, converting from TIF to JPEG and resizing at the same time results in the loss of layers/masks in the resulting JPEG image – not so good.&lt;/p&gt;
&lt;p&gt;
	There is a workaround, and that involves splitting the resizer command into two parts. Luckily both Nuxeo and ImageMagick are fine with using pipe-lined commands. So, what I split the single default resizer command into a conversion and then a re-size. I overrode the existing contribution with the following….&lt;/p&gt;
&lt;p&gt;
	&amp;lt;command name="resizer" enabled="true"&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;commandLine&amp;gt;convert&amp;lt;/commandLine&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;parameterString&amp;gt; #{inputFilePath}[0] jpg:- | convert - -resize #{targetWidth}x#{targetHeight} –depth&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #{targetDepth} #{outputFilePath}&amp;lt;/parameterString&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;installationDirective&amp;gt;You need to install ImageMagick&amp;lt;/installationDirective&amp;gt;&lt;br /&gt;
	&amp;lt;/command&amp;gt;&lt;/p&gt;
&lt;p&gt;
	In the new “resizer” the input file first gets converted to a JPEG file (represented by the -), which is then piped into a convert command to resize the JPEG as required. This may cause slightly more work, but TIF files now get converted and resized as expected.&lt;/p&gt;
&lt;p&gt;
	Resolving the TIF conversion issue with a simple contribution is a fairly simple solution.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;One or the Other...&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
	Unfortunately, not all fixes are so straight forward. The “CropAndResize” command is used by the tiling service to facilitate annotations. Crop and resize issues a pipelined ImageMagick command (stream | convert … see below) that takes an input stream and converts the image to a specified size using a given color map. Problem is – the color map is hardcoded as RGB – which is an issue for any image in a CMYK color space.&lt;/p&gt;
&lt;p&gt;
	&amp;lt;command name="cropAndResize" enabled="true"&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;commandLine&amp;gt;stream&amp;lt;/commandLine&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;parameterString&amp;gt; -map rgb -storage-type char -extract #{tileWidth}x#{tileHeight}+#{offsetX}+#{offsetY}&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #{inputFilePath} - | convert -depth 8 -size #{tileWidth}x#{tileHeight} -resize&lt;br /&gt;
	&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; #{targetWidth}x#{targetHeight}! rgb:- #{outputFilePath} &amp;lt;/parameterString&amp;gt;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;installationDirective&amp;gt;You need to install ImageMagic.&amp;lt;/installationDirective&amp;gt;&lt;br /&gt;
	&amp;lt;command/&amp;gt;&lt;/p&gt;
&lt;p&gt;
	The –map rgb in the cropAndResize command can be changed to –map cmyk (and the piped output changed to cmyk:-) … and CMYK images will now appear properly for annotations. However, RGB images are no longer tiled correctly. In this case programmatic changes are required to determine the color space of the image being processed and then to pass the appropriate color map value to cropAndResize as a parameter. &amp;nbsp;Getting the color space could be part of an existing Identify command (where all image objects are picked up) or it could be done in a separate process using “identify –format %[colorspace] filename.tif” (although this will incur extra processing costs).&lt;/p&gt;
&lt;p&gt;
	To make this work the image tiling package and imaging core package need to be modified.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Big Image Efficiencies... next time&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
	Finally, when it comes to dealing with big files in Nuxeo (100MB+) there is room for improvement. I haven’t yet walked through the whole process but I have watched the number of temp files that get created during the ingestion process. At first blush it appears that there is an opportunity to make this more efficient – which is really important for large files! However, I will have to dig into this another time.&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-03-13T19:52:36Z</dc:date>
  </entry>
  <entry>
    <title>Assessing the Cost of Nuxeo versus Commercial Alternatives</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=14109" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=14109</id>
    <updated>2012-03-07T18:36:28Z</updated>
    <published>2012-03-07T18:30:35Z</published>
    <summary type="html">&lt;p&gt;
	When customers ask about the cost of Nuxeo I always answer in terms of value.&amp;nbsp; The primary reason for this is simple; I think that the value of an open source approach is by far the more important discussion and will underpin any discussion of cost (or investment). However, understanding cost is critical to making any investment!&lt;/p&gt;
&lt;p&gt;
	The following table outlines the costs associated with Nuxeo versus traditional commercial solutions. &amp;nbsp;Arguably there are other categories which could be included the list. However, these are, I think, the items with the most cost impact.&lt;/p&gt;
&lt;table border="1" cellpadding="0" cellspacing="0"&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p align="right"&gt;
					 &lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Nuxeo&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Commercial&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Comments&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;License Fees&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					None&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					Server and/or user license fees. Adding more users or servers dramatically increases the costs.&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					Open Source – no initial fees, but more importantly no barriers to implementing more servers or adding additional users (inside or outside your company)&lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Maintenance Fees&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					None&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					Typically 20-25% of license fees. More users and servers increases annual maintenance costs as well&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					For commercial solutions maintenance fees are required just to get access to new releases of software.&lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Connect Subscription&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					Convenience features and access to online Studio development suite&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					None&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					The connect subscription is optional, but is required if annual support is required&lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Annual Support&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					Per Application irrespective of number of servers or users. Multiple levels of support are available with requisite Service Level commitments.&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					None in standard maintenance model&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					Nuxeo annual support is optional. In practice, commercial software often has additional premium support costs as well as those not covered by maintenance.&lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Development&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					Required to implement customer’s business requirements. The size and scope of this effort is tied directly to requirements. Simple customizations with Studio, more complex with Nuxeo IDE.&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					For true off the shelf software there may be no development required (or possible!).&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					Nuxeo-based solutions are built to suit your business requirements, rather than having to mold your requirements to a commercial solution. It’s typical for some level of integration development (at a minimum) with commercial solutions.&lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					Included in development&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					A separate step in commercial products to configure fields, content types, view, etc.&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					Configuration allows for some customization of Commercial solutions, but scope and flexibility are limited.&lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Initial Implementation&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					Tied to scope&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					Tied to scope&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					Assumed neutral in terms of cost, however, this is not always the case.&lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Server Updates (hot fixes)&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					With annual support the application of server hot fixes is (almost) trivial. Otherwise, manual updates are still possible, but require additional effort.&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					Included with annual maintenance, but the effort to install varies based on the vendor and the product.&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					 &lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="width:112px;"&gt;
				&lt;p&gt;
					&lt;strong&gt;Upgrades&lt;/strong&gt;&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:168px;"&gt;
				&lt;p&gt;
					There will be an ongoing cost to maintaining custom developed code.&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:192px;"&gt;
				&lt;p&gt;
					There will be a cost to maintaining any custom-developed integrations.&lt;/p&gt;
			&lt;/td&gt;
			&lt;td style="width:167px;"&gt;
				&lt;p&gt;
					Difficult to compare in the abstract, however, Nuxeo is architected in a way that promotes extension and redefinition of function while maintaining ease of upgrade.&lt;/p&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	The bottom line: a Nuxeo-based solution will likely yield a cost savings over a commercial alternative. In the worst case scenario the cost difference may be neutral. However, as I mentioned at the start, I think that the real benefit (value) of Nuxeo comes from its flexibility, extensibility, scalability, performance, standardization, build-to-purpose, rapid pace of development. While estimating cost is necessary, defining the value of Nuxeo to your organization is imperative!&lt;/p&gt;
&lt;p&gt;
	I'm very interested to hear how others feel about this...&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-03-07T18:30:35Z</dc:date>
  </entry>
  <entry>
    <title>Extracting EXIF, IPTC, XMP and more with Drew Noakes metadata-extractor-2.5.0-RC3</title>
    <link rel="alternate" href="http://concena.com/c/blogs/find_entry?entryId=14092" />
    <author>
      <name>Bruce Grant</name>
    </author>
    <id>http://concena.com/c/blogs/find_entry?entryId=14092</id>
    <updated>2012-03-05T21:28:01Z</updated>
    <published>2012-03-05T13:33:39Z</published>
    <summary type="html">&lt;p&gt;
	Nuxeo already uses an earlier version of the metadata-extractor library. Problem is, this version is somewhat dated (circa 2006/2007) and has very limited support for the broad range of embedded metadata. Well, the new 2.5.0-RC3 version looks to address this limitation by adding support for a much broader array of embedded metadata standards - including XMP! Here&amp;#39;s a link to the &lt;a href="http://code.google.com/p/metadata-extractor/" target="_blank"&gt;metadata-extractor project&lt;/a&gt;. Thanks Drew!&lt;/p&gt;
&lt;p&gt;
	There are enough structural changes between 2.3.0 and 2.5.0-RC3 that simply replacing the JAR will not work. In the case of Nuxeo that would have meant finding and fixing all the touch points with the metadata-extractor. I opted for a simpler option (that in no way impacts existing code).&lt;/p&gt;
&lt;p&gt;
	1. Downloaded the sources to metadata-extractor-2.5.0-RC3 and the changed the package name from com.noakes.* to com.noakes.custom.* . I then recompiled to create a -RC3.1 jar.&lt;/p&gt;
&lt;p&gt;
	2. Copied the -RC3.1 jar into my nxserver/lib directory (along with xmpcore.jar - comes with RC3 jar download)&lt;/p&gt;
&lt;p&gt;
	3. Overrode and then modified PictureChangedListener to explicitly use -RC3.1. Then added the following code (snippet only). All of this code runs after Nuxeo has processed the blob and set what metadata it can. Obviously this can be made smarter to check to see if (as is the case for JPEGs) Nuxeo found and set the EXIF/IPTC metadata. And of course, longer term it will be best if the newer 2.5.0-RC3 is baked into Nuxeo!&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ImagingService service;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Map&amp;lt;String, Object&amp;gt; map;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; service = Framework.getService(ImagingService.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; BufferedInputStream in = new BufferedInputStream(blob.getStream());&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Metadata metadata = ImageMetadataReader.readMetadata(in, true);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; exifDirectory1 = metadata.getDirectory(ExifIFD0Directory.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // metadata.getDirectory(ExifInteropDirectory.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; exifDirectory3 = metadata.getDirectory(ExifSubIFDDirectory.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; iptcDirectory = metadata.getDirectory(IptcDirectory.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // metadata.getDirectory(XmpDirectory.class);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (exifDirectory1 != null) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Date dateTimeOriginal = getExif1Date(exifDirectory1.TAG_DATETIME);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; int width = getExif1Int(exifDirectory1.TAG_X_RESOLUTION);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :&lt;br /&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :&lt;/p&gt;
&lt;p&gt;
	The getExif1xxx functions do the necessary checking to make sure that tag exists and conversion to proper type. For example...&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; private int getExif1Int(int tag) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int result;&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (exifDirectory1.containsTag(tag)) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = exifDirectory1.getInt(tag);&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (MetadataException e) {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = 0;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = 0;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
	&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; return result;&lt;br /&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;</summary>
    <dc:creator>Bruce Grant</dc:creator>
    <dc:date>2012-03-05T13:33:39Z</dc:date>
  </entry>
</feed>

