Added: websites/staging/ace/trunk/content/docs/ace-deployment-strategies.html
==============================================================================
--- websites/staging/ace/trunk/content/docs/ace-deployment-strategies.html 
(added)
+++ websites/staging/ace/trunk/content/docs/ace-deployment-strategies.html Mon 
Nov 24 22:42:13 2014
@@ -0,0 +1,480 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+  <head>
+    <title>Deployment Strategies</title>
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+    <meta property="og:image" content="//www.apache.org/images/asf_logo.gif" />
+    <link href="/css/bootstrap.min.css" rel="stylesheet" media="screen">
+    <link href="/css/prettify.css" rel="stylesheet" media="screen">
+    <link href="/css/code.css" rel="stylesheet" media="screen">
+    <script src="//code.jquery.com/jquery.js"></script>
+    <script src="/js/bootstrap.min.js"></script>    
+    <script src="/js/prettify.js"></script>
+    
+    
+    
+    <script>
+    $(function () { prettyPrint() })
+    $().dropdown()
+    </script>
+  </head>
+  <body style="padding-top: 50px;">
+    <div class="navbar navbar-fixed-top navbar-inverse">
+      <div class="navbar-inner">
+        <div class="container">
+          <a class="brand" href="/index.html">Apache ACE&trade;</a>
+          <ul class="nav">
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">News <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/news.html">News</a>
+      </li>
+      <li>
+        <a href="/on-the-web.html">On the web</a>
+      </li>
+    </ul>
+  </li>
+  <li>
+    <a href="/downloads.html">Downloads</a>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Users <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/user-doc/introduction.html">Introduction</a>
+      </li>
+      <li>
+        <a href="/user-doc/getting-started.html">Getting Started</a>
+      </li>
+      <li>
+        <a href="/user-doc/user-guide.html">User Guide</a>
+      </li>
+      <li>
+        <a href="/user-doc/features.html">Features</a>
+      </li>
+      <li>
+        <a href="/user-doc/shellapi.html">Client Shell API</a>
+      </li>
+           <li>
+        <a href="/user-doc/restapi.html">Client REST API</a>
+      </li>
+      <li>
+        <a href="/user-doc/useradmin-ui.html">User Management Guide</a>
+      </li>
+      <li>
+        <a href="/user-doc/faq.html">FAQ</a>
+      </li>
+      <li>
+        <a href="/user-doc/support.html">Support</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Developers <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/dev-doc/getting-started.html">Getting Started</a>
+      </li>
+      <li>
+        <a href="/dev-doc/requirements/">Requirements</a>
+      </li>
+      <li>
+        <a href="/dev-doc/architecture.html">Architecture</a>
+      </li>
+      <li>
+        <a href="/dev-doc/analysis/">Analysis</a>
+      </li>
+      <li>
+        <a href="/dev-doc/design/">Design</a>
+      </li>
+      <li>
+        <a href="/dev-doc/coding-standards.html">Coding Standards</a>
+      </li>
+      <li>
+        <a href="/dev-doc/release-guide.html">Release Guide</a>
+      </li>
+      <li>
+        <a href="/dev-doc/writing-tests.html">Writing unit/integration 
tests</a>
+      </li>
+      <li>
+        <a href="/dev-doc/adding-custom-artifact-types.html">Adding custom 
artifact types</a>
+      </li>
+      <li>
+        <a href="/dev-doc/configuring-relay-servers.html">Configuring and 
using relay servers</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Involved <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/get-involved/mailing-lists.html">Mailing Lists</a>
+      </li>
+      <li>
+        <a href="/get-involved/issue-tracking.html">Issue Tracking</a>
+      </li>
+      <li>
+        <a href="/get-involved/continuous-integration.html">Continuous 
Integration</a>
+      </li>
+      <li>
+        <a href="/get-involved/source-code.html">Source Code</a>
+      </li>
+      <li>
+        <a href="/get-involved/project-team.html">Project Team</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Wiki <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a 
href="https://cwiki.apache.org/confluence/display/ACE/Board+Reports";>Board 
Reports <i class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a 
href="https://cwiki.apache.org/confluence/display/ACE/Index";>Homepage <i 
class="icon-share-alt"></i></a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Apache <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="http://www.apache.org/";>Apache Homepage <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="http://www.apache.org/licenses/";>Licenses <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="http://www.apache.org/security/";>Security <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="http://www.apache.org/foundation/thanks.html";>Thanks <i 
class="icon-share-alt"></i></a>
+      </li>
+    </ul>
+  </li>
+</ul>
+
+        </div>
+      </div>
+    </div>
+    <div class="container">
+      <p><a href="/"><i class='icon-home'></i> Home</a>&nbsp;&raquo&nbsp;<a 
href="/docs/">Docs</a></p>
+      <h1>Deployment Strategies</h1>
+      <div class="clear"></div>
+      <div id="content"><p><em>Implementing custom update policies</em></p>
+<p>last updated: April 19th, 2012</p>
+<h2 id="introduction">Introduction</h2>
+<p>This article describes how ACE deploys new deployment packages to targets 
and how this strategy can be adapted to support more sophisticated 
scenario's.<br />
+The remainder of this article assumes the reader has basic knowledge of the 
principles behind ACE, and has sufficient programming skills. For this 
article, the latest code of ACE (0.8.1-SNAPSHOT, rev.1326140) was used.</p>
+<h2 id="provisioning">Provisioning</h2>
+<p>Apache ACE is all about provisioning software artifacts to targets. 
Software artifacts, or simply, artifacts, can be compiled code, configuration 
files, or any other artifact needed for a software system to operate. 
Provisioned artifacts are bundled in so-called "deployment packages", that is 
comprised of the differences between the target's current artifacts and the 
to-be-deployed artifacts. To distinguish between deployment packages, each one 
is given its own version. The increment of versions is done automatically by 
ACE when changes are committed to its repository.<br />
+When a new deployment package is available, it is not automatically sent to 
the target as the communication between target and management server (ACE) is 
unidirectional and initiated by the target. A target has to periodically check 
whether new deployment packages are available, and if so, do something with 
it.</p>
+<h2 id="understanding-aces-deployment-strategy">Understanding ACE's deployment 
strategy</h2>
+<p>Upon startup, the management agent, which represents a target, schedules 
several tasks that periodically synchronize the local state with that of the 
management server. Two of these tasks relate to the handling of deployment 
packages: <code>DeploymentCheckTask</code> and 
<code>DeploymentUpdateTask</code>. Figure 1 shows the relationship between the 
various components.</p>
+<p><img alt="Figure 1: class diagram" 
src="deployment_strategy_classdiagram.svg" title="Figure 1: class diagram" 
/><br />
+Figure 1: deployment strategy class diagram.</p>
+<p>The <code>DeploymentCheckTask</code> is responsible for periodically 
checking the management server for newer versions of deployment packages and if 
found emits an event. The <code>DeploymentUpdateTask</code> also periodically 
checks the management server, and if it finds a newer version, automatically 
downloads and installs it.</p>
+<p><img alt="Figure 2: sequence diagram" 
src="deployment_strategy_update_seq.svg" title="Figure 2: sequence diagram" 
/><br />
+Figure 2: deployment strategy sequence diagram.</p>
+<p>Figure 2 shows a more detailed sequence diagram of the deployment update 
strategy in ACE. The scheduler in the management agent calls the run()-method 
of the DeploymentUpdateTask once every <em>N</em> seconds. This method in its 
turn makes several calls to the <code>DeploymentService</code>, which acts as a 
facade for other services in ACE. The <code>DeploymentService</code> is queried 
for the highest local and remote versions. If the remote version is newer than 
the local version, a deployment package containing the changes between the 
local and the remote version is installed. Note that this installation is done 
in a best effort strategy: if it fails, all changes are rolled back to what 
they were. As a consequence, if the installation fails one time, it probably 
will fail the next time as well. </p>
+<h3 id="tweaking-the-deployment-strategy">Tweaking the deployment strategy</h3>
+<p>By default, the management agent allows the interval in which the update 
task is run to be customized. To change this interval, the management agent 
should be started with the extra system property 
"<code>-Dsyncinterval=1500</code>". The value of this property is interpreted 
as the interval time in milliseconds. Note that this property also changes the 
interval of other tasks as well, so setting it to a lower interval could 
potentially raise lots of traffic to your management server.</p>
+<p>Another thing you can customize is whether or not the update task should 
run at all. This is done by starting the management agent with the system 
property "<code>-Dorg.apache.ace.deployment.task=disabled</code>". While this 
option is not really useful out-of-the-box (the target is not be able to obtain 
any version at all) it opens up a possibility for providing custom deployment 
strategies.</p>
+<h2 id="implementing-a-custom-deployment-strategy">Implementing a custom 
deployment strategy</h2>
+<p>To implement our own deployment strategy, we need to create a bundle that 
provides the management agent with our update task. We will start with an 
update task that simply prints something to the console each time it is run and 
expand it later on. As can be seen in figure 1, a task is anything that 
implements the <code>Runnable</code> interface, so our update task needs to do 
as well. Furthermore, we will use the DependencyManager component from Felix to 
provide us with the right dependent services, the most important one being the 
<code>DeploymentService</code>.<br />
+The (stub) code for our update task looks like:</p>
+<table class="codehilitetable"><tr><td class="linenos"><div 
class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14</pre></div></td><td class="code"><div class="codehilite"><pre><span 
class="kn">package</span> <span class="n">net</span><span 
class="o">.</span><span class="na">luminis</span><span class="o">.</span><span 
class="na">ace</span><span class="o">.</span><span 
class="na">updatetask</span><span class="o">;</span>
+
+<span class="kn">import</span> <span 
class="nn">org.apache.ace.deployment.service.DeploymentService</span><span 
class="o">;</span>
+<span class="kn">import</span> <span 
class="nn">org.osgi.service.log.LogService</span><span class="o">;</span>
+
+<span class="kd">public</span> <span class="kd">class</span> <span 
class="nc">MyUpdateTask</span> <span class="kd">implements</span> <span 
class="n">Runnable</span> <span class="o">{</span>
+    <span class="c1">// injected by DependencyManager</span>
+    <span class="kd">private</span> <span class="n">DeploymentService</span> 
<span class="n">m_service</span><span class="o">;</span> 
+    <span class="kd">private</span> <span class="n">LogService</span> <span 
class="n">m_logService</span><span class="o">;</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">run</span><span class="o">()</span> <span class="o">{</span>
+        <span class="n">System</span><span class="o">.</span><span 
class="na">out</span><span class="o">.</span><span 
class="na">println</span><span class="o">(</span><span class="s">&quot;Hello 
from MyUpdateTask: &quot;</span> <span class="o">+</span> <span 
class="k">new</span> <span class="n">java</span><span class="o">.</span><span 
class="na">util</span><span class="o">.</span><span class="na">Date</span><span 
class="o">());</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+</td></tr></table>
+
+<p>The bundle activator that registers our update task as service:</p>
+<table class="codehilitetable"><tr><td class="linenos"><div 
class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36</pre></div></td><td class="code"><div class="codehilite"><pre><span 
class="kn">package</span> <span class="n">net</span><span 
class="o">.</span><span class="na">luminis</span><span class="o">.</span><span 
class="na">ace</span><span class="o">.</span><span 
class="na">updatetask</span><span class="o">;</span>
+
+<span class="kn">import</span> <span 
class="nn">java.util.Properties</span><span class="o">;</span>
+
+<span class="kn">import</span> <span 
class="nn">org.apache.ace.deployment.service.DeploymentService</span><span 
class="o">;</span>
+<span class="kn">import</span> <span 
class="nn">org.apache.ace.scheduler.constants.SchedulerConstants</span><span 
class="o">;</span>
+<span class="kn">import</span> <span 
class="nn">org.apache.felix.dm.DependencyActivatorBase</span><span 
class="o">;</span>
+<span class="kn">import</span> <span 
class="nn">org.apache.felix.dm.DependencyManager</span><span class="o">;</span>
+<span class="kn">import</span> <span 
class="nn">org.osgi.framework.BundleContext</span><span class="o">;</span>
+<span class="kn">import</span> <span 
class="nn">org.osgi.service.log.LogService</span><span class="o">;</span>
+
+<span class="kd">public</span> <span class="kd">class</span> <span 
class="nc">Activator</span> <span class="kd">extends</span> <span 
class="n">DependencyActivatorBase</span> <span class="o">{</span>
+  <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">init</span><span class="o">(</span><span 
class="n">BundleContext</span> <span class="n">context</span><span 
class="o">,</span> <span class="n">DependencyManager</span> <span 
class="n">manager</span><span class="o">)</span> <span class="kd">throws</span> 
<span class="n">Exception</span> <span class="o">{</span>
+    <span class="n">Properties</span> <span class="n">props</span> <span 
class="o">=</span> <span class="k">new</span> <span 
class="n">Properties</span><span class="o">();</span>
+    <span class="n">props</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">SchedulerConstants</span><span class="o">.</span><span 
class="na">SCHEDULER_NAME_KEY</span><span class="o">,</span> <span 
class="n">MyUpdateTask</span><span class="o">.</span><span 
class="na">class</span><span class="o">.</span><span 
class="na">getName</span><span class="o">());</span>
+    <span class="n">props</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">SchedulerConstants</span><span class="o">.</span><span 
class="na">SCHEDULER_DESCRIPTION_KEY</span><span class="o">,</span> <span 
class="s">&quot;My own deployment update service.&quot;</span><span 
class="o">);</span>
+    <span class="n">props</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">SchedulerConstants</span><span class="o">.</span><span 
class="na">SCHEDULER_RECIPE</span><span class="o">,</span> <span 
class="s">&quot;5000&quot;</span><span class="o">);</span>
+
+    <span class="n">manager</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">createComponent</span><span class="o">()</span>
+      <span class="o">.</span><span class="na">setInterface</span><span 
class="o">(</span><span class="n">Runnable</span><span class="o">.</span><span 
class="na">class</span><span class="o">.</span><span 
class="na">getName</span><span class="o">(),</span> <span 
class="n">props</span><span class="o">)</span>
+      <span class="o">.</span><span class="na">setImplementation</span><span 
class="o">(</span><span class="k">new</span> <span 
class="n">MyUpdateTask</span><span class="o">())</span>
+      <span class="o">.</span><span class="na">add</span><span 
class="o">(</span><span class="n">createServiceDependency</span><span 
class="o">()</span>
+        <span class="o">.</span><span class="na">setService</span><span 
class="o">(</span><span class="n">DeploymentService</span><span 
class="o">.</span><span class="na">class</span><span class="o">)</span>
+        <span class="o">.</span><span class="na">setRequired</span><span 
class="o">(</span><span class="kc">true</span><span class="o">)</span>
+      <span class="o">)</span>
+      <span class="o">.</span><span class="na">add</span><span 
class="o">(</span><span class="n">createServiceDependency</span><span 
class="o">()</span>
+        <span class="o">.</span><span class="na">setService</span><span 
class="o">(</span><span class="n">LogService</span><span 
class="o">.</span><span class="na">class</span><span class="o">)</span>
+        <span class="o">.</span><span class="na">setRequired</span><span 
class="o">(</span><span class="kc">false</span><span class="o">)</span>
+      <span class="o">)</span>
+    <span class="o">);</span>
+  <span class="o">}</span>
+
+  <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">destroy</span><span class="o">(</span><span 
class="n">BundleContext</span> <span class="n">context</span><span 
class="o">,</span> <span class="n">DependencyManager</span> <span 
class="n">manager</span><span class="o">)</span> <span class="kd">throws</span> 
<span class="n">Exception</span> <span class="o">{</span>
+    <span class="c1">// Nothing</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+</td></tr></table>
+
+<p>The activator isn't that different from any other one, the only interesting 
part is the service properties that we register along with our update task. The 
three properties are used by the ACE's scheduler to determine that our service 
is actually a scheduled task. With the "recipe" key, the scheduler is told what 
interval (in milliseconds) is to be used to execute our task. In our case the 
recipe is set to 5000, causing our task to be run once every five seconds.<br />
+To complete the whole cycle, we need some build scripting. For this, we use <a 
href="http://bndtools.org";>BndTools</a>:</p>
+<div class="codehilite"><pre>Bundle-Name: My Update Task
+Bundle-Version: 0.0.1
+Bundle-SymbolicName: net.luminis.ace.updatetask
+Bundle-Activator: net.luminis.ace.updatetask.Activator
+Private-Package: net.luminis.ace.updatetask
+Import-Package: *
+-buildpath: org.apache.ace.deployment.task.base;version=0.8,\
+     org.apache.ace.scheduler.api;version=0.8,\
+     org.apache.felix.dependencymanager;version=3.0,\
+     osgi.core;version=4.2.0,\
+     osgi.cmpn;version=4.2.0
+</pre></div>
+
+
+<p>To let the management agent to find and use our custom update task bundle, 
we need to add the JAR-file to its class path, and start the management agent 
with the following options:</p>
+<div class="codehilite"><pre><span class="o">[</span>localhost:~/<span 
class="o">]</span><span class="nv">$ </span>java 
-Dorg.apache.ace.deployment.task<span class="o">=</span>disabled <span 
class="se">\</span>
+ -cp 
org.apache.ace.launcher-0.8.1-SNAPSHOT.jar:net.luminis.ace.updatetask-1.0.0.jar 
<span class="se">\</span>
+ org.apache.ace.launcher.Main <span class="se">\</span>
+ bundle<span class="o">=</span>net.luminis.ace.updatetask.Activator <span 
class="se">\</span>
+ identification<span class="o">=</span>myTarget <span class="se">\</span>
+ discovery<span class="o">=</span>http://localhost:8080
+</pre></div>
+
+
+<p>Note that besides adding our bundle to the class path, we also have added 
the <code>bundle</code> argument to tell the management agent to include our 
bundle activator in its startup.<br />
+If everything went well, one of the first few lines printed out on the console 
should be something like:</p>
+<div class="codehilite"><pre><span class="n">Adding</span> <span 
class="n">additional</span> <span class="n">bundle</span> <span 
class="n">activator</span><span class="p">:</span> <span 
class="n">net</span><span class="p">.</span><span class="n">luminis</span><span 
class="p">.</span><span class="n">ace</span><span class="p">.</span><span 
class="n">updatetask</span><span class="p">.</span><span 
class="n">Activator</span>
+<span class="n">Not</span> <span class="n">starting</span> <span 
class="n">activator</span> <span class="n">org</span><span 
class="p">.</span><span class="n">apache</span><span class="p">.</span><span 
class="n">ace</span><span class="p">.</span><span 
class="n">deployment</span><span class="p">.</span><span 
class="n">task</span><span class="p">.</span>
+<span class="p">...</span>
+</pre></div>
+
+
+<p>After startup, our update task should print a message stating its existence 
to the console every five seconds.</p>
+<p>With the boiler plating in place, its time to make our update task a little 
more interesting. We change the code of our update task to the following (for 
brevity, only the run() method is shown):</p>
+<table class="codehilitetable"><tr><td class="linenos"><div 
class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24</pre></div></td><td class="code"><div class="codehilite"><pre><span 
class="kd">public</span> <span class="kt">void</span> <span 
class="nf">run</span><span class="o">()</span> <span class="o">{</span>
+    <span class="k">try</span> <span class="o">{</span>
+        <span class="n">Version</span> <span class="n">local</span> <span 
class="o">=</span> <span class="n">m_service</span><span 
class="o">.</span><span class="na">getHighestLocalVersion</span><span 
class="o">();</span>
+        <span class="n">Version</span> <span class="n">remote</span> <span 
class="o">=</span> <span class="n">m_service</span><span 
class="o">.</span><span class="na">getHighestRemoteVersion</span><span 
class="o">();</span>
+
+        <span class="k">if</span> <span class="o">((</span><span 
class="n">remote</span> <span class="o">!=</span> <span 
class="kc">null</span><span class="o">)</span> <span 
class="o">&amp;&amp;</span> <span class="o">((</span><span 
class="n">local</span> <span class="o">==</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">||</span> <span 
class="o">(</span><span class="n">remote</span><span class="o">.</span><span 
class="na">compareTo</span><span class="o">(</span><span 
class="n">local</span><span class="o">)</span> <span class="o">&gt;</span> 
<span class="mi">0</span><span class="o">)))</span> <span class="o">{</span>
+            <span class="c1">// Ask user whether this update should 
proceed...</span>
+            <span class="n">System</span><span class="o">.</span><span 
class="na">out</span><span class="o">.</span><span 
class="na">println</span><span class="o">(</span><span class="s">&quot;Update 
available! Upgrade from &quot;</span> <span class="o">+</span> <span 
class="n">local</span> <span class="o">+</span> <span class="s">&quot; to 
&quot;</span> <span class="o">+</span> <span class="n">remote</span> <span 
class="o">+</span> <span class="s">&quot; [Y/N]?&quot;</span><span 
class="o">);</span>
+
+            <span class="n">BufferedReader</span> <span 
class="n">reader</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">BufferedReader</span><span class="o">(</span><span 
class="k">new</span> <span class="n">InputStreamReader</span><span 
class="o">(</span><span class="n">System</span><span class="o">.</span><span 
class="na">in</span><span class="o">));</span>
+            <span class="n">String</span> <span class="n">result</span> <span 
class="o">=</span> <span class="n">reader</span><span class="o">.</span><span 
class="na">readLine</span><span class="o">();</span>
+
+            <span class="k">if</span> <span class="o">(</span><span 
class="s">&quot;y&quot;</span><span class="o">.</span><span 
class="na">equalsIgnoreCase</span><span class="o">(</span><span 
class="n">result</span><span class="o">))</span> <span class="o">{</span>
+                <span class="c1">// Ask the deployer service to install this 
update...</span>
+                <span class="n">m_service</span><span class="o">.</span><span 
class="na">installVersion</span><span class="o">(</span><span 
class="n">remote</span><span class="o">,</span> <span 
class="n">local</span><span class="o">);</span>
+
+                <span class="n">m_logService</span><span 
class="o">.</span><span class="na">log</span><span class="o">(</span><span 
class="n">LogService</span><span class="o">.</span><span 
class="na">LOG_INFO</span><span class="o">,</span> <span class="s">&quot;Update 
installed!&quot;</span><span class="o">);</span>
+            <span class="o">}</span>
+        <span class="o">}</span>
+    <span class="o">}</span> <span class="k">catch</span> <span 
class="o">(</span><span class="n">IOException</span> <span 
class="n">e</span><span class="o">)</span> <span class="o">{</span>
+        <span class="n">m_logService</span><span class="o">.</span><span 
class="na">log</span><span class="o">(</span><span 
class="n">LogService</span><span class="o">.</span><span 
class="na">LOG_WARNING</span><span class="o">,</span> <span 
class="s">&quot;Update failed!&quot;</span><span class="o">,</span> <span 
class="n">e</span><span class="o">);</span>
+    <span class="o">}</span> <span class="k">catch</span> <span 
class="o">(</span><span class="n">Exception</span> <span 
class="n">e</span><span class="o">)</span> <span class="o">{</span>
+        <span class="n">m_logService</span><span class="o">.</span><span 
class="na">log</span><span class="o">(</span><span 
class="n">LogService</span><span class="o">.</span><span 
class="na">LOG_WARNING</span><span class="o">,</span> <span 
class="s">&quot;Update failed!&quot;</span><span class="o">,</span> <span 
class="n">e</span><span class="o">);</span>
+<span class="o">}</span>
+</pre></div>
+</td></tr></table>
+
+<p>This new implementation first asks the <code>DeploymentService</code> what 
the current local (= version current running on management agent) and remote (= 
version available in the management server) versions are. If the remote version 
is newer/higher than the local version, than we ask the user for permission to 
install the update. When given, the <code>DeploymentService</code> is requested 
to upgrade from the local version to the remote version.<br />
+If you would run this code, you'll notice that if the user doesn't respond 
within the task's interval, a new task is started, causing an ever increasing 
number of tasks to be waiting for user input in case an update is available. 
Currently, due to the current implementation of ACE's scheduler, there is no 
way of disabling this behavior (although it is not really difficult to resolve 
this problem locally in your task).</p>
+<h2 id="taking-it-a-step-further">Taking it a step further…</h2>
+<p>So far, we've reused the <code>DeploymentService</code> facade from ACE to 
tweak the update process of the management agent a bit. However, there still 
some magic going on in the installation of newer versions (all the logic behind 
<code>DeploymentService#installVersion</code>).  
+Let's explore this method a bit more into detail. The 
<code>installVersion</code> method roughly (some details are left out for 
brevity) has the following implementation:</p>
+<table class="codehilitetable"><tr><td class="linenos"><div 
class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39</pre></div></td><td class="code"><div class="codehilite"><pre><span 
class="c1">// injected by Felix&#39; dependency manager</span>
+<span class="kd">volatile</span> <span class="n">Deployment</span> <span 
class="n">m_deployer</span><span class="o">;</span>
+<span class="kd">volatile</span> <span class="n">EventAdmin</span> <span 
class="n">m_eventAdmin</span><span class="o">;</span>
+<span class="kd">volatile</span> <span class="n">Identification</span> <span 
class="n">m_identification</span><span class="o">;</span>
+<span class="c1">// denotes the host + port where ACE is listening, e.g. 
http://192.168.1.1:8080/</span>
+<span class="kd">final</span> <span class="n">String</span> <span 
class="n">m_host</span><span class="o">;</span>
+
+<span class="cm">/**</span>
+<span class="cm"> * @see 
org.apache.ace.deployment.service.impl.DeploymentServiceImpl#installVersion</span>
+<span class="cm">*/</span>
+<span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">installVersion</span><span class="o">(</span><span 
class="n">Version</span> <span class="n">highestRemoteVersion</span><span 
class="o">,</span> <span class="n">Version</span> <span 
class="n">highestLocalVersion</span><span class="o">)</span> <span 
class="kd">throws</span> <span class="n">Exception</span> <span 
class="o">{</span>
+    <span class="n">InputStream</span> <span class="n">inputStream</span> 
<span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
+
+    <span class="k">try</span> <span class="o">{</span>
+        <span class="n">String</span> <span class="n">version</span> <span 
class="o">=</span> <span class="n">highestRemoteVersion</span><span 
class="o">.</span><span class="na">toString</span><span class="o">();</span>
+        <span class="n">URL</span> <span class="n">baseURL</span> <span 
class="o">=</span> <span class="k">new</span> <span class="n">URL</span><span 
class="o">(</span><span class="n">m_host</span><span class="o">,</span> <span 
class="s">&quot;deployment/&quot;</span> <span class="o">+</span> <span 
class="n">m_identification</span><span class="o">.</span><span 
class="na">getID</span><span class="o">()</span> <span class="o">+</span> <span 
class="s">&quot;/versions/&quot;</span><span class="o">);</span>
+        <span class="k">if</span> <span class="o">(</span><span 
class="n">highestLocalVersion</span> <span class="o">!=</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+            <span class="n">version</span> <span class="o">+=</span> <span 
class="s">&quot;?current=&quot;</span> <span class="o">+</span> <span 
class="n">highestLocalVersion</span><span class="o">.</span><span 
class="na">toString</span><span class="o">();</span>
+        <span class="o">}</span>
+        <span class="n">URL</span> <span class="n">dataURL</span> <span 
class="o">=</span> <span class="k">new</span> <span class="n">URL</span><span 
class="o">(</span><span class="n">baseURL</span><span class="o">,</span> <span 
class="n">version</span><span class="o">);</span>
+        <span class="n">inputStream</span> <span class="o">=</span> <span 
class="n">dataURL</span><span class="o">.</span><span 
class="na">openStream</span><span class="o">();</span>
+
+        <span class="c1">// Post event for audit log</span>
+        <span class="n">String</span> <span class="n">topic</span> <span 
class="o">=</span> <span 
class="s">&quot;org/apache/ace/deployment/INSTALL&quot;</span><span 
class="o">;</span>
+        <span class="n">m_eventAdmin</span><span class="o">.</span><span 
class="na">postEvent</span><span class="o">(</span><span 
class="n">createEvent</span><span class="o">(</span><span 
class="n">topic</span><span class="o">,</span> <span 
class="n">version</span><span class="o">,</span> <span 
class="n">dataURL</span><span class="o">));</span>
+
+        <span class="n">m_deployer</span><span class="o">.</span><span 
class="na">install</span><span class="o">(</span><span 
class="n">inputStream</span><span class="o">);</span>
+    <span class="o">}</span>
+    <span class="k">finally</span> <span class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span><span 
class="n">inputStream</span> <span class="o">!=</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+            <span class="k">try</span> <span class="o">{</span>
+                <span class="n">inputStream</span><span 
class="o">.</span><span class="na">close</span><span class="o">();</span>
+            <span class="o">}</span>
+            <span class="k">catch</span> <span class="o">(</span><span 
class="n">Exception</span> <span class="n">ex</span><span class="o">)</span> 
<span class="o">{</span>
+                <span class="c1">// Not much we can do.</span>
+            <span class="o">}</span>
+        <span class="o">}</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+</td></tr></table>
+
+<p>Basically, the method builds up an URL to access the deployment service of 
ACE. Through this URL, the deployment-service creates a deployment package 
containing the changed artifacts between the given local and remote version. 
The <code>InputStream</code> containing this deployment package is given to the 
<code>Deployment</code> service (a facade to the standard DeploymentAdmin 
service) to be installed. Note that if the installation of the deployment 
package fails, an exception is thrown. As mentioned earlier, the installation 
of deployment packages is done in a "all or nothing" strategy, meaning that if 
it fails, all changes are reverted. For more details on this, you can read the 
DeploymentAdmin specification (see [2], chapter 114).<br />
+Aside the actual installation of the deployment package, an event is also 
posted to keep track of this installation. This event is picked up by the 
<code>AuditLog</code> service of ACE to track all changes made to the 
management agent (<em>one can argue whether this shouldn't be a responsibility 
of the Deployment facade</em>). </p>
+<p>Now we have seen how the installation of deployment packages is implemented 
in ACE, we can even tweak that process a bit. For example, we could first 
download the deployment package entirely to a temporary location, and install 
it from there. Or, as we have access to the deployment package, we could also 
provide the user additional information about its contents, perhaps showing a 
change log or a summary of its contents, before installing it.</p>
+<h2 id="references">References</h2>
+<ol>
+<li><a href="http://svn.apache.org/repos/asf/ace/";>ACE subversion</a>;</li>
+<li><a href="http://www.osgi.org/Download/Release4V42";>OSGi 4.2 compendium 
specification</a>.</li>
+</ol></div>
+      <hr>
+      <footer>
+        <p>Copyright &#169; 2012-2014 <a href="http://www.apache.org/";>The 
Apache Software Foundation</a>, Licensed under the <a 
href="http://www.apache.org/licenses/LICENSE-2.0";>Apache License, Version 
2.0</a>.<br/>Apache ACE, the Apache ACE logo, Apache and the Apache feather 
logo are trademarks of The Apache Software Foundation. All other marks 
mentioned may be trademarks or registered trademarks of their respective 
owners.</p>
+      </footer>
+    </div>
+  </body>
+</html>

Added: websites/staging/ace/trunk/content/docs/ace-roles.html
==============================================================================
--- websites/staging/ace/trunk/content/docs/ace-roles.html (added)
+++ websites/staging/ace/trunk/content/docs/ace-roles.html Mon Nov 24 22:42:13 
2014
@@ -0,0 +1,195 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+  <head>
+    <title>Roles</title>
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+    <meta property="og:image" content="//www.apache.org/images/asf_logo.gif" />
+    <link href="/css/bootstrap.min.css" rel="stylesheet" media="screen">
+    <link href="/css/prettify.css" rel="stylesheet" media="screen">
+    <link href="/css/code.css" rel="stylesheet" media="screen">
+    <script src="//code.jquery.com/jquery.js"></script>
+    <script src="/js/bootstrap.min.js"></script>    
+    <script src="/js/prettify.js"></script>
+    
+    
+    
+    <script>
+    $(function () { prettyPrint() })
+    $().dropdown()
+    </script>
+  </head>
+  <body style="padding-top: 50px;">
+    <div class="navbar navbar-fixed-top navbar-inverse">
+      <div class="navbar-inner">
+        <div class="container">
+          <a class="brand" href="/index.html">Apache ACE&trade;</a>
+          <ul class="nav">
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">News <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/news.html">News</a>
+      </li>
+      <li>
+        <a href="/on-the-web.html">On the web</a>
+      </li>
+    </ul>
+  </li>
+  <li>
+    <a href="/downloads.html">Downloads</a>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Users <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/user-doc/introduction.html">Introduction</a>
+      </li>
+      <li>
+        <a href="/user-doc/getting-started.html">Getting Started</a>
+      </li>
+      <li>
+        <a href="/user-doc/user-guide.html">User Guide</a>
+      </li>
+      <li>
+        <a href="/user-doc/features.html">Features</a>
+      </li>
+      <li>
+        <a href="/user-doc/shellapi.html">Client Shell API</a>
+      </li>
+           <li>
+        <a href="/user-doc/restapi.html">Client REST API</a>
+      </li>
+      <li>
+        <a href="/user-doc/useradmin-ui.html">User Management Guide</a>
+      </li>
+      <li>
+        <a href="/user-doc/faq.html">FAQ</a>
+      </li>
+      <li>
+        <a href="/user-doc/support.html">Support</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Developers <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/dev-doc/getting-started.html">Getting Started</a>
+      </li>
+      <li>
+        <a href="/dev-doc/requirements/">Requirements</a>
+      </li>
+      <li>
+        <a href="/dev-doc/architecture.html">Architecture</a>
+      </li>
+      <li>
+        <a href="/dev-doc/analysis/">Analysis</a>
+      </li>
+      <li>
+        <a href="/dev-doc/design/">Design</a>
+      </li>
+      <li>
+        <a href="/dev-doc/coding-standards.html">Coding Standards</a>
+      </li>
+      <li>
+        <a href="/dev-doc/release-guide.html">Release Guide</a>
+      </li>
+      <li>
+        <a href="/dev-doc/writing-tests.html">Writing unit/integration 
tests</a>
+      </li>
+      <li>
+        <a href="/dev-doc/adding-custom-artifact-types.html">Adding custom 
artifact types</a>
+      </li>
+      <li>
+        <a href="/dev-doc/configuring-relay-servers.html">Configuring and 
using relay servers</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Involved <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/get-involved/mailing-lists.html">Mailing Lists</a>
+      </li>
+      <li>
+        <a href="/get-involved/issue-tracking.html">Issue Tracking</a>
+      </li>
+      <li>
+        <a href="/get-involved/continuous-integration.html">Continuous 
Integration</a>
+      </li>
+      <li>
+        <a href="/get-involved/source-code.html">Source Code</a>
+      </li>
+      <li>
+        <a href="/get-involved/project-team.html">Project Team</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Wiki <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a 
href="https://cwiki.apache.org/confluence/display/ACE/Board+Reports";>Board 
Reports <i class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a 
href="https://cwiki.apache.org/confluence/display/ACE/Index";>Homepage <i 
class="icon-share-alt"></i></a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Apache <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="http://www.apache.org/";>Apache Homepage <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="http://www.apache.org/licenses/";>Licenses <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="http://www.apache.org/security/";>Security <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="http://www.apache.org/foundation/thanks.html";>Thanks <i 
class="icon-share-alt"></i></a>
+      </li>
+    </ul>
+  </li>
+</ul>
+
+        </div>
+      </div>
+    </div>
+    <div class="container">
+      <p><a href="/"><i class='icon-home'></i> Home</a>&nbsp;&raquo&nbsp;<a 
href="/docs/">Docs</a></p>
+      <h1>Roles</h1>
+      <div class="clear"></div>
+      <div id="content"><p>These are the different roles in the system. Users 
of the system can be assigned one or more roles. The roles are also used in the 
different <a href="use-cases/">use cases</a>.</p>
+<h2 id="release-manager">Release Manager</h2>
+<p>The release manager manages the software configuration, linking artifacts 
to features and features to distributions.</p>
+<h2 id="target-manager">Target Manager</h2>
+<p>The target manager manages the total population of targets and assigns them 
to target operators.</p>
+<h2 id="target-operator">Target Operator</h2>
+<p>The target operator manages a (limited) set of targets designated to him by 
the target manager. He is responsible for accepting changes to the software 
configuration for those targets.</p>
+<h2 id="remote-target-operator">Remote Target Operator</h2>
+<p>Like the target operator, the remote target operator manages a limited set 
of targets.</p>
+<h2 id="license-manager">License Manager</h2>
+<p>The license manager manages the relationship between the targets and the 
distributions.</p>
+<h2 id="administrator">Administrator</h2>
+<p>The administrator manages the users, system settings, rights and security 
certificates for the whole ecosystem.</p>
+<h2 id="target">Target</h2>
+<p>A target runs the management agent that is responsible for updating the 
target.</p>
+<h2 id="server">Server</h2>
+<p>The server manages all the metadata that expresses what artifacts should be 
installed on what targets over time. It also contains an OBR for managing the 
actual artifacts.</p>
+<h2 id="relay-server">Relay server</h2>
+<p>The relay server acts as a cache for the server. It synchronizes with the 
server and might only contain a subset of the metadata to service a subset of 
the targets.</p>
+<h2 id="software-developer">Software Developer</h2>
+<p>The software developer provides artifacts that will be added to the 
OBR.</p></div>
+      <hr>
+      <footer>
+        <p>Copyright &#169; 2012-2014 <a href="http://www.apache.org/";>The 
Apache Software Foundation</a>, Licensed under the <a 
href="http://www.apache.org/licenses/LICENSE-2.0";>Apache License, Version 
2.0</a>.<br/>Apache ACE, the Apache ACE logo, Apache and the Apache feather 
logo are trademarks of The Apache Software Foundation. All other marks 
mentioned may be trademarks or registered trademarks of their respective 
owners.</p>
+      </footer>
+    </div>
+  </body>
+</html>

Added: websites/staging/ace/trunk/content/docs/ace_dnd_artifacts.png
==============================================================================
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/docs/ace_dnd_artifacts.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/ace_dnd_artifacts_fail.png
==============================================================================
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/docs/ace_dnd_artifacts_fail.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/ace_dnd_artifacts_ok.png
==============================================================================
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/docs/ace_dnd_artifacts_ok.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/ace_dynamic_association.png
==============================================================================
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/docs/ace_dynamic_association.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/ace_server_topology.png
==============================================================================
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/docs/ace_server_topology.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/ace_server_ui.png
==============================================================================
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/docs/ace_server_ui.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/ace_static_association.png
==============================================================================
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/docs/ace_static_association.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/ace_target_tag_editor.png
==============================================================================
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/docs/ace_target_tag_editor.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/ace_user_management_admin_ui.png
==============================================================================
Binary file - no diff available.

Propchange: 
websites/staging/ace/trunk/content/docs/ace_user_management_admin_ui.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: 
websites/staging/ace/trunk/content/docs/ace_user_management_newuser_ui.png
==============================================================================
Binary file - no diff available.

Propchange: 
websites/staging/ace/trunk/content/docs/ace_user_management_newuser_ui.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/ace_user_management_user_ui.png
==============================================================================
Binary file - no diff available.

Propchange: 
websites/staging/ace/trunk/content/docs/ace_user_management_user_ui.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: websites/staging/ace/trunk/content/docs/adding-custom-artifact-types.html
==============================================================================
--- websites/staging/ace/trunk/content/docs/adding-custom-artifact-types.html 
(added)
+++ websites/staging/ace/trunk/content/docs/adding-custom-artifact-types.html 
Mon Nov 24 22:42:13 2014
@@ -0,0 +1,396 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+  <head>
+    <title>Adding custom artifact types</title>
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+    <meta property="og:image" content="//www.apache.org/images/asf_logo.gif" />
+    <link href="/css/bootstrap.min.css" rel="stylesheet" media="screen">
+    <link href="/css/prettify.css" rel="stylesheet" media="screen">
+    <link href="/css/code.css" rel="stylesheet" media="screen">
+    <script src="//code.jquery.com/jquery.js"></script>
+    <script src="/js/bootstrap.min.js"></script>    
+    <script src="/js/prettify.js"></script>
+    
+    
+    
+    <script>
+    $(function () { prettyPrint() })
+    $().dropdown()
+    </script>
+  </head>
+  <body style="padding-top: 50px;">
+    <div class="navbar navbar-fixed-top navbar-inverse">
+      <div class="navbar-inner">
+        <div class="container">
+          <a class="brand" href="/index.html">Apache ACE&trade;</a>
+          <ul class="nav">
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">News <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/news.html">News</a>
+      </li>
+      <li>
+        <a href="/on-the-web.html">On the web</a>
+      </li>
+    </ul>
+  </li>
+  <li>
+    <a href="/downloads.html">Downloads</a>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Users <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/user-doc/introduction.html">Introduction</a>
+      </li>
+      <li>
+        <a href="/user-doc/getting-started.html">Getting Started</a>
+      </li>
+      <li>
+        <a href="/user-doc/user-guide.html">User Guide</a>
+      </li>
+      <li>
+        <a href="/user-doc/features.html">Features</a>
+      </li>
+      <li>
+        <a href="/user-doc/shellapi.html">Client Shell API</a>
+      </li>
+           <li>
+        <a href="/user-doc/restapi.html">Client REST API</a>
+      </li>
+      <li>
+        <a href="/user-doc/useradmin-ui.html">User Management Guide</a>
+      </li>
+      <li>
+        <a href="/user-doc/faq.html">FAQ</a>
+      </li>
+      <li>
+        <a href="/user-doc/support.html">Support</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Developers <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/dev-doc/getting-started.html">Getting Started</a>
+      </li>
+      <li>
+        <a href="/dev-doc/requirements/">Requirements</a>
+      </li>
+      <li>
+        <a href="/dev-doc/architecture.html">Architecture</a>
+      </li>
+      <li>
+        <a href="/dev-doc/analysis/">Analysis</a>
+      </li>
+      <li>
+        <a href="/dev-doc/design/">Design</a>
+      </li>
+      <li>
+        <a href="/dev-doc/coding-standards.html">Coding Standards</a>
+      </li>
+      <li>
+        <a href="/dev-doc/release-guide.html">Release Guide</a>
+      </li>
+      <li>
+        <a href="/dev-doc/writing-tests.html">Writing unit/integration 
tests</a>
+      </li>
+      <li>
+        <a href="/dev-doc/adding-custom-artifact-types.html">Adding custom 
artifact types</a>
+      </li>
+      <li>
+        <a href="/dev-doc/configuring-relay-servers.html">Configuring and 
using relay servers</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Involved <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/get-involved/mailing-lists.html">Mailing Lists</a>
+      </li>
+      <li>
+        <a href="/get-involved/issue-tracking.html">Issue Tracking</a>
+      </li>
+      <li>
+        <a href="/get-involved/continuous-integration.html">Continuous 
Integration</a>
+      </li>
+      <li>
+        <a href="/get-involved/source-code.html">Source Code</a>
+      </li>
+      <li>
+        <a href="/get-involved/project-team.html">Project Team</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Wiki <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a 
href="https://cwiki.apache.org/confluence/display/ACE/Board+Reports";>Board 
Reports <i class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a 
href="https://cwiki.apache.org/confluence/display/ACE/Index";>Homepage <i 
class="icon-share-alt"></i></a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Apache <b 
class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="http://www.apache.org/";>Apache Homepage <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="http://www.apache.org/licenses/";>Licenses <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="http://www.apache.org/security/";>Security <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship <i 
class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="http://www.apache.org/foundation/thanks.html";>Thanks <i 
class="icon-share-alt"></i></a>
+      </li>
+    </ul>
+  </li>
+</ul>
+
+        </div>
+      </div>
+    </div>
+    <div class="container">
+      <p><a href="/"><i class='icon-home'></i> Home</a>&nbsp;&raquo&nbsp;<a 
href="/docs/">Docs</a></p>
+      <h1>Adding custom artifact types</h1>
+      <div class="clear"></div>
+      <div id="content"><p>Out of the box, ACE comes with support for bundles 
and configuration files that follow the
+Auto Configuration specification. However, it is possible to extend ACE with 
support for
+new types of artifacts. Doing so requires you to do three things:</p>
+<ol>
+<li>Write a resource processor, according to the Deployment Admin 
specification.</li>
+<li>Write an ArtifactRecognizer service implementation.</li>
+<li>Write an ArtifactHelper service implementation.</li>
+</ol>
+<p>This document explains how to write each of these, and how to subsequently 
deploy them
+appropriately.</p>
+<h2 id="writing-a-resource-processor">Writing a resource processor</h2>
+<p>A resource processor implements the ResourceProcessor interface as defined 
in the
+Deployment Admin specification (OSGi Compendium 114.10). It describes in 
detail the
+contract that needs to be implemented and also contains an example. If you 
want to get
+started quickly, you can use the following code:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span 
class="kd">class</span> <span class="nc">Processor</span> <span 
class="kd">implements</span> <span class="n">ResourceProcessor</span> <span 
class="o">{</span>
+    <span class="kd">private</span> <span class="kd">volatile</span> <span 
class="n">DeploymentSession</span> <span class="n">m_session</span><span 
class="o">;</span>
+    <span class="kd">private</span> <span class="n">String</span> <span 
class="n">m_deploymentPackageName</span><span class="o">;</span>
+    <span class="kd">private</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> 
<span class="n">m_toInstall</span><span class="o">;</span>
+    <span class="kd">private</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> 
<span class="n">m_toRemove</span><span class="o">;</span>
+
+    <span class="cm">/**</span>
+<span class="cm">     * Sets up the necessary environment for a deployment 
session.</span>
+<span class="cm">     */</span>
+    <span class="kd">private</span> <span class="kt">void</span> <span 
class="nf">startSession</span><span class="o">(</span><span 
class="n">DeploymentSession</span> <span class="n">session</span><span 
class="o">)</span> <span class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span><span 
class="n">m_session</span> <span class="o">!=</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+            <span class="k">throw</span> <span class="k">new</span> <span 
class="nf">IllegalArgumentException</span><span class="o">(</span><span 
class="s">&quot;This resource processor is currently processing another 
deployment session, installing deploymentpackage&quot;</span> <span 
class="o">+</span> <span class="n">m_session</span><span 
class="o">.</span><span class="na">getTargetDeploymentPackage</span><span 
class="o">().</span><span class="na">getName</span><span class="o">());</span>
+        <span class="o">}</span>
+        <span class="n">m_session</span> <span class="o">=</span> <span 
class="n">session</span><span class="o">;</span>
+        <span class="n">m_toInstall</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">ArrayList</span><span 
class="o">&lt;</span><span class="n">String</span><span class="o">&gt;();</span>
+        <span class="n">m_toRemove</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">ArrayList</span><span 
class="o">&lt;</span><span class="n">String</span><span class="o">&gt;();</span>
+        <span class="n">String</span> <span class="n">fromSource</span> <span 
class="o">=</span> <span class="n">session</span><span class="o">.</span><span 
class="na">getSourceDeploymentPackage</span><span class="o">().</span><span 
class="na">getName</span><span class="o">();</span>
+        <span class="n">String</span> <span class="n">fromTarget</span> <span 
class="o">=</span> <span class="n">session</span><span class="o">.</span><span 
class="na">getTargetDeploymentPackage</span><span class="o">().</span><span 
class="na">getName</span><span class="o">();</span>
+        <span class="k">if</span> <span class="o">(</span><span 
class="n">fromSource</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="s">&quot;&quot;</span><span class="o">))</span> <span class="o">{</span>
+            <span class="n">m_deploymentPackageName</span> <span 
class="o">=</span> <span class="n">fromTarget</span><span class="o">;</span>
+        <span class="o">}</span>
+        <span class="k">else</span> <span class="o">{</span>
+            <span class="n">m_deploymentPackageName</span> <span 
class="o">=</span> <span class="n">fromSource</span><span class="o">;</span>
+        <span class="o">}</span>
+    <span class="o">}</span>
+
+    <span class="cm">/**</span>
+<span class="cm">     * Ends a deployment session.</span>
+<span class="cm">     */</span>
+    <span class="kd">private</span> <span class="kt">void</span> <span 
class="nf">endSession</span><span class="o">()</span> <span class="o">{</span>
+        <span class="n">m_session</span> <span class="o">=</span> <span 
class="kc">null</span><span class="o">;</span>
+        <span class="n">m_deploymentPackageName</span> <span 
class="o">=</span> <span class="kc">null</span><span class="o">;</span>
+        <span class="n">m_toInstall</span> <span class="o">=</span> <span 
class="kc">null</span><span class="o">;</span>
+        <span class="n">m_toRemove</span> <span class="o">=</span> <span 
class="kc">null</span><span class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="kd">private</span> <span class="kt">void</span> <span 
class="nf">ensureSession</span><span class="o">()</span>  <span 
class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span><span 
class="n">m_session</span> <span class="o">==</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+            <span class="k">throw</span> <span class="k">new</span> <span 
class="nf">IllegalStateException</span><span class="o">(</span><span 
class="s">&quot;This resource processor is currently not part of a deployment 
session.&quot;</span><span class="o">);</span>
+        <span class="o">}</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">begin</span><span class="o">(</span><span 
class="n">DeploymentSession</span> <span class="n">session</span><span 
class="o">)</span> <span class="o">{</span>
+        <span class="n">startSession</span><span class="o">(</span><span 
class="n">session</span><span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">process</span><span class="o">(</span><span class="n">String</span> 
<span class="n">name</span><span class="o">,</span> <span 
class="n">InputStream</span> <span class="n">stream</span><span 
class="o">)</span> <span class="kd">throws</span> <span 
class="n">ResourceProcessorException</span> <span class="o">{</span>
+        <span class="n">ensureSession</span><span class="o">();</span>
+        <span class="n">m_toInstall</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span class="n">name</span><span 
class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">dropped</span><span class="o">(</span><span class="n">String</span> 
<span class="n">resource</span><span class="o">)</span> <span 
class="kd">throws</span> <span class="n">ResourceProcessorException</span> 
<span class="o">{</span>
+        <span class="n">ensureSession</span><span class="o">();</span>
+        <span class="n">m_toRemove</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">resource</span><span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">dropAllResources</span><span class="o">()</span> <span 
class="kd">throws</span> <span class="n">ResourceProcessorException</span> 
<span class="o">{</span>
+        <span class="n">ensureSession</span><span class="o">();</span>
+        <span class="n">m_toRemove</span><span class="o">.</span><span 
class="na">addAll</span><span class="o">(</span><span 
class="n">Collections</span><span class="o">.</span><span 
class="na">EMPTY_LIST</span> <span class="cm">/* should be a list of all 
current resources */</span><span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">prepare</span><span class="o">()</span> <span 
class="kd">throws</span> <span class="n">ResourceProcessorException</span> 
<span class="o">{</span>
+        <span class="n">ensureSession</span><span class="o">();</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">commit</span><span class="o">()</span> <span class="o">{</span>
+        <span class="n">ensureSession</span><span class="o">();</span>
+        <span class="k">while</span> <span class="o">(!</span><span 
class="n">m_toInstall</span><span class="o">.</span><span 
class="na">isEmpty</span><span class="o">())</span> <span class="o">{</span>
+            <span class="n">System</span><span class="o">.</span><span 
class="na">out</span><span class="o">.</span><span 
class="na">println</span><span class="o">(</span><span 
class="s">&quot;installing: &quot;</span> <span class="o">+</span> <span 
class="n">m_toInstall</span><span class="o">.</span><span 
class="na">remove</span><span class="o">(</span><span class="mi">0</span><span 
class="o">));</span>
+        <span class="o">}</span>
+        <span class="k">while</span> <span class="o">(!</span><span 
class="n">m_toRemove</span><span class="o">.</span><span 
class="na">isEmpty</span><span class="o">())</span> <span class="o">{</span>
+            <span class="n">System</span><span class="o">.</span><span 
class="na">out</span><span class="o">.</span><span 
class="na">println</span><span class="o">(</span><span 
class="s">&quot;removing: &quot;</span> <span class="o">+</span> <span 
class="n">m_toRemove</span><span class="o">.</span><span 
class="na">remove</span><span class="o">(</span><span class="mi">0</span><span 
class="o">));</span>
+        <span class="o">}</span>
+        <span class="n">endSession</span><span class="o">();</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">rollback</span><span class="o">()</span> <span class="o">{</span>
+        <span class="c1">// nothing special to do.</span>
+        <span class="n">ensureSession</span><span class="o">();</span>
+        <span class="n">endSession</span><span class="o">();</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">cancel</span><span class="o">()</span> <span class="o">{</span>
+        <span class="n">ensureSession</span><span class="o">();</span>
+        <span class="c1">// Nothing to do: we have no long-running operation, 
we only read the stream.</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>This should be enough to get you started, but the code takes a few 
shortcuts so please do
+take some time to read the specification and implement each method 
correctly.</p>
+<p>The next step then is to publish this processor as an OSGi service. Don't 
forget to add
+the <tt>SERVICE_PID</tt> property and set its value, because that is how the 
processor is
+later recognized. Package everything up in an OSGi bundle and make sure to 
include these
+two headers in its manifest:</p>
+<div class="codehilite"><pre><span class="n">Deployment</span><span 
class="o">-</span><span class="n">ProvidesResourceProcessor</span><span 
class="p">:</span> <span class="n">org</span><span class="p">.</span><span 
class="n">apache</span><span class="p">.</span><span class="n">ace</span><span 
class="p">.</span><span class="n">resourceprocessor</span><span 
class="p">.</span><span class="n">custom</span>
+<span class="n">DeploymentPackage</span><span class="o">-</span><span 
class="n">Customizer</span><span class="p">:</span> <span class="n">true</span>
+</pre></div>
+
+
+<p>The first one should match the PID you used earlier.</p>
+<h2 id="writing-an-artifacthelper-and-artifactrecognizer">Writing an 
ArtifactHelper and ArtifactRecognizer</h2>
+<p>These services can usually just be implemented by the same class. The 
artifact recognizer
+is used to identify an artifact as being of this specific type. How it does 
that is up to
+the implementation. It might do something as simple as look at the file 
extension, but a
+lot of recognizers will also inspect (part of) the actual file. The artifact 
helper then
+contains all kinds of methods to help ACE deal with this specific type of 
artifact. The
+API documentation of these two interfaces explains the methods in detail. 
Again, let's get
+started with an implementation of both for a very simple artifact: a file with 
a specific
+extension:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span 
class="kd">class</span> <span class="nc">CustomArtifactHelper</span> <span 
class="kd">implements</span> <span class="n">ArtifactRecognizer</span><span 
class="o">,</span> <span class="n">ArtifactHelper</span> <span 
class="o">{</span>
+    <span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">KEY_FILENAME</span> <span class="o">=</span> <span 
class="s">&quot;filename&quot;</span><span class="o">;</span>
+    <span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">MIMETYPE</span> <span class="o">=</span> <span 
class="s">&quot;application/vnd.apache.ace.custom&quot;</span><span 
class="o">;</span>
+    <span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">PROCESSOR</span> <span class="o">=</span> <span 
class="s">&quot;org.apache.ace.resourceprocessor.custom&quot;</span><span 
class="o">;</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">boolean</span> <span 
class="nf">canUse</span><span class="o">(</span><span 
class="n">ArtifactObject</span> <span class="n">object</span><span 
class="o">)</span> <span class="o">{</span>
+        <span class="k">return</span> <span class="o">(</span><span 
class="n">object</span> <span class="o">==</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">?</span> <span 
class="kc">false</span> <span class="o">:</span> <span 
class="n">MIMETYPE</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">object</span><span class="o">.</span><span 
class="na">getMimetype</span><span class="o">());</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">ArtifactPreprocessor</span> 
<span class="nf">getPreprocessor</span><span class="o">()</span> <span 
class="o">{</span>
+        <span class="k">return</span> <span class="kc">null</span><span 
class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="o">&lt;</span><span 
class="n">TYPE</span> <span class="kd">extends</span> <span 
class="n">ArtifactObject</span><span class="o">&gt;</span> <span 
class="n">String</span> <span class="n">getAssociationFilter</span><span 
class="o">(</span><span class="n">TYPE</span> <span class="n">obj</span><span 
class="o">,</span> <span class="n">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">String</span><span class="o">&gt;</span> <span 
class="n">properties</span><span class="o">)</span> <span class="o">{</span>
+        <span class="k">return</span> <span class="s">&quot;(&quot;</span> 
<span class="o">+</span> <span class="n">ArtifactObject</span><span 
class="o">.</span><span class="na">KEY_ARTIFACT_NAME</span> <span 
class="o">+</span> <span class="s">&quot;=&quot;</span> <span 
class="o">+</span> <span class="n">obj</span><span class="o">.</span><span 
class="na">getAttribute</span><span class="o">(</span><span 
class="n">ArtifactObject</span><span class="o">.</span><span 
class="na">KEY_ARTIFACT_NAME</span><span class="o">)</span> <span 
class="o">+</span> <span class="s">&quot;)&quot;</span><span class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="o">&lt;</span><span 
class="n">TYPE</span> <span class="kd">extends</span> <span 
class="n">ArtifactObject</span><span class="o">&gt;</span> <span 
class="kt">int</span> <span class="n">getCardinality</span><span 
class="o">(</span><span class="n">TYPE</span> <span class="n">obj</span><span 
class="o">,</span> <span class="n">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">String</span><span class="o">&gt;</span> <span 
class="n">properties</span><span class="o">)</span> <span class="o">{</span>
+        <span class="k">return</span> <span class="n">Integer</span><span 
class="o">.</span><span class="na">MAX_VALUE</span><span class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">Comparator</span><span 
class="o">&lt;</span><span class="n">ArtifactObject</span><span 
class="o">&gt;</span> <span class="n">getComparator</span><span 
class="o">()</span> <span class="o">{</span>
+        <span class="k">return</span> <span class="kc">null</span><span 
class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">Map</span><span 
class="o">&lt;</span><span class="n">String</span><span class="o">,</span> 
<span class="n">String</span><span class="o">&gt;</span> <span 
class="n">checkAttributes</span><span class="o">(</span><span 
class="n">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">String</span><span class="o">&gt;</span> <span 
class="n">attributes</span><span class="o">)</span> <span class="o">{</span>
+        <span class="k">return</span> <span class="n">attributes</span><span 
class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="n">String</span><span 
class="o">[]</span> <span class="nf">getDefiningKeys</span><span 
class="o">()</span> <span class="o">{</span>
+        <span class="k">return</span> <span class="k">new</span> <span 
class="n">String</span><span class="o">[]</span> <span class="o">{</span><span 
class="n">ArtifactObject</span><span class="o">.</span><span 
class="na">KEY_ARTIFACT_NAME</span><span class="o">};</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="n">String</span><span 
class="o">[]</span> <span class="nf">getMandatoryAttributes</span><span 
class="o">()</span> <span class="o">{</span>
+        <span class="k">return</span> <span class="k">new</span> <span 
class="n">String</span><span class="o">[]</span> <span class="o">{</span><span 
class="n">ArtifactObject</span><span class="o">.</span><span 
class="na">KEY_ARTIFACT_NAME</span><span class="o">};</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">String</span> <span 
class="nf">recognize</span><span class="o">(</span><span 
class="n">ArtifactResource</span> <span class="n">artifact</span><span 
class="o">)</span> <span class="o">{</span>
+        <span class="c1">// here we can examine the stream to check the 
contents of the artifact</span>
+        <span class="c1">// for this demo, our check is just for the extension 
of the URL, which is</span>
+        <span class="c1">// a bit simplistic</span>
+        <span class="k">if</span> <span class="o">(</span><span 
class="n">artifact</span><span class="o">.</span><span 
class="na">getURL</span><span class="o">().</span><span 
class="na">toExternalForm</span><span class="o">().</span><span 
class="na">endsWith</span><span class="o">(</span><span 
class="s">&quot;.custom&quot;</span><span class="o">))</span> <span 
class="o">{</span>
+            <span class="k">return</span> <span class="n">MIMETYPE</span><span 
class="o">;</span>
+        <span class="o">}</span>
+        <span class="k">return</span> <span class="kc">null</span><span 
class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">Map</span><span 
class="o">&lt;</span><span class="n">String</span><span class="o">,</span> 
<span class="n">String</span><span class="o">&gt;</span> <span 
class="n">extractMetaData</span><span class="o">(</span><span 
class="n">ArtifactResource</span> <span class="n">artifact</span><span 
class="o">)</span> <span class="kd">throws</span> <span 
class="n">IllegalArgumentException</span> <span class="o">{</span>
+        <span class="n">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">String</span><span class="o">&gt;</span> <span 
class="n">result</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">HashMap</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">String</span><span class="o">&gt;();</span>
+        <span class="n">result</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">ArtifactObject</span><span class="o">.</span><span 
class="na">KEY_PROCESSOR_PID</span><span class="o">,</span> <span 
class="n">PROCESSOR</span><span class="o">);</span>
+        <span class="n">result</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">ArtifactObject</span><span class="o">.</span><span 
class="na">KEY_MIMETYPE</span><span class="o">,</span> <span 
class="n">MIMETYPE</span><span class="o">);</span>
+        <span class="n">String</span> <span class="n">name</span> <span 
class="o">=</span> <span class="k">new</span> <span class="n">File</span><span 
class="o">(</span><span class="n">artifact</span><span class="o">.</span><span 
class="na">getURL</span><span class="o">().</span><span 
class="na">getFile</span><span class="o">()).</span><span 
class="na">getName</span><span class="o">();</span>
+        <span class="n">result</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">ArtifactObject</span><span class="o">.</span><span 
class="na">KEY_ARTIFACT_NAME</span><span class="o">,</span> <span 
class="n">name</span><span class="o">);</span>
+        <span class="n">result</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">KEY_FILENAME</span><span class="o">,</span> <span 
class="n">name</span><span class="o">);</span>
+        <span class="k">return</span> <span class="n">result</span><span 
class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">boolean</span> <span 
class="nf">canHandle</span><span class="o">(</span><span 
class="n">String</span> <span class="n">mimetype</span><span class="o">)</span> 
<span class="o">{</span>
+        <span class="k">return</span> <span class="n">MIMETYPE</span><span 
class="o">.</span><span class="na">equals</span><span class="o">(</span><span 
class="n">mimetype</span><span class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">String</span> <span 
class="nf">getExtension</span><span class="o">(</span><span 
class="n">ArtifactResource</span> <span class="n">artifact</span><span 
class="o">)</span> <span class="o">{</span>
+        <span class="k">return</span> <span 
class="s">&quot;.custom&quot;</span><span class="o">;</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Again, this is no production code, but it should get you started quickly. 
This code will
+recognize artifacts that have the ".custom" file extension. No effort is done 
here to look
+at the contents of the file just to keep the example simple. Publish this 
instance as both
+an ArtifactHelper and an ArtifactRecognizer and make sure to add a service 
property for
+the mime type: <tt>ArtifactObject.KEY_MIMETYPE</tt>,
+<tt>CustomArtifactHelper.MIMETYPE</tt>.</p>
+<p>Wrap it up in a bundle, and you're ready to use your custom artifact in 
ACE.</p>
+<h2 id="installing-everything-in-ace">Installing everything in ACE</h2>
+<p>To add the new artifact type to ACE, you first have to take the bundle that 
contained the
+ArtifactHelper and ArtifactRecognizer service and add that to ACE. The bundle 
should be
+part of the ACE client. If you use the "all in one" server, add it to that.</p>
+<p>The second step is to upload the resource processor to ACE. You can do that 
like you
+upload any other bundle. Just add it to the artifact column. After adding it, 
it will not
+show up in the column, but ACE will send it to a target if that target needs 
an artifact
+of this type.</p>
+<p>Should you ever discover that you made a mistake in your resource 
processor, you can
+simply upload a newer one. Just make sure you bump the version and ACE will 
ensure that
+everybody gets this latest version.</p></div>
+      <hr>
+      <footer>
+        <p>Copyright &#169; 2012-2014 <a href="http://www.apache.org/";>The 
Apache Software Foundation</a>, Licensed under the <a 
href="http://www.apache.org/licenses/LICENSE-2.0";>Apache License, Version 
2.0</a>.<br/>Apache ACE, the Apache ACE logo, Apache and the Apache feather 
logo are trademarks of The Apache Software Foundation. All other marks 
mentioned may be trademarks or registered trademarks of their respective 
owners.</p>
+      </footer>
+    </div>
+  </body>
+</html>


Reply via email to