You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/12/21 13:10:51 UTC

[01/12] incubator-brooklyn git commit: downstream-parent does not set Export-Package

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 9b7ad2e3c -> e3b0389ff


downstream-parent does not set Export-Package

There's no need for a downstream project to automatically export
brooklyn.* and org.apache.brooklyn.* and it causes a number of issues
when loading bundles into catalogues.


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/13e38d94
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/13e38d94
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/13e38d94

Branch: refs/heads/master
Commit: 13e38d945a6e8e3ebc70c6e4a6aeeb3ca78444ba
Parents: c8ec662
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Wed Dec 16 14:38:11 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Thu Dec 17 12:28:01 2015 +0000

----------------------------------------------------------------------
 usage/downstream-parent/pom.xml | 8 --------
 1 file changed, 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/13e38d94/usage/downstream-parent/pom.xml
----------------------------------------------------------------------
diff --git a/usage/downstream-parent/pom.xml b/usage/downstream-parent/pom.xml
index 6580281..c4d5a74 100644
--- a/usage/downstream-parent/pom.xml
+++ b/usage/downstream-parent/pom.xml
@@ -447,16 +447,8 @@
                 <supportedProjectType>jar</supportedProjectType>
               </supportedProjectTypes>
               <instructions>
-                <!-- OSGi specific instruction -->
                 <!--
-                    By default packages containing impl and internal
-                    are not included in the export list. Setting an
-                    explicit wildcard will include all packages
-                    regardless of name.
-                    In time we should minimize our export lists to
-                    what is really needed.
                 -->
-                <Export-Package>brooklyn.*,org.apache.brooklyn.*</Export-Package>
                 <!-- Brooklyn-Feature prefix triggers inclusion of the project's metadata in the server's features list. -->
                 <Brooklyn-Feature-Name>${project.name}</Brooklyn-Feature-Name>
               </instructions>


[06/12] incubator-brooklyn git commit: type registry: adds validation, best version support, aliases, tags

Posted by he...@apache.org.
type registry: adds validation, best version support, aliases, tags

and a simple registry with lookup tests


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/420ea303
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/420ea303
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/420ea303

Branch: refs/heads/master
Commit: 420ea303498f56b38b59ef221f45bf02ddcf19f3
Parents: 1265796
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Nov 26 10:04:02 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Dec 17 12:36:16 2015 +0000

----------------------------------------------------------------------
 .../api/typereg/BrooklynTypeRegistry.java       |  28 ++-
 .../brooklyn/api/typereg/RegisteredType.java    |   8 +-
 .../core/catalog/internal/CatalogUtils.java     |  10 +-
 .../typereg/AbstractTypePlanTransformer.java    |   2 +-
 .../core/typereg/BasicBrooklynTypeRegistry.java | 115 ++++++++++--
 .../core/typereg/BasicRegisteredType.java       |  34 +++-
 .../core/typereg/RegisteredTypePredicates.java  |  89 ++++++++-
 .../brooklyn/core/typereg/RegisteredTypes.java  | 137 ++++++++++----
 .../internal/CatalogItemComparatorTest.java     |  12 +-
 .../typereg/BasicBrooklynTypeRegistryTest.java  | 186 +++++++++++++++++++
 .../typereg/RegisteredTypePredicatesTest.java   |  19 +-
 .../BrooklynEntityDecorationResolver.java       |   2 +-
 .../brooklyn/test/lite/CampYamlLiteTest.java    |   2 +-
 .../rest/resources/CatalogResource.java         |   2 +-
 .../util/collections/CollectionFunctionals.java |  23 ++-
 .../collections/CollectionFunctionalsTest.java  |  24 +++
 16 files changed, 585 insertions(+), 108 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java b/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
index 78c49d8..eb59d27 100644
--- a/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
+++ b/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
@@ -23,7 +23,9 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.util.guava.Maybe;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Predicate;
 
 
@@ -48,23 +50,29 @@ public interface BrooklynTypeRegistry {
      * taking the best version if the version is null or a default marker,
      * returning null if no matches are found. */
     RegisteredType get(String symbolicName, String version);
-    /** as {@link #get(String, String)} but allows <code>"name:version"</code> 
-     * (the {@link RegisteredType#getId()}) in addition to the unversioned name,
-     * using a default marker if no version can be inferred */
+    /** as {@link #get(String, String)} but the given string here 
+     * is allowed to match any of:
+     * <li>the given string as an ID including version (<code>"name:version"</code>) 
+     * <li>the symbolic name unversioned, or
+     * <li>an alias */
     RegisteredType get(String symbolicNameWithOptionalVersion);
-    
-    // TODO remove
-//    /** as {@link #get(String, String)}, but applying the optionally supplied {@link RegisteredTypeLoadingContext} */ 
-//    RegisteredType get(String symbolicName, String version, @Nullable RegisteredTypeLoadingContext context);
-//    /** as {@link #get(String)}, but applying the optionally supplied {@link RegisteredTypeLoadingContext} */ 
-//    RegisteredType get(String symbolicNameWithOptionalVersion, @Nullable RegisteredTypeLoadingContext context);
+
+    /** as {@link #get(String)} but further filtering for the additional context */
+    public RegisteredType get(String symbolicNameOrAliasWithOptionalVersion, RegisteredTypeLoadingContext context);
+    /** returns a wrapper of the result of {@link #get(String, RegisteredTypeLoadingContext)} 
+     * including a detailed message if absent */
+    public Maybe<RegisteredType> getMaybe(String symbolicNameOrAliasWithOptionalVersion, RegisteredTypeLoadingContext context);
 
     // NB the seemingly more correct generics <T,SpecT extends AbstractBrooklynObjectSpec<T,SpecT>> 
     // cause compile errors, not in Eclipse, but in maven (?) 
-    // TODO do these belong here, or in a separate master TypePlanTransformer ?  see also BrooklynTypePlanTransformer 
+    // TODO do these belong here, or in a separate master TypePlanTransformer ?  see also BrooklynTypePlanTransformer
+    @Beta
     <SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpec(RegisteredType type, @Nullable RegisteredTypeLoadingContext optionalContext, @Nullable Class<SpecT> optionalSpecSuperType);
+    @Beta
     <SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpecFromPlan(@Nullable String planFormat, Object planData, @Nullable RegisteredTypeLoadingContext optionalContext, @Nullable Class<SpecT> optionalSpecSuperType);
+    @Beta
     <T> T createBean(RegisteredType type, @Nullable RegisteredTypeLoadingContext optionalContext, @Nullable Class<T> optionalResultSuperType);
+    @Beta
     <T> T createBeanFromPlan(String planFormat, Object planData, @Nullable RegisteredTypeLoadingContext optionalConstraint, @Nullable Class<T> optionalBeanSuperType);
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java b/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
index 2674736..29b64d3 100644
--- a/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
+++ b/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
@@ -21,8 +21,6 @@ package org.apache.brooklyn.api.typereg;
 import java.util.Collection;
 import java.util.Set;
 
-import javax.annotation.Nullable;
-
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.objs.BrooklynObject;
@@ -75,6 +73,12 @@ public interface RegisteredType extends Identifiable {
      */
     boolean isDisabled();
 
+    /** Alias words defined for this type */
+    Set<String> getAliases();
+
+    /** Tags attached to this item */
+    Set<Object> getTags();
+    
     /** @return implementation details, so that the framework can find a suitable {@link BrooklynTypePlanTransformer} 
      * which can then use this object to instantiate this type */
     TypeImplementationPlan getPlan();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
index ef455c6..078e1d7 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
@@ -43,6 +43,7 @@ import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl.RebindTracker;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
 import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts;
+import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
 import org.apache.brooklyn.core.typereg.RegisteredTypes;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.text.Strings;
@@ -85,7 +86,7 @@ public class CatalogUtils {
         ManagementContext mgmt = ((EntityInternal)entity).getManagementContext();
         String catId = entity.getCatalogItemId();
         if (Strings.isBlank(catId)) return JavaBrooklynClassLoadingContext.create(mgmt);
-        RegisteredType cat = RegisteredTypes.validate(mgmt.getTypeRegistry().get(catId), RegisteredTypeLoadingContexts.spec(Entity.class));
+        RegisteredType cat = RegisteredTypes.validate(mgmt.getTypeRegistry().get(catId), RegisteredTypeLoadingContexts.spec(Entity.class)).get();
         if (cat==null) {
             log.warn("Cannot load "+catId+" to get classloader for "+entity+"; will try with standard loader, but might fail subsequently");
             return JavaBrooklynClassLoadingContext.create(mgmt);
@@ -267,9 +268,10 @@ public class CatalogUtils {
     }
 
     public static boolean isBestVersion(ManagementContext mgmt, CatalogItem<?,?> item) {
-        RegisteredType bestVersion = mgmt.getTypeRegistry().get(item.getSymbolicName(), BrooklynCatalog.DEFAULT_VERSION);
-        if (bestVersion==null) return false;
-        return (bestVersion.getVersion().equals(item.getVersion()));
+        RegisteredType best = RegisteredTypes.getBestVersion(mgmt.getTypeRegistry().getAll(
+            RegisteredTypePredicates.symbolicName(item.getSymbolicName())));
+        if (best==null) return false;
+        return (best.getVersion().equals(item.getVersion()));
     }
 
     /** @deprecated since 0.9.0 use {@link BrooklynTypeRegistry#get(String, org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind, Class)} */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
index ee49d39..283b7da 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
@@ -128,7 +128,7 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra
     protected <T> T validate(T createdObject, RegisteredType type, RegisteredTypeLoadingContext constraint) {
         if (createdObject==null) return null;
         try {
-            return RegisteredTypes.validate(createdObject, type, constraint);
+            return RegisteredTypes.validate(createdObject, type, constraint).get();
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);
             throw new IllegalStateException("Created incompatible object: "+Exceptions.collapseText(e), e);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
index b36be34..a642861 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
@@ -18,6 +18,7 @@
  */
 package org.apache.brooklyn.core.typereg;
 
+import java.util.Map;
 import java.util.Set;
 
 import javax.annotation.Nullable;
@@ -34,7 +35,8 @@ import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
@@ -43,16 +45,17 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.api.client.util.Preconditions;
+import com.google.common.annotations.Beta;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
 
 public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
 
-    @SuppressWarnings("unused")
     private static final Logger log = LoggerFactory.getLogger(BasicBrooklynTypeRegistry.class);
     
     private ManagementContext mgmt;
+    private Map<String,RegisteredType> localRegisteredTypes = MutableMap.of();
 
     public BasicBrooklynTypeRegistry(ManagementContext mgmt) {
         this.mgmt = mgmt;
@@ -62,40 +65,95 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
         return getAll(Predicates.alwaysTrue());
     }
     
+    private Iterable<RegisteredType> getAllWithoutCatalog(Predicate<? super RegisteredType> filter) {
+        // TODO thread safety
+        // TODO optimisation? make indexes and look up?
+        return Iterables.filter(localRegisteredTypes.values(), filter);
+    }
+
+    private RegisteredType getExactWithoutLegacyCatalog(String symbolicName, String version, RegisteredTypeLoadingContext constraint) {
+        // TODO look in any nested/private registries
+        RegisteredType item = localRegisteredTypes.get(symbolicName+":"+version);
+        return RegisteredTypes.validate(item, constraint).orNull();
+    }
+
     @SuppressWarnings("deprecation")
     @Override
     public Iterable<RegisteredType> getAll(Predicate<? super RegisteredType> filter) {
-        return Iterables.filter(Iterables.transform(mgmt.getCatalog().getCatalogItems(), RegisteredTypes.CI_TO_RT), filter);
+        return Iterables.filter(Iterables.concat(
+                getAllWithoutCatalog(filter),
+                Iterables.transform(mgmt.getCatalog().getCatalogItems(), RegisteredTypes.CI_TO_RT)), 
+            filter);
     }
 
     @SuppressWarnings("deprecation")
-    private RegisteredType get(String symbolicName, String version, RegisteredTypeLoadingContext constraint) {
-        // probably constraint is not useful?
-        if (constraint==null) constraint = RegisteredTypeLoadingContexts.any();
+    private Maybe<RegisteredType> getSingle(String symbolicNameOrAliasIfNoVersion, final String versionFinal, final RegisteredTypeLoadingContext contextFinal) {
+        RegisteredTypeLoadingContext context = contextFinal;
+        if (context==null) context = RegisteredTypeLoadingContexts.any();
+        String version = versionFinal;
         if (version==null) version = BrooklynCatalog.DEFAULT_VERSION;
+
+        RegisteredType type;
+        if (!BrooklynCatalog.DEFAULT_VERSION.equals(version)) {
+            type = getExactWithoutLegacyCatalog(symbolicNameOrAliasIfNoVersion, version, context);
+            if (type!=null) return Maybe.of(type);
+        }
         
-        // TODO lookup here, using constraints
+        if (BrooklynCatalog.DEFAULT_VERSION.equals(version)) {
+            Iterable<RegisteredType> types = getAll(Predicates.and(RegisteredTypePredicates.symbolicName(symbolicNameOrAliasIfNoVersion), 
+                RegisteredTypePredicates.satisfies(context)));
+            if (Iterables.isEmpty(types)) {
+                // look for alias if no exact symbolic name match AND no version is specified
+                types = getAll(Predicates.and(RegisteredTypePredicates.alias(symbolicNameOrAliasIfNoVersion), 
+                    RegisteredTypePredicates.satisfies(context) ) );
+                // if there are multiple symbolic names then throw?
+                Set<String> uniqueSymbolicNames = MutableSet.of();
+                for (RegisteredType t: types) {
+                    uniqueSymbolicNames.add(t.getSymbolicName());
+                }
+                if (uniqueSymbolicNames.size()>1) {
+                    log.warn("Multiple matches found for alias '"+symbolicNameOrAliasIfNoVersion+"': "+uniqueSymbolicNames+"; "
+                        + "picking highest version across different symbolic names. Use symbolic_name:version syntax to prevent this lookup.");
+                }
+            }
+            if (!Iterables.isEmpty(types)) {
+                type = RegisteredTypes.getBestVersion(types);
+                if (type!=null) return Maybe.of(type);
+            }
+        }
         
         // fallback to catalog
-        CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(symbolicName, version);
-        // TODO apply constraint
-        return RegisteredTypes.CI_TO_RT.apply( item );
+        CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(symbolicNameOrAliasIfNoVersion, version);
+        if (item!=null) 
+            return Maybe.of( RegisteredTypes.CI_TO_RT.apply( item ) );
+        
+        return Maybe.absent("No matches for "+symbolicNameOrAliasIfNoVersion+
+            (versionFinal!=null ? ":"+versionFinal : "")+
+            (contextFinal!=null ? " ("+contextFinal+")" : "") );
     }
 
     @Override
     public RegisteredType get(String symbolicName, String version) {
-        return get(symbolicName, version, null);
+        return getSingle(symbolicName, version, null).orNull();
     }
     
-    private RegisteredType get(String symbolicNameWithOptionalVersion, RegisteredTypeLoadingContext constraint) {
-        // probably constraint is not useful?
+    @Override
+    public RegisteredType get(String symbolicNameWithOptionalVersion, RegisteredTypeLoadingContext context) {
+        return getMaybe(symbolicNameWithOptionalVersion, context).orNull();
+    }
+    @Override
+    public Maybe<RegisteredType> getMaybe(String symbolicNameWithOptionalVersion, RegisteredTypeLoadingContext context) {
+        Maybe<RegisteredType> r1 = null;
         if (CatalogUtils.looksLikeVersionedId(symbolicNameWithOptionalVersion)) {
             String symbolicName = CatalogUtils.getSymbolicNameFromVersionedId(symbolicNameWithOptionalVersion);
             String version = CatalogUtils.getVersionFromVersionedId(symbolicNameWithOptionalVersion);
-            return get(symbolicName, version, constraint);
-        } else {
-            return get(symbolicNameWithOptionalVersion, BrooklynCatalog.DEFAULT_VERSION, constraint);
+            r1 = getSingle(symbolicName, version, context);
+            if (r1.isPresent()) return r1;
         }
+
+        Maybe<RegisteredType> r2 = getSingle(symbolicNameWithOptionalVersion, BrooklynCatalog.DEFAULT_VERSION, context);
+        if (r2.isPresent() || r1==null) return r2;
+        return r1;
     }
 
     @Override
@@ -191,7 +249,8 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
             }
             if (constraint.getAlreadyEncounteredTypes().contains(type.getSymbolicName())) {
                 // avoid recursive cycle
-                // TODO implement using java if permitted
+                // TODO create type using java if permitted?
+                // OR remove this creator from those permitted
             }
         }
         constraint = RegisteredTypeLoadingContexts.withBeanSuperType(constraint, optionalResultSuperType);
@@ -207,4 +266,26 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
             optionalConstraint, optionalBeanSuperType);
     }
 
+    @Beta // API is stabilising
+    public void addToLocalUnpersistedTypeRegistry(RegisteredType type, boolean canForce) {
+        Preconditions.checkNotNull(type);
+        Preconditions.checkNotNull(type.getSymbolicName());
+        Preconditions.checkNotNull(type.getVersion());
+        Preconditions.checkNotNull(type.getId());
+        if (!type.getId().equals(type.getSymbolicName()+":"+type.getVersion()))
+            Asserts.fail("Registered type "+type+" has ID / symname mismatch");
+        
+        RegisteredType oldType = localRegisteredTypes.get(type.getId());
+        if (oldType==null || canForce) {
+            log.debug("Inserting "+type+" into "+this);
+            localRegisteredTypes.put(type.getId(), type);
+        } else {
+            if (oldType == type) {
+                // ignore if same instance
+                // (equals not yet implemented, so would be the same, but misleading)
+                return;
+            }
+            throw new IllegalStateException("Cannot add "+type+" to catalog; different "+oldType+" is already present");
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java
index 3905d65..05f0773 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicRegisteredType.java
@@ -36,17 +36,20 @@ import com.google.common.collect.ImmutableSet;
 /** Instances are usually created by methods in {@link RegisteredTypes}. */
 public class BasicRegisteredType implements RegisteredType {
 
+    final RegisteredTypeKind kind;
     final String symbolicName;
     final String version;
-    final RegisteredTypeKind kind;
     
-    Set<Object> superTypes = MutableSet.of();
-    List<OsgiBundleWithUrl> bundles = MutableList.of();
+    final List<OsgiBundleWithUrl> bundles = MutableList.of();
     String displayName;
     String description;
     String iconUrl;
+    
+    final Set<Object> superTypes = MutableSet.of();
     boolean deprecated;
     boolean disabled;
+    final Set<String> aliases = MutableSet.of();
+    final Set<Object> tags = MutableSet.of();
     
     TypeImplementationPlan implementationPlan;
 
@@ -63,6 +66,11 @@ public class BasicRegisteredType implements RegisteredType {
     public String getId() {
         return symbolicName + (version!=null ? ":"+version : "");
     }
+    
+    @Override
+    public RegisteredTypeKind getKind() {
+        return kind;
+    }
 
     @Override
     public String getSymbolicName() {
@@ -73,11 +81,6 @@ public class BasicRegisteredType implements RegisteredType {
     public String getVersion() {
         return version;
     }
-
-    @Override
-    public RegisteredTypeKind getKind() {
-        return kind;
-    }
     
     @Override
     public Collection<OsgiBundleWithUrl> getLibraries() {
@@ -100,6 +103,11 @@ public class BasicRegisteredType implements RegisteredType {
     }
     
     @Override
+    public Set<Object> getSuperTypes() {
+        return ImmutableSet.copyOf(superTypes);
+    }
+
+    @Override
     public boolean isDisabled() {
         return disabled;
     }
@@ -110,10 +118,16 @@ public class BasicRegisteredType implements RegisteredType {
     }
     
     @Override
-    public Set<Object> getSuperTypes() {
-        return ImmutableSet.copyOf(superTypes);
+    public Set<String> getAliases() {
+        return ImmutableSet.copyOf(aliases);
+    }
+
+    @Override
+    public Set<Object> getTags() {
+        return ImmutableSet.copyOf(tags);
     }
 
+    
     @Beta  // TODO depending how useful this is, it might be better to replace by a static WeakHashMap in RegisteredTypes
     public ConfigBag getCache() {
         return cache;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
index ebeccd7..bf6fb6f 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
@@ -20,14 +20,15 @@ package org.apache.brooklyn.core.typereg;
 
 import javax.annotation.Nullable;
 
-import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
 import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
+import org.apache.brooklyn.util.collections.CollectionFunctionals;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
@@ -93,6 +94,9 @@ public class RegisteredTypePredicates {
         }
     }
 
+    public static Predicate<RegisteredType> symbolicName(final String name) {
+        return symbolicName(Predicates.equalTo(name));
+    }
     public static Predicate<RegisteredType> symbolicName(final Predicate<? super String> filter) {
         return new SymbolicNameMatches(filter);
     }
@@ -109,6 +113,63 @@ public class RegisteredTypePredicates {
         }
     }
 
+    public static Predicate<RegisteredType> version(final String name) {
+        return version(Predicates.equalTo(name));
+    }
+    public static Predicate<RegisteredType> version(final Predicate<? super String> filter) {
+        return new versionMatches(filter);
+    }
+    
+    private static class versionMatches implements Predicate<RegisteredType> {
+        private final Predicate<? super String> filter;
+        
+        public versionMatches(Predicate<? super String> filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable RegisteredType item) {
+            return (item != null) && filter.apply(item.getVersion());
+        }
+    }
+
+    public static Predicate<RegisteredType> alias(final String alias) {
+        return aliases(CollectionFunctionals.any(Predicates.equalTo(alias)));
+    }
+    public static Predicate<RegisteredType> aliases(final Predicate<Iterable<String>> filter) {
+        return new AliasesMatch(filter);
+    }
+    
+    private static class AliasesMatch implements Predicate<RegisteredType> {
+        private final Predicate<Iterable<String>> filter;
+        
+        public AliasesMatch(Predicate<Iterable<String>> filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable RegisteredType item) {
+            return (item != null) && filter.apply(item.getAliases());
+        }
+    }
+
+    public static Predicate<RegisteredType> tag(final Object tag) {
+        return tags(CollectionFunctionals.any(Predicates.equalTo(tag)));
+    }
+    public static Predicate<RegisteredType> tags(final Predicate<Iterable<Object>> filter) {
+        return new TagsMatch(filter);
+    }
+    
+    private static class TagsMatch implements Predicate<RegisteredType> {
+        private final Predicate<Iterable<Object>> filter;
+        
+        public TagsMatch(Predicate<Iterable<Object>> filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable RegisteredType item) {
+            return (item != null) && filter.apply(item.getTags());
+        }
+    }
+
     public static <T> Predicate<RegisteredType> anySuperType(final Predicate<Class<T>> filter) {
         return new AnySuperTypeMatches(filter);
     }
@@ -158,7 +219,6 @@ public class RegisteredTypePredicates {
     public static Predicate<RegisteredType> isBestVersion(final ManagementContext mgmt) {
         return new IsBestVersion(mgmt);
     }
-
     private static class IsBestVersion implements Predicate<RegisteredType> {
         private final ManagementContext mgmt;
 
@@ -170,11 +230,28 @@ public class RegisteredTypePredicates {
             return isBestVersion(mgmt, item);
         }
     }
- 
     public static boolean isBestVersion(ManagementContext mgmt, RegisteredType item) {
-        RegisteredType bestVersion = mgmt.getTypeRegistry().get(item.getSymbolicName(), BrooklynCatalog.DEFAULT_VERSION);
-        if (bestVersion==null) return false;
-        return (bestVersion.getVersion().equals(item.getVersion()));
+        if (item==null) return false;
+        Iterable<RegisteredType> matches = mgmt.getTypeRegistry().getAll(
+            RegisteredTypePredicates.symbolicName(item.getSymbolicName()) );
+        if (!matches.iterator().hasNext()) return false;
+        RegisteredType best = RegisteredTypes.getBestVersion(matches);
+        return (best.getVersion().equals(item.getVersion()));
+    }
+    
+    public static Predicate<RegisteredType> satisfies(RegisteredTypeLoadingContext context) {
+        return new SatisfiesContext(context);
+    }
+    private static class SatisfiesContext implements Predicate<RegisteredType> {
+        private final RegisteredTypeLoadingContext context;
+
+        public SatisfiesContext(RegisteredTypeLoadingContext context) {
+            this.context = context;
+        }
+        @Override
+        public boolean apply(@Nullable RegisteredType item) {
+            return RegisteredTypes.validate(item, context).isPresent();
+        }
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
index 18f8f43..3a89e60 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
@@ -19,6 +19,8 @@
 package org.apache.brooklyn.core.typereg;
 
 import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
@@ -30,7 +32,6 @@ import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind;
-import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
 import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.api.typereg.RegisteredType.TypeImplementationPlan;
 import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
@@ -39,15 +40,18 @@ import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
 import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer.JavaClassNameTypeImplementationPlan;
+import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.text.NaturalOrderComparator;
+import org.apache.brooklyn.util.text.VersionComparator;
 import org.apache.brooklyn.util.yaml.Yamls;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ComparisonChain;
 import com.google.common.reflect.TypeToken;
 
 /**
@@ -88,16 +92,18 @@ public class RegisteredTypes {
         }
         
         BasicRegisteredType type = (BasicRegisteredType) spec(item.getSymbolicName(), item.getVersion(), impl, item.getCatalogItemJavaType());
-        type.bundles = item.getLibraries()==null ? ImmutableList.<OsgiBundleWithUrl>of() : ImmutableList.<OsgiBundleWithUrl>copyOf(item.getLibraries());
         type.displayName = item.getDisplayName();
         type.description = item.getDescription();
         type.iconUrl = item.getIconUrl();
+        
+        if (item.getLibraries()!=null) type.bundles.addAll(item.getLibraries());
         type.disabled = item.isDisabled();
         type.deprecated = item.isDeprecated();
+        if (item.getLibraries()!=null) type.bundles.addAll(item.getLibraries());
+        // aliases aren't on item
+        if (item.tags()!=null) type.tags.addAll(item.tags().getTags());
 
-        // TODO
-        // probably not: javaType, specType, registeredTypeName ...
-        // maybe: tags ?
+        // these things from item we ignore: javaType, specType, registeredTypeName ...
         return type;
     }
 
@@ -135,7 +141,6 @@ public class RegisteredTypes {
         }
         return type;
     }
-
     @Beta
     public static RegisteredType addSuperType(RegisteredType type, @Nullable RegisteredType superType) {
         if (superType!=null) {
@@ -146,6 +151,53 @@ public class RegisteredTypes {
         }
         return type;
     }
+    @Beta
+    public static RegisteredType addSuperTypes(RegisteredType type, Iterable<Object> superTypesAsClassOrRegisteredType) {
+        if (superTypesAsClassOrRegisteredType!=null) {
+            for (Object superType: superTypesAsClassOrRegisteredType) {
+                if (superType==null) {
+                    // nothing
+                } else if (superType instanceof Class) {
+                    addSuperType(type, (Class<?>)superType);
+                } else if (superType instanceof RegisteredType) {
+                    addSuperType(type, (RegisteredType)superType);
+                } else {
+                    throw new IllegalStateException(superType+" supplied as a supertype of "+type+" but it is not a supported supertype");
+                }
+            }
+        }
+        return type;
+    }
+
+    @Beta
+    public static RegisteredType addAlias(RegisteredType type, String alias) {
+        if (alias!=null) {
+            ((BasicRegisteredType)type).aliases.add( alias );
+        }
+        return type;
+    }
+    @Beta
+    public static RegisteredType addAliases(RegisteredType type, Iterable<String> aliases) {
+        if (aliases!=null) {
+            for (String alias: aliases) addAlias(type, alias);
+        }
+        return type;
+    }
+
+    @Beta
+    public static RegisteredType addTag(RegisteredType type, Object tag) {
+        if (tag!=null) {
+            ((BasicRegisteredType)type).tags.add( tag );
+        }
+        return type;
+    }
+    @Beta
+    public static RegisteredType addTags(RegisteredType type, Iterable<?> tags) {
+        if (tags!=null) {
+            for (Object tag: tags) addTag(type, tag);
+        }
+        return type;
+    }
 
     /** returns the implementation data for a spec if it is a string (e.g. plan yaml or java class name); else throws */
     @Beta
@@ -232,16 +284,16 @@ public class RegisteredTypes {
         return false;
     }
 
-    public static RegisteredType validate(RegisteredType item, final RegisteredTypeLoadingContext constraint) {
-        if (item==null || constraint==null) return item;
+    public static Maybe<RegisteredType> validate(RegisteredType item, final RegisteredTypeLoadingContext constraint) {
+        if (item==null || constraint==null) return Maybe.of(item);
         if (constraint.getExpectedKind()!=null && !constraint.getExpectedKind().equals(item.getKind()))
-            throw new IllegalStateException(item+" is not the expected kind "+constraint.getExpectedKind());
+            return Maybe.absent(item+" is not the expected kind "+constraint.getExpectedKind());
         if (constraint.getExpectedJavaSuperType()!=null) {
             if (!isSubtypeOf(item, constraint.getExpectedJavaSuperType())) {
-                throw new IllegalStateException(item+" is not for the expected type "+constraint.getExpectedJavaSuperType());
+                return Maybe.absent(item+" is not for the expected type "+constraint.getExpectedJavaSuperType());
             }
         }
-        return item;
+        return Maybe.of(item);
     }
 
     /** 
@@ -258,68 +310,87 @@ public class RegisteredTypes {
         return true;
     }
 
-    public static <T> T validate(final T object, final RegisteredType type, final RegisteredTypeLoadingContext constraint) {
+    public static RegisteredType getBestVersion(Iterable<RegisteredType> types) {
+        if (types==null || !types.iterator().hasNext()) return null;
+        return Collections.max(MutableList.copyOf(types), RegisteredTypeComparator.INSTANCE);
+    }
+    
+    public static class RegisteredTypeComparator implements Comparator<RegisteredType> {
+        public static Comparator<RegisteredType> INSTANCE = new RegisteredTypeComparator();
+        private RegisteredTypeComparator() {}
+        @Override
+        public int compare(RegisteredType o1, RegisteredType o2) {
+            return ComparisonChain.start()
+                .compareTrueFirst(o1.isDisabled(), o2.isDisabled())
+                .compareTrueFirst(o1.isDeprecated(), o2.isDeprecated())
+                .compare(o1.getSymbolicName(), o2.getSymbolicName(), NaturalOrderComparator.INSTANCE)
+                .compare(o1.getVersion(), o2.getVersion(), VersionComparator.INSTANCE)
+                .result();
+        }
+    }
+
+    public static <T> Maybe<T> validate(final T object, final RegisteredType type, final RegisteredTypeLoadingContext constraint) {
         RegisteredTypeKind kind = type!=null ? type.getKind() : constraint!=null ? constraint.getExpectedKind() : null;
         if (kind==null) {
             if (object instanceof AbstractBrooklynObjectSpec) kind=RegisteredTypeKind.SPEC;
             else kind=RegisteredTypeKind.BEAN;
         }
-        return new RegisteredTypeKindVisitor<T>() {
+        return new RegisteredTypeKindVisitor<Maybe<T>>() {
             @Override
-            protected T visitSpec() {
+            protected Maybe<T> visitSpec() {
                 return validateSpec(object, type, constraint);
             }
 
             @Override
-            protected T visitBean() {
+            protected Maybe<T> visitBean() {
                 return validateBean(object, type, constraint);
             }
         }.visit(kind);
     }
 
-    private static <T> T validateBean(T object, RegisteredType type, final RegisteredTypeLoadingContext constraint) {
-        if (object==null) return null;
+    private static <T> Maybe<T> validateBean(T object, RegisteredType type, final RegisteredTypeLoadingContext constraint) {
+        if (object==null) return Maybe.absent("object is null");
         
         if (type!=null) {
             if (type.getKind()!=RegisteredTypeKind.BEAN)
-                throw new IllegalStateException("Validating a bean when type is "+type.getKind()+" "+type);
+                return Maybe.absent("Validating a bean when type is "+type.getKind()+" "+type);
             if (!isSubtypeOf(object.getClass(), type))
-                throw new IllegalStateException(object+" does not have all the java supertypes of "+type);
+                return Maybe.absent(object+" does not have all the java supertypes of "+type);
         }
 
         if (constraint!=null) {
             if (constraint.getExpectedKind()!=RegisteredTypeKind.BEAN)
-                throw new IllegalStateException("Validating a bean when constraint expected "+constraint.getExpectedKind());
+                return Maybe.absent("Validating a bean when constraint expected "+constraint.getExpectedKind());
             if (constraint.getExpectedJavaSuperType()!=null && !constraint.getExpectedJavaSuperType().isInstance(object))
-                throw new IllegalStateException(object+" is not of the expected java supertype "+constraint.getExpectedJavaSuperType());
+                return Maybe.absent(object+" is not of the expected java supertype "+constraint.getExpectedJavaSuperType());
         }
         
-        return object;
+        return Maybe.of(object);
     }
 
-    private static <T> T validateSpec(T object, RegisteredType rType, final RegisteredTypeLoadingContext constraint) {
-        if (object==null) return null;
+    private static <T> Maybe<T> validateSpec(T object, RegisteredType rType, final RegisteredTypeLoadingContext constraint) {
+        if (object==null) return Maybe.absent("object is null");
         
         if (!(object instanceof AbstractBrooklynObjectSpec)) {
-            throw new IllegalStateException("Found "+object+" when expecting a spec");
+            Maybe.absent("Found "+object+" when expecting a spec");
         }
         Class<?> targetType = ((AbstractBrooklynObjectSpec<?,?>)object).getType();
         
         if (targetType==null) {
-            throw new IllegalStateException("Spec "+object+" does not have a target type");
+            Maybe.absent("Spec "+object+" does not have a target type");
         }
         
         if (rType!=null) {
             if (rType.getKind()!=RegisteredTypeKind.SPEC)
-                throw new IllegalStateException("Validating a spec when type is "+rType.getKind()+" "+rType);
+                Maybe.absent("Validating a spec when type is "+rType.getKind()+" "+rType);
             if (!isSubtypeOf(targetType, rType))
-                throw new IllegalStateException(object+" does not have all the java supertypes of "+rType);
+                Maybe.absent(object+" does not have all the java supertypes of "+rType);
         }
 
         if (constraint!=null) {
             if (constraint.getExpectedJavaSuperType()!=null) {
                 if (!constraint.getExpectedJavaSuperType().isAssignableFrom(targetType)) {
-                    throw new IllegalStateException(object+" does not target the expected java supertype "+constraint.getExpectedJavaSuperType());
+                    Maybe.absent(object+" does not target the expected java supertype "+constraint.getExpectedJavaSuperType());
                 }
                 if (constraint.getExpectedJavaSuperType().isAssignableFrom(BrooklynObjectInternal.class)) {
                     // don't check spec type; any spec is acceptable
@@ -328,15 +399,15 @@ public class RegisteredTypes {
                     Class<? extends AbstractBrooklynObjectSpec<?, ?>> specType = RegisteredTypeLoadingContexts.lookupSpecTypeForTarget( (Class<? extends BrooklynObject>) constraint.getExpectedJavaSuperType());
                     if (specType==null) {
                         // means a problem in our classification of spec types!
-                        throw new IllegalStateException(object+" is returned as spec for unexpected java supertype "+constraint.getExpectedJavaSuperType());
+                        Maybe.absent(object+" is returned as spec for unexpected java supertype "+constraint.getExpectedJavaSuperType());
                     }
                     if (!specType.isAssignableFrom(object.getClass())) {
-                        throw new IllegalStateException(object+" is not a spec of the expected java supertype "+constraint.getExpectedJavaSuperType());
+                        Maybe.absent(object+" is not a spec of the expected java supertype "+constraint.getExpectedJavaSuperType());
                     }
                 }
             }
         }
-        return object;
+        return Maybe.of(object);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java
index e7d43cd..3c8ce83 100644
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparatorTest.java
@@ -21,22 +21,25 @@ package org.apache.brooklyn.core.catalog.internal;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
-import org.testng.annotations.Test;
 import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
-import org.apache.brooklyn.core.catalog.internal.CatalogItemComparator;
+import org.testng.annotations.Test;
 
 public class CatalogItemComparatorTest {
     private static final String RC2 = "10.5.8-rc2";
     private static final String STABLE = "10.5.8";
 
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     @Test
     public void testComparison() {
         compare("0.0.1", "0.0.2", 1);
         compare("0.0.2", "0.0.1", -1);
         compare("0.0.1-qual", "0.0.2", 1);
         compare("0.0.1.qual", "0.0.2", 1);
-        compare("0.0.1-qual", "0.0.1_qual", 0);
+        
+        // NB: semantics of this changed in 090-SNAPSHOT not to be 0 unless identical
+        // (remove when we're used to this)
+//        compare("0.0.1-qual", "0.0.1_qual", 0);
+        
         compare("0.0.1.qual", "0.0.1.qual", 0);
         compare("0.0.1", "0.0.2-SNAPSHOT", -1);
         compare("0.0.1", "0.0.2.SNAPSHOT", -1);
@@ -70,6 +73,7 @@ public class CatalogItemComparatorTest {
         assertTrue(cmp.compare(v(RC2), v("10.5.8-beta1")) == cmp.compare(v(RC2), v("10.5.8-beta3")));
     }
     
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     private void compare(String v1, String v2, int expected) {
         CatalogItemComparator cmp = CatalogItemComparator.INSTANCE;
         assertEquals(cmp.compare(v(v1), v(v2)), expected);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java b/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
new file mode 100644
index 0000000..a62ab7e
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.typereg;
+
+import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+public class BasicBrooklynTypeRegistryTest extends BrooklynMgmtUnitTestSupport {
+
+    private BasicBrooklynTypeRegistry registry() {
+        return (BasicBrooklynTypeRegistry) mgmt.getTypeRegistry();
+    }
+    
+    private void add(RegisteredType type) {
+        add(type, false);
+    }
+    private void add(RegisteredType type, boolean canForce) {
+        registry().addToLocalUnpersistedTypeRegistry(type, canForce);
+    }
+    
+    private final static RegisteredType SAMPLE_TYPE = RegisteredTypes.bean("item.A", "1", new BasicTypeImplementationPlan("ignore", null), String.class);
+    private final static RegisteredType SAMPLE_TYPE2 = RegisteredTypes.bean("item.A", "2", new BasicTypeImplementationPlan("ignore", null), String.class);
+    
+    @Test
+    public void testAddAndGet() {
+        Assert.assertFalse( Iterables.contains(registry().getAll(), SAMPLE_TYPE) );
+        Assert.assertNull( registry().get(SAMPLE_TYPE.getSymbolicName(), SAMPLE_TYPE.getVersion()) );
+        Assert.assertNull( registry().get(SAMPLE_TYPE.getId()) );
+        add(SAMPLE_TYPE);
+        
+        Assert.assertTrue( Iterables.contains(registry().getAll(), SAMPLE_TYPE) );
+        Assert.assertEquals( registry().get(SAMPLE_TYPE.getSymbolicName(), SAMPLE_TYPE.getVersion()), SAMPLE_TYPE );
+        Assert.assertEquals( registry().get(SAMPLE_TYPE.getId()), SAMPLE_TYPE );
+        
+        Assert.assertTrue( Iterables.contains(registry().getAll(
+            RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName())), SAMPLE_TYPE) );
+    }
+
+    @Test
+    public void testCantAddSameIdUnlessSameInstanceOrForced() {
+        add(SAMPLE_TYPE);
+        RegisteredType sampleTypeClone = RegisteredTypes.bean("item.A", "1", new BasicTypeImplementationPlan("ignore", null), String.class);
+        add(sampleTypeClone, true);
+        Assert.assertNotEquals( registry().get(SAMPLE_TYPE.getId()), SAMPLE_TYPE );
+        
+        add(SAMPLE_TYPE, true);
+        Assert.assertEquals( registry().get(SAMPLE_TYPE.getId()), SAMPLE_TYPE );
+
+        try {
+            add(sampleTypeClone);
+            Asserts.shouldHaveFailedPreviously();
+        } catch (Exception e) {
+            Asserts.expectedFailureContains(e, SAMPLE_TYPE.getSymbolicName());
+        }
+        
+        // only one entry
+        Assert.assertEquals( Iterables.size(registry().getAll(
+            RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 1);
+        // unversioned request returns sample
+        Assert.assertEquals( registry().get(SAMPLE_TYPE.getSymbolicName()), SAMPLE_TYPE );
+    }
+
+    @Test
+    public void testGettingBestVersion() {
+        add(SAMPLE_TYPE);
+        add(SAMPLE_TYPE2);
+        
+        Assert.assertTrue( Iterables.contains(registry().getAll(), SAMPLE_TYPE) );
+        Assert.assertTrue( Iterables.contains(registry().getAll(), SAMPLE_TYPE2) );
+        Assert.assertEquals( registry().get(SAMPLE_TYPE.getId()), SAMPLE_TYPE );
+        Assert.assertEquals( registry().get(SAMPLE_TYPE2.getId()), SAMPLE_TYPE2 );
+        Assert.assertNotEquals( registry().get(SAMPLE_TYPE2.getId()), SAMPLE_TYPE );
+        
+        Assert.assertEquals( Iterables.size(registry().getAll(
+            RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 2);
+        
+        // unversioned request returns latest
+        Assert.assertEquals( registry().get(SAMPLE_TYPE.getSymbolicName()), SAMPLE_TYPE2 );
+    }
+
+    @Test
+    public void testGetWithFilter() {
+        add(SAMPLE_TYPE);
+        
+        Assert.assertEquals( Iterables.size(registry().getAll(Predicates.and(
+            RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()),
+            RegisteredTypePredicates.subtypeOf(String.class)
+            ))), 1 );
+        Assert.assertTrue( Iterables.isEmpty(registry().getAll(Predicates.and(
+                RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()),
+                RegisteredTypePredicates.subtypeOf(Integer.class)
+            ))) );
+    }
+    
+    @Test
+    public void testGetWithContext() {
+        add(SAMPLE_TYPE);
+        Assert.assertEquals( registry().get(SAMPLE_TYPE.getId(),  
+            RegisteredTypeLoadingContexts.bean(String.class)), SAMPLE_TYPE );
+        Assert.assertEquals( registry().get(SAMPLE_TYPE.getId(),  
+            RegisteredTypeLoadingContexts.bean(Integer.class)), null );
+    }
+
+    @Test
+    public void testAlias() {
+        add(SAMPLE_TYPE);
+        add(SAMPLE_TYPE2);
+        
+        RegisteredType sampleType15WithAliases = RegisteredTypes.addAliases(
+            RegisteredTypes.bean("item.A", "1.1", new BasicTypeImplementationPlan("ignore", null), String.class),
+            MutableList.of("my_a", "the_a"));
+        add(sampleType15WithAliases);
+        Assert.assertEquals(sampleType15WithAliases.getAliases(), MutableSet.of("my_a", "the_a"));
+        
+        Assert.assertEquals( Iterables.size(registry().getAll(
+            RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 3);
+        
+        Assert.assertEquals( registry().get("my_a"), sampleType15WithAliases );
+        Assert.assertEquals( registry().get("the_a"), sampleType15WithAliases );
+        Assert.assertEquals( registry().get(sampleType15WithAliases.getId()), sampleType15WithAliases );
+        
+        // but unadorned type still returns v2
+        Assert.assertEquals( registry().get(sampleType15WithAliases.getSymbolicName()), SAMPLE_TYPE2 );
+        
+        // and filters work
+        Assert.assertEquals( registry().getAll(RegisteredTypePredicates.alias("the_a")),
+            MutableList.of(sampleType15WithAliases) );
+        Assert.assertEquals( registry().get("my_a",  
+            RegisteredTypeLoadingContexts.bean(String.class)), sampleType15WithAliases );
+        Assert.assertEquals( registry().get("my_a",  
+            RegisteredTypeLoadingContexts.bean(Integer.class)), null );
+    }
+
+    @Test
+    public void testTags() {
+        add(SAMPLE_TYPE);
+        add(SAMPLE_TYPE2);
+        
+        RegisteredType sampleType15WithTags = RegisteredTypes.addTags(
+            RegisteredTypes.bean("item.A", "1.1", new BasicTypeImplementationPlan("ignore", null), String.class),
+            MutableList.of("my_a", "the_a"));
+        add(sampleType15WithTags);
+        Assert.assertEquals(sampleType15WithTags.getTags(), MutableSet.of("my_a", "the_a"));
+        
+        Assert.assertEquals( Iterables.size(registry().getAll(
+            RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 3);
+        
+        Assert.assertEquals( registry().get(sampleType15WithTags.getId()), sampleType15WithTags );
+        
+        // and filters work
+        Assert.assertEquals( registry().getAll(RegisteredTypePredicates.tag("the_a")),
+            MutableList.of(sampleType15WithTags) );
+        
+        // but can't lookup by tag as a get
+        Assert.assertEquals( registry().get("my_a"), null );
+        
+        // and unadorned type still returns v2
+        Assert.assertEquals( registry().get(sampleType15WithTags.getSymbolicName()), SAMPLE_TYPE2 );
+        
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java b/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java
index 145c056..9523946 100644
--- a/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicatesTest.java
@@ -24,28 +24,13 @@ import static org.testng.Assert.assertTrue;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
+import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Predicates;
 
 
-public class RegisteredTypePredicatesTest {
-    private LocalManagementContext mgmt;
-    
-    @BeforeMethod(alwaysRun = true)
-    public void setUp() throws Exception {
-        mgmt = LocalManagementContextForTests.newInstance();
-    }
-    
-    @AfterMethod(alwaysRun = true)
-    public void tearDown() throws Exception {
-        if (mgmt != null) Entities.destroyAll(mgmt);
-    }
+public class RegisteredTypePredicatesTest extends BrooklynMgmtUnitTestSupport {
 
     @Test
     public void testDisplayName() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
index 0147b9d..acde8ec 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
@@ -115,7 +115,7 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
             String policyType = decoLoader.getTypeName().get();
             ManagementContext mgmt = instantiator.loader.getManagementContext();
             
-            RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(policyType), RegisteredTypeLoadingContexts.spec(Policy.class));
+            RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(policyType), RegisteredTypeLoadingContexts.spec(Policy.class)).get();
             PolicySpec<?> spec;
             if (item!=null) {
                 spec = mgmt.getTypeRegistry().createSpec(item, null, PolicySpec.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
index d8e4b1d..57adfeb 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
@@ -230,7 +230,7 @@ public class CampYamlLiteTest {
     }
 
     private void assertMgmtHasSampleMyCatalogApp(String symbolicName, String bundleUrl) {
-        RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(symbolicName), RegisteredTypeLoadingContexts.spec(Entity.class));
+        RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(symbolicName), RegisteredTypeLoadingContexts.spec(Entity.class)).get();
         assertNotNull(item, "failed to load item with id=" + symbolicName + " from catalog. Entries were: " +
                 Joiner.on(",").join(mgmt.getTypeRegistry().getAll()));
         assertEquals(item.getSymbolicName(), symbolicName);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
index ecbeffb..03b05f9 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
@@ -149,7 +149,7 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
                 Entitlements.getEntitlementContext().user());
         }
         try {
-            RegisteredType item = RegisteredTypes.validate(mgmt().getTypeRegistry().get(entityId), RegisteredTypeLoadingContexts.spec(Entity.class));
+            RegisteredType item = RegisteredTypes.validate(mgmt().getTypeRegistry().get(entityId), RegisteredTypeLoadingContexts.spec(Entity.class)).get();
             if (item==null) {
                 throw WebResourceUtils.notFound("Entity with id '%s' not found", entityId);
             }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java b/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java
index aa6831b..91f53f9 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/collections/CollectionFunctionals.java
@@ -205,15 +205,36 @@ public class CollectionFunctionals {
 
     // ---------
     
+    /** 
+     * Returns a predicate for a collection which is true if 
+     * all elements in the collection given to the predicate
+     * which satisfies the predicate given here.
+     * <p>
+     * This will return true for the empty set.
+     * To require additionally that there is at least one
+     * use {@link #quorum(QuorumCheck, Predicate)} with
+     * {@link QuorumChecks#allAndAtLeastOne()}. */
     public static <T,TT extends Iterable<T>> Predicate<TT> all(Predicate<T> attributeSatisfies) {
         return quorum(QuorumChecks.all(), attributeSatisfies);
     }
 
+    /** Returns a predicate for a collection which is true if 
+     * there is at least one element in the collection given to the predicate
+     * which satisfies the predicate given here. 
+     */
+    public static <T,TT extends Iterable<T>> Predicate<TT> any(Predicate<T> attributeSatisfies) {
+        // implementation could be more efficient -- ie succeed fast
+        return quorum(QuorumChecks.atLeastOne(), attributeSatisfies);
+    }
+
+    /** Returns a predicate for a collection which is true if 
+     * the number of elements in the collection satisfying the predicate given here
+     * passes the {@link QuorumCheck} given here.
+     */
     public static <T,TT extends Iterable<T>> Predicate<TT> quorum(QuorumCheck quorumCheck, Predicate<T> attributeSatisfies) {
         return new QuorumSatisfies<T, TT>(quorumCheck, attributeSatisfies);
     }
 
-
     private static final class QuorumSatisfies<I,T extends Iterable<I>> implements Predicate<T> {
         private final Predicate<I> itemCheck;
         private final QuorumCheck quorumCheck;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/420ea303/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java
index 1d75297..1ce4015 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/collections/CollectionFunctionalsTest.java
@@ -22,6 +22,7 @@ import org.apache.brooklyn.util.collections.CollectionFunctionals;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
@@ -55,4 +56,27 @@ public class CollectionFunctionalsTest {
         Assert.assertEquals(CollectionFunctionals.firstElement().apply(ImmutableList.of("a")), "a");
         Assert.assertEquals(CollectionFunctionals.firstElement().apply(ImmutableList.of("a", "b", "c")), "a");
     }
+
+    @Test
+    public void testAllAndAny() {
+        Assert.assertEquals(CollectionFunctionals.all(Predicates.equalTo(1)).apply(
+            MutableList.of(1, 1, 1)), true);
+        Assert.assertEquals(CollectionFunctionals.all(Predicates.equalTo(1)).apply(
+            MutableList.<Integer>of()), true);
+        Assert.assertEquals(CollectionFunctionals.all(Predicates.equalTo(1)).apply(
+            MutableList.of(1, 0, 1)), false);
+        Assert.assertEquals(CollectionFunctionals.all(Predicates.equalTo(1)).apply(
+            MutableList.of(0, 0, 0)), false);
+        
+        Assert.assertEquals(CollectionFunctionals.any(Predicates.equalTo(1)).apply(
+            MutableList.of(1, 1, 1)), true);
+        Assert.assertEquals(CollectionFunctionals.any(Predicates.equalTo(1)).apply(
+            MutableList.<Integer>of()), false);
+        Assert.assertEquals(CollectionFunctionals.any(Predicates.equalTo(1)).apply(
+            MutableList.of(1, 0, 1)), true);
+        Assert.assertEquals(CollectionFunctionals.any(Predicates.equalTo(1)).apply(
+            MutableList.of(0, 0, 0)), false);
+        
+    }
+    
 }


[08/12] incubator-brooklyn git commit: resolve the curious Maybe.Present(null) making use of new Absent.isNull()

Posted by he...@apache.org.
resolve the curious Maybe.Present(null) making use of new Absent.isNull()


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/3900e19d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/3900e19d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/3900e19d

Branch: refs/heads/master
Commit: 3900e19d6df17bf1f605508b62dbcea98b336467
Parents: 0b9b2e3
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Dec 17 13:59:48 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Dec 17 14:23:02 2015 +0000

----------------------------------------------------------------------
 .../core/catalog/internal/CatalogUtils.java     |  2 +-
 .../typereg/AbstractTypePlanTransformer.java    | 15 ++++-------
 .../core/typereg/BasicBrooklynTypeRegistry.java | 11 ++++----
 .../brooklyn/core/typereg/RegisteredTypes.java  | 27 +++++++++++---------
 .../BrooklynEntityDecorationResolver.java       |  3 ++-
 .../rest/resources/ApplicationResource.java     | 24 +++++++++++------
 .../rest/resources/CatalogResource.java         | 16 ++++++++----
 7 files changed, 55 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3900e19d/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
index fbf34f7..a1b2040 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
@@ -87,7 +87,7 @@ public class CatalogUtils {
         String catId = entity.getCatalogItemId();
         if (Strings.isBlank(catId)) return JavaBrooklynClassLoadingContext.create(mgmt);
         Maybe<RegisteredType> cat = RegisteredTypes.tryValidate(mgmt.getTypeRegistry().get(catId), RegisteredTypeLoadingContexts.spec(Entity.class));
-        if (cat.get()==null) {
+        if (cat.isNull()) {
             log.warn("Cannot load "+catId+" to get classloader for "+entity+"; will try with standard loader, but might fail subsequently");
             return JavaBrooklynClassLoadingContext.create(mgmt);
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3900e19d/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
index 7b91529..8f671f2 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
@@ -23,6 +23,7 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
 import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.javalang.JavaClassNames;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -98,7 +99,7 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra
     @Override
     public Object create(final RegisteredType type, final RegisteredTypeLoadingContext context) {
         try {
-            return validate(new RegisteredTypeKindVisitor<Object>() {
+            return tryValidate(new RegisteredTypeKindVisitor<Object>() {
                 @Override protected Object visitSpec() {
                     try { 
                         AbstractBrooklynObjectSpec<?, ?> result = createSpec(type, context);
@@ -112,7 +113,7 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra
                     } catch (Exception e) { throw Exceptions.propagate(e); }
                 }
                 
-            }.visit(type.getKind()), type, context);
+            }.visit(type.getKind()), type, context).get();
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);
             if (!(e instanceof UnsupportedTypePlanException)) {
@@ -125,14 +126,8 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra
     /** Validates the object. Subclasses may do further validation based on the context. 
      * @throw UnsupportedTypePlanException if we want to quietly abandon this, any other exception to report the problem, when validation fails
      * @return the created object for fluent usage */
-    protected <T> T validate(T createdObject, RegisteredType type, RegisteredTypeLoadingContext constraint) {
-        if (createdObject==null) return null;
-        try {
-            return RegisteredTypes.tryValidate(createdObject, type, constraint).get();
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            throw new IllegalStateException("Created incompatible object: "+Exceptions.collapseText(e), e);
-        }
+    protected <T> Maybe<T> tryValidate(T createdObject, RegisteredType type, RegisteredTypeLoadingContext constraint) {
+        return RegisteredTypes.tryValidate(createdObject, type, constraint);
     }
 
     protected abstract AbstractBrooklynObjectSpec<?,?> createSpec(RegisteredType type, RegisteredTypeLoadingContext context) throws Exception;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3900e19d/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
index 496c028..1b47648 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
@@ -71,10 +71,10 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
         return Iterables.filter(localRegisteredTypes.values(), filter);
     }
 
-    private RegisteredType getExactWithoutLegacyCatalog(String symbolicName, String version, RegisteredTypeLoadingContext constraint) {
+    private Maybe<RegisteredType> getExactWithoutLegacyCatalog(String symbolicName, String version, RegisteredTypeLoadingContext constraint) {
         // TODO look in any nested/private registries
         RegisteredType item = localRegisteredTypes.get(symbolicName+":"+version);
-        return RegisteredTypes.tryValidate(item, constraint).orNull();
+        return RegisteredTypes.tryValidate(item, constraint);
     }
 
     @SuppressWarnings("deprecation")
@@ -93,12 +93,11 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
         String version = versionFinal;
         if (version==null) version = BrooklynCatalog.DEFAULT_VERSION;
 
-        RegisteredType type;
         if (!BrooklynCatalog.DEFAULT_VERSION.equals(version)) {
             // normal code path when version is supplied
             
-            type = getExactWithoutLegacyCatalog(symbolicNameOrAliasIfNoVersion, version, context);
-            if (type!=null) return Maybe.of(type);
+            Maybe<RegisteredType> type = getExactWithoutLegacyCatalog(symbolicNameOrAliasIfNoVersion, version, context);
+            if (type.isPresent()) return type;
         }
 
         if (BrooklynCatalog.DEFAULT_VERSION.equals(version)) {
@@ -123,7 +122,7 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
                 }
             }
             if (!Iterables.isEmpty(types)) {
-                type = RegisteredTypes.getBestVersion(types);
+                RegisteredType type = RegisteredTypes.getBestVersion(types);
                 if (type!=null) return Maybe.of(type);
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3900e19d/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
index 2f792f0..0c7b09b 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
@@ -24,7 +24,6 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
-import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.catalog.CatalogItem;
@@ -42,6 +41,7 @@ import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
 import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer.JavaClassNameTypeImplementationPlan;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.guava.Maybe.Absent;
 import org.apache.brooklyn.util.text.NaturalOrderComparator;
 import org.apache.brooklyn.util.text.VersionComparator;
 import org.apache.brooklyn.util.yaml.Yamls;
@@ -284,13 +284,15 @@ public class RegisteredTypes {
     }
 
     /** Validates that the given type matches the context (if supplied);
-     * returns a Maybe(null) if the type is null. */
+     * if not satisfied. returns an {@link Absent} if failed with details of the error,
+     * with {@link Absent#isNull()} true if the object is null. */
     public static Maybe<RegisteredType> tryValidate(RegisteredType item, final RegisteredTypeLoadingContext constraint) {
         // kept as a Maybe in case someone wants a wrapper around item validity;
         // unclear what the contract should be, as this can return Maybe.Present(null)
         // which is suprising, but it is more natural to callers otherwise they'll likely do a separate null check on the item
         // (often handling null different to errors) so the Maybe.get() is redundant as they have an object for the input anyway.
-        if (item==null || constraint==null) return Maybe.of(item);
+        
+        if (item==null || constraint==null) return Maybe.ofDisallowingNull(item);
         if (constraint.getExpectedKind()!=null && !constraint.getExpectedKind().equals(item.getKind()))
             return Maybe.absent(item+" is not the expected kind "+constraint.getExpectedKind());
         if (constraint.getExpectedJavaSuperType()!=null) {
@@ -336,9 +338,10 @@ public class RegisteredTypes {
 
     /** validates that the given object (required) satisfies the constraints implied by the given
      * type and context object, using {@link Maybe} as the result set absent containing the error(s)
-     * if not satisfied */
-    public static <T> Maybe<T> tryValidate(@Nonnull final T object, @Nullable final RegisteredType type, @Nullable final RegisteredTypeLoadingContext context) {
-        if (object==null) return Maybe.absent("object is null");
+     * if not satisfied. returns an {@link Absent} if failed with details of the error,
+     * with {@link Absent#isNull()} true if the object is null. */
+    public static <T> Maybe<T> tryValidate(final T object, @Nullable final RegisteredType type, @Nullable final RegisteredTypeLoadingContext context) {
+        if (object==null) return Maybe.absentNull("object is null");
         
         RegisteredTypeKind kind = type!=null ? type.getKind() : context!=null ? context.getExpectedKind() : null;
         if (kind==null) {
@@ -348,18 +351,18 @@ public class RegisteredTypes {
         return new RegisteredTypeKindVisitor<Maybe<T>>() {
             @Override
             protected Maybe<T> visitSpec() {
-                return validateSpec(object, type, context);
+                return tryValidateSpec(object, type, context);
             }
 
             @Override
             protected Maybe<T> visitBean() {
-                return validateBean(object, type, context);
+                return tryValidateBean(object, type, context);
             }
         }.visit(kind);
     }
 
-    private static <T> Maybe<T> validateBean(T object, RegisteredType type, final RegisteredTypeLoadingContext context) {
-        if (object==null) return Maybe.absent("object is null");
+    private static <T> Maybe<T> tryValidateBean(T object, RegisteredType type, final RegisteredTypeLoadingContext context) {
+        if (object==null) return Maybe.absentNull("object is null");
         
         if (type!=null) {
             if (type.getKind()!=RegisteredTypeKind.BEAN)
@@ -378,8 +381,8 @@ public class RegisteredTypes {
         return Maybe.of(object);
     }
 
-    private static <T> Maybe<T> validateSpec(T object, RegisteredType rType, final RegisteredTypeLoadingContext constraint) {
-        if (object==null) return Maybe.absent("object is null");
+    private static <T> Maybe<T> tryValidateSpec(T object, RegisteredType rType, final RegisteredTypeLoadingContext constraint) {
+        if (object==null) return Maybe.absentNull("object is null");
         
         if (!(object instanceof AbstractBrooklynObjectSpec)) {
             Maybe.absent("Found "+object+" when expecting a spec");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3900e19d/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
index e4f500d..6734875 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
@@ -118,7 +118,8 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
             
             Maybe<RegisteredType> item = RegisteredTypes.tryValidate(mgmt.getTypeRegistry().get(policyType), RegisteredTypeLoadingContexts.spec(Policy.class));
             PolicySpec<?> spec;
-            if (item.get()!=null) {
+            if (!item.isNull()) {
+                // throw error if absent for any reason other than null
                 spec = mgmt.getTypeRegistry().createSpec(item.get(), null, PolicySpec.class);
             } else {
                 Class<? extends Policy> type = decoLoader.getType(Policy.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3900e19d/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
index 83c6423..22a4502 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
@@ -45,6 +45,7 @@ import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.core.config.ConstraintViolationException;
 import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.EntityPredicates;
@@ -75,6 +76,7 @@ import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.exceptions.UserFacingException;
+import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.javalang.JavaClassNames;
 import org.apache.brooklyn.util.text.Strings;
 import org.codehaus.jackson.JsonNode;
@@ -402,15 +404,21 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
     }
 
     private void checkSpecTypeIsValid(String type, Class<? extends BrooklynObject> subType) {
-        if (RegisteredTypes.tryValidate(mgmt().getTypeRegistry().get(type), RegisteredTypeLoadingContexts.spec(subType)) == null) {
-            try {
-                brooklyn().getCatalogClassLoader().loadClass(type);
-            } catch (ClassNotFoundException e) {
-                log.debug("Class not found for type '" + type + "'; reporting 404", e);
-                throw WebResourceUtils.notFound("Undefined type '%s'", type);
-            }
-            log.info(JavaClassNames.simpleClassName(subType)+" type '{}' not defined in catalog but is on classpath; continuing", type);
+        Maybe<RegisteredType> typeV = RegisteredTypes.tryValidate(mgmt().getTypeRegistry().get(type), RegisteredTypeLoadingContexts.spec(subType));
+        if (!typeV.isNull()) {
+            // found, throw if any problem
+            typeV.get();
+            return;
+        }
+        
+        // not found, try classloading
+        try {
+            brooklyn().getCatalogClassLoader().loadClass(type);
+        } catch (ClassNotFoundException e) {
+            log.debug("Class not found for type '" + type + "'; reporting 404", e);
+            throw WebResourceUtils.notFound("Undefined type '%s'", type);
         }
+        log.info(JavaClassNames.simpleClassName(subType)+" type '{}' not defined in catalog but is on classpath; continuing", type);
     }
     
     private void checkEntityTypeIsValid(String type) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3900e19d/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
index 0993f16..01bf992 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
@@ -65,6 +65,7 @@ import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.StringPredicates;
 import org.apache.brooklyn.util.text.Strings;
@@ -149,15 +150,20 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
                 Entitlements.getEntitlementContext().user());
         }
         try {
-            RegisteredType item = mgmt().getTypeRegistry().get(entityId);
-            if (item==null) {
+            Maybe<RegisteredType> item = RegisteredTypes.tryValidate(mgmt().getTypeRegistry().get(entityId), RegisteredTypeLoadingContexts.spec(Entity.class));
+            if (item.isNull()) {
                 throw WebResourceUtils.notFound("Entity with id '%s' not found", entityId);
             }
-            RegisteredTypes.tryValidate(item, RegisteredTypeLoadingContexts.spec(Entity.class));
+            if (item.isAbsent()) {
+                throw WebResourceUtils.notFound("Item with id '%s' is not an entity", entityId);
+            }
+            
+            brooklyn().getCatalog().deleteCatalogItem(item.get().getSymbolicName(), item.get().getVersion());
             
-            brooklyn().getCatalog().deleteCatalogItem(item.getSymbolicName(), item.getVersion());
         } catch (NoSuchElementException e) {
-            throw WebResourceUtils.notFound("Entity with id '%s' not found", entityId);
+            // shouldn't come here
+            throw WebResourceUtils.notFound("Entity with id '%s' could not be deleted", entityId);
+            
         }
     }
 


[11/12] incubator-brooklyn git commit: This closes #1114

Posted by he...@apache.org.
This closes #1114


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/5388dbe6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/5388dbe6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/5388dbe6

Branch: refs/heads/master
Commit: 5388dbe69039a11c2a0690014dccf71487cedf59
Parents: 9b7ad2e 816f617
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Dec 21 11:43:09 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Dec 21 11:43:09 2015 +0000

----------------------------------------------------------------------
 .../core/catalog/internal/CatalogUtils.java     |   4 +-
 .../apache/brooklyn/core/config/Sanitizer.java  |   2 +-
 .../core/typereg/BasicBrooklynTypeRegistry.java |   3 +-
 .../enricher/stock/reducer/Reducer.java         |   2 +-
 parent/pom.xml                                  |   2 +-
 .../location/WinRmMachineLocationLiveTest.java  |   3 +-
 usage/downstream-parent/pom.xml                 |  31 +++--
 .../brooklyn/launcher/BrooklynLauncherTest.java |   4 +-
 usage/qa/pom.xml                                |  17 ++-
 .../downstreamparent/DownstreamParentTest.java  |  64 ++++++++++
 .../test/projects/downstream-parent-test/README |   5 +
 .../projects/downstream-parent-test/pom.xml     | 120 +++++++++++++++++++
 .../src/main/java/com/example/HelloEntity.java  |  26 ++++
 .../main/java/com/example/HelloEntityImpl.java  |  31 +++++
 .../src/main/resources/blueprint.yaml           |  19 +++
 .../src/main/resources/catalog.bom              |  33 +++++
 .../brooklyn/test/framework/TestSensorImpl.java |   2 +-
 17 files changed, 346 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5388dbe6/parent/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5388dbe6/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
----------------------------------------------------------------------


[07/12] incubator-brooklyn git commit: clean-up of type registry work following PR comments; all addressed apart from weird validate semantics

Posted by he...@apache.org.
clean-up of type registry work following PR comments; all addressed apart from weird validate semantics


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/48bb7985
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/48bb7985
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/48bb7985

Branch: refs/heads/master
Commit: 48bb79857ce0f841017d5d4721bfd510e902d7f1
Parents: 420ea30
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Dec 10 14:17:31 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Dec 17 13:22:51 2015 +0000

----------------------------------------------------------------------
 .../api/typereg/BrooklynTypeRegistry.java       |  2 +-
 .../core/catalog/internal/CatalogUtils.java     |  8 ++--
 .../core/location/BasicLocationRegistry.java    |  2 +-
 .../typereg/AbstractTypePlanTransformer.java    |  2 +-
 .../core/typereg/BasicBrooklynTypeRegistry.java | 26 ++++++++-----
 .../core/typereg/RegisteredTypePredicates.java  | 22 +++++------
 .../brooklyn/core/typereg/RegisteredTypes.java  | 40 ++++++++++++--------
 .../typereg/BasicBrooklynTypeRegistryTest.java  | 18 ++++-----
 .../BrooklynEntityDecorationResolver.java       |  7 ++--
 .../catalog/CatalogYamlLocationTest.java        |  4 +-
 .../catalog/CatalogYamlVersioningTest.java      | 14 +++----
 .../brooklyn/test/lite/CampYamlLiteTest.java    |  4 +-
 .../rest/resources/ApplicationResource.java     |  2 +-
 .../rest/resources/CatalogResource.java         |  4 +-
 14 files changed, 88 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java b/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
index eb59d27..17a7fb3 100644
--- a/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
+++ b/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
@@ -42,7 +42,7 @@ public interface BrooklynTypeRegistry {
     }
     
     Iterable<RegisteredType> getAll();
-    Iterable<RegisteredType> getAll(Predicate<? super RegisteredType> filter);
+    Iterable<RegisteredType> getMatching(Predicate<? super RegisteredType> filter);
 
     /** @return The item matching the given given 
      * {@link RegisteredType#getSymbolicName() symbolicName} 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
index 078e1d7..fbf34f7 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
@@ -86,12 +86,12 @@ public class CatalogUtils {
         ManagementContext mgmt = ((EntityInternal)entity).getManagementContext();
         String catId = entity.getCatalogItemId();
         if (Strings.isBlank(catId)) return JavaBrooklynClassLoadingContext.create(mgmt);
-        RegisteredType cat = RegisteredTypes.validate(mgmt.getTypeRegistry().get(catId), RegisteredTypeLoadingContexts.spec(Entity.class)).get();
-        if (cat==null) {
+        Maybe<RegisteredType> cat = RegisteredTypes.tryValidate(mgmt.getTypeRegistry().get(catId), RegisteredTypeLoadingContexts.spec(Entity.class));
+        if (cat.get()==null) {
             log.warn("Cannot load "+catId+" to get classloader for "+entity+"; will try with standard loader, but might fail subsequently");
             return JavaBrooklynClassLoadingContext.create(mgmt);
         }
-        return newClassLoadingContext(mgmt, cat);
+        return newClassLoadingContext(mgmt, cat.get());
     }
 
     public static BrooklynClassLoadingContext newClassLoadingContext(@Nullable ManagementContext mgmt, String catalogItemId, Collection<? extends OsgiBundleWithUrl> libraries) {
@@ -268,7 +268,7 @@ public class CatalogUtils {
     }
 
     public static boolean isBestVersion(ManagementContext mgmt, CatalogItem<?,?> item) {
-        RegisteredType best = RegisteredTypes.getBestVersion(mgmt.getTypeRegistry().getAll(
+        RegisteredType best = RegisteredTypes.getBestVersion(mgmt.getTypeRegistry().getMatching(
             RegisteredTypePredicates.symbolicName(item.getSymbolicName())));
         if (best==null) return false;
         return (best.getVersion().equals(item.getVersion()));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java b/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java
index 202ecf4..b8452f3 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java
@@ -288,7 +288,7 @@ public class BasicLocationRegistry implements LocationRegistry {
                 definedLocations.putAll(oldDefined);
             }
             
-            for (RegisteredType item: mgmt.getTypeRegistry().getAll(RegisteredTypePredicates.IS_LOCATION)) {
+            for (RegisteredType item: mgmt.getTypeRegistry().getMatching(RegisteredTypePredicates.IS_LOCATION)) {
                 updateDefinedLocation(item);
                 count++;
             }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
index 283b7da..7b91529 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java
@@ -128,7 +128,7 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra
     protected <T> T validate(T createdObject, RegisteredType type, RegisteredTypeLoadingContext constraint) {
         if (createdObject==null) return null;
         try {
-            return RegisteredTypes.validate(createdObject, type, constraint).get();
+            return RegisteredTypes.tryValidate(createdObject, type, constraint).get();
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);
             throw new IllegalStateException("Created incompatible object: "+Exceptions.collapseText(e), e);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
index a642861..496c028 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
@@ -62,7 +62,7 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
     }
     
     public Iterable<RegisteredType> getAll() {
-        return getAll(Predicates.alwaysTrue());
+        return getMatching(Predicates.alwaysTrue());
     }
     
     private Iterable<RegisteredType> getAllWithoutCatalog(Predicate<? super RegisteredType> filter) {
@@ -74,12 +74,12 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
     private RegisteredType getExactWithoutLegacyCatalog(String symbolicName, String version, RegisteredTypeLoadingContext constraint) {
         // TODO look in any nested/private registries
         RegisteredType item = localRegisteredTypes.get(symbolicName+":"+version);
-        return RegisteredTypes.validate(item, constraint).orNull();
+        return RegisteredTypes.tryValidate(item, constraint).orNull();
     }
 
     @SuppressWarnings("deprecation")
     @Override
-    public Iterable<RegisteredType> getAll(Predicate<? super RegisteredType> filter) {
+    public Iterable<RegisteredType> getMatching(Predicate<? super RegisteredType> filter) {
         return Iterables.filter(Iterables.concat(
                 getAllWithoutCatalog(filter),
                 Iterables.transform(mgmt.getCatalog().getCatalogItems(), RegisteredTypes.CI_TO_RT)), 
@@ -95,16 +95,20 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
 
         RegisteredType type;
         if (!BrooklynCatalog.DEFAULT_VERSION.equals(version)) {
+            // normal code path when version is supplied
+            
             type = getExactWithoutLegacyCatalog(symbolicNameOrAliasIfNoVersion, version, context);
             if (type!=null) return Maybe.of(type);
         }
-        
+
         if (BrooklynCatalog.DEFAULT_VERSION.equals(version)) {
-            Iterable<RegisteredType> types = getAll(Predicates.and(RegisteredTypePredicates.symbolicName(symbolicNameOrAliasIfNoVersion), 
+            // alternate code path, if version blank or default
+            
+            Iterable<RegisteredType> types = getMatching(Predicates.and(RegisteredTypePredicates.symbolicName(symbolicNameOrAliasIfNoVersion), 
                 RegisteredTypePredicates.satisfies(context)));
             if (Iterables.isEmpty(types)) {
                 // look for alias if no exact symbolic name match AND no version is specified
-                types = getAll(Predicates.and(RegisteredTypePredicates.alias(symbolicNameOrAliasIfNoVersion), 
+                types = getMatching(Predicates.and(RegisteredTypePredicates.alias(symbolicNameOrAliasIfNoVersion), 
                     RegisteredTypePredicates.satisfies(context) ) );
                 // if there are multiple symbolic names then throw?
                 Set<String> uniqueSymbolicNames = MutableSet.of();
@@ -112,8 +116,10 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
                     uniqueSymbolicNames.add(t.getSymbolicName());
                 }
                 if (uniqueSymbolicNames.size()>1) {
-                    log.warn("Multiple matches found for alias '"+symbolicNameOrAliasIfNoVersion+"': "+uniqueSymbolicNames+"; "
-                        + "picking highest version across different symbolic names. Use symbolic_name:version syntax to prevent this lookup.");
+                    String message = "Multiple matches found for alias '"+symbolicNameOrAliasIfNoVersion+"': "+uniqueSymbolicNames+"; "
+                        + "refusing to select any.";
+                    log.warn(message);
+                    return Maybe.absent(message);
                 }
             }
             if (!Iterables.isEmpty(types)) {
@@ -122,7 +128,7 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
             }
         }
         
-        // fallback to catalog
+        // missing case is to look for exact version in legacy catalog
         CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(symbolicNameOrAliasIfNoVersion, version);
         if (item!=null) 
             return Maybe.of( RegisteredTypes.CI_TO_RT.apply( item ) );
@@ -275,7 +281,7 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
         if (!type.getId().equals(type.getSymbolicName()+":"+type.getVersion()))
             Asserts.fail("Registered type "+type+" has ID / symname mismatch");
         
-        RegisteredType oldType = localRegisteredTypes.get(type.getId());
+        RegisteredType oldType = mgmt.getTypeRegistry().get(type.getId());
         if (oldType==null || canForce) {
             log.debug("Inserting "+type+" into "+this);
             localRegisteredTypes.put(type.getId(), type);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
index bf6fb6f..2c02874 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
@@ -117,13 +117,13 @@ public class RegisteredTypePredicates {
         return version(Predicates.equalTo(name));
     }
     public static Predicate<RegisteredType> version(final Predicate<? super String> filter) {
-        return new versionMatches(filter);
+        return new VersionMatches(filter);
     }
     
-    private static class versionMatches implements Predicate<RegisteredType> {
+    private static class VersionMatches implements Predicate<RegisteredType> {
         private final Predicate<? super String> filter;
         
-        public versionMatches(Predicate<? super String> filter) {
+        public VersionMatches(Predicate<? super String> filter) {
             this.filter = filter;
         }
         @Override
@@ -135,14 +135,14 @@ public class RegisteredTypePredicates {
     public static Predicate<RegisteredType> alias(final String alias) {
         return aliases(CollectionFunctionals.any(Predicates.equalTo(alias)));
     }
-    public static Predicate<RegisteredType> aliases(final Predicate<Iterable<String>> filter) {
+    public static Predicate<RegisteredType> aliases(final Predicate<? super Iterable<String>> filter) {
         return new AliasesMatch(filter);
     }
     
     private static class AliasesMatch implements Predicate<RegisteredType> {
-        private final Predicate<Iterable<String>> filter;
+        private final Predicate<? super Iterable<String>> filter;
         
-        public AliasesMatch(Predicate<Iterable<String>> filter) {
+        public AliasesMatch(Predicate<? super Iterable<String>> filter) {
             this.filter = filter;
         }
         @Override
@@ -154,14 +154,14 @@ public class RegisteredTypePredicates {
     public static Predicate<RegisteredType> tag(final Object tag) {
         return tags(CollectionFunctionals.any(Predicates.equalTo(tag)));
     }
-    public static Predicate<RegisteredType> tags(final Predicate<Iterable<Object>> filter) {
+    public static Predicate<RegisteredType> tags(final Predicate<? super Iterable<Object>> filter) {
         return new TagsMatch(filter);
     }
     
     private static class TagsMatch implements Predicate<RegisteredType> {
-        private final Predicate<Iterable<Object>> filter;
+        private final Predicate<? super Iterable<Object>> filter;
         
-        public TagsMatch(Predicate<Iterable<Object>> filter) {
+        public TagsMatch(Predicate<? super Iterable<Object>> filter) {
             this.filter = filter;
         }
         @Override
@@ -232,7 +232,7 @@ public class RegisteredTypePredicates {
     }
     public static boolean isBestVersion(ManagementContext mgmt, RegisteredType item) {
         if (item==null) return false;
-        Iterable<RegisteredType> matches = mgmt.getTypeRegistry().getAll(
+        Iterable<RegisteredType> matches = mgmt.getTypeRegistry().getMatching(
             RegisteredTypePredicates.symbolicName(item.getSymbolicName()) );
         if (!matches.iterator().hasNext()) return false;
         RegisteredType best = RegisteredTypes.getBestVersion(matches);
@@ -250,7 +250,7 @@ public class RegisteredTypePredicates {
         }
         @Override
         public boolean apply(@Nullable RegisteredType item) {
-            return RegisteredTypes.validate(item, context).isPresent();
+            return RegisteredTypes.tryValidate(item, context).isPresent();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
index 3a89e60..2f792f0 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
@@ -19,12 +19,12 @@
 package org.apache.brooklyn.core.typereg;
 
 import java.lang.reflect.Method;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.catalog.CatalogItem;
@@ -40,7 +40,6 @@ import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
 import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer.JavaClassNameTypeImplementationPlan;
-import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.text.NaturalOrderComparator;
@@ -52,6 +51,7 @@ import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.Ordering;
 import com.google.common.reflect.TypeToken;
 
 /**
@@ -96,7 +96,6 @@ public class RegisteredTypes {
         type.description = item.getDescription();
         type.iconUrl = item.getIconUrl();
         
-        if (item.getLibraries()!=null) type.bundles.addAll(item.getLibraries());
         type.disabled = item.isDisabled();
         type.deprecated = item.isDeprecated();
         if (item.getLibraries()!=null) type.bundles.addAll(item.getLibraries());
@@ -284,7 +283,13 @@ public class RegisteredTypes {
         return false;
     }
 
-    public static Maybe<RegisteredType> validate(RegisteredType item, final RegisteredTypeLoadingContext constraint) {
+    /** Validates that the given type matches the context (if supplied);
+     * returns a Maybe(null) if the type is null. */
+    public static Maybe<RegisteredType> tryValidate(RegisteredType item, final RegisteredTypeLoadingContext constraint) {
+        // kept as a Maybe in case someone wants a wrapper around item validity;
+        // unclear what the contract should be, as this can return Maybe.Present(null)
+        // which is suprising, but it is more natural to callers otherwise they'll likely do a separate null check on the item
+        // (often handling null different to errors) so the Maybe.get() is redundant as they have an object for the input anyway.
         if (item==null || constraint==null) return Maybe.of(item);
         if (constraint.getExpectedKind()!=null && !constraint.getExpectedKind().equals(item.getKind()))
             return Maybe.absent(item+" is not the expected kind "+constraint.getExpectedKind());
@@ -312,7 +317,7 @@ public class RegisteredTypes {
 
     public static RegisteredType getBestVersion(Iterable<RegisteredType> types) {
         if (types==null || !types.iterator().hasNext()) return null;
-        return Collections.max(MutableList.copyOf(types), RegisteredTypeComparator.INSTANCE);
+        return Ordering.from(RegisteredTypeComparator.INSTANCE).max(types);
     }
     
     public static class RegisteredTypeComparator implements Comparator<RegisteredType> {
@@ -329,8 +334,13 @@ public class RegisteredTypes {
         }
     }
 
-    public static <T> Maybe<T> validate(final T object, final RegisteredType type, final RegisteredTypeLoadingContext constraint) {
-        RegisteredTypeKind kind = type!=null ? type.getKind() : constraint!=null ? constraint.getExpectedKind() : null;
+    /** validates that the given object (required) satisfies the constraints implied by the given
+     * type and context object, using {@link Maybe} as the result set absent containing the error(s)
+     * if not satisfied */
+    public static <T> Maybe<T> tryValidate(@Nonnull final T object, @Nullable final RegisteredType type, @Nullable final RegisteredTypeLoadingContext context) {
+        if (object==null) return Maybe.absent("object is null");
+        
+        RegisteredTypeKind kind = type!=null ? type.getKind() : context!=null ? context.getExpectedKind() : null;
         if (kind==null) {
             if (object instanceof AbstractBrooklynObjectSpec) kind=RegisteredTypeKind.SPEC;
             else kind=RegisteredTypeKind.BEAN;
@@ -338,17 +348,17 @@ public class RegisteredTypes {
         return new RegisteredTypeKindVisitor<Maybe<T>>() {
             @Override
             protected Maybe<T> visitSpec() {
-                return validateSpec(object, type, constraint);
+                return validateSpec(object, type, context);
             }
 
             @Override
             protected Maybe<T> visitBean() {
-                return validateBean(object, type, constraint);
+                return validateBean(object, type, context);
             }
         }.visit(kind);
     }
 
-    private static <T> Maybe<T> validateBean(T object, RegisteredType type, final RegisteredTypeLoadingContext constraint) {
+    private static <T> Maybe<T> validateBean(T object, RegisteredType type, final RegisteredTypeLoadingContext context) {
         if (object==null) return Maybe.absent("object is null");
         
         if (type!=null) {
@@ -358,11 +368,11 @@ public class RegisteredTypes {
                 return Maybe.absent(object+" does not have all the java supertypes of "+type);
         }
 
-        if (constraint!=null) {
-            if (constraint.getExpectedKind()!=RegisteredTypeKind.BEAN)
-                return Maybe.absent("Validating a bean when constraint expected "+constraint.getExpectedKind());
-            if (constraint.getExpectedJavaSuperType()!=null && !constraint.getExpectedJavaSuperType().isInstance(object))
-                return Maybe.absent(object+" is not of the expected java supertype "+constraint.getExpectedJavaSuperType());
+        if (context!=null) {
+            if (context.getExpectedKind()!=RegisteredTypeKind.BEAN)
+                return Maybe.absent("Validating a bean when constraint expected "+context.getExpectedKind());
+            if (context.getExpectedJavaSuperType()!=null && !context.getExpectedJavaSuperType().isInstance(object))
+                return Maybe.absent(object+" is not of the expected java supertype "+context.getExpectedJavaSuperType());
         }
         
         return Maybe.of(object);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java b/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
index a62ab7e..6f2f573 100644
--- a/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistryTest.java
@@ -56,7 +56,7 @@ public class BasicBrooklynTypeRegistryTest extends BrooklynMgmtUnitTestSupport {
         Assert.assertEquals( registry().get(SAMPLE_TYPE.getSymbolicName(), SAMPLE_TYPE.getVersion()), SAMPLE_TYPE );
         Assert.assertEquals( registry().get(SAMPLE_TYPE.getId()), SAMPLE_TYPE );
         
-        Assert.assertTrue( Iterables.contains(registry().getAll(
+        Assert.assertTrue( Iterables.contains(registry().getMatching(
             RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName())), SAMPLE_TYPE) );
     }
 
@@ -78,7 +78,7 @@ public class BasicBrooklynTypeRegistryTest extends BrooklynMgmtUnitTestSupport {
         }
         
         // only one entry
-        Assert.assertEquals( Iterables.size(registry().getAll(
+        Assert.assertEquals( Iterables.size(registry().getMatching(
             RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 1);
         // unversioned request returns sample
         Assert.assertEquals( registry().get(SAMPLE_TYPE.getSymbolicName()), SAMPLE_TYPE );
@@ -95,7 +95,7 @@ public class BasicBrooklynTypeRegistryTest extends BrooklynMgmtUnitTestSupport {
         Assert.assertEquals( registry().get(SAMPLE_TYPE2.getId()), SAMPLE_TYPE2 );
         Assert.assertNotEquals( registry().get(SAMPLE_TYPE2.getId()), SAMPLE_TYPE );
         
-        Assert.assertEquals( Iterables.size(registry().getAll(
+        Assert.assertEquals( Iterables.size(registry().getMatching(
             RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 2);
         
         // unversioned request returns latest
@@ -106,11 +106,11 @@ public class BasicBrooklynTypeRegistryTest extends BrooklynMgmtUnitTestSupport {
     public void testGetWithFilter() {
         add(SAMPLE_TYPE);
         
-        Assert.assertEquals( Iterables.size(registry().getAll(Predicates.and(
+        Assert.assertEquals( Iterables.size(registry().getMatching(Predicates.and(
             RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()),
             RegisteredTypePredicates.subtypeOf(String.class)
             ))), 1 );
-        Assert.assertTrue( Iterables.isEmpty(registry().getAll(Predicates.and(
+        Assert.assertTrue( Iterables.isEmpty(registry().getMatching(Predicates.and(
                 RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()),
                 RegisteredTypePredicates.subtypeOf(Integer.class)
             ))) );
@@ -136,7 +136,7 @@ public class BasicBrooklynTypeRegistryTest extends BrooklynMgmtUnitTestSupport {
         add(sampleType15WithAliases);
         Assert.assertEquals(sampleType15WithAliases.getAliases(), MutableSet.of("my_a", "the_a"));
         
-        Assert.assertEquals( Iterables.size(registry().getAll(
+        Assert.assertEquals( Iterables.size(registry().getMatching(
             RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 3);
         
         Assert.assertEquals( registry().get("my_a"), sampleType15WithAliases );
@@ -147,7 +147,7 @@ public class BasicBrooklynTypeRegistryTest extends BrooklynMgmtUnitTestSupport {
         Assert.assertEquals( registry().get(sampleType15WithAliases.getSymbolicName()), SAMPLE_TYPE2 );
         
         // and filters work
-        Assert.assertEquals( registry().getAll(RegisteredTypePredicates.alias("the_a")),
+        Assert.assertEquals( registry().getMatching(RegisteredTypePredicates.alias("the_a")),
             MutableList.of(sampleType15WithAliases) );
         Assert.assertEquals( registry().get("my_a",  
             RegisteredTypeLoadingContexts.bean(String.class)), sampleType15WithAliases );
@@ -166,13 +166,13 @@ public class BasicBrooklynTypeRegistryTest extends BrooklynMgmtUnitTestSupport {
         add(sampleType15WithTags);
         Assert.assertEquals(sampleType15WithTags.getTags(), MutableSet.of("my_a", "the_a"));
         
-        Assert.assertEquals( Iterables.size(registry().getAll(
+        Assert.assertEquals( Iterables.size(registry().getMatching(
             RegisteredTypePredicates.symbolicName(SAMPLE_TYPE.getSymbolicName()))), 3);
         
         Assert.assertEquals( registry().get(sampleType15WithTags.getId()), sampleType15WithTags );
         
         // and filters work
-        Assert.assertEquals( registry().getAll(RegisteredTypePredicates.tag("the_a")),
+        Assert.assertEquals( registry().getMatching(RegisteredTypePredicates.tag("the_a")),
             MutableList.of(sampleType15WithTags) );
         
         // but can't lookup by tag as a get

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
index acde8ec..e4f500d 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
@@ -37,6 +37,7 @@ import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts;
 import org.apache.brooklyn.core.typereg.RegisteredTypes;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.guava.Maybe;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
@@ -115,10 +116,10 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
             String policyType = decoLoader.getTypeName().get();
             ManagementContext mgmt = instantiator.loader.getManagementContext();
             
-            RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(policyType), RegisteredTypeLoadingContexts.spec(Policy.class)).get();
+            Maybe<RegisteredType> item = RegisteredTypes.tryValidate(mgmt.getTypeRegistry().get(policyType), RegisteredTypeLoadingContexts.spec(Policy.class));
             PolicySpec<?> spec;
-            if (item!=null) {
-                spec = mgmt.getTypeRegistry().createSpec(item, null, PolicySpec.class);
+            if (item.get()!=null) {
+                spec = mgmt.getTypeRegistry().createSpec(item.get(), null, PolicySpec.class);
             } else {
                 Class<? extends Policy> type = decoLoader.getType(Policy.class);
                 spec = PolicySpec.create(type)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
index 291a06a..47925e5 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
@@ -53,7 +53,7 @@ public class CatalogYamlLocationTest extends AbstractYamlTest {
 
     @AfterMethod
     public void tearDown() {
-        for (RegisteredType ci : mgmt().getTypeRegistry().getAll(RegisteredTypePredicates.IS_LOCATION)) {
+        for (RegisteredType ci : mgmt().getTypeRegistry().getMatching(RegisteredTypePredicates.IS_LOCATION)) {
             mgmt().getCatalog().deleteCatalogItem(ci.getSymbolicName(), ci.getVersion());
         }
     }
@@ -246,7 +246,7 @@ public class CatalogYamlLocationTest extends AbstractYamlTest {
     }
 
     private int countCatalogLocations() {
-        return Iterables.size(mgmt().getTypeRegistry().getAll(RegisteredTypePredicates.IS_LOCATION));
+        return Iterables.size(mgmt().getTypeRegistry().getMatching(RegisteredTypePredicates.IS_LOCATION));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
index f92f3a4..440c114 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
@@ -121,11 +121,11 @@ public class CatalogYamlVersioningTest extends AbstractYamlTest {
         addCatalogEntity(symbolicName, version);
         
         Iterable<RegisteredType> matches;
-        matches = types.getAll(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
+        matches = types.getMatching(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
         assertTrue(matches.iterator().hasNext());
         
         mgmt().getCatalog().deleteCatalogItem(symbolicName, version);
-        matches = types.getAll(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
+        matches = types.getMatching(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
         assertFalse(matches.iterator().hasNext());
     }
     
@@ -135,11 +135,11 @@ public class CatalogYamlVersioningTest extends AbstractYamlTest {
         addCatalogEntity(symbolicName, null);
 
         Iterable<RegisteredType> matches;
-        matches = types.getAll(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
+        matches = types.getMatching(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
         assertTrue(matches.iterator().hasNext());
         
         mgmt().getCatalog().deleteCatalogItem(symbolicName, BasicBrooklynCatalog.NO_VERSION);
-        matches = types.getAll(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
+        matches = types.getMatching(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
         assertFalse(matches.iterator().hasNext());
     }
     
@@ -150,7 +150,7 @@ public class CatalogYamlVersioningTest extends AbstractYamlTest {
         String v2 = "0.2.0-SNAPSHOT";
         addCatalogEntity(symbolicName, v1);
         addCatalogEntity(symbolicName, v2);
-        Iterable<RegisteredType> items = types.getAll(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
+        Iterable<RegisteredType> items = types.getMatching(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
         assertEquals(Iterables.size(items), 2);
     }
     
@@ -212,7 +212,7 @@ public class CatalogYamlVersioningTest extends AbstractYamlTest {
                 "      type: referrent\n" +
                 "      version: 1.1"));
         
-        Iterable<RegisteredType> items = types.getAll(RegisteredTypePredicates.symbolicName(Predicates.equalTo("referrer")));
+        Iterable<RegisteredType> items = types.getMatching(RegisteredTypePredicates.symbolicName(Predicates.equalTo("referrer")));
         Assert.assertEquals(Iterables.size(items), 1, "Wrong number of: "+items);
         RegisteredType item = Iterables.getOnlyElement(items);
         Assert.assertEquals(item.getVersion(), "1.0");
@@ -239,7 +239,7 @@ public class CatalogYamlVersioningTest extends AbstractYamlTest {
     }
     
     private void assertSingleCatalogItem(String symbolicName, String version) {
-        Iterable<RegisteredType> items = types.getAll(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
+        Iterable<RegisteredType> items = types.getMatching(RegisteredTypePredicates.symbolicName(Predicates.equalTo(symbolicName)));
         RegisteredType item = Iterables.getOnlyElement(items);
         assertEquals(item.getSymbolicName(), symbolicName);
         assertEquals(item.getVersion(), version);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
index 57adfeb..9cd6bc5 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
@@ -230,11 +230,13 @@ public class CampYamlLiteTest {
     }
 
     private void assertMgmtHasSampleMyCatalogApp(String symbolicName, String bundleUrl) {
-        RegisteredType item = RegisteredTypes.validate(mgmt.getTypeRegistry().get(symbolicName), RegisteredTypeLoadingContexts.spec(Entity.class)).get();
+        RegisteredType item = mgmt.getTypeRegistry().get(symbolicName);
         assertNotNull(item, "failed to load item with id=" + symbolicName + " from catalog. Entries were: " +
                 Joiner.on(",").join(mgmt.getTypeRegistry().getAll()));
         assertEquals(item.getSymbolicName(), symbolicName);
 
+        RegisteredTypes.tryValidate(item, RegisteredTypeLoadingContexts.spec(Entity.class)).get();
+        
         // stored as yaml, not java
         String planYaml = RegisteredTypes.getImplementationDataStringForSpec(item);
         assertNotNull(planYaml);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
index 89f253a..83c6423 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
@@ -402,7 +402,7 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
     }
 
     private void checkSpecTypeIsValid(String type, Class<? extends BrooklynObject> subType) {
-        if (RegisteredTypes.validate(mgmt().getTypeRegistry().get(type), RegisteredTypeLoadingContexts.spec(subType)) == null) {
+        if (RegisteredTypes.tryValidate(mgmt().getTypeRegistry().get(type), RegisteredTypeLoadingContexts.spec(subType)) == null) {
             try {
                 brooklyn().getCatalogClassLoader().loadClass(type);
             } catch (ClassNotFoundException e) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/48bb7985/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
index 03b05f9..0993f16 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
@@ -149,10 +149,12 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
                 Entitlements.getEntitlementContext().user());
         }
         try {
-            RegisteredType item = RegisteredTypes.validate(mgmt().getTypeRegistry().get(entityId), RegisteredTypeLoadingContexts.spec(Entity.class)).get();
+            RegisteredType item = mgmt().getTypeRegistry().get(entityId);
             if (item==null) {
                 throw WebResourceUtils.notFound("Entity with id '%s' not found", entityId);
             }
+            RegisteredTypes.tryValidate(item, RegisteredTypeLoadingContexts.spec(Entity.class));
+            
             brooklyn().getCatalog().deleteCatalogItem(item.getSymbolicName(), item.getVersion());
         } catch (NoSuchElementException e) {
             throw WebResourceUtils.notFound("Entity with id '%s' not found", entityId);


[02/12] incubator-brooklyn git commit: Forbid all imports from com.google.api.client

Posted by he...@apache.org.
Forbid all imports from com.google.api.client

Rather than com.google.api.client.repackaged.


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/c8ec662f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/c8ec662f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/c8ec662f

Branch: refs/heads/master
Commit: c8ec662fa548d3e4b54ed8fc4b9b53b1c7dc4d98
Parents: 548eaba
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Wed Dec 16 11:27:24 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Thu Dec 17 12:28:01 2015 +0000

----------------------------------------------------------------------
 .../org/apache/brooklyn/core/catalog/internal/CatalogUtils.java | 4 ++--
 .../main/java/org/apache/brooklyn/core/config/Sanitizer.java    | 2 +-
 .../apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java | 3 +--
 .../org/apache/brooklyn/enricher/stock/reducer/Reducer.java     | 2 +-
 parent/pom.xml                                                  | 2 +-
 .../base/test/location/WinRmMachineLocationLiveTest.java        | 3 +--
 .../java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java | 5 ++---
 .../java/org/apache/brooklyn/test/framework/TestSensorImpl.java | 2 +-
 8 files changed, 10 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c8ec662f/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
index ef455c6..c6eb076 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
@@ -50,9 +50,9 @@ import org.apache.brooklyn.util.time.Time;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.api.client.util.Preconditions;
 import com.google.common.annotations.Beta;
 import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
 import com.google.common.base.Stopwatch;
 
 public class CatalogUtils {
@@ -287,7 +287,7 @@ public class CatalogUtils {
     /** @deprecated since it was introduced in 0.9.0; TBD where this should live */
     public static void setDeprecated(ManagementContext mgmt, String symbolicNameAndOptionalVersion, boolean newValue) {
         RegisteredType item = mgmt.getTypeRegistry().get(symbolicNameAndOptionalVersion);
-        Preconditions.checkNotNull(item, "No such item: "+symbolicNameAndOptionalVersion);
+        Preconditions.checkNotNull(item, "No such item: " + symbolicNameAndOptionalVersion);
         setDeprecated(mgmt, item.getSymbolicName(), item.getVersion(), newValue);
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c8ec662f/core/src/main/java/org/apache/brooklyn/core/config/Sanitizer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/Sanitizer.java b/core/src/main/java/org/apache/brooklyn/core/config/Sanitizer.java
index f9b5de5..59ca6af 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/Sanitizer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/Sanitizer.java
@@ -24,9 +24,9 @@ import java.util.Set;
 
 import org.apache.brooklyn.util.core.config.ConfigBag;
 
-import com.google.api.client.util.Lists;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c8ec662f/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
index b36be34..5e3555d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
@@ -34,7 +34,6 @@ import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
@@ -42,7 +41,7 @@ import org.apache.brooklyn.util.text.Identifiers;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.api.client.util.Preconditions;
+import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c8ec662f/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/Reducer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/Reducer.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/Reducer.java
index db3a72d..558d50a 100644
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/Reducer.java
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/Reducer.java
@@ -39,12 +39,12 @@ import org.apache.brooklyn.util.text.StringFunctions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.api.client.util.Lists;
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
 import com.google.common.reflect.TypeToken;
 
 @SuppressWarnings("serial")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c8ec662f/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 2e9a91c..a09d168 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -929,7 +929,7 @@
                             </module>
                             <module name="TreeWalker">
                                 <module name="IllegalImport">
-                                    <property name="illegalPkgs" value="com.google.api.client.repackaged,org.python.google"/>
+                                    <property name="illegalPkgs" value="com.google.api.client,org.python.google"/>
                                 </module>
                             </module>
                         </module>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c8ec662f/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
index ad16403..884da19 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
@@ -35,7 +35,6 @@ import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
@@ -48,7 +47,7 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import com.google.api.client.util.Charsets;
+import com.google.common.base.Charsets;
 import com.google.common.base.Joiner;
 import com.google.common.base.Stopwatch;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c8ec662f/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
index ff7e0d4..2ef13ca 100644
--- a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
+++ b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
@@ -33,7 +33,6 @@ import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.core.test.entity.TestApplicationImpl;
 import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.launcher.BrooklynLauncher;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -61,9 +60,9 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.Test;
 import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
 
-import com.google.api.client.util.Preconditions;
 import com.google.common.base.Charsets;
 import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -339,7 +338,7 @@ public class BrooklynLauncherTest {
     }
 
     private BrooklynLauncher newLauncherForTests(boolean minimal) {
-        Preconditions.checkArgument(launcher==null, "can only be used if no launcher yet");
+        Preconditions.checkArgument(launcher == null, "can only be used if no launcher yet");
         BrooklynLauncher launcher = BrooklynLauncher.newInstance();
         if (minimal)
             launcher.brooklynProperties(LocalManagementContextForTests.builder(true).buildProperties());

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c8ec662f/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java
index f368cf5..d042991 100644
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java
+++ b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java
@@ -18,7 +18,7 @@
  */
 package org.apache.brooklyn.test.framework;
 
-import com.google.api.client.util.Objects;
+import com.google.common.base.Objects;
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;


[10/12] incubator-brooklyn git commit: misc tidy

Posted by he...@apache.org.
misc tidy


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/93ddbd46
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/93ddbd46
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/93ddbd46

Branch: refs/heads/master
Commit: 93ddbd4659150c18644d9271748d66155d9c62fd
Parents: 3900e19
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Dec 17 14:22:41 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Dec 17 14:57:41 2015 +0000

----------------------------------------------------------------------
 .../apache/brooklyn/util/core/flags/ClassCoercionException.java  | 2 ++
 .../org/apache/brooklyn/util/core/flags/MethodCoercions.java     | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/93ddbd46/core/src/main/java/org/apache/brooklyn/util/core/flags/ClassCoercionException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/flags/ClassCoercionException.java b/core/src/main/java/org/apache/brooklyn/util/core/flags/ClassCoercionException.java
index 6257c9e..cea7484 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/flags/ClassCoercionException.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/flags/ClassCoercionException.java
@@ -23,6 +23,8 @@ package org.apache.brooklyn.util.core.flags;
  * class to another.
  */
 public class ClassCoercionException extends ClassCastException {
+    private static final long serialVersionUID = -4616045237993172497L;
+
     public ClassCoercionException() {
         super();
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/93ddbd46/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java b/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java
index 2af5f56..a243581 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/flags/MethodCoercions.java
@@ -117,7 +117,7 @@ public class MethodCoercions {
                 if (parameterTypes.length != numOptionParams) return false;
 
                 for (int paramCount = 0; paramCount < numOptionParams; paramCount++) {
-                    if (!TypeCoercions.tryCoerce(((List) arguments).get(paramCount),
+                    if (!TypeCoercions.tryCoerce(((List<?>) arguments).get(paramCount),
                             TypeToken.of(parameterTypes[paramCount])).isPresentAndNonNull()) return false;
                 }
                 return true;
@@ -141,7 +141,7 @@ public class MethodCoercions {
         if (matchingMethod.isPresent()) {
             Method method = matchingMethod.get();
             try {
-                int numOptionParams = ((List)arguments).size();
+                int numOptionParams = ((List<?>)arguments).size();
                 Object[] coercedArguments = new Object[numOptionParams];
                 for (int paramCount = 0; paramCount < numOptionParams; paramCount++) {
                     Object argument = arguments.get(paramCount);


[09/12] incubator-brooklyn git commit: support isNull on Maybe, including an "absent because null" semantics. simplifies api usage when contexts handle null differently, but a present null is confusing.

Posted by he...@apache.org.
support isNull on Maybe, including an "absent because null" semantics.
simplifies api usage when contexts handle null differently, but a present null is confusing.


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/0b9b2e31
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/0b9b2e31
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/0b9b2e31

Branch: refs/heads/master
Commit: 0b9b2e3172e2f35f27d77d867c316e98eba61290
Parents: 48bb798
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Dec 17 13:44:07 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Dec 17 14:23:02 2015 +0000

----------------------------------------------------------------------
 .../org/apache/brooklyn/util/guava/Maybe.java   | 104 ++++++++++++++++---
 1 file changed, 92 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0b9b2e31/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java b/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java
index 2264362..6b3df49 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java
@@ -71,27 +71,65 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> {
     public static <T> Maybe<T> absent(final Supplier<? extends RuntimeException> exceptionSupplier) {
         return new Absent<T>(Preconditions.checkNotNull(exceptionSupplier));
     }
+
+    /** as {@link #absentNull(String)} but with a generic message */
+    public static <T> Maybe<T> absentNull() {
+        return absentNull("value is null");
+    }
     
-    public static <T> Maybe<T> of(@Nullable T value) {
+    /** like {@link #absent(String)} but {@link #isNull()} will return true on the result. */
+    public static <T> Maybe<T> absentNull(String message) {
+        return new AbsentNull<T>(message);
+    }
+    
+    /** Creates a new Maybe object which is present. 
+     * The argument may be null and the object still present, 
+     * which may be confusing in some contexts
+     * (traditional {@link Optional} usages) but
+     * may be natural in others (where null is a valid value, distinguished from no value set). 
+     * See also {@link #ofDisallowingNull(Object)}. */
+    public static <T> Maybe<T> ofAllowingNull(@Nullable T value) {
         return new Present<T>(value);
     }
 
-    /** creates an instance wrapping a {@link SoftReference}, so it might go absent later on */
-    public static <T> Maybe<T> soft(T value) {
+    /** Creates a new Maybe object which is present if and only if the argument is not null.
+     * If the argument is null, then an {@link #absentNull()} is returned,
+     * on which {@link #isNull()} will be true. */
+    public static <T> Maybe<T> ofDisallowingNull(@Nullable T value) {
+        if (value==null) return absentNull();
+        return new Present<T>(value);
+    }
+
+    /** Creates a new Maybe object.
+     * Currently this uses {@link #ofAllowingNull(Object)} semantics,
+     * but it is recommended to use that method for clarity 
+     * if the argument might be null. */
+    // note: Optional throws if null is supplied; we might want to do the same here
+    public static <T> Maybe<T> of(@Nullable T value) {
+        return ofAllowingNull(value);
+    }
+
+    /** Creates a new Maybe object using {@link #ofDisallowingNull(Object)} semantics. 
+     * It is recommended to use that method for clarity. 
+     * This method is provided for consistency with {@link Optional#fromNullable(Object)}. */
+    public static <T> Maybe<T> fromNullable(@Nullable T value) {
+        return ofDisallowingNull(value);
+    }
+    
+    /** creates an instance wrapping a {@link SoftReference}, so it might go absent later on.
+     * if null is supplied the result is a present null. */
+    public static <T> Maybe<T> soft(@Nonnull T value) {
         return softThen(value, null);
     }
-    /** creates an instance wrapping a {@link SoftReference}, using the second item given if lost */
+    /** creates an instance wrapping a {@link SoftReference}, using the second item given 
+     * if the first argument is dereferenced.
+     * however if the first argument is null, this is a permanent present null,
+     * as {@link #of(Object)} with null. */
     public static <T> Maybe<T> softThen(T value, Maybe<T> ifEmpty) {
         if (value==null) return of((T)null);
         return new SoftlyPresent<T>(value).usingAfterExpiry(ifEmpty);
     }
 
-    /** like {@link Optional#fromNullable(Object)}, returns absent if the argument is null */
-    public static <T> Maybe<T> fromNullable(@Nullable T value) {
-        if (value==null) return absent();
-        return new Present<T>(value);
-    }
-
     public static <T> Maybe<T> of(final Optional<T> value) {
         if (value.isPresent()) return new AbstractPresent<T>() {
             private static final long serialVersionUID = -5735268814211401356L;
@@ -99,6 +137,11 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> {
             public T get() {
                 return value.get();
             }
+            @Override
+            public boolean isNull() {
+                // should always be false as per Optional contract
+                return get()==null;
+            }
         };
         return absent();
     }
@@ -110,6 +153,10 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> {
             public T get() {
                 return value.get();
             }
+            @Override
+            public boolean isNull() {
+                return get()==null;
+            }
         };
     }
     
@@ -125,11 +172,16 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> {
         return !isPresent(); 
     }
     public boolean isAbsentOrNull() {
-        return !isPresentAndNonNull();
+        return isAbsent() || isNull();
     }
     public boolean isPresentAndNonNull() {
-        return isPresent() && get()!=null;
+        return isPresent() && !isNull();
     }
+    /** Whether the value is null, if present, or
+     * if it was specified as absent because it was null,
+     * e.g. using {@link #fromNullable(Object)}.
+     */
+    public abstract boolean isNull();
     
     public T or(T nextValue) {
         if (isPresent()) return get();
@@ -162,6 +214,10 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> {
             public V get() {
                 return f.apply(Maybe.this.get());
             }
+            @Override
+            public boolean isNull() {
+                return get()==null;
+            }
         };
         return absent();
     }
@@ -209,6 +265,10 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> {
             return false;
         }
         @Override
+        public boolean isNull() {
+            return false;
+        }
+        @Override
         public T get() {
             throw getException();
         }
@@ -217,6 +277,17 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> {
         }
     }
 
+    public static class AbsentNull<T> extends Absent<T> {
+        private static final long serialVersionUID = 2422627709567857268L;
+        public AbsentNull(String message) {
+            super(new IllegalStateExceptionSupplier(message));
+        }
+        @Override
+        public boolean isNull() {
+            return true;
+        }
+    }
+    
     public static abstract class AbstractPresent<T> extends Maybe<T> {
         private static final long serialVersionUID = -2266743425340870492L;
         protected AbstractPresent() {
@@ -237,6 +308,10 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> {
         public T get() {
             return value;
         }
+        @Override
+        public boolean isNull() {
+            return value==null;
+        }
     }
 
     public static class SoftlyPresent<T> extends Maybe<T> {
@@ -264,6 +339,11 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> {
         public boolean isPresent() {
             return value.get()!=null || (defaultValue!=null && defaultValue.isPresent()); 
         }
+        @Override
+        public boolean isNull() {
+            // null not allowed here
+            return false;
+        }
         public Maybe<T> solidify() {
             return Maybe.fromNullable(value.get());
         }


[04/12] incubator-brooklyn git commit: Test loading downstream-project into catalogue

Posted by he...@apache.org.
Test loading downstream-project into catalogue

Acceptance test that auto-checks whether projects using
downstream-parent will work when loaded from bundle libraries rather
than the classpath.


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/816f6179
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/816f6179
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/816f6179

Branch: refs/heads/master
Commit: 816f6179dd1256a1019dbf961bca68120fe4c6a2
Parents: ac9ea5d
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Thu Dec 17 12:26:20 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Thu Dec 17 12:28:04 2015 +0000

----------------------------------------------------------------------
 usage/qa/pom.xml                                |  17 ++-
 .../downstreamparent/DownstreamParentTest.java  |  64 ++++++++++
 .../test/projects/downstream-parent-test/README |   5 +
 .../projects/downstream-parent-test/pom.xml     | 120 +++++++++++++++++++
 .../src/main/java/com/example/HelloEntity.java  |  26 ++++
 .../main/java/com/example/HelloEntityImpl.java  |  31 +++++
 .../src/main/resources/blueprint.yaml           |  19 +++
 .../src/main/resources/catalog.bom              |  33 +++++
 8 files changed, 314 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/816f6179/usage/qa/pom.xml
----------------------------------------------------------------------
diff --git a/usage/qa/pom.xml b/usage/qa/pom.xml
index fd0266d..35ba6ec 100644
--- a/usage/qa/pom.xml
+++ b/usage/qa/pom.xml
@@ -83,6 +83,12 @@
             <classifier>tests</classifier>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-verifier</artifactId>
+            <version>1.5</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -102,7 +108,16 @@
                         </execution>
                     </executions>
             </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes combine.children="append">
+                        <exclude>src/test/projects/downstream-parent-test/README</exclude>
+                    </excludes>
+                  </configuration>
+            </plugin>
         </plugins>
     </build> 
 </project>
-
+v

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/816f6179/usage/qa/src/test/java/org/apache/brooklyn/qa/downstreamparent/DownstreamParentTest.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/downstreamparent/DownstreamParentTest.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/downstreamparent/DownstreamParentTest.java
new file mode 100644
index 0000000..33c4c42
--- /dev/null
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/downstreamparent/DownstreamParentTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.qa.downstreamparent;
+
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.brooklyn.util.net.Networking;
+import org.apache.maven.it.Verifier;
+import org.apache.maven.shared.utils.io.FileUtils;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+public class DownstreamParentTest {
+
+    private static final String PROJECTS_DIR = "src/test/projects";
+    private static final String WORK_DIR = "target/ut/";
+
+    /**
+     * Asserts that a trivial project using brooklyn-downstream-parent can be
+     * loaded into Brooklyn's catalogue and its entities deployed.
+     */
+    @Test(groups = "Integration")
+    public void testDownstreamProjectsCanBeLoadedIntoBrooklynCatalogByDefault() throws Exception {
+        int port = Networking.nextAvailablePort(57000);
+        File dir = getBasedir("downstream-parent-test");
+        Verifier verifier = new Verifier(dir.getAbsolutePath());
+        verifier.setMavenDebug(true);
+        verifier.executeGoal("post-integration-test", ImmutableMap.of(
+                "bindPort", String.valueOf(port)));
+        verifier.verifyErrorFreeLog();
+        verifier.verifyTextInLog("Hello from the init method of the HelloEntity");
+    }
+
+    /** Replicates the behaviour of getBasedir in JUnit's TestResources class */
+    public File getBasedir(String project) throws IOException {
+        File src = (new File(PROJECTS_DIR, project)).getCanonicalFile();
+        assertTrue(src.isDirectory(), "Test project directory does not exist: " + src.getPath());
+        File basedir = (new File(WORK_DIR, getClass().getSimpleName() + "_" + project)).getCanonicalFile();
+        FileUtils.deleteDirectory(basedir);
+        assertTrue(basedir.mkdirs(), "Test project working directory created");
+        FileUtils.copyDirectoryStructure(src, basedir);
+        return basedir;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/816f6179/usage/qa/src/test/projects/downstream-parent-test/README
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/projects/downstream-parent-test/README b/usage/qa/src/test/projects/downstream-parent-test/README
new file mode 100644
index 0000000..3f2f574
--- /dev/null
+++ b/usage/qa/src/test/projects/downstream-parent-test/README
@@ -0,0 +1,5 @@
+A successful build of this project (`mvn clean verify`) means that projects that
+use brooklyn-downstream-parent can be loaded into Brooklyn's catalogue by default.
+
+If the build fails there is almost certainly something wrong with the parent and
+the wider consumers of Brooklyn will probably face similar problems.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/816f6179/usage/qa/src/test/projects/downstream-parent-test/pom.xml
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/projects/downstream-parent-test/pom.xml b/usage/qa/src/test/projects/downstream-parent-test/pom.xml
new file mode 100644
index 0000000..7e3c0e0
--- /dev/null
+++ b/usage/qa/src/test/projects/downstream-parent-test/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.brooklyn.downstream-parent-test</groupId>
+    <artifactId>catalogue-load-test</artifactId>
+    <version>0.9.0-SNAPSHOT</version> <!-- BROOKLYN_VERSION -->
+    <packaging>jar</packaging>
+
+    <name>Downstream parent catalogue load test test</name>
+
+    <parent>
+        <groupId>org.apache.brooklyn</groupId>
+        <artifactId>brooklyn-downstream-parent</artifactId>
+        <version>0.9.0-SNAPSHOT</version> <!-- BROOKLYN_VERSION -->
+    </parent>
+
+    <repositories>
+        <repository>
+            <id>apache-snapshots</id>
+            <url>https://repository.apache.org/content/repositories/snapshots/</url>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>sonatype-nexus-snapshots</id>
+            <name>Sonatype Nexus Snapshots</name>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases>
+                <enabled>false</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-all</artifactId>
+            <version>0.9.0-SNAPSHOT</version> <!-- BROOKLYN_VERSION -->
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>${basedir}/src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>io.brooklyn.maven</groupId>
+                <artifactId>brooklyn-maven-plugin</artifactId>
+                <version>0.3.0-SNAPSHOT</version>
+                <executions>
+                    <execution>
+                        <id>Run and deploy Brooklyn</id>
+                        <goals>
+                            <goal>start-server</goal>
+                        </goals>
+                        <configuration>
+                            <bindPort>${bindPort}</bindPort>
+                            <!--
+                            Make sure that the test entities aren't already on the classpath.
+                            -->
+                            <outputDirOnClasspath>false</outputDirOnClasspath>
+                            <arguments>
+                                <argument>--catalogInitial</argument>
+                                <argument>${project.build.outputDirectory}/catalog.bom</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>Deploy entity from catalogue</id>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>deploy</goal>
+                        </goals>
+                        <configuration>
+                            <blueprint>${project.build.outputDirectory}/blueprint.yaml</blueprint>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>Stop Brooklyn</id>
+                        <goals>
+                            <goal>stop-server</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/816f6179/usage/qa/src/test/projects/downstream-parent-test/src/main/java/com/example/HelloEntity.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/projects/downstream-parent-test/src/main/java/com/example/HelloEntity.java b/usage/qa/src/test/projects/downstream-parent-test/src/main/java/com/example/HelloEntity.java
new file mode 100644
index 0000000..242708b
--- /dev/null
+++ b/usage/qa/src/test/projects/downstream-parent-test/src/main/java/com/example/HelloEntity.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.example;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.ImplementedBy;
+
+@ImplementedBy(HelloEntityImpl.class)
+public interface HelloEntity extends Entity {
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/816f6179/usage/qa/src/test/projects/downstream-parent-test/src/main/java/com/example/HelloEntityImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/projects/downstream-parent-test/src/main/java/com/example/HelloEntityImpl.java b/usage/qa/src/test/projects/downstream-parent-test/src/main/java/com/example/HelloEntityImpl.java
new file mode 100644
index 0000000..76d9ffd
--- /dev/null
+++ b/usage/qa/src/test/projects/downstream-parent-test/src/main/java/com/example/HelloEntityImpl.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.example;
+
+import org.apache.brooklyn.core.entity.AbstractEntity;
+
+public class HelloEntityImpl extends AbstractEntity implements HelloEntity {
+
+    @Override
+    public void init() {
+        super.init();
+        System.out.println("Hello from the init method of the HelloEntity");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/816f6179/usage/qa/src/test/projects/downstream-parent-test/src/main/resources/blueprint.yaml
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/projects/downstream-parent-test/src/main/resources/blueprint.yaml b/usage/qa/src/test/projects/downstream-parent-test/src/main/resources/blueprint.yaml
new file mode 100644
index 0000000..76cc82e
--- /dev/null
+++ b/usage/qa/src/test/projects/downstream-parent-test/src/main/resources/blueprint.yaml
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+services:
+- type: downstream-project

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/816f6179/usage/qa/src/test/projects/downstream-parent-test/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/projects/downstream-parent-test/src/main/resources/catalog.bom b/usage/qa/src/test/projects/downstream-parent-test/src/main/resources/catalog.bom
new file mode 100644
index 0000000..c168c72
--- /dev/null
+++ b/usage/qa/src/test/projects/downstream-parent-test/src/main/resources/catalog.bom
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+brooklyn.catalog:
+  version: 1.0
+
+  brooklyn.libraries:
+  - "file://${project.build.directory}/${project.build.finalName}.${project.packaging}"
+
+  items:
+
+  - id: downstream-project
+    name: Downstream project
+    itemType: template
+    description: |
+      A downstream project
+    item:
+      services:
+      - type: com.example.HelloEntity


[12/12] incubator-brooklyn git commit: This closes #1073

Posted by he...@apache.org.
This closes #1073

Conflicts:
	core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java -- imports only


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/e3b0389f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/e3b0389f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/e3b0389f

Branch: refs/heads/master
Commit: e3b0389ff8d3457e281cd4443ed604f6cf8786b6
Parents: 5388dbe 93ddbd4
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Dec 21 11:49:06 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Dec 21 11:49:06 2015 +0000

----------------------------------------------------------------------
 .../api/typereg/BrooklynTypeRegistry.java       |  30 ++-
 .../brooklyn/api/typereg/RegisteredType.java    |   8 +-
 .../catalog/internal/CatalogItemComparator.java |  96 +--------
 .../core/catalog/internal/CatalogUtils.java     |  14 +-
 .../core/location/BasicLocationRegistry.java    |   2 +-
 .../typereg/AbstractTypePlanTransformer.java    |  15 +-
 .../core/typereg/BasicBrooklynTypeRegistry.java | 125 ++++++++++--
 .../core/typereg/BasicRegisteredType.java       |  34 +++-
 .../core/typereg/RegisteredTypePredicates.java  |  89 ++++++++-
 .../brooklyn/core/typereg/RegisteredTypes.java  | 162 +++++++++++----
 .../util/core/flags/ClassCoercionException.java |   2 +
 .../util/core/flags/MethodCoercions.java        |   4 +-
 .../internal/CatalogItemComparatorTest.java     |  12 +-
 .../typereg/BasicBrooklynTypeRegistryTest.java  | 186 +++++++++++++++++
 .../typereg/RegisteredTypePredicatesTest.java   |  19 +-
 .../BrooklynEntityDecorationResolver.java       |   8 +-
 .../catalog/CatalogYamlLocationTest.java        |   4 +-
 .../catalog/CatalogYamlVersioningTest.java      |  14 +-
 .../brooklyn/test/lite/CampYamlLiteTest.java    |   4 +-
 .../rest/resources/ApplicationResource.java     |  24 ++-
 .../rest/resources/CatalogResource.java         |  16 +-
 .../util/collections/CollectionFunctionals.java |  23 ++-
 .../org/apache/brooklyn/util/guava/Maybe.java   | 104 ++++++++--
 .../brooklyn/util/text/ComparableVersion.java   |   5 +-
 .../util/text/NaturalOrderComparator.java       |  16 +-
 .../org/apache/brooklyn/util/text/Strings.java  |  26 ---
 .../brooklyn/util/text/VersionComparator.java   | 199 +++++++++++++++++++
 .../collections/CollectionFunctionalsTest.java  |  24 +++
 .../util/text/ComparableVersionTest.java        |  49 +++--
 .../util/text/NaturalOrderComparatorTest.java   |  61 +++---
 .../apache/brooklyn/util/text/StringsTest.java  |   4 -
 .../util/text/VersionComparatorTest.java        | 102 ++++++++++
 32 files changed, 1144 insertions(+), 337 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e3b0389f/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e3b0389f/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e3b0389f/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
index 5e3555d,1b47648..5d4bbf6
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
@@@ -41,7 -44,8 +44,8 @@@ import org.apache.brooklyn.util.text.Id
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
 -import com.google.api.client.util.Preconditions;
+ import com.google.common.annotations.Beta;
 +import com.google.common.base.Preconditions;
  import com.google.common.base.Predicate;
  import com.google.common.base.Predicates;
  import com.google.common.collect.Iterables;


[05/12] incubator-brooklyn git commit: introduce VersionComparator and use it where appropriate

Posted by he...@apache.org.
introduce VersionComparator and use it where appropriate

in prep for RegisteredType best version support


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/1265796f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/1265796f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/1265796f

Branch: refs/heads/master
Commit: 1265796fb1673b15586c02e5bbc7aede2e37882e
Parents: 3584f5b
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Nov 26 08:45:19 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Dec 17 12:36:15 2015 +0000

----------------------------------------------------------------------
 .../catalog/internal/CatalogItemComparator.java |  96 +--------
 .../brooklyn/util/text/ComparableVersion.java   |   5 +-
 .../util/text/NaturalOrderComparator.java       |  16 +-
 .../org/apache/brooklyn/util/text/Strings.java  |  26 ---
 .../brooklyn/util/text/VersionComparator.java   | 199 +++++++++++++++++++
 .../util/text/ComparableVersionTest.java        |  49 +++--
 .../util/text/NaturalOrderComparatorTest.java   |  61 +++---
 .../apache/brooklyn/util/text/StringsTest.java  |   4 -
 .../util/text/VersionComparatorTest.java        | 102 ++++++++++
 9 files changed, 386 insertions(+), 172 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1265796f/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparator.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparator.java
index dc41457..abd4d08 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparator.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemComparator.java
@@ -18,13 +18,11 @@
  */
 package org.apache.brooklyn.core.catalog.internal;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
 
 import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.util.text.NaturalOrderComparator;
+import org.apache.brooklyn.util.text.VersionComparator;
 
 /**
  * Largest version first order.
@@ -33,7 +31,6 @@ import org.apache.brooklyn.util.text.NaturalOrderComparator;
  * and if equal puts larger versions first, snapshots at the back.
  */
 public class CatalogItemComparator<T,SpecT> implements Comparator<CatalogItem<T, SpecT>> {
-    private static final String SNAPSHOT = "SNAPSHOT";
 
     public static final CatalogItemComparator<?, ?> INSTANCE = new CatalogItemComparator<Object, Object>();
 
@@ -48,95 +45,8 @@ public class CatalogItemComparator<T,SpecT> implements Comparator<CatalogItem<T,
         if (symbolicNameComparison != 0) {
             return symbolicNameComparison;
         } else {
-            String v1 = o1.getVersion();
-            String v2 = o2.getVersion();
-
-            boolean isV1Snapshot = v1.toUpperCase().contains(SNAPSHOT);
-            boolean isV2Snapshot = v2.toUpperCase().contains(SNAPSHOT);
-            if (isV1Snapshot == isV2Snapshot) {
-                String[] v1Parts = split(v1);
-                String[] v2Parts = split(v2);
-                return -compare(v1Parts, v2Parts);
-            } else if (isV1Snapshot) {
-                return 1;
-            } else {
-                return -1;
-            }
-        }
-    }
-
-    private String[] split(String v) {
-        Collection<String> parts = new ArrayList<String>();
-        int startPos = 0;
-        int delimPos;
-        while ((delimPos = v.indexOf('.', startPos)) != -1) {
-            String part = v.substring(startPos, delimPos);
-            if (parse(part) != -1) {
-                parts.add(part);
-            } else {
-                break;
-            }
-            startPos = delimPos+1;
-        }
-        String remaining = v.substring(startPos);
-        parts.addAll(Arrays.asList(remaining.split("[^\\d]", 2)));
-        return parts.toArray(new String[parts.size()]);
-    }
-
-    private int compare(String[] v1Parts, String[] v2Parts) {
-        int len = Math.max(v1Parts.length, v2Parts.length);
-        for (int i = 0; i < len; i++) {
-            if (i == v1Parts.length) {
-                return isNumber(v2Parts[i]) ? -1 : 1;
-            }
-            if (i == v2Parts.length) {
-                return isNumber(v1Parts[i]) ? 1 : -1;
-            }
-
-            String p1 = v1Parts[i];
-            String p2 = v2Parts[i];
-            int n1 = parse(p1);
-            int n2 = parse(p2);
-            if (n1 != -1 && n2 != -1) {
-                if (n1 != n2) {
-                    return compare(n1, n2);
-                }
-            } else if (n1 == -1 && n2 != -1) {
-                return -1;
-            } else if (n1 != -1 && n2 == -1) {
-                return 1;
-            } else {
-                int cmp = NaturalOrderComparator.INSTANCE.compare(p1, p2);
-                if (cmp < 0) {
-                    return -1;
-                } else if (cmp > 0) {
-                    return 1;
-                }
-            }
+            return Collections.reverseOrder(VersionComparator.INSTANCE).compare(o1.getVersion(), o2.getVersion());
         }
-        return 0;
     }
 
-    private boolean isNumber(String v) {
-        return parse(v) != -1;
-    }
-
-    //Replace with Integer.compare in J7
-    private int compare(int n1, int n2) {
-        if (n1 == n2) {
-            return 0;
-        } else if (n1 < n2) {
-            return -1;
-        } else {
-            return 1;
-        }
-    }
-
-    private int parse(String p) {
-        try {
-            return Integer.parseInt(p);
-        } catch (NumberFormatException e) {
-            return -1;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1265796f/utils/common/src/main/java/org/apache/brooklyn/util/text/ComparableVersion.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/ComparableVersion.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/ComparableVersion.java
index 9065603..339f1ca 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/ComparableVersion.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/ComparableVersion.java
@@ -19,7 +19,8 @@
 package org.apache.brooklyn.util.text;
 
 
-/** takes a version string, and compares to other versions, using {@link NaturalOrderComparator} */
+/** takes a version string, and compares to other versions, 
+ * using {@link VersionComparator} */
 public class ComparableVersion implements Comparable<String> {
 
     public final String version;
@@ -29,7 +30,7 @@ public class ComparableVersion implements Comparable<String> {
     }
 
     public int compareTo(String target) {
-        return new NaturalOrderComparator().compare(version, target);
+        return VersionComparator.INSTANCE.compare(version, target);
     }
     
     public boolean isGreaterThanOrEqualTo(String target) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1265796f/utils/common/src/main/java/org/apache/brooklyn/util/text/NaturalOrderComparator.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/NaturalOrderComparator.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/NaturalOrderComparator.java
index be53acc..d76244a 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/NaturalOrderComparator.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/NaturalOrderComparator.java
@@ -50,12 +50,15 @@ package org.apache.brooklyn.util.text;
 
 import java.util.Comparator;
 
-/** comparator which takes two strings and puts them in an order with special rules for numbers to be placed in numeric order;
+/** comparator which takes two strings and puts them in an order 
+ * with special rules for numbers (whole number) to be placed in numeric order;
  * e.g. "10">"9", including when those numbers occur in the midst of equal text; e.g. "a10" > "a9";
  * but not if the text differs; e.g. "a10" < "b9"
  * <p>
  * class is thread-safe. nulls not supported. (to support nulls, wrap in guava:
  * <code>Ordering.from(NaturalOrderComparator.INSTANCE).nullsFirst()</code>)
+ * <p>
+ * NOTE: decimals are treated like a word-split, not a decimal point, i.e. 1.9 < 1.10 
  */
 public class NaturalOrderComparator implements Comparator<String> {
     
@@ -136,6 +139,17 @@ public class NaturalOrderComparator implements Comparator<String> {
                 if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0) {
                     return result;
                 }
+            } else if ((Character.isDigit(ca) || nza>0) && (Character.isDigit(cb) || nzb>0)) {
+                // both sides are numbers, but at least one is a sequence of zeros
+                if (nza==0) {
+                    // b=0, a>0
+                    return 1;
+                }
+                if (nzb==0) {
+                    // inverse
+                    return -1;
+                }
+                // both sides were zero, continue to next check below
             }
 
             if (ca == 0 && cb == 0) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1265796f/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
index 626a312..d092abb 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
@@ -138,19 +138,6 @@ public class Strings {
         }
     }
 
-    /** removes the first suffix in the list which is present at the end of string
-     * and returns that string; ignores subsequent suffixes if a matching one is found;
-     * returns the original string if no suffixes are at the end
-     * @deprecated since 0.7.0 use {@link #removeFromEnd(String, String)} or {@link #removeAllFromEnd(String, String...)}
-     */
-    @Deprecated
-    public static String removeFromEnd(String string, String ...suffixes) {
-        if (isEmpty(string)) return string;
-        for (String suffix : suffixes)
-            if (suffix!=null && string.endsWith(suffix)) return string.substring(0, string.length() - suffix.length());
-        return string;
-    }
-
     /**
      * As removeFromEnd, but repeats until all such suffixes are gone
      */
@@ -184,19 +171,6 @@ public class Strings {
         }
     }
 
-    /** removes the first prefix in the list which is present at the start of string
-     * and returns that string; ignores subsequent prefixes if a matching one is found;
-     * returns the original string if no prefixes match
-     * @deprecated since 0.7.0 use {@link #removeFromStart(String, String)}
-     */
-    @Deprecated
-    public static String removeFromStart(String string, String ...prefixes) {
-        if (isEmpty(string)) return string;
-        for (String prefix : prefixes)
-            if (prefix!=null && string.startsWith(prefix)) return string.substring(prefix.length());
-        return string;
-    }
-
     /**
      * As {@link #removeFromStart(String, String)}, repeating until all such prefixes are gone.
      */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1265796f/utils/common/src/main/java/org/apache/brooklyn/util/text/VersionComparator.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/VersionComparator.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/VersionComparator.java
new file mode 100644
index 0000000..94553b0
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/VersionComparator.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.util.text;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+
+import org.apache.brooklyn.util.text.NaturalOrderComparator;
+import org.apache.brooklyn.util.text.Strings;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * {@link Comparator} for version strings.
+ * <p>
+ * SNAPSHOT items always lowest rated, 
+ * then splitting on dots,
+ * using natural order comparator (so "9" < "10" and "4u8" < "4u20"),
+ * and preferring segments without qualifiers ("4" > "4beta").
+ * <p>
+ * Impossible to follow semantics for all versioning schemes but 
+ * does the obvious right thing for normal schemes
+ * and pretty well in fringe cases.
+ * <p>
+ * See test case for lots of examples.
+ */
+public class VersionComparator implements Comparator<String> {
+    
+    private static final String SNAPSHOT = "SNAPSHOT";
+
+    public static final VersionComparator INSTANCE = new VersionComparator();
+
+    public static VersionComparator getInstance() {
+        return INSTANCE;
+    }
+
+    @Override
+    public int compare(String v1, String v2) {
+        if (v1==null && v2==null) return 0;
+        if (v1==null) return -1;
+        if (v2==null) return 1;
+        
+        boolean isV1Snapshot = v1.toUpperCase().contains(SNAPSHOT);
+        boolean isV2Snapshot = v2.toUpperCase().contains(SNAPSHOT);
+        if (isV1Snapshot == isV2Snapshot) {
+            // if snapshot status is the same, look at dot-split parts first
+            return compareDotSplitParts(splitOnDot(v1), splitOnDot(v2));
+        } else {
+            // snapshot goes first
+            return isV1Snapshot ? -1 : 1;
+        }
+    }
+
+    @VisibleForTesting
+    static String[] splitOnDot(String v) {
+        return v.split("(?<=\\.)|(?=\\.)");
+    }
+    
+    private int compareDotSplitParts(String[] v1Parts, String[] v2Parts) {
+        for (int i = 0; ; i++) {
+            if (i >= v1Parts.length && i >= v2Parts.length) {
+                // end of both
+                return 0;
+            }
+            if (i == v1Parts.length) {
+                // sequence depends whether the extra part *starts with* a number
+                // ie
+                //                   2.0 < 2.0.0
+                // and
+                //   2.0.qualifier < 2.0 < 2.0.0qualifier < 2.0.0-qualifier < 2.0.0.qualifier < 2.0.0 < 2.0.9-qualifier
+                return isNumberInFirstCharPossiblyAfterADot(v2Parts, i) ? -1 : 1;
+            }
+            if (i == v2Parts.length) {
+                // as above but inverted
+                return isNumberInFirstCharPossiblyAfterADot(v1Parts, i) ? 1 : -1;
+            }
+            // not at end; compare this dot split part
+            
+            int result = compareDotSplitPart(v1Parts[i], v2Parts[i]);
+            if (result!=0) return result;
+        }
+    }
+    
+    private int compareDotSplitPart(String v1, String v2) {
+        String[] v1Parts = splitOnNonWordChar(v1);
+        String[] v2Parts = splitOnNonWordChar(v2);
+        
+        for (int i = 0; ; i++) {
+            if (i >= v1Parts.length && i >= v2Parts.length) {
+                // end of both
+                return 0;
+            }
+            if (i == v1Parts.length) {
+                // shorter set always wins here; i.e.
+                // 1-qualifier < 1
+                return 1;
+            }
+            if (i == v2Parts.length) {
+                // as above but inverted
+                return -1;
+            }
+            // not at end; compare this dot split part
+            
+            String v1p = v1Parts[i];
+            String v2p = v2Parts[i];
+            
+            if (v1p.equals(v2p)) continue;
+            
+            if (isNumberInFirstChar(v1p) || isNumberInFirstChar(v2p)) {
+                // something starting with a number is higher than something not
+                if (!isNumberInFirstChar(v1p)) return -1;
+                if (!isNumberInFirstChar(v2p)) return 1;
+                
+                // both start with numbers; can use natural order comparison *unless*
+                // one is purely a number AND the other *begins* with that number,
+                // followed by non-digit chars, in which case prefer the pure number
+                // ie:
+                //           1beta < 1
+                // but note
+                //            1 < 2beta < 11beta
+                if (isNumber(v1p) || isNumber(v2p)) {
+                    if (!isNumber(v1p)) {
+                        if (v1p.startsWith(v2p)) {
+                            if (!isNumberInFirstChar(Strings.removeFromStart(v1p, v2p))) {
+                                // v2 is a number, and v1 is the same followed by non-numbers
+                                return -1;
+                            }
+                        }
+                    }
+                    if (!isNumber(v2p)) {
+                        // as above but inverted
+                        if (v2p.startsWith(v1p)) {
+                            if (!isNumberInFirstChar(Strings.removeFromStart(v2p, v1p))) {
+                                return 1;
+                            }
+                        }
+                    }
+                    // both numbers, skip to natural order comparison
+                }
+            }
+            
+            // otherwise it is in-order
+            int result = NaturalOrderComparator.INSTANCE.compare(v1p, v2p);
+            if (result!=0) return result;
+        }
+    }
+
+    @VisibleForTesting
+    static String[] splitOnNonWordChar(String v) {
+        Collection<String> parts = new ArrayList<String>();
+        String remaining = v;
+        
+        // use lookahead to split on all non-letter non-numbers, putting them into their own buckets 
+        parts.addAll(Arrays.asList(remaining.split("(?<=[^0-9\\p{L}])|(?=[^0-9\\p{L}])")));
+        return parts.toArray(new String[parts.size()]);
+    }
+
+    @VisibleForTesting
+    static boolean isNumberInFirstCharPossiblyAfterADot(String[] parts, int i) {
+        if (parts==null || parts.length<=i) return false;
+        if (isNumberInFirstChar(parts[i])) return true;
+        if (".".equals(parts[i])) {
+            if (parts.length>i+1)
+                if (isNumberInFirstChar(parts[i+1])) 
+                    return true;
+        }
+        return false;
+    }
+
+    @VisibleForTesting
+    static boolean isNumberInFirstChar(String v) {
+        if (v==null || v.length()==0) return false;
+        return Character.isDigit(v.charAt(0));
+    }
+    
+    @VisibleForTesting
+    static boolean isNumber(String v) {
+        if (v==null || v.length()==0) return false;
+        return v.matches("[\\d]+");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1265796f/utils/common/src/test/java/org/apache/brooklyn/util/text/ComparableVersionTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/text/ComparableVersionTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/text/ComparableVersionTest.java
index 16b07b8..a730ade 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/text/ComparableVersionTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/text/ComparableVersionTest.java
@@ -18,37 +18,46 @@
  */
 package org.apache.brooklyn.util.text;
 
-import org.apache.brooklyn.util.text.NaturalOrderComparator;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 public class ComparableVersionTest {
 
-    public static final NaturalOrderComparator noc = new NaturalOrderComparator();
-    
+    ComparableVersion v = new ComparableVersion("10.5.8");
+    ComparableVersion v_rc2 = new ComparableVersion("10.5.8-rc2");
+
     @Test
     public void testBasicOnes() {
-        Assert.assertEquals(0, noc.compare("a", "a"));
-        Assert.assertTrue(noc.compare("a", "b") < 0);
-        Assert.assertTrue(noc.compare("b", "a") > 0);
+        Assert.assertTrue(v.isGreaterThanAndNotEqualTo("10.5"));
+        Assert.assertTrue(v.isGreaterThanOrEqualTo("10.5.8"));
+        Assert.assertFalse(v.isGreaterThanAndNotEqualTo("10.5.8"));
+
+        Assert.assertTrue(v.isLessThanAndNotEqualTo("10.6"));
+        Assert.assertTrue(v.isLessThanOrEqualTo("10.5.8"));
+        Assert.assertFalse(v.isLessThanAndNotEqualTo("10.5.8"));
+        
+        Assert.assertTrue(v.isLessThanAndNotEqualTo("10.5.8.1"));
         
-        Assert.assertTrue(noc.compare("9", "10") < 0);
-        Assert.assertTrue(noc.compare("10", "9") > 0);
+        Assert.assertTrue(v_rc2.isLessThanAndNotEqualTo("10.5.8-rc3")) ;
+        Assert.assertTrue(v_rc2.isGreaterThanAndNotEqualTo("10.5.8-rc1"));
         
-        Assert.assertTrue(noc.compare("b10", "a9") > 0);
-        Assert.assertTrue(noc.compare("b9", "a10") > 0);
+        Assert.assertTrue(v_rc2.isGreaterThanAndNotEqualTo("10.5.8-beta1")==v_rc2.isGreaterThanAndNotEqualTo("10.5.8-beta3"));
         
-        Assert.assertTrue(noc.compare(" 9", "10") < 0);
-        Assert.assertTrue(noc.compare("10", " 9") > 0);
+        Assert.assertTrue(v.isInRange("[10.5,10.6)"));
+        Assert.assertFalse(v.isInRange("[10.5,10.5.8)"));
+        Assert.assertTrue(v.isInRange("[10.5,)"));
+        Assert.assertTrue(v.isInRange("[9,)"));
+        Assert.assertFalse(v.isInRange("(10.5.8,)"));
+        Assert.assertFalse(v.isInRange("[10.6,)"));
+        Assert.assertTrue(v.isInRange("[,11)"));
+        Assert.assertTrue(v.isInRange("[,]"));
     }
 
-    @Test
-    public void testVersionNumbers() {
-        Assert.assertEquals(0, noc.compare("10.5.8", "10.5.8"));
-        Assert.assertTrue(noc.compare("10.5", "9.9") > 0);
-        Assert.assertTrue(noc.compare("10.5.1", "10.5") > 0);
-        Assert.assertTrue(noc.compare("10.5.1", "10.6") < 0);
-        Assert.assertTrue(noc.compare("10.5.1-1", "10.5.1-0") > 0);
-    }
+    @Test(expectedExceptions={IllegalArgumentException.class})
+    public void testError1() { v.isInRange("10.5"); }
+    @Test(expectedExceptions={IllegalArgumentException.class})
+    public void testError2() { v.isInRange("[10.5"); }
+    @Test(expectedExceptions={IllegalArgumentException.class})
+    public void testError3() { v.isInRange("[10.5]"); }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1265796f/utils/common/src/test/java/org/apache/brooklyn/util/text/NaturalOrderComparatorTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/text/NaturalOrderComparatorTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/text/NaturalOrderComparatorTest.java
index 3e99e58..3113c8e 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/text/NaturalOrderComparatorTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/text/NaturalOrderComparatorTest.java
@@ -31,38 +31,47 @@ public class NaturalOrderComparatorTest {
     ComparableVersion v_rc2 = new ComparableVersion("10.5.8-rc2");
     
     @Test
-    public void testBasicOnes() {
-        Assert.assertTrue(v.isGreaterThanAndNotEqualTo("10.5"));
-        Assert.assertTrue(v.isGreaterThanOrEqualTo("10.5.8"));
-        Assert.assertFalse(v.isGreaterThanAndNotEqualTo("10.5.8"));
-
-        Assert.assertTrue(v.isLessThanAndNotEqualTo("10.6"));
-        Assert.assertTrue(v.isLessThanOrEqualTo("10.5.8"));
-        Assert.assertFalse(v.isLessThanAndNotEqualTo("10.5.8"));
+    public void testNoc() {
+        Assert.assertEquals(noc.compare("0a", "1"), -1);
+        
+        Assert.assertEquals(noc.compare("0", "1"), -1);
+        Assert.assertEquals(noc.compare("1", "10"), -1);
+        Assert.assertEquals(noc.compare("9", "10"), -1);
+        Assert.assertEquals(noc.compare("a", "b"), -1);
+        Assert.assertEquals(noc.compare("a9", "a10"), -1);
         
-        Assert.assertTrue(v.isLessThanAndNotEqualTo("10.5.8.1"));
+        Assert.assertEquals(noc.compare("0.9", "0.91"), -1);
+        Assert.assertEquals(noc.compare("0.90", "0.91"), -1);
+        Assert.assertEquals(noc.compare("1.2.x", "1.09.x"), -1);
+        
+        Assert.assertEquals(noc.compare("0", "1a"), -1);
+        Assert.assertEquals(noc.compare("0a", "1"), -1);
+    }
+    
+    @Test
+    public void testBasicOnes() {
+        Assert.assertEquals(0, noc.compare("a", "a"));
+        Assert.assertTrue(noc.compare("a", "b") < 0);
+        Assert.assertTrue(noc.compare("b", "a") > 0);
         
-        Assert.assertTrue(v_rc2.isLessThanAndNotEqualTo("10.5.8-rc3")) ;
-        Assert.assertTrue(v_rc2.isGreaterThanAndNotEqualTo("10.5.8-rc1"));
+        Assert.assertTrue(noc.compare("9", "10") < 0);
+        Assert.assertTrue(noc.compare("10", "9") > 0);
         
-        Assert.assertTrue(v_rc2.isGreaterThanAndNotEqualTo("10.5.8-beta1")==v_rc2.isGreaterThanAndNotEqualTo("10.5.8-beta3"));
+        Assert.assertTrue(noc.compare("b10", "a9") > 0);
+        Assert.assertTrue(noc.compare("b9", "a10") > 0);
         
-        Assert.assertTrue(v.isInRange("[10.5,10.6)"));
-        Assert.assertFalse(v.isInRange("[10.5,10.5.8)"));
-        Assert.assertTrue(v.isInRange("[10.5,)"));
-        Assert.assertTrue(v.isInRange("[9,)"));
-        Assert.assertFalse(v.isInRange("(10.5.8,)"));
-        Assert.assertFalse(v.isInRange("[10.6,)"));
-        Assert.assertTrue(v.isInRange("[,11)"));
-        Assert.assertTrue(v.isInRange("[,]"));
+        Assert.assertTrue(noc.compare(" 9", "10") < 0);
+        Assert.assertTrue(noc.compare("10", " 9") > 0);
     }
 
-    @Test(expectedExceptions={IllegalArgumentException.class})
-    public void testError1() { v.isInRange("10.5"); }
-    @Test(expectedExceptions={IllegalArgumentException.class})
-    public void testError2() { v.isInRange("[10.5"); }
-    @Test(expectedExceptions={IllegalArgumentException.class})
-    public void testError3() { v.isInRange("[10.5]"); }
+    @Test
+    public void testVersionNumbers() {
+        Assert.assertEquals(0, noc.compare("10.5.8", "10.5.8"));
+        Assert.assertTrue(noc.compare("10.5", "9.9") > 0);
+        Assert.assertTrue(noc.compare("10.5.1", "10.5") > 0);
+        Assert.assertTrue(noc.compare("10.5.1", "10.6") < 0);
+        Assert.assertTrue(noc.compare("10.5.1-1", "10.5.1-0") > 0);
+    }
 
     @Test(groups="WIP", enabled=false)
     public void testUnderscoreDoesNotChangeMeaningOfNumberInNoc() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1265796f/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java
index 85ba659..a861a10 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java
@@ -102,9 +102,7 @@ public class StringsTest extends FixedLocaleTest {
 
         assertEquals(Strings.removeFromEnd("foobar", "bar"), "foo");
         assertEquals(Strings.removeFromEnd("foo", "bar"), "foo");
-        assertEquals(Strings.removeFromEnd("foobar", "foo", "bar"), "foo");
         // test they are applied in order
-        assertEquals(Strings.removeFromEnd("foobar", "ar", "bar", "b"), "foob");
     }
 
     public void testRemoveAllFromEnd() {
@@ -127,8 +125,6 @@ public class StringsTest extends FixedLocaleTest {
 
         assertEquals(Strings.removeFromStart("foobar", "foo"), "bar");
         assertEquals(Strings.removeFromStart("foo", "bar"), "foo");
-        assertEquals(Strings.removeFromStart("foobar", "foo", "bar"), "bar");
-        assertEquals(Strings.removeFromStart("foobar", "ob", "fo", "foo", "o"), "obar");
     }
 
     public void testRemoveAllFromStart() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1265796f/utils/common/src/test/java/org/apache/brooklyn/util/text/VersionComparatorTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/text/VersionComparatorTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/text/VersionComparatorTest.java
new file mode 100644
index 0000000..00fdb6e
--- /dev/null
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/text/VersionComparatorTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.util.text;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.List;
+
+import org.apache.brooklyn.util.collections.MutableList;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class VersionComparatorTest {
+
+    @Test
+    public void testStaticHelpers() {
+        Assert.assertEquals(VersionComparator.splitOnDot("a.b.cc"), new String[] { "a", ".", "b", ".", "cc" });
+        Assert.assertEquals(VersionComparator.splitOnDot("a..b-c"), new String[] { "a", ".", ".", "b-c" });
+
+        Assert.assertEquals(VersionComparator.splitOnNonWordChar("a1-b__cc9c"), new String[] { 
+            "a1", "-", "b", "_", "_", "cc9c" });
+
+        Assert.assertEquals(VersionComparator.isNumberInFirstChar("1a"), true);
+        Assert.assertEquals(VersionComparator.isNumberInFirstChar("a1"), false);
+        Assert.assertEquals(VersionComparator.isNumberInFirstChar(""), false);
+        Assert.assertEquals(VersionComparator.isNumberInFirstChar(null), false);
+        
+        Assert.assertEquals(VersionComparator.isNumber("1"), true);
+        Assert.assertEquals(VersionComparator.isNumber("1111"), true);
+        Assert.assertEquals(VersionComparator.isNumber("1a"), false);
+        Assert.assertEquals(VersionComparator.isNumber("a1"), false);
+        Assert.assertEquals(VersionComparator.isNumber(""), false);
+        Assert.assertEquals(VersionComparator.isNumber(null), false);
+    }
+    
+    @Test
+    public void testComparison() {
+        VersionComparator.INSTANCE.compare("B", "B-2");
+        
+        assertVersionOrder("0", "1");
+        assertVersionOrder("0", "0.0", "0.9", "0.10", "0.10.0", "1");
+        
+        assertVersionOrder("a", "b");
+        
+        assertVersionOrder("1beta", "1", "2beta", "11beta");
+        assertVersionOrder("beta", "0", "1beta", "1-alpha", "1", "11beta", "11-alpha", "11");
+        assertVersionOrder("1.0-a", "1.0-b", "1.0");
+        
+        assertVersionOrder("qualifier", "0qualifier", "0-qualifier", "0", "1-qualifier", "1");
+
+        assertVersionOrder("2.0.qualifier", "2.0", "2.0.0qualifier", "2.0.0-qualifier", "2.0.0.qualifier", "2.0.0");
+        assertVersionOrder("2.0.qualifier.0", "2.0", "2.0.0qualifier.0", "2.0.0-qualifier.0", "2.0.0.qualifier.0", "2.0.0", "2.0.0.0");
+        
+        assertVersionOrder("0", "0.0", "0.1", "0.1.0", "0.1.1", "0.2", "0.2.1", "1", "1.0", "2");
+        // case sensitive
+        assertVersionOrder("AA", "Aa", "aa");
+        // letters in order, ignoring case, and using natural order on numbers, splitting at word boundaries
+        assertVersionOrder("A", "B-2", "B-10", "B", "B0", "C", "b", "b1", "b9", "b10", "c", "0");
+        // and non-letter symbols are compared, in alpha order (e.g. - less than _) with dots even higher
+        assertVersionOrder("0-qual", "0", "0.1", "1-qualC", "1_qualB", "1.qualA", "1", "1.0");
+        
+        // numeric comparison works with qualifiers, preferring unqualified
+        assertVersionOrder("0--qual", "0-qual", "0-qualB", "0-qualB2", "0-qualB10", "0-qualC", "0.qualA", "0", "0.1.qual", "0.1", "1");
+        
+        // all snapshots rated lower
+        assertVersionOrder(
+            "0_SNAPSHOT", "0.1.SNAPSHOT", "1-SNAPSHOT-X-X", "1-SNAPSHOT-X", "1-SNAPSHOT-XX-X", "1-SNAPSHOT-XX", "1-SNAPSHOT", 
+            "1.0-SNAPSHOT-B", "1.0.SNAPSHOT-A", 
+            "1.2-SNAPSHOT", "1.10-SNAPSHOT",
+            "qualifer",
+            "0", "0.1", "1");
+    }
+    
+    private static void assertVersionOrder(String v1, String v2, String ...otherVersions) {
+        List<String> versions = MutableList.<String>of().append(v1, v2, otherVersions);
+        
+        for (int i=0; i<versions.size(); i++) {
+            for (int j=0; j<versions.size(); j++) {
+                assertEquals(VersionComparator.getInstance().compare(
+                        versions.get(i), versions.get(j)),
+                    new Integer(i).compareTo(j), "comparing "+versions.get(i)+" and "+versions.get(j));
+            }
+        }
+    }
+
+}


[03/12] incubator-brooklyn git commit: downstream-parent excludes a number of non-OSGi packages

Posted by he...@apache.org.
downstream-parent excludes a number of non-OSGi packages

All of them can break catalogue loading.


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/ac9ea5d3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/ac9ea5d3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/ac9ea5d3

Branch: refs/heads/master
Commit: ac9ea5d37502dafe8c9d7a901979d542cfe88287
Parents: 13e38d9
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Wed Dec 16 14:38:56 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Thu Dec 17 12:28:02 2015 +0000

----------------------------------------------------------------------
 usage/downstream-parent/pom.xml | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ac9ea5d3/usage/downstream-parent/pom.xml
----------------------------------------------------------------------
diff --git a/usage/downstream-parent/pom.xml b/usage/downstream-parent/pom.xml
index c4d5a74..c1731fd 100644
--- a/usage/downstream-parent/pom.xml
+++ b/usage/downstream-parent/pom.xml
@@ -448,8 +448,29 @@
               </supportedProjectTypes>
               <instructions>
                 <!--
+                  Exclude packages used by Brooklyn that are not OSGi bundles. Including any
+                  of the below may cause bundles to fail to load into the catalogue with
+                  messages like "Unable to resolve 150.0: missing requirement [150.0]
+                  osgi.wiring.package; (osgi.wiring.package=com.maxmind.geoip2)".
+                -->
+                <Import-Package>
+                  !com.maxmind.geoip2.*,
+                  !io.airlift.command.*,
+                  !io.cloudsoft.winrm4j.*,
+                  !javax.inject.*,
+                  !org.apache.felix.framework.*,
+                  !org.apache.http.*,
+                  !org.jclouds.googlecomputeengine.*,
+                  !org.osgi.jmx,
+                  !org.python.*,
+                  !org.reflections.*,
+                  !org.w3c.tidy.*,
+                  *
+                </Import-Package>
+                <!--
+                  Brooklyn-Feature prefix triggers inclusion of the project's metadata in the
+                  server's features list.
                 -->
-                <!-- Brooklyn-Feature prefix triggers inclusion of the project's metadata in the server's features list. -->
                 <Brooklyn-Feature-Name>${project.name}</Brooklyn-Feature-Name>
               </instructions>
             </configuration>