ace-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r1527522 [1/3] - in /ace/trunk: org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/ org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ org.apache.ace.client.repository/src/org/apache/ace/...
Date Mon, 30 Sep 2013 12:00:27 GMT
Author: jawi
Date: Mon Sep 30 12:00:26 2013
New Revision: 1527522

URL: http://svn.apache.org/r1527522
Log:
ACE-384 - add size estimation for DP:

- when an artifact is added to a repository, it size is stored as well;
- when a deployment is defined for a target, the sizes of all included
  artifacts are included as well;
- the DeploymentServlet now also responds to a HEAD request, in which
  it calculates an estimation of the deployment package (= size of all
  included artifacts + an additional factor to compensate for deviations
  caused by RPs);
- added some basic unit and integration tests.


Modified:
    ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java
    ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java
    ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java
    ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/bundle/impl/BundleHelperTest.java
    ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/configuration/impl/ConfigurationHelperImplTest.java
    ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/impl/ArtifactTest.java
    ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/impl/ModelTest.java
    ace/trunk/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java
    ace/trunk/org.apache.ace.deployment/bnd.bnd
    ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/ArtifactData.java
    ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/filebased/FileBasedProvider.java
    ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/impl/ArtifactDataImpl.java
    ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/repositorybased/BaseRepositoryHandler.java
    ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/repositorybased/RepositoryBasedProvider.java
    ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/DeploymentServlet.java
    ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestData.java
    ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/DeploymentTest.java
    ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/filebased/FileBasedProviderTest.java
    ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/RepositoryBasedProviderTest.java
    ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/servlet/DeploymentServletTest.java
    ace/trunk/org.apache.ace.obr/test/org/apache/ace/obr/metadata/bindeximpl/BindexMetadataTest.java

Modified: ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java (original)
+++ ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java Mon Sep 30 12:00:26 2013
@@ -85,7 +85,7 @@ public abstract class BaseRepositoryAdmi
             m_name = String.format("user-%s", Long.toHexString(System.nanoTime()));
         }
 
-        public Dictionary getCredentials() {
+        public Dictionary<Object, Object> getCredentials() {
             return new Properties();
         }
 
@@ -93,7 +93,7 @@ public abstract class BaseRepositoryAdmi
             return m_name;
         }
 
-        public Dictionary getProperties() {
+        public Dictionary<Object, Object> getProperties() {
             return new Properties();
         }
 
@@ -237,11 +237,14 @@ public abstract class BaseRepositoryAdmi
     }
 
     protected ArtifactObject createBasicBundleObject(String symbolicName, String version, String processorPID) {
+        return createBasicBundleObject(symbolicName, version, processorPID, null);
+    }
+    
+    protected ArtifactObject createBasicBundleObject(String symbolicName, String version, String processorPID, String size) {
         Map<String, String> attr = new HashMap<String, String>();
         attr.put(BundleHelper.KEY_SYMBOLICNAME, symbolicName);
         attr.put(ArtifactObject.KEY_MIMETYPE, BundleHelper.MIMETYPE);
         attr.put(ArtifactObject.KEY_URL, "http://" + symbolicName + "-" + ((version == null) ? "null" : version));
-        Map<String, String> tags = new HashMap<String, String>();
 
         if (version != null) {
             attr.put(BundleHelper.KEY_VERSION, version);
@@ -249,6 +252,11 @@ public abstract class BaseRepositoryAdmi
         if (processorPID != null) {
             attr.put(BundleHelper.KEY_RESOURCE_PROCESSOR_PID, processorPID);
         }
+        if (size != null) {
+            attr.put(ArtifactObject.KEY_SIZE, size);
+        }
+
+        Map<String, String> tags = new HashMap<String, String>();
         return m_artifactRepository.create(attr, tags);
     }
 

Modified: ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java (original)
+++ ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java Mon Sep 30 12:00:26 2013
@@ -28,7 +28,6 @@ import static org.apache.ace.client.repo
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -52,8 +51,6 @@ import org.apache.ace.client.repository.
 import org.apache.ace.log.AuditEvent;
 import org.apache.ace.log.LogEvent;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventHandler;
 import org.osgi.service.useradmin.User;
 
 /**
@@ -65,498 +62,499 @@ public class StatefulTargetRepositoryTes
         setUpTestCase();
 
         final String targetId = "myNewTarget2";
-        
+
         final Map<String, String> attr = new HashMap<String, String>();
-		attr.put(TargetObject.KEY_ID, targetId);
-		
-		final Map<String, String> tags = new HashMap<String, String>();
-		final StatefulTargetObject sgo = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
-		    public StatefulTargetObject call() throws Exception {
-		        return m_statefulTargetRepository.preregister(attr, tags);
-		    }
-		}, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
-		
-		assertTrue("Without any deployment versions, and no information in the shop, we should not need to approve.", !sgo.needsApprove());
-		assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
-		assertEquals("We expect the registration state to be New;", StoreState.New, sgo.getStoreState());
-		assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion());
-		
-		final ArtifactObject b11 = createBasicBundleObject("bundle1", "1", null);
-		
-		FeatureObject g1 = createBasicFeatureObject("feature1");
-		FeatureObject g2 = createBasicFeatureObject("feature2"); // note that this feature is not associated to a bundle.
-		
-		createDynamicBundle2FeatureAssociation(b11, g1);
-		
-		final DistributionObject l1 = createBasicDistributionObject("distribution1");
-		
-		m_feature2distributionRepository.create(g1, l1);
-		m_feature2distributionRepository.create(g2, l1);
-		
-		runAndWaitForEvent(new Callable<Distribution2TargetAssociation>() {
-		    public Distribution2TargetAssociation call() throws Exception {
-		        return m_distribution2targetRepository.create(l1, sgo.getTargetObject());
-		    }
-		}, false, Distribution2TargetAssociation.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
-		
-		assertTrue("We added information that influences our target, so we should need to approve it.", sgo.needsApprove());
-		assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
-		assertEquals("We expect the registration state to be Unapproved;", StoreState.Unapproved, sgo.getStoreState());
-		assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length);
-		assertEquals("According to the deployment, this target needs 0 bundles", 0, sgo.getArtifactsFromDeployment().length);
-		assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion());
-		
-		runAndWaitForEvent(new Callable<Object>() {
-		    public Object call() throws Exception {
-		        createBasicDeploymentVersionObject(targetId, "1", b11);
-		        return null;
-		    }
-		}, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
-		
-		assertFalse("We manually created a deployment version that reflects the shop, so no approval should be necessary.", sgo.needsApprove());
-		assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
-		assertEquals("We expect the registration state to be Approved;", StoreState.Approved, sgo.getStoreState());
-		assertEquals("According to the shop, this target needs 1 bundle;", 1, sgo.getArtifactsFromShop().length);
-		assertEquals("According to the deployment, this target needs 1 bundle;", 1, sgo.getArtifactsFromDeployment().length);
-		
-		runAndWaitForEvent(new Callable<ArtifactObject>() {
-		    public ArtifactObject call() throws Exception {
-		        return createBasicBundleObject("bundle1", "2", null);
-		    }
-		}, false, ArtifactObject.TOPIC_ADDED, Artifact2FeatureAssociation.TOPIC_CHANGED, TOPIC_STATUS_CHANGED);
-		
+        attr.put(TargetObject.KEY_ID, targetId);
+
+        final Map<String, String> tags = new HashMap<String, String>();
+        final StatefulTargetObject sgo = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
+            public StatefulTargetObject call() throws Exception {
+                return m_statefulTargetRepository.preregister(attr, tags);
+            }
+        }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
+
+        assertTrue("Without any deployment versions, and no information in the shop, we should not need to approve.", !sgo.needsApprove());
+        assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
+        assertEquals("We expect the registration state to be New;", StoreState.New, sgo.getStoreState());
+        assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion());
+
+        final ArtifactObject b11 = createBasicBundleObject("bundle1", "1", null);
+
+        FeatureObject g1 = createBasicFeatureObject("feature1");
+        FeatureObject g2 = createBasicFeatureObject("feature2"); // note that this feature is not associated to a
+                                                                 // bundle.
+
+        createDynamicBundle2FeatureAssociation(b11, g1);
+
+        final DistributionObject l1 = createBasicDistributionObject("distribution1");
+
+        m_feature2distributionRepository.create(g1, l1);
+        m_feature2distributionRepository.create(g2, l1);
+
+        runAndWaitForEvent(new Callable<Distribution2TargetAssociation>() {
+            public Distribution2TargetAssociation call() throws Exception {
+                return m_distribution2targetRepository.create(l1, sgo.getTargetObject());
+            }
+        }, false, Distribution2TargetAssociation.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
+
+        assertTrue("We added information that influences our target, so we should need to approve it.", sgo.needsApprove());
+        assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
+        assertEquals("We expect the registration state to be Unapproved;", StoreState.Unapproved, sgo.getStoreState());
+        assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length);
+        assertEquals("According to the deployment, this target needs 0 bundles", 0, sgo.getArtifactsFromDeployment().length);
+        assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion());
+
+        runAndWaitForEvent(new Callable<Object>() {
+            public Object call() throws Exception {
+                createBasicDeploymentVersionObject(targetId, "1", b11);
+                return null;
+            }
+        }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
+
+        assertFalse("We manually created a deployment version that reflects the shop, so no approval should be necessary.", sgo.needsApprove());
+        assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
+        assertEquals("We expect the registration state to be Approved;", StoreState.Approved, sgo.getStoreState());
+        assertEquals("According to the shop, this target needs 1 bundle;", 1, sgo.getArtifactsFromShop().length);
+        assertEquals("According to the deployment, this target needs 1 bundle;", 1, sgo.getArtifactsFromDeployment().length);
+
+        runAndWaitForEvent(new Callable<ArtifactObject>() {
+            public ArtifactObject call() throws Exception {
+                return createBasicBundleObject("bundle1", "2", null);
+            }
+        }, false, ArtifactObject.TOPIC_ADDED, Artifact2FeatureAssociation.TOPIC_CHANGED, TOPIC_STATUS_CHANGED);
+
         assertTrue("We added a new version of a bundle that is used by the target, so approval should be necessary.", sgo.needsApprove());
-		assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
-		assertEquals("We expect the registration state to be Unapproved;", StoreState.Unapproved, sgo.getStoreState());
-		assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length);
-		assertEquals("The shop should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromShop()[0].getURL());
-		assertEquals("According to the deployment, this target needs 1 bundle", 1, sgo.getArtifactsFromDeployment().length);
-		assertEquals("The deployment should tell use we need bundle URL 'bundle1-1';", "http://bundle1-1", sgo.getArtifactsFromDeployment()[0].getUrl());
-		assertEquals("1", sgo.getCurrentVersion());
-		
-		String newVersion = sgo.approve();
-		
+        assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
+        assertEquals("We expect the registration state to be Unapproved;", StoreState.Unapproved, sgo.getStoreState());
+        assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length);
+        assertEquals("The shop should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromShop()[0].getURL());
+        assertEquals("According to the deployment, this target needs 1 bundle", 1, sgo.getArtifactsFromDeployment().length);
+        assertEquals("The deployment should tell use we need bundle URL 'bundle1-1';", "http://bundle1-1", sgo.getArtifactsFromDeployment()[0].getUrl());
+        assertEquals("1", sgo.getCurrentVersion());
+
+        String newVersion = sgo.approve();
+
         runAndWaitForEvent(new Callable<Void>() {
             public Void call() throws Exception {
                 m_repositoryAdmin.commit();
                 return null;
             }
         }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
-		
-		assertFalse("Immediately after approval, no approval is necessary.", sgo.needsApprove());
-		assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
-		assertEquals("We expect the registration state to be Approved;", StoreState.Approved, sgo.getStoreState());
-		assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length);
-		assertEquals("The shop should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromShop()[0].getURL());
-		assertEquals("According to the deployment, this target needs 1 bundle", 1, sgo.getArtifactsFromDeployment().length);
-		assertEquals("The deployment should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromDeployment()[0].getUrl());
-		assertEquals( "We expect two deployment versions;", 2, m_deploymentVersionRepository.get().size());
-		assertEquals(newVersion, sgo.getCurrentVersion());
-		
-		// clean up this object ourselves; we cannot rely on cleanUp() in this case.
-		runAndWaitForEvent(new Callable<Object>() {
-		    public Object call() throws Exception {
-		        m_statefulTargetRepository.unregister(targetId);
-		        return null;
-		    }
-		}, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED);
-
-	 	StatefulTargetObject target = findStatefulTarget(targetId);
-	 	assertNull("Target should be removed?!", target);
-		
-		cleanUp();
+
+        assertFalse("Immediately after approval, no approval is necessary.", sgo.needsApprove());
+        assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState());
+        assertEquals("We expect the registration state to be Approved;", StoreState.Approved, sgo.getStoreState());
+        assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length);
+        assertEquals("The shop should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromShop()[0].getURL());
+        assertEquals("According to the deployment, this target needs 1 bundle", 1, sgo.getArtifactsFromDeployment().length);
+        assertEquals("The deployment should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromDeployment()[0].getUrl());
+        assertEquals("We expect two deployment versions;", 2, m_deploymentVersionRepository.get().size());
+        assertEquals(newVersion, sgo.getCurrentVersion());
+
+        // clean up this object ourselves; we cannot rely on cleanUp() in this case.
+        runAndWaitForEvent(new Callable<Object>() {
+            public Object call() throws Exception {
+                m_statefulTargetRepository.unregister(targetId);
+                return null;
+            }
+        }, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED);
+
+        StatefulTargetObject target = findStatefulTarget(targetId);
+        assertNull("Target should be removed?!", target);
+
+        cleanUp();
     }
 
     public void testStatefulAuditAndRegister() throws Exception {
         setUpTestCase();
 
         // preregister target
-		final Map<String, String> attr = new HashMap<String, String>();
-		attr.put(TargetObject.KEY_ID, "myNewTarget3");
-		final Map<String, String> tags = new HashMap<String, String>();
-		
-		final StatefulTargetObject sgo1 = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
-		    public StatefulTargetObject call() throws Exception {
-		        return m_statefulTargetRepository.preregister(attr, tags);
-		    }
-		}, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
-		
-		// do checks
-		assertTrue("We just preregistered a target, so it should be registered.", sgo1.isRegistered());
-		
-		// add auditlog data
-		List<LogEvent> events = new ArrayList<LogEvent>();
-		Properties props = new Properties();
-		events.add(new LogEvent("myNewTarget3", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
-		// add an (old) set of target properties
-		Properties props2 = new Properties();
-		props2.put("mykey", "myoldvalue");
-		props2.put("myoldkey", "myoldvalue");
-		events.add(new LogEvent("myNewTarget3", 1, 2, 2, AuditEvent.TARGETPROPERTIES_SET, props2));
-		// add a new set of target properties
-		Properties props3 = new Properties();
-		props3.put("mykey", "myvalue");
-		events.add(new LogEvent("myNewTarget3", 1, 3, 3, AuditEvent.TARGETPROPERTIES_SET, props3));
-		m_auditLogStore.put(events);
-		m_statefulTargetRepository.refresh();
-		
-		// do checks
-		TargetObject to = sgo1.getTargetObject();
-		assertNotNull("Stateful target should be backed by a target object.", to);
-		assertEquals("Target should have a property mykey with value myvalue.", "myvalue", to.getTag("target.mykey"));
-		assertNull("This old key should no longer have been associated with this target.", to.getTag("target.myoldkey"));
-		assertTrue("Adding auditlog data for a target does not influence its isRegistered().", sgo1.isRegistered());
-		
-		// add auditlog data for other target
-		events = new ArrayList<LogEvent>();
-		props = new Properties();
-		events.add(new LogEvent("myNewTarget4", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
-		m_auditLogStore.put(events);
-		runAndWaitForEvent(new Callable<Object>() {
-		    public Object call() throws Exception {
-		        m_statefulTargetRepository.refresh();
-		        return false;
-		    }
-		}, false, TOPIC_ADDED);
-		final StatefulTargetObject sgo2 = findStatefulTarget("myNewTarget4");
-		
-		// do checks
-		assertTrue("Adding auditlog data for a target does not influence its isRegistered().", sgo1.isRegistered());
-		try {
-		    sgo1.getTargetObject();
-		}
-		catch (IllegalStateException ise) {
-		    assertTrue("We should be able to get sgo1's targetObject.", false);
-		}
-		assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered());
-		try {
-		    sgo2.getTargetObject();
-		    assertTrue("We should not be able to get sgo2's targetObject.", false);
-		}
-		catch (IllegalStateException ise) {
-		    // expected
-		}
-		
-		// remove original target
-		runAndWaitForEvent(new Callable<Object>() {
-		    public Object call() throws Exception {
-		        m_statefulTargetRepository.unregister(sgo1.getID());
-		        return null;
-		    }
-		}, false, TargetObject.TOPIC_REMOVED, TOPIC_STATUS_CHANGED);
-		
-		// do checks
-		assertTrue("sgo1 is now only found in the auditlog, so it cannot be registered.", !sgo1.isRegistered());
-		try {
-		    sgo1.getTargetObject();
-		    assertTrue("We should not be able to get sgo1's targetObject.", false);
-		}
-		catch (IllegalStateException ise) {
-		    // expected
-		}
-		assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered());
-		try {
-		    sgo2.getTargetObject();
-		    assertTrue("We should not be able to get sgo2's targetObject.", false);
-		}
-		catch (IllegalStateException ise) {
-		    // expected
-		}
-		
-		// register second target
-		runAndWaitForEvent(new Callable<Object>() {
-		    public Object call() throws Exception {
-		        sgo2.register();
-		        return null;
-		    }
-		}, false, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
-		
-		// do checks
-		assertTrue("sgo1 is now only found in the auditlog, so it cannot be in registered.", !sgo1.isRegistered());
-		try {
-		    sgo1.getTargetObject();
-		    assertTrue("We should not be able to get sgo1's targetObject.", false);
-		}
-		catch (IllegalStateException ise) {
-		    // expected
-		}
-		assertTrue("sgo2 has been registered.", sgo2.isRegistered());
-		try {
-		    sgo2.getTargetObject();
-		}
-		catch (IllegalStateException ise) {
-		    assertTrue("We should be able to get sgo2's targetObject.", false);
-		}
-		
-		int nrRegistered =
-		    m_statefulTargetRepository.get(
-		        m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")"))
-		        .size();
-		assert nrRegistered == 1 : "We expect to filter out one registered target, but we find " + nrRegistered;
-		
-		// Finally, create a distribution object
-		final DistributionObject l1 = createBasicDistributionObject("thedistribution");
-		
-		assertTrue("We just created a Stateful target object, is should not be registered", !sgo1.isRegistered());
-		
-		// register sgo1 again and create an association in 1 go
-		Distribution2TargetAssociation lgw1 = runAndWaitForEvent(new Callable<Distribution2TargetAssociation>() {
-		    public Distribution2TargetAssociation call() throws Exception {
-		        sgo1.register();
-		        return m_distribution2targetRepository.create(l1, sgo1.getTargetObject());
-		    }
-		}, false, Distribution2TargetAssociation.TOPIC_ADDED, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
-		
-		// checks
-		nrRegistered =
-		    m_statefulTargetRepository.get(
-		        m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")"))
-		        .size();
-		assert nrRegistered == 2 : "We expect to filter out two registered targets, but we find " + nrRegistered;
-		assertTrue("A stateful target object should be registered", sgo1.isRegistered());
-		assertTrue("The stateful target object should be associated to the distribution.", sgo1.isAssociated(l1, DistributionObject.class));
-		assertTrue("Both ends of distribution - stateful target should be satisfied.", lgw1.isSatisfied());
-		
-		cleanUp();
+        final Map<String, String> attr = new HashMap<String, String>();
+        attr.put(TargetObject.KEY_ID, "myNewTarget3");
+        final Map<String, String> tags = new HashMap<String, String>();
+
+        final StatefulTargetObject sgo1 = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
+            public StatefulTargetObject call() throws Exception {
+                return m_statefulTargetRepository.preregister(attr, tags);
+            }
+        }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
+
+        // do checks
+        assertTrue("We just preregistered a target, so it should be registered.", sgo1.isRegistered());
+
+        // add auditlog data
+        List<LogEvent> events = new ArrayList<LogEvent>();
+        Properties props = new Properties();
+        events.add(new LogEvent("myNewTarget3", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
+        // add an (old) set of target properties
+        Properties props2 = new Properties();
+        props2.put("mykey", "myoldvalue");
+        props2.put("myoldkey", "myoldvalue");
+        events.add(new LogEvent("myNewTarget3", 1, 2, 2, AuditEvent.TARGETPROPERTIES_SET, props2));
+        // add a new set of target properties
+        Properties props3 = new Properties();
+        props3.put("mykey", "myvalue");
+        events.add(new LogEvent("myNewTarget3", 1, 3, 3, AuditEvent.TARGETPROPERTIES_SET, props3));
+        m_auditLogStore.put(events);
+        m_statefulTargetRepository.refresh();
+
+        // do checks
+        TargetObject to = sgo1.getTargetObject();
+        assertNotNull("Stateful target should be backed by a target object.", to);
+        assertEquals("Target should have a property mykey with value myvalue.", "myvalue", to.getTag("target.mykey"));
+        assertNull("This old key should no longer have been associated with this target.", to.getTag("target.myoldkey"));
+        assertTrue("Adding auditlog data for a target does not influence its isRegistered().", sgo1.isRegistered());
+
+        // add auditlog data for other target
+        events = new ArrayList<LogEvent>();
+        props = new Properties();
+        events.add(new LogEvent("myNewTarget4", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
+        m_auditLogStore.put(events);
+        runAndWaitForEvent(new Callable<Object>() {
+            public Object call() throws Exception {
+                m_statefulTargetRepository.refresh();
+                return false;
+            }
+        }, false, TOPIC_ADDED);
+        final StatefulTargetObject sgo2 = findStatefulTarget("myNewTarget4");
+
+        // do checks
+        assertTrue("Adding auditlog data for a target does not influence its isRegistered().", sgo1.isRegistered());
+        try {
+            sgo1.getTargetObject();
+        }
+        catch (IllegalStateException ise) {
+            assertTrue("We should be able to get sgo1's targetObject.", false);
+        }
+        assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered());
+        try {
+            sgo2.getTargetObject();
+            assertTrue("We should not be able to get sgo2's targetObject.", false);
+        }
+        catch (IllegalStateException ise) {
+            // expected
+        }
+
+        // remove original target
+        runAndWaitForEvent(new Callable<Object>() {
+            public Object call() throws Exception {
+                m_statefulTargetRepository.unregister(sgo1.getID());
+                return null;
+            }
+        }, false, TargetObject.TOPIC_REMOVED, TOPIC_STATUS_CHANGED);
+
+        // do checks
+        assertTrue("sgo1 is now only found in the auditlog, so it cannot be registered.", !sgo1.isRegistered());
+        try {
+            sgo1.getTargetObject();
+            assertTrue("We should not be able to get sgo1's targetObject.", false);
+        }
+        catch (IllegalStateException ise) {
+            // expected
+        }
+        assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered());
+        try {
+            sgo2.getTargetObject();
+            assertTrue("We should not be able to get sgo2's targetObject.", false);
+        }
+        catch (IllegalStateException ise) {
+            // expected
+        }
+
+        // register second target
+        runAndWaitForEvent(new Callable<Object>() {
+            public Object call() throws Exception {
+                sgo2.register();
+                return null;
+            }
+        }, false, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
+
+        // do checks
+        assertTrue("sgo1 is now only found in the auditlog, so it cannot be in registered.", !sgo1.isRegistered());
+        try {
+            sgo1.getTargetObject();
+            assertTrue("We should not be able to get sgo1's targetObject.", false);
+        }
+        catch (IllegalStateException ise) {
+            // expected
+        }
+        assertTrue("sgo2 has been registered.", sgo2.isRegistered());
+        try {
+            sgo2.getTargetObject();
+        }
+        catch (IllegalStateException ise) {
+            assertTrue("We should be able to get sgo2's targetObject.", false);
+        }
+
+        int nrRegistered =
+            m_statefulTargetRepository.get(
+                m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")"))
+                .size();
+        assert nrRegistered == 1 : "We expect to filter out one registered target, but we find " + nrRegistered;
+
+        // Finally, create a distribution object
+        final DistributionObject l1 = createBasicDistributionObject("thedistribution");
+
+        assertTrue("We just created a Stateful target object, is should not be registered", !sgo1.isRegistered());
+
+        // register sgo1 again and create an association in 1 go
+        Distribution2TargetAssociation lgw1 = runAndWaitForEvent(new Callable<Distribution2TargetAssociation>() {
+            public Distribution2TargetAssociation call() throws Exception {
+                sgo1.register();
+                return m_distribution2targetRepository.create(l1, sgo1.getTargetObject());
+            }
+        }, false, Distribution2TargetAssociation.TOPIC_ADDED, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
+
+        // checks
+        nrRegistered =
+            m_statefulTargetRepository.get(
+                m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")"))
+                .size();
+        assert nrRegistered == 2 : "We expect to filter out two registered targets, but we find " + nrRegistered;
+        assertTrue("A stateful target object should be registered", sgo1.isRegistered());
+        assertTrue("The stateful target object should be associated to the distribution.", sgo1.isAssociated(l1, DistributionObject.class));
+        assertTrue("Both ends of distribution - stateful target should be satisfied.", lgw1.isSatisfied());
+
+        cleanUp();
     }
 
     public void testStatefulAuditAndRemove() throws Exception {
         setUpTestCase();
 
         // preregister gateway
-		final Map<String, String> attr = new HashMap<String, String>();
-		attr.put(TargetObject.KEY_ID, "myNewGatewayA");
-		final Map<String, String> tags = new HashMap<String, String>();
-		
-		final StatefulTargetObject sgo1 = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
-		    public StatefulTargetObject call() throws Exception {
-		        return m_statefulTargetRepository.preregister(attr, tags);
-		    }
-		}, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
-		
-		// do checks
-		assertTrue("We just preregistered a gateway, so it should be registered.", sgo1.isRegistered());
-		
-		// add auditlog data
-		List<LogEvent> events = new ArrayList<LogEvent>();
-		Properties props = new Properties();
-		events.add(new LogEvent("myNewGatewayA", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
-		m_auditLogStore.put(events);
-		m_statefulTargetRepository.refresh();
-		
-		// do checks
-		assertTrue("Adding auditlog data for a gateway does not influence its isRegistered().", sgo1.isRegistered());
-		try {
-		    sgo1.getTargetObject();
-		}
-		catch (IllegalStateException ise) {
-		    assertTrue("We should be able to get sgo1's gatewayObject.", false);
-		}
-		// add auditlog data for other gateway
-		events = new ArrayList<LogEvent>();
-		props = new Properties();
-		events.add(new LogEvent("myNewGatewayB", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
-		m_auditLogStore.put(events);
-		runAndWaitForEvent(new Callable<Object>() {
-		    public Object call() throws Exception {
-		        m_statefulTargetRepository.refresh();
-		        return false;
-		    }
-		}, false, TOPIC_ADDED);
-		final StatefulTargetObject sgo2 = findStatefulTarget("myNewGatewayB");
-		
-		// do checks
-		assertTrue("Adding auditlog data for a gateway does not influence its isRegistered().", sgo1.isRegistered());
-		try {
-		    sgo1.getTargetObject();
-		}
-		catch (IllegalStateException ise) {
-		    assertTrue("We should be able to get sgo1's gatewayObject.", false);
-		}
-		assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered());
-		try {
-		    sgo2.getTargetObject();
-		    assertTrue("We should not be able to get sgo2's gatewayObject.", false);
-		}
-		catch (IllegalStateException ise) {
-		    // expected
-		}
-		// remove original gateway
-		runAndWaitForEvent(new Callable<Object>() {
-		    public Object call() throws Exception {
-		        m_statefulTargetRepository.remove(sgo1);
-		        return null;
-		    }
-		}, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED);
-		
-		// do checks
-		assertTrue("sgo1 is now only found in the auditlog, so it cannot be registered.", !sgo1.isRegistered());
-		try {
-		    sgo1.getTargetObject();
-		    assertTrue("We should not be able to get sgo1's gatewayObject.", false);
-		}
-		catch (IllegalStateException ise) {
-		    // expected
-		}
-		
-		assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered());
-		try {
-		    sgo2.getTargetObject();
-		    assertTrue("We should not be able to get sgo2's gatewayObject.", false);
-		}
-		catch (IllegalStateException ise) {
-		    // expected
-		}
-		
-		// register second gateway
-		runAndWaitForEvent(new Callable<Object>() {
-		    public Object call() throws Exception {
-		        sgo2.register();
-		        return null;
-		    }
-		}, false, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
-		
-		// do checks
-		assertTrue("sgo1 is now only found in the auditlog, so it cannot be in registered.", !sgo1.isRegistered());
-		try {
-		    sgo1.getTargetObject();
-		    assertTrue("We should not be able to get sgo1's gatewayObject.", false);
-		}
-		catch (IllegalStateException ise) {
-		    // expected
-		}
-		assertTrue("sgo2 has been registered.", sgo2.isRegistered());
-		try {
-		    sgo2.getTargetObject();
-		}
-		catch (IllegalStateException ise) {
-		    assertTrue("We should be able to get sgo2's gatewayObject.", false);
-		}
-		
-		int nrRegistered = m_statefulTargetRepository.get(m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")")).size();
-		assert nrRegistered == 1 : "We expect to filter out one registered gateway, but we find " + nrRegistered;
-		
-		// Finally, refresh the repository; it should cause sgo1 to be re-created (due to its audit log)...
-		// ACE-167 does not cover this scenario, but at a later time this should be fixed as well (see ACE-230).
-		m_statefulTargetRepository.refresh();
-		
-		int count = m_statefulTargetRepository.get(m_bundleContext.createFilter("(" + KEY_ID + "=myNewGatewayA)")).size();
-		assertTrue("We expected sgo1 to be re-created!", count == 1);
-		
-		cleanUp();
+        final Map<String, String> attr = new HashMap<String, String>();
+        attr.put(TargetObject.KEY_ID, "myNewGatewayA");
+        final Map<String, String> tags = new HashMap<String, String>();
+
+        final StatefulTargetObject sgo1 = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
+            public StatefulTargetObject call() throws Exception {
+                return m_statefulTargetRepository.preregister(attr, tags);
+            }
+        }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
+
+        // do checks
+        assertTrue("We just preregistered a gateway, so it should be registered.", sgo1.isRegistered());
+
+        // add auditlog data
+        List<LogEvent> events = new ArrayList<LogEvent>();
+        Properties props = new Properties();
+        events.add(new LogEvent("myNewGatewayA", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
+        m_auditLogStore.put(events);
+        m_statefulTargetRepository.refresh();
+
+        // do checks
+        assertTrue("Adding auditlog data for a gateway does not influence its isRegistered().", sgo1.isRegistered());
+        try {
+            sgo1.getTargetObject();
+        }
+        catch (IllegalStateException ise) {
+            assertTrue("We should be able to get sgo1's gatewayObject.", false);
+        }
+        // add auditlog data for other gateway
+        events = new ArrayList<LogEvent>();
+        props = new Properties();
+        events.add(new LogEvent("myNewGatewayB", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
+        m_auditLogStore.put(events);
+        runAndWaitForEvent(new Callable<Object>() {
+            public Object call() throws Exception {
+                m_statefulTargetRepository.refresh();
+                return false;
+            }
+        }, false, TOPIC_ADDED);
+        final StatefulTargetObject sgo2 = findStatefulTarget("myNewGatewayB");
+
+        // do checks
+        assertTrue("Adding auditlog data for a gateway does not influence its isRegistered().", sgo1.isRegistered());
+        try {
+            sgo1.getTargetObject();
+        }
+        catch (IllegalStateException ise) {
+            assertTrue("We should be able to get sgo1's gatewayObject.", false);
+        }
+        assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered());
+        try {
+            sgo2.getTargetObject();
+            assertTrue("We should not be able to get sgo2's gatewayObject.", false);
+        }
+        catch (IllegalStateException ise) {
+            // expected
+        }
+        // remove original gateway
+        runAndWaitForEvent(new Callable<Object>() {
+            public Object call() throws Exception {
+                m_statefulTargetRepository.remove(sgo1);
+                return null;
+            }
+        }, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED);
+
+        // do checks
+        assertTrue("sgo1 is now only found in the auditlog, so it cannot be registered.", !sgo1.isRegistered());
+        try {
+            sgo1.getTargetObject();
+            assertTrue("We should not be able to get sgo1's gatewayObject.", false);
+        }
+        catch (IllegalStateException ise) {
+            // expected
+        }
+
+        assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered());
+        try {
+            sgo2.getTargetObject();
+            assertTrue("We should not be able to get sgo2's gatewayObject.", false);
+        }
+        catch (IllegalStateException ise) {
+            // expected
+        }
+
+        // register second gateway
+        runAndWaitForEvent(new Callable<Object>() {
+            public Object call() throws Exception {
+                sgo2.register();
+                return null;
+            }
+        }, false, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
+
+        // do checks
+        assertTrue("sgo1 is now only found in the auditlog, so it cannot be in registered.", !sgo1.isRegistered());
+        try {
+            sgo1.getTargetObject();
+            assertTrue("We should not be able to get sgo1's gatewayObject.", false);
+        }
+        catch (IllegalStateException ise) {
+            // expected
+        }
+        assertTrue("sgo2 has been registered.", sgo2.isRegistered());
+        try {
+            sgo2.getTargetObject();
+        }
+        catch (IllegalStateException ise) {
+            assertTrue("We should be able to get sgo2's gatewayObject.", false);
+        }
+
+        int nrRegistered = m_statefulTargetRepository.get(m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")")).size();
+        assert nrRegistered == 1 : "We expect to filter out one registered gateway, but we find " + nrRegistered;
+
+        // Finally, refresh the repository; it should cause sgo1 to be re-created (due to its audit log)...
+        // ACE-167 does not cover this scenario, but at a later time this should be fixed as well (see ACE-230).
+        m_statefulTargetRepository.refresh();
+
+        int count = m_statefulTargetRepository.get(m_bundleContext.createFilter("(" + KEY_ID + "=myNewGatewayA)")).size();
+        assertTrue("We expected sgo1 to be re-created!", count == 1);
+
+        cleanUp();
     }
 
     public void testStatefulAuditLog() throws Exception {
         setUpTestCase();
-        
+
         final String targetId = String.format("target-%s", Long.toHexString(System.nanoTime()));
 
         List<LogEvent> events = new ArrayList<LogEvent>();
-		Properties props = new Properties();
+        Properties props = new Properties();
+
+        events.add(new LogEvent(targetId, 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
+        // fill auditlog; no install data
+        m_auditLogStore.put(events);
+
+        runAndWaitForEvent(new Callable<Void>() {
+            public Void call() throws Exception {
+                m_statefulTargetRepository.refresh();
+                return null;
+            }
+        }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_ADDED);
 
-		events.add(new LogEvent(targetId, 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
-		// fill auditlog; no install data
-		m_auditLogStore.put(events);
-		
-		runAndWaitForEvent(new Callable<Void>() {
-		    public Void call() throws Exception {
-		    	m_statefulTargetRepository.refresh();
-		        return null;
-		    }
-		}, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_ADDED);
-		
-		StatefulTargetObject sgo = findStatefulTarget(targetId);
-		assertNotNull("Expected new target object to become available!", sgo);
-		
-		assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState());
-		
-		// fill auditlog with complete-data
-		events = new ArrayList<LogEvent>();
-		props = new Properties();
-		props.put(AuditEvent.KEY_NAME, "mypackage");
-		props.put(AuditEvent.KEY_VERSION, "123");
-		events.add(new LogEvent(targetId, 1, 2, 2, AuditEvent.DEPLOYMENTCONTROL_INSTALL, props));
-		
-		m_auditLogStore.put(events);
-		
-		runAndWaitForEvent(new Callable<Void>() {
-		    public Void call() throws Exception {
-		    	m_statefulTargetRepository.refresh();
-		        return null;
-		    }
-		}, false, StatefulTargetObject.TOPIC_STATUS_CHANGED, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED);
-
-		assertEquals("Our last install version should be 123;", "123", sgo.getLastInstallVersion());
-		assertEquals("We expect our object's provisioning state to be InProgress;", ProvisioningState.InProgress, sgo.getProvisioningState());
-		
-		// fill auditlog with install data
-		events = new ArrayList<LogEvent>();
-		props = new Properties();
-		props.put(AuditEvent.KEY_NAME, "mypackage");
-		props.put(AuditEvent.KEY_VERSION, "123");
-		props.put(AuditEvent.KEY_SUCCESS, "false");
-		events.add(new LogEvent(targetId, 1, 3, 3, AuditEvent.DEPLOYMENTADMIN_COMPLETE, props));
-		
-		m_auditLogStore.put(events);
-		
-		runAndWaitForEvent(new Callable<Void>() {
-		    public Void call() throws Exception {
-		    	m_statefulTargetRepository.refresh();
-		        return null;
-		    }
-		}, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED);
-		
-		assertEquals("Our last install version should be 123;", "123", sgo.getLastInstallVersion());
-		assertEquals("We expect our object's provisioning state to be Failed;", ProvisioningState.Failed, sgo.getProvisioningState());
-		assertFalse("Our last install was not successful, but according to the sgo it was.", sgo.getLastInstallSuccess());
-		
-		sgo.acknowledgeInstallVersion("123");
-		
-		assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState());
-		
-		// add another install event.
-		events = new ArrayList<LogEvent>();
-		props = new Properties();
-		props.put(AuditEvent.KEY_NAME, "mypackage");
-		props.put(AuditEvent.KEY_VERSION, "124");
-		events.add(new LogEvent(targetId, 1, 4, 4, AuditEvent.DEPLOYMENTCONTROL_INSTALL, props));
-		
-		m_auditLogStore.put(events);
-		
-		runAndWaitForEvent(new Callable<Void>() {
-		    public Void call() throws Exception {
-		    	m_statefulTargetRepository.refresh();
-		        return null;
-		    }
-		}, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED);
-		
-		assertEquals("Our last install version should be 124;", "124", sgo.getLastInstallVersion());
-		assertEquals("We expect our object's provisioning state to be InProgress;", ProvisioningState.InProgress, sgo.getProvisioningState());
-		
-		// fill auditlog with install data
-		events = new ArrayList<LogEvent>();
-		props = new Properties();
-		props.put(AuditEvent.KEY_NAME, "mypackage");
-		props.put(AuditEvent.KEY_VERSION, "124");
-		props.put(AuditEvent.KEY_SUCCESS, "true");
-		events.add(new LogEvent(targetId, 1, 5, 5, AuditEvent.DEPLOYMENTADMIN_COMPLETE, props));
-		
-		m_auditLogStore.put(events);
-		
-		runAndWaitForEvent(new Callable<Void>() {
-		    public Void call() throws Exception {
-		    	m_statefulTargetRepository.refresh();
-		        return null;
-		    }
-		}, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED);
-		
-		assertEquals("Our last install version should be 124;", "124", sgo.getLastInstallVersion());
-		assertEquals("We expect our object's provisioning state to be OK;", ProvisioningState.OK, sgo.getProvisioningState());
-		assertTrue("Our last install was successful, but according to the sgo it was not.", sgo.getLastInstallSuccess());
-		
-		sgo.acknowledgeInstallVersion("124");
-		
-		assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState());
+        StatefulTargetObject sgo = findStatefulTarget(targetId);
+        assertNotNull("Expected new target object to become available!", sgo);
+
+        assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState());
+
+        // fill auditlog with complete-data
+        events = new ArrayList<LogEvent>();
+        props = new Properties();
+        props.put(AuditEvent.KEY_NAME, "mypackage");
+        props.put(AuditEvent.KEY_VERSION, "123");
+        events.add(new LogEvent(targetId, 1, 2, 2, AuditEvent.DEPLOYMENTCONTROL_INSTALL, props));
+
+        m_auditLogStore.put(events);
+
+        runAndWaitForEvent(new Callable<Void>() {
+            public Void call() throws Exception {
+                m_statefulTargetRepository.refresh();
+                return null;
+            }
+        }, false, StatefulTargetObject.TOPIC_STATUS_CHANGED, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED);
+
+        assertEquals("Our last install version should be 123;", "123", sgo.getLastInstallVersion());
+        assertEquals("We expect our object's provisioning state to be InProgress;", ProvisioningState.InProgress, sgo.getProvisioningState());
+
+        // fill auditlog with install data
+        events = new ArrayList<LogEvent>();
+        props = new Properties();
+        props.put(AuditEvent.KEY_NAME, "mypackage");
+        props.put(AuditEvent.KEY_VERSION, "123");
+        props.put(AuditEvent.KEY_SUCCESS, "false");
+        events.add(new LogEvent(targetId, 1, 3, 3, AuditEvent.DEPLOYMENTADMIN_COMPLETE, props));
+
+        m_auditLogStore.put(events);
+
+        runAndWaitForEvent(new Callable<Void>() {
+            public Void call() throws Exception {
+                m_statefulTargetRepository.refresh();
+                return null;
+            }
+        }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED);
+
+        assertEquals("Our last install version should be 123;", "123", sgo.getLastInstallVersion());
+        assertEquals("We expect our object's provisioning state to be Failed;", ProvisioningState.Failed, sgo.getProvisioningState());
+        assertFalse("Our last install was not successful, but according to the sgo it was.", sgo.getLastInstallSuccess());
+
+        sgo.acknowledgeInstallVersion("123");
+
+        assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState());
+
+        // add another install event.
+        events = new ArrayList<LogEvent>();
+        props = new Properties();
+        props.put(AuditEvent.KEY_NAME, "mypackage");
+        props.put(AuditEvent.KEY_VERSION, "124");
+        events.add(new LogEvent(targetId, 1, 4, 4, AuditEvent.DEPLOYMENTCONTROL_INSTALL, props));
+
+        m_auditLogStore.put(events);
+
+        runAndWaitForEvent(new Callable<Void>() {
+            public Void call() throws Exception {
+                m_statefulTargetRepository.refresh();
+                return null;
+            }
+        }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED);
+
+        assertEquals("Our last install version should be 124;", "124", sgo.getLastInstallVersion());
+        assertEquals("We expect our object's provisioning state to be InProgress;", ProvisioningState.InProgress, sgo.getProvisioningState());
+
+        // fill auditlog with install data
+        events = new ArrayList<LogEvent>();
+        props = new Properties();
+        props.put(AuditEvent.KEY_NAME, "mypackage");
+        props.put(AuditEvent.KEY_VERSION, "124");
+        props.put(AuditEvent.KEY_SUCCESS, "true");
+        events.add(new LogEvent(targetId, 1, 5, 5, AuditEvent.DEPLOYMENTADMIN_COMPLETE, props));
+
+        m_auditLogStore.put(events);
+
+        runAndWaitForEvent(new Callable<Void>() {
+            public Void call() throws Exception {
+                m_statefulTargetRepository.refresh();
+                return null;
+            }
+        }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED);
+
+        assertEquals("Our last install version should be 124;", "124", sgo.getLastInstallVersion());
+        assertEquals("We expect our object's provisioning state to be OK;", ProvisioningState.OK, sgo.getProvisioningState());
+        assertTrue("Our last install was successful, but according to the sgo it was not.", sgo.getLastInstallSuccess());
+
+        sgo.acknowledgeInstallVersion("124");
+
+        assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState());
     }
 
     public void testStatefulCreateRemove() throws Exception {
@@ -565,95 +563,163 @@ public class StatefulTargetRepositoryTes
         final String targetId = "myNewTarget1";
 
         final Map<String, String> attr = new HashMap<String, String>();
-		attr.put(TargetObject.KEY_ID, targetId);
-		final Map<String, String> tags = new HashMap<String, String>();
-		
-		try {
-		    m_statefulTargetRepository.create(attr, tags);
-		    fail("Creating a stateful target repository should not be allowed.");
-		}
-		catch (UnsupportedOperationException uoe) {
-		    // expected
-		}
-		
-		final StatefulTargetObject sgo = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
-		    public StatefulTargetObject call() throws Exception {
-		        return m_statefulTargetRepository.preregister(attr, tags);
-		    }
-		}, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
-		
-		assertNotNull("We expect to found our new target in the repository!", findStatefulTarget(targetId));
-		
-		// Removing stateful objects is now (partially) supported; see ACE-167 & ACE-230...
-		m_statefulTargetRepository.remove(sgo);
-		
-		assertNull("We expect to NOT found our target in the repository!", findStatefulTarget(targetId));
-		
-		cleanUp();
+        attr.put(TargetObject.KEY_ID, targetId);
+        final Map<String, String> tags = new HashMap<String, String>();
+
+        try {
+            m_statefulTargetRepository.create(attr, tags);
+            fail("Creating a stateful target repository should not be allowed.");
+        }
+        catch (UnsupportedOperationException uoe) {
+            // expected
+        }
+
+        final StatefulTargetObject sgo = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
+            public StatefulTargetObject call() throws Exception {
+                return m_statefulTargetRepository.preregister(attr, tags);
+            }
+        }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
+
+        assertNotNull("We expect to found our new target in the repository!", findStatefulTarget(targetId));
+
+        // Removing stateful objects is now (partially) supported; see ACE-167 & ACE-230...
+        m_statefulTargetRepository.remove(sgo);
+
+        assertNull("We expect to NOT found our target in the repository!", findStatefulTarget(targetId));
+
+        cleanUp();
     }
 
     public void testStatefulSetAutoApprove() throws Exception {
         setUpTestCase();
 
         final String targetId = "a_target";
-        
+
         // register target with
-		final Map<String, String> attr = new HashMap<String, String>();
-		attr.put(TargetObject.KEY_ID, targetId);
-		attr.put(TargetObject.KEY_AUTO_APPROVE, String.valueOf(true));
-		final Map<String, String> tags = new HashMap<String, String>();
-		
-		final StatefulTargetObject sgo = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
-		    public StatefulTargetObject call() throws Exception {
-		        return m_statefulTargetRepository.preregister(attr, tags);
-		    }
-		}, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
-		
-		assertNotNull("We expect to found our new target in the repository!", findStatefulTarget(targetId));
-		
-		assertTrue("The target should have auto approved value: true but got: false.", sgo.getAutoApprove());
-		
-		sgo.setAutoApprove(false);
-		
-		assertFalse("The target should have auto approved value: false but got: true.", sgo.getAutoApprove());
-		
-		// clean up
-		runAndWaitForEvent(new Callable<Object>() {
-		    public Object call() throws Exception {
-		        m_statefulTargetRepository.unregister(targetId);
-		        return null;
-		    }
-		}, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED);
+        final Map<String, String> attr = new HashMap<String, String>();
+        attr.put(TargetObject.KEY_ID, targetId);
+        attr.put(TargetObject.KEY_AUTO_APPROVE, String.valueOf(true));
+        final Map<String, String> tags = new HashMap<String, String>();
+
+        final StatefulTargetObject sgo = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
+            public StatefulTargetObject call() throws Exception {
+                return m_statefulTargetRepository.preregister(attr, tags);
+            }
+        }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
+
+        assertNotNull("We expect to found our new target in the repository!", findStatefulTarget(targetId));
+
+        assertTrue("The target should have auto approved value: true but got: false.", sgo.getAutoApprove());
+
+        sgo.setAutoApprove(false);
+
+        assertFalse("The target should have auto approved value: false but got: true.", sgo.getAutoApprove());
+
+        // clean up
+        runAndWaitForEvent(new Callable<Object>() {
+            public Object call() throws Exception {
+                m_statefulTargetRepository.unregister(targetId);
+                return null;
+            }
+        }, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED);
     }
 
-	public void testStrangeNamesInTargets() throws Exception {
+    public void testStrangeNamesInTargets() throws Exception {
         setUpTestCase();
-        
+
         final String targetID = ":)";
 
         List<LogEvent> events = new ArrayList<LogEvent>();
-		Properties props = new Properties();
+        Properties props = new Properties();
+
+        // add a target with a weird name.
+        events.add(new LogEvent(targetID, 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
+        // fill auditlog; no install data
+        m_auditLogStore.put(events);
+
+        runAndWaitForEvent(new Callable<Void>() {
+            public Void call() throws Exception {
+                m_statefulTargetRepository.refresh();
+                return null;
+            }
+        }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_ADDED);
+
+        StatefulTargetObject sgo = findStatefulTarget(targetID);
+        assertNotNull("Target not added to repository?!", sgo);
+
+        sgo.register();
+
+        assertTrue("After registring our target, we assume it to be registered.", sgo.getRegistrationState().equals(RegistrationState.Registered));
+
+        assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState());
+    }
+
+    /**
+     * Tests that the artifact sizes are propagated to the {@link DeploymentArtifact}s in the deployment repository, see
+     * ACE-384.
+     */
+    public void testDeploymentVersionObjectSize() throws Exception {
+        setUpTestCase();
+
+        final String targetId = "myNewTarget3";
 
-		// add a target with a weird name.
-		events.add(new LogEvent(targetID, 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props));
-		// fill auditlog; no install data
-		m_auditLogStore.put(events);
-
-		runAndWaitForEvent(new Callable<Void>() {
-		    public Void call() throws Exception {
-		    	m_statefulTargetRepository.refresh();
-		        return null;
-		    }
-		}, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_ADDED);
-
-		StatefulTargetObject sgo = findStatefulTarget(targetID);
-		assertNotNull("Target not added to repository?!", sgo);
-		
-		sgo.register();
-		
-		assertTrue("After registring our target, we assume it to be registered.", sgo.getRegistrationState().equals(RegistrationState.Registered));
+        final Map<String, String> attr = new HashMap<String, String>();
+        attr.put(TargetObject.KEY_ID, targetId);
+
+        final Map<String, String> tags = new HashMap<String, String>();
+        final StatefulTargetObject sgo = runAndWaitForEvent(new Callable<StatefulTargetObject>() {
+            public StatefulTargetObject call() throws Exception {
+                return m_statefulTargetRepository.preregister(attr, tags);
+            }
+        }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED);
+
+        assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion());
+
+        final ArtifactObject b1 = createBasicBundleObject("bundle1", "1", null, "10");
+        final ArtifactObject b2 = createBasicBundleObject("bundle2", "1", null);
+        final ArtifactObject b3 = createBasicBundleObject("bundle3", "1", null, "foo");
+
+        FeatureObject f1 = createBasicFeatureObject("feature1");
+
+        createDynamicBundle2FeatureAssociation(b1, f1);
+        createDynamicBundle2FeatureAssociation(b2, f1);
+        createDynamicBundle2FeatureAssociation(b3, f1);
+
+        final DistributionObject d1 = createBasicDistributionObject("distribution1");
+
+        m_feature2distributionRepository.create(f1, d1);
+
+        runAndWaitForEvent(new Callable<Distribution2TargetAssociation>() {
+            public Distribution2TargetAssociation call() throws Exception {
+                return m_distribution2targetRepository.create(d1, sgo.getTargetObject());
+            }
+        }, false, Distribution2TargetAssociation.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
+
+        assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion());
 
-		assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState());
+        DeploymentVersionObject deploymentVersionObject = runAndWaitForEvent(new Callable<DeploymentVersionObject>() {
+            public DeploymentVersionObject call() throws Exception {
+                return createBasicDeploymentVersionObject(targetId, "1", b1, b2, b3);
+            }
+        }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED);
+
+        assertNotNull(deploymentVersionObject);
+
+        DeploymentArtifact[] deploymentArtifacts = deploymentVersionObject.getDeploymentArtifacts();
+        for (DeploymentArtifact deploymentArtifact : deploymentArtifacts) {
+            if (deploymentArtifact.getUrl().contains("bundle1")) {
+                assertEquals(10L, deploymentArtifact.getSize());
+            }
+            else if (deploymentArtifact.getUrl().contains("bundle2")) {
+                assertEquals(-1L, deploymentArtifact.getSize());
+            }
+            else if (deploymentArtifact.getUrl().contains("bundle3")) {
+                assertEquals(-1L, deploymentArtifact.getSize());
+            }
+            else {
+                fail("Unknown bundle?! " + deploymentArtifact.getUrl());
+            }
+        }
     }
 
     private DeploymentVersionObject createBasicDeploymentVersionObject(String targetID, String version,
@@ -671,11 +737,11 @@ public class StatefulTargetRepositoryTes
             if (artifact.getAttribute(BundleHelper.KEY_VERSION) != null) {
                 directives.put(BundleHelper.KEY_VERSION, artifact.getAttribute(BundleHelper.KEY_VERSION));
             }
-            artifacts.add(m_deploymentVersionRepository.createDeploymentArtifact(artifact.getURL(), directives));
+            artifacts.add(m_deploymentVersionRepository.createDeploymentArtifact(artifact.getURL(), artifact.getSize(), directives));
         }
         return m_deploymentVersionRepository.create(attr, tags, artifacts.toArray(new DeploymentArtifact[0]));
     }
-    
+
     private Artifact2FeatureAssociation createDynamicBundle2FeatureAssociation(ArtifactObject artifact,
         FeatureObject feature) {
         Map<String, String> properties = new HashMap<String, String>();
@@ -684,8 +750,7 @@ public class StatefulTargetRepositoryTes
     }
 
     /**
-     * The following code is borrowed from RepositoryTest.java, and is used to instantiate and
-     * use repository servlets.
+     * The following code is borrowed from RepositoryTest.java, and is used to instantiate and use repository servlets.
      */
     private StatefulTargetObject findStatefulTarget(String targetID) throws InvalidSyntaxException {
         for (StatefulTargetObject sgo : m_statefulTargetRepository.get()) {
@@ -697,13 +762,13 @@ public class StatefulTargetRepositoryTes
     }
 
     /**
-	 * @throws IOException
-	 * @throws InterruptedException
-	 * @throws InvalidSyntaxException
-	 */
-	private void setUpTestCase() throws Exception {
-		User user = new MockUser();
-		String customer = "customer-" + Long.toHexString(System.currentTimeMillis());
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws InvalidSyntaxException
+     */
+    private void setUpTestCase() throws Exception {
+        User user = new MockUser();
+        String customer = "customer-" + Long.toHexString(System.currentTimeMillis());
 
         startRepositoryService();
 
@@ -722,5 +787,5 @@ public class StatefulTargetRepositoryTes
 
         m_repositoryAdmin.login(loginContext);
         m_repositoryAdmin.checkout();
-	}
+    }
 }

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java Mon Sep 30 12:00:26 2013
@@ -26,8 +26,8 @@ import java.net.URL;
 /**
  * Denotes a 'physical' artifact that is located by an URL, and provide means to access the contents of this artifact.
  * <p>
- * Note that an artifact can be located on a remote machine, which might need credentials to access its contents. 
- * This interface allows one to access the resource without having to worry about supplying those credentials, as the
+ * Note that an artifact can be located on a remote machine, which might need credentials to access its contents. This
+ * interface allows one to access the resource without having to worry about supplying those credentials, as the
  * implementor of this class has to worry about this instead.
  * </p>
  */
@@ -36,9 +36,9 @@ public interface ArtifactResource {
     /**
      * Returns the location of this artifact.
      * <p>
-     * Note that although {@link URL#openConnection()} allows you to directly open a connection to the resource,
-     * in fact this may fail due to, for example, missing authentication credentials. Use {@link #openStream()}
-     * instead to access the contents of the resource.
+     * Note that although {@link URL#openConnection()} allows you to directly open a connection to the resource, in fact
+     * this may fail due to, for example, missing authentication credentials. Use {@link #openStream()} instead to
+     * access the contents of the resource.
      * </p>
      * 
      * @return the URL to the 'physical' location of the artifact, never <code>null</code>.
@@ -46,10 +46,20 @@ public interface ArtifactResource {
     URL getURL();
 
     /**
+     * Returns the size, in bytes, of this artifact.
+     * 
+     * @return a size, in bytes, >= 0L. If the size of this artifact is unknown, <tt>-1L</tt> should be returned.
+     * @throws IOException
+     *             in case of I/O errors determining the size of the artifact.
+     */
+    long getSize() throws IOException;
+
+    /**
      * Provides access to the contents of the artifact.
      * 
-     * @return an input stream, never <code>null</code>. 
-     * @throws IOException in case of I/O errors opening the artifact.
+     * @return an input stream, never <code>null</code>.
+     * @throws IOException
+     *             in case of I/O errors opening the artifact.
      * @see #getURL()
      */
     InputStream openStream() throws IOException;

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java Mon Sep 30 12:00:26 2013
@@ -30,8 +30,8 @@ import org.apache.ace.client.repository.
 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
 
 /**
- * Implementation class for the ArtifactObject. For 'what it does', see ArtifactObject,
- * for 'how it works', see RepositoryObjectImpl.<br>
+ * Implementation class for the ArtifactObject. For 'what it does', see ArtifactObject, for 'how it works', see
+ * RepositoryObjectImpl.<br>
  * <br>
  * Some functionality of this class is delegated to implementers of {@link ArtifactHelper}.
  */
@@ -39,8 +39,8 @@ public class ArtifactObjectImpl extends 
     private final static String XML_NODE = "artifact";
 
     /*
-     * As a general rule, RepositoryObjects do not know about their repository. However, since the Helper
-     * to be used is dictated by the repository, this rule is broken for this class.
+     * As a general rule, RepositoryObjects do not know about their repository. However, since the Helper to be used is
+     * dictated by the repository, this rule is broken for this class.
      */
     private final ArtifactRepositoryImpl m_repo;
 
@@ -58,7 +58,7 @@ public class ArtifactObjectImpl extends 
         super(reader, notifier, XML_NODE);
         m_repo = repo;
     }
-    
+
     private static String[] completeMandatoryAttributes(String[] mandatory) {
         String[] result = new String[mandatory.length + 1];
         for (int i = 0; i < mandatory.length; i++) {
@@ -91,6 +91,19 @@ public class ArtifactObjectImpl extends 
         return getHelper().getComparator();
     }
 
+    @Override
+    public long getSize() {
+        String size = getAttribute(KEY_SIZE);
+        try {
+            if (size != null) {
+                return Long.parseLong(size);
+            }
+        }
+        catch (NumberFormatException exception) {
+        }
+        return -1L;
+    }
+
     public String getURL() {
         return getAttribute(KEY_URL);
     }
@@ -127,7 +140,7 @@ public class ArtifactObjectImpl extends 
     String[] getDefiningKeys() {
         return getHelper().getDefiningKeys().clone();
     }
-    
+
     private ArtifactHelper getHelper() {
         // getMimetype is safe, as is getHelper, and m_repo is final, so no
         // need to synchronize here...

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java Mon Sep 30 12:00:26 2013
@@ -22,7 +22,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.ArrayList;
@@ -340,6 +339,7 @@ public class ArtifactRepositoryImpl exte
 
         helper.checkAttributes(attributes);
         attributes.put(ArtifactObject.KEY_ARTIFACT_DESCRIPTION, "");
+        attributes.put(ArtifactObject.KEY_SIZE, Long.toString(resource.getSize()));
         if (overwrite) {
             attributes.put(ArtifactObject.KEY_MIMETYPE, mimetype);
         }
@@ -574,6 +574,15 @@ public class ArtifactRepositoryImpl exte
                 return url;
             }
 
+            @Override
+            public long getSize() throws IOException {
+                // Take care of the fact that an URL could need credentials to be accessible!!!
+                URLConnection conn = m_connectionFactory.createConnection(getURL());
+                conn.setUseCaches(true);
+                return conn.getContentLength();
+            }
+
+            @Override
             public InputStream openStream() throws IOException {
                 // Take care of the fact that an URL could need credentials to be accessible!!!
                 URLConnection conn = m_connectionFactory.createConnection(getURL());

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java Mon Sep 30 12:00:26 2013
@@ -26,46 +26,58 @@ import org.apache.ace.client.repository.
 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
 
-
 /**
- * This class is a basic implementation of DeploymentArtifact, with additional facilities
- * for serializing this artifacts with its directives.
+ * This class is a basic implementation of DeploymentArtifact, with additional facilities for serializing this artifacts
+ * with its directives.
  */
 public class DeploymentArtifactImpl implements DeploymentArtifact {
     private final static String XML_NODE = "deploymentArtifact";
     private final static String XML_NODE_URL = "url";
+    private final static String XML_NODE_SIZE = "size";
     private final static String XML_NODE_DIRECTIVES = "directives";
+
     private final String m_url;
+    private final long m_size;
     private final Map<String, String> m_directives = new HashMap<String, String>();
 
     /**
      * Creates a new DeploymentArtifactImpl.
-     * @param url The url to the new artifact, as a string; should not be null;
+     * 
+     * @param url
+     *            The url to the new artifact, as a string; should not be null;
+     * @param size
+     *            the estimated size of the new artifact, in bytes, or -1L if unknown.
      */
-    public DeploymentArtifactImpl(String url) {
+    public DeploymentArtifactImpl(String url, long size) {
         if (url == null) {
             throw new IllegalArgumentException("The url should not be null.");
         }
         m_url = url;
+        m_size = size;
     }
 
     /**
      * Creates a new DeploymentArtifactImpl by deserializing it from an XML stream.
-     * @param reader A stream reader for the XML representation of this object.
+     * 
+     * @param reader
+     *            A stream reader for the XML representation of this object.
      */
     public DeploymentArtifactImpl(HierarchicalStreamReader reader) {
-        reader.moveDown();
+        reader.moveDown(); // url
         m_url = reader.getValue();
-        reader.moveUp();
+        reader.moveUp(); // deploymentArtifact
+        reader.moveDown(); // size
+        String size = reader.getValue();
+        m_size = (size == null) ? -1L : Long.parseLong(size);
+        reader.moveUp(); // deploymentArtifact
 
-        reader.moveDown();
+        reader.moveDown(); // directives
         while (reader.hasMoreChildren()) {
-            reader.moveDown();
+            reader.moveDown(); // directive
             m_directives.put(reader.getNodeName(), reader.getValue());
             reader.moveUp();
         }
         reader.moveUp();
-
     }
 
     /**
@@ -75,9 +87,13 @@ public class DeploymentArtifactImpl impl
         writer.startNode(XML_NODE);
 
         writer.startNode(XML_NODE_URL);
-        writer.setValue(m_url);
+        writer.setValue(getUrl());
         writer.endNode(); // url node
 
+        writer.startNode(XML_NODE_SIZE);
+        writer.setValue(Long.toString(getSize()));
+        writer.endNode(); // size node
+
         writer.startNode(XML_NODE_DIRECTIVES);
         for (Map.Entry<String, String> entry : m_directives.entrySet()) {
             writer.startNode(entry.getKey());
@@ -100,14 +116,22 @@ public class DeploymentArtifactImpl impl
         m_directives.put(key, value);
     }
 
+    @Override
     public String getDirective(String key) {
         return m_directives.get(key);
     }
 
+    @Override
     public String[] getKeys() {
         return m_directives.keySet().toArray(new String[m_directives.size()]);
     }
 
+    @Override
+    public long getSize() {
+        return m_size;
+    }
+
+    @Override
     public String getUrl() {
         return m_url;
     }
@@ -123,7 +147,7 @@ public class DeploymentArtifactImpl impl
         boolean result = true;
 
         result &= getUrl().equals(dai.getUrl());
-
+        result &= (getSize() == dai.getSize());
         result &= (getKeys().length == dai.getKeys().length);
 
         for (String key : getKeys()) {
@@ -136,8 +160,11 @@ public class DeploymentArtifactImpl impl
     @Override
     public int hashCode() {
         int result = getUrl().hashCode();
+        //
+        result ^= (int) (m_size ^ (m_size >>> 32));
+        ;
 
-        for (String key : getKeys()) {
+        for (String key : m_directives.keySet()) {
             result ^= getDirective(key).hashCode();
         }
 
@@ -149,9 +176,9 @@ public class DeploymentArtifactImpl impl
         StringBuilder result = new StringBuilder(getUrl() + " [ ");
         for (String key : getKeys()) {
             result.append(key)
-            .append(": ")
-            .append(getDirective(key))
-            .append(" ");
+                .append(": ")
+                .append(getDirective(key))
+                .append(" ");
         }
         result.append("]");
 

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java Mon Sep 30 12:00:26 2013
@@ -113,8 +113,8 @@ public class DeploymentVersionRepository
         return result;
     }
 
-    public DeploymentArtifact createDeploymentArtifact(String url, Map<String, String> directives) {
-        DeploymentArtifactImpl result =  new DeploymentArtifactImpl(url);
+    public DeploymentArtifact createDeploymentArtifact(String url, long size, Map<String, String> directives) {
+        DeploymentArtifactImpl result =  new DeploymentArtifactImpl(url, size);
         for (Map.Entry<String, String> entry : directives.entrySet()) {
             result.addDirective(entry.getKey(), entry.getValue());
         }

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java Mon Sep 30 12:00:26 2013
@@ -54,7 +54,6 @@ import org.apache.ace.client.repository.
 import org.apache.ace.client.repository.repository.Feature2DistributionAssociationRepository;
 import org.apache.ace.client.repository.repository.FeatureRepository;
 import org.apache.ace.client.repository.repository.TargetRepository;
-import org.apache.ace.client.repository.stateful.impl.StatefulTargetRepositoryImpl;
 import org.apache.ace.connectionfactory.ConnectionFactory;
 import org.apache.ace.repository.Repository;
 import org.apache.ace.repository.ext.BackupRepository;

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java Mon Sep 30 12:00:26 2013
@@ -60,6 +60,11 @@ public interface ArtifactObject extends 
      * Holds a human-readable description for this artifact.
      */
     public static final String KEY_ARTIFACT_DESCRIPTION = "artifactDescription";
+    /** 
+     * Key to be used in the <code>ArtifactObject</code>'s attributes.
+     * Holds the (estimated) size, in bytes, for this artifact.
+     */
+    public static final String KEY_SIZE = "artifactSize";
 
     public static final String TOPIC_ENTITY_ROOT = ArtifactObject.class.getSimpleName() + "/";
 
@@ -112,6 +117,10 @@ public interface ArtifactObject extends 
      */
     public String getDescription();
     /**
+     * Returns an (estimated) size, in bytes, for this object, can be -1L if no size is known.
+     */
+    public long getSize();
+    /**
      * Sets a description for this artifact.
      */
     public void setDescription(String value);

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java Mon Sep 30 12:00:26 2013
@@ -54,6 +54,11 @@ public interface DeploymentArtifact {
      * @return the URL for this deployment artifact.
      */
     public String getUrl();
+    
+    /**
+     * @return the (estimated) size of this deployment artifact, in bytes.
+     */
+    public long getSize();
 
     /**
      * @param key A key String, such as the <code>DIRECTIVE_</code> constants in

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java Mon Sep 30 12:00:26 2013
@@ -42,5 +42,5 @@ public interface DeploymentVersionReposi
      * @param directives A map of directives to be packed into the object.
      * @return The newly created deployment artifact object.
      */
-    public DeploymentArtifact createDeploymentArtifact(String url, Map<String, String> directives);
+    public DeploymentArtifact createDeploymentArtifact(String url, long size, Map<String, String> directives);
 }

Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java Mon Sep 30 12:00:26 2013
@@ -568,7 +568,7 @@ public class StatefulTargetRepositoryImp
                 directives.put(DeploymentArtifact.REPOSITORY_PATH, repositoryPath);
             }
 
-            result.add(m_deploymentRepository.createDeploymentArtifact(bundle.getURL(), directives));
+            result.add(m_deploymentRepository.createDeploymentArtifact(bundle.getURL(), bundle.getSize(), directives));
         }
 
         for (ArtifactObject artifact : artifacts.keySet()) {
@@ -584,7 +584,7 @@ public class StatefulTargetRepositoryImp
                 directives.put(DeploymentArtifact.REPOSITORY_PATH, repositoryPath);
             }
             result.add(m_deploymentRepository.createDeploymentArtifact(
-                m_artifactRepository.preprocessArtifact(artifact, to, targetID, version), directives));
+                m_artifactRepository.preprocessArtifact(artifact, to, targetID, version), artifact.getSize(), directives));
         }
 
         return result.toArray(new DeploymentArtifact[result.size()]);



Mime
View raw message