Big refactoring of new type registry code * call the class RegisteredTypeLoadingContext instead of constraint, improve method names based on better understood semantics * clean up how plans can be passed directly, without needing an anonymous RegisteredType * move BrooklynClassLoadingContext to API project (keeping temporary sub-interface in core)
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/e932d5fc Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/e932d5fc Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/e932d5fc Branch: refs/heads/master Commit: e932d5fcf0686440a295ed27d205454512153549 Parents: 904c45e Author: Alex Heneveld <[email protected]> Authored: Mon Nov 9 16:09:56 2015 +0000 Committer: Alex Heneveld <[email protected]> Committed: Tue Nov 10 17:13:02 2015 +0000 ---------------------------------------------------------------------- .../BrooklynClassLoadingContext.java | 50 ++++ .../api/typereg/BrooklynTypeRegistry.java | 19 +- .../api/typereg/RegisteredTypeConstraint.java | 50 ---- .../typereg/RegisteredTypeLoadingContext.java | 50 ++++ .../catalog/internal/BasicBrooklynCatalog.java | 29 +-- .../core/catalog/internal/CatalogUtils.java | 6 +- .../core/mgmt/EntityManagementUtils.java | 15 +- .../AbstractBrooklynClassLoadingContext.java | 5 +- .../BrooklynClassLoadingContext.java | 30 +-- .../BrooklynClassLoadingContextSequential.java | 1 + ...ssLoaderFromBrooklynClassLoadingContext.java | 2 + .../internal/AbstractManagementContext.java | 2 +- .../core/mgmt/persist/XmlMementoSerializer.java | 2 +- .../core/mgmt/rebind/RebindIteration.java | 2 +- .../brooklyn/core/objs/BasicSpecParameter.java | 2 +- .../brooklyn/core/plan/PlanToSpecFactory.java | 36 ++- .../entity/AbstractEntitySpecResolver.java | 2 +- .../entity/CatalogEntitySpecResolver.java | 6 +- .../entity/DelegatingEntitySpecResolver.java | 2 +- .../core/resolve/entity/EntitySpecResolver.java | 2 +- .../resolve/entity/JavaEntitySpecResolver.java | 2 +- .../typereg/AbstractTypePlanTransformer.java | 16 +- .../core/typereg/BasicBrooklynTypeRegistry.java | 59 +++-- .../typereg/BrooklynTypePlanTransformer.java | 10 +- .../JavaClassNameTypePlanTransformer.java | 12 +- .../core/typereg/RegisteredTypeConstraints.java | 206 ---------------- .../typereg/RegisteredTypeLoadingContexts.java | 234 +++++++++++++++++++ .../brooklyn/core/typereg/RegisteredTypes.java | 8 +- .../core/typereg/TypePlanTransformers.java | 6 +- .../brooklyn/util/core/ResourceUtils.java | 3 +- .../objs/BasicSpecParameterFromListTest.java | 2 +- .../entity/resolve/ChefEntitySpecResolver.java | 2 +- .../HardcodedCatalogEntitySpecResolver.java | 2 +- .../api/AssemblyTemplateSpecInstantiator.java | 2 +- .../BrooklynAssemblyTemplateInstantiator.java | 2 +- .../BrooklynComponentTemplateResolver.java | 2 +- .../BrooklynEntityDecorationResolver.java | 4 +- .../spi/creation/BrooklynEntityMatcher.java | 2 +- .../creation/BrooklynYamlTypeInstantiator.java | 2 +- .../spi/creation/CampInternalUtils.java | 2 +- .../brooklyn/spi/creation/CampResolver.java | 13 +- .../spi/creation/CampToSpecTransformer.java | 2 +- .../spi/creation/CampTypePlanTransformer.java | 14 +- .../service/ServiceTypeResolverAdaptor.java | 2 +- .../service/UrlServiceSpecResolver.java | 13 +- .../camp/brooklyn/AbstractYamlTest.java | 6 +- .../BrooklynYamlTypeInstantiatorTest.java | 2 +- .../brooklyn/test/lite/CampYamlLiteTest.java | 4 +- .../test/lite/TestAppAssemblyInstantiator.java | 2 +- .../rest/resources/ApplicationResource.java | 4 +- .../rest/resources/CatalogResource.java | 4 +- 51 files changed, 531 insertions(+), 426 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/api/src/main/java/org/apache/brooklyn/api/mgmt/classloading/BrooklynClassLoadingContext.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/classloading/BrooklynClassLoadingContext.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/classloading/BrooklynClassLoadingContext.java new file mode 100644 index 0000000..f95c0d8 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/classloading/BrooklynClassLoadingContext.java @@ -0,0 +1,50 @@ +/* + * 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.api.mgmt.classloading; + +import java.net.URL; + +import javax.annotation.Nullable; + +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.util.guava.Maybe; + +/** + * Provides functionality for loading classes based on the current context + * (e.g. the bundles of a registered type from which an entity is created) + */ +public interface BrooklynClassLoadingContext { + + public ManagementContext getManagementContext(); + public Class<?> loadClass(String className); + public <T> Class<? extends T> loadClass(String className, @Nullable Class<T> supertype); + + public Maybe<Class<?>> tryLoadClass(String className); + public <T> Maybe<Class<? extends T>> tryLoadClass(String className, @Nullable Class<T> supertype); + + /** As {@link ClassLoader#getResource(String)} */ + public URL getResource(String name); + + /** + * As {@link ClassLoader#getResources(String)} but returning an {@link Iterable} rather than + * an {@link java.util.Enumeration}. + */ + public Iterable<URL> getResources(String name); + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/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 f98f12f..476034f 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 @@ -45,24 +45,25 @@ public interface BrooklynTypeRegistry { /** @return The item matching the given given * {@link RegisteredType#getSymbolicName() symbolicName} * and optionally {@link RegisteredType#getVersion()}, - * filtered for the optionally supplied {@link RegisteredTypeConstraint}, + * filtered for the optionally supplied {@link RegisteredTypeLoadingContext}, * 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, @Nullable RegisteredTypeConstraint constraint); - /** as {@link #get(String, String, RegisteredTypeConstraint)} with no constraints */ + RegisteredType get(String symbolicName, String version, @Nullable RegisteredTypeLoadingContext constraint); + /** as {@link #get(String, String, RegisteredTypeLoadingContext)} with no constraints */ RegisteredType get(String symbolicName, String version); - /** as {@link #get(String, String, RegisteredTypeConstraint)} but allows <code>"name:version"</code> + /** as {@link #get(String, String, RegisteredTypeLoadingContext)} 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 */ - RegisteredType get(String symbolicNameWithOptionalVersion, @Nullable RegisteredTypeConstraint constraint); - /** as {@link #get(String, RegisteredTypeConstraint)} but with no constraints */ + RegisteredType get(String symbolicNameWithOptionalVersion, @Nullable RegisteredTypeLoadingContext constraint); + /** as {@link #get(String, RegisteredTypeLoadingContext)} but with no constraints */ RegisteredType get(String symbolicNameWithOptionalVersion); // NB the seemingly more correct generics <T,SpecT extends AbstractBrooklynObjectSpec<T,SpecT>> // cause compile errors, not in Eclipse, but in maven (?) - <SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpec(RegisteredType type, @Nullable RegisteredTypeConstraint optionalConstraint, Class<SpecT> optionalSpecSuperType); + <SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpec(RegisteredType type, @Nullable RegisteredTypeLoadingContext optionalConstraint, Class<SpecT> optionalSpecSuperType); + <SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpecFromPlan(String planFormat, Object planData, @Nullable RegisteredTypeLoadingContext optionalConstraint, Class<SpecT> optionalSpecSuperType); - // TODO when we support beans -// <T> T createBean(RegisteredType type, @Nullable RegisteredTypeConstraint optionalConstraint, Class<T> optionalResultSuperType); + <T> T createBean(RegisteredType type, @Nullable RegisteredTypeLoadingContext optionalConstraint, Class<T> optionalResultSuperType); + <T> T createBeanFromPlan(String planFormat, Object planData, @Nullable RegisteredTypeLoadingContext optionalConstraint, Class<T> optionalBeanSuperType); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredTypeConstraint.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredTypeConstraint.java b/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredTypeConstraint.java deleted file mode 100644 index 8bcff38..0000000 --- a/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredTypeConstraint.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.api.typereg; - -import java.util.Set; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.entity.EntitySpec; -import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind; - -public interface RegisteredTypeConstraint { - - /** The kind required, if specified. */ - @Nullable public RegisteredTypeKind getKind(); - - /** A java super-type or interface that should be filtered for; - * for specs, this refers to the target type, not the spec - * (eg {@link Entity} not {@link EntitySpec}). - * If nothing is specified, this returns {@link Object}'s class. */ - @Nonnull public Class<?> getJavaSuperType(); - - /** encountered types, so that during resolution, - * if we have already attempted to resolve a given type, - * the instantiator can avoid recursive cycles */ - @Nonnull public Set<String> getEncounteredTypes(); - - /** A special loader to use, if available. - * For internal use only; implementations should be a BrooklynClassLoadingContext */ - @Nullable public Object getLoader(); - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredTypeLoadingContext.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredTypeLoadingContext.java b/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredTypeLoadingContext.java new file mode 100644 index 0000000..d37666e --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredTypeLoadingContext.java @@ -0,0 +1,50 @@ +/* + * 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.api.typereg; + +import java.util.Set; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; +import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind; + +public interface RegisteredTypeLoadingContext { + + /** The kind required, if specified. */ + @Nullable public RegisteredTypeKind getExpectedKind(); + + /** A java super-type or interface that should be filtered for; + * for specs, this refers to the target type, not the spec + * (eg {@link Entity} not {@link EntitySpec}). + * If nothing is specified, this returns {@link Object}'s class. */ + @Nonnull public Class<?> getExpectedJavaSuperType(); + + /** encountered types, so that during resolution, + * if we have already attempted to resolve a given type, + * the instantiator can avoid recursive cycles */ + @Nonnull public Set<String> getAlreadyEncounteredTypes(); + + /** A loader to use, supplying additional search paths */ + @Nullable public BrooklynClassLoadingContext getLoader(); + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java index 262e3b4..0832b4f 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java @@ -37,15 +37,14 @@ import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.api.objs.SpecParameter; import org.apache.brooklyn.core.catalog.CatalogPredicates; import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes; import org.apache.brooklyn.core.location.BasicLocationRegistry; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.core.objs.BasicSpecParameter; -import org.apache.brooklyn.core.plan.PlanToSpecFactory; -import org.apache.brooklyn.core.plan.PlanToSpecTransformer; +import org.apache.brooklyn.core.typereg.BrooklynTypePlanTransformer; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.collections.MutableSet; @@ -303,7 +302,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { if (loadedItem == null) throw new RuntimeException(item+" not in catalog; cannot create spec"); if (loadedItem.getSpecType()==null) return null; - SpecT spec = internalCreateSpecWithTransformers(mgmt, loadedItem, MutableSet.<String>of()); + SpecT spec = internalCreateSpecLegacy(mgmt, loadedItem, MutableSet.<String>of(), false); if (spec != null) { return spec; } @@ -312,16 +311,18 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { } /** @deprecated since introduction in 0.9.0, only used for backwards compatibility, can be removed any time; - * uses the type-creation info on the item */ + * uses the type-creation info on the item. + * deprecated transformers must be included by routines which don't use {@link BrooklynTypePlanTransformer} instances; + * otherwise deprecated transformers should be excluded. (deprecation is taken as equivalent to having a new-style transformer.) */ @Deprecated - public static <T,SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT internalCreateSpecWithTransformers(ManagementContext mgmt, final CatalogItem<T, SpecT> item, final Set<String> encounteredTypes) { + public static <T,SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT internalCreateSpecLegacy(ManagementContext mgmt, final CatalogItem<T, SpecT> item, final Set<String> encounteredTypes, boolean includeDeprecatedTransformers) { // deprecated lookup if (encounteredTypes.contains(item.getSymbolicName())) { throw new IllegalStateException("Type being resolved '"+item.getSymbolicName()+"' has already been encountered in " + encounteredTypes + "; recursive cycle detected"); } - Maybe<SpecT> specMaybe = PlanToSpecFactory.attemptWithLoaders(mgmt, new Function<PlanToSpecTransformer, SpecT>() { + Maybe<SpecT> specMaybe = org.apache.brooklyn.core.plan.PlanToSpecFactory.attemptWithLoaders(mgmt, includeDeprecatedTransformers, new Function<org.apache.brooklyn.core.plan.PlanToSpecTransformer, SpecT>() { @Override - public SpecT apply(PlanToSpecTransformer input) { + public SpecT apply(org.apache.brooklyn.core.plan.PlanToSpecTransformer input) { return input.createCatalogSpec(item, encounteredTypes); } }); @@ -331,14 +332,6 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { return specMaybe.get(); } - /** - * as internalCreateSpecFromItemWithTransformers, but marking contexts where the creation is being attempted - * @deprecated since introduction in 0.9.0, only used for backwards compatibility, can be removed any time */ - @Deprecated - public static <T,SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT internalCreateSpecAttempting(ManagementContext mgmt, final CatalogItem<T, SpecT> item, final Set<String> encounteredTypes) { - return internalCreateSpecWithTransformers(mgmt, item, encounteredTypes); - } - @Deprecated /** @deprecated since 0.7.0 only used by other deprecated items */ private <T,SpecT> CatalogItemDtoAbstract<T,SpecT> getAbstractCatalogItem(CatalogItem<T,SpecT> item) { while (item instanceof CatalogItemDo) item = ((CatalogItemDo<T,SpecT>)item).itemDto; @@ -772,7 +765,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { .libraries(libraryBundles) .build(); @SuppressWarnings("unchecked") - AbstractBrooklynObjectSpec<?, ?> spec = internalCreateSpecAttempting(mgmt, itemToAttempt, MutableSet.<String>of()); + AbstractBrooklynObjectSpec<?, ?> spec = internalCreateSpecLegacy(mgmt, itemToAttempt, MutableSet.<String>of(), true); if (spec!=null) { catalogItemType = candidateCiType; planYaml = candidateYaml; @@ -814,7 +807,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog { .libraries(libraryBundles) .build(); @SuppressWarnings("unchecked") - AbstractBrooklynObjectSpec<?, ?> cutdownSpec = internalCreateSpecAttempting(mgmt, itemToAttempt, MutableSet.<String>of()); + AbstractBrooklynObjectSpec<?, ?> cutdownSpec = internalCreateSpecLegacy(mgmt, itemToAttempt, MutableSet.<String>of(), true); if (cutdownSpec!=null) { catalogItemType = candidateCiType; planYaml = candidateYaml; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/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 2955895..4a54800 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 @@ -27,6 +27,7 @@ import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry; import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl; @@ -34,7 +35,6 @@ import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.core.BrooklynLogging; import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker; import org.apache.brooklyn.core.entity.EntityInternal; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContextSequential; import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.classloading.OsgiBrooklynClassLoadingContext; @@ -42,7 +42,7 @@ import org.apache.brooklyn.core.mgmt.ha.OsgiManager; 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.RegisteredTypeConstraints; +import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.text.Strings; import org.apache.brooklyn.util.time.Time; @@ -80,7 +80,7 @@ public class CatalogUtils { ManagementContext mgmt = ((EntityInternal)entity).getManagementContext(); String catId = entity.getCatalogItemId(); if (Strings.isBlank(catId)) return JavaBrooklynClassLoadingContext.create(mgmt); - RegisteredType cat = mgmt.getTypeRegistry().get(catId, RegisteredTypeConstraints.spec(Entity.class)); + RegisteredType cat = mgmt.getTypeRegistry().get(catId, RegisteredTypeLoadingContexts.spec(Entity.class)); 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); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java index e1a5593..0f8da61 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java @@ -39,8 +39,7 @@ import org.apache.brooklyn.core.effector.Effectors; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.entity.EntityFunctions; import org.apache.brooklyn.core.entity.trait.Startable; -import org.apache.brooklyn.core.plan.PlanToSpecFactory; -import org.apache.brooklyn.core.plan.PlanToSpecTransformer; +import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts; import org.apache.brooklyn.entity.stock.BasicApplication; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; @@ -52,7 +51,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.annotations.Beta; -import com.google.common.base.Function; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -89,14 +87,9 @@ public class EntityManagementUtils { return createUnstarted(mgmt, spec); } + @SuppressWarnings("unchecked") public static EntitySpec<? extends Application> createEntitySpecForApplication(ManagementContext mgmt, final String plan) { - // TODO-type-registry - return PlanToSpecFactory.attemptWithLoaders(mgmt, new Function<PlanToSpecTransformer, EntitySpec<? extends Application>>() { - @Override - public EntitySpec<? extends Application> apply(PlanToSpecTransformer input) { - return input.createApplicationSpec(plan); - } - }).get(); + return mgmt.getTypeRegistry().createSpecFromPlan(null, plan, RegisteredTypeLoadingContexts.spec(Application.class), EntitySpec.class); } @Deprecated /** @deprecated since 0.9.0; use {@link BrooklynTypeRegistry#createSpec(RegisteredType, org.apache.brooklyn.api.typereg.RegisteredTypeConstraint, Class)} */ @@ -108,7 +101,7 @@ public class EntityManagementUtils { @Deprecated /** @deprecated since 0.9.0; use {@link BrooklynTypeRegistry#createSpec(RegisteredType, org.apache.brooklyn.api.typereg.RegisteredTypeConstraint, Class)} */ // not used in Brooklyn public static <T,SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(ManagementContext mgmt, final CatalogItem<T, SpecT> item, final Set<String> encounteredTypes) { - return BasicBrooklynCatalog.internalCreateSpecWithTransformers(mgmt, item, encounteredTypes); + return BasicBrooklynCatalog.internalCreateSpecLegacy(mgmt, item, encounteredTypes, true); } /** container for operation which creates something and which wants to return both http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/AbstractBrooklynClassLoadingContext.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/AbstractBrooklynClassLoadingContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/AbstractBrooklynClassLoadingContext.java index 10d3c99..8003948 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/AbstractBrooklynClassLoadingContext.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/AbstractBrooklynClassLoadingContext.java @@ -3,6 +3,7 @@ package org.apache.brooklyn.core.mgmt.classloading; import javax.annotation.Nullable; import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.util.guava.Maybe; import com.google.common.base.Objects; @@ -25,7 +26,9 @@ import com.google.common.base.Objects; * specific language governing permissions and limitations * under the License. */ -public abstract class AbstractBrooklynClassLoadingContext implements BrooklynClassLoadingContext { +@SuppressWarnings("deprecation") +public abstract class AbstractBrooklynClassLoadingContext implements BrooklynClassLoadingContext, + org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext { protected final ManagementContext mgmt; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContext.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContext.java index 20e8719..b6a5e50 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContext.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContext.java @@ -18,33 +18,11 @@ */ package org.apache.brooklyn.core.mgmt.classloading; -import java.net.URL; - -import javax.annotation.Nullable; - -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.util.guava.Maybe; /** - * Provides functionality for loading classes based on the current context - * (e.g. catalog item, entity, etc). + * @deprecated since 0.9.0; moved to API package; use the super-interface + * {@link org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext} */ -public interface BrooklynClassLoadingContext { - - public ManagementContext getManagementContext(); - public Class<?> loadClass(String className); - public <T> Class<? extends T> loadClass(String className, @Nullable Class<T> supertype); - - public Maybe<Class<?>> tryLoadClass(String className); - public <T> Maybe<Class<? extends T>> tryLoadClass(String className, @Nullable Class<T> supertype); - - /** As {@link ClassLoader#getResource(String)} */ - public URL getResource(String name); - - /** - * As {@link ClassLoader#getResources(String)} but returning an {@link Iterable} rather than - * an {@link java.util.Enumeration}. - */ - public Iterable<URL> getResources(String name); - +@Deprecated +public interface BrooklynClassLoadingContext extends org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext { } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java index 9b49599..530039a 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Set; import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableSet; import org.apache.brooklyn.util.exceptions.Exceptions; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromBrooklynClassLoadingContext.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromBrooklynClassLoadingContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromBrooklynClassLoadingContext.java index dbd6d2c..f36e2ac 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromBrooklynClassLoadingContext.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromBrooklynClassLoadingContext.java @@ -20,6 +20,8 @@ package org.apache.brooklyn.core.mgmt.classloading; import java.net.URL; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; + public class ClassLoaderFromBrooklynClassLoadingContext extends ClassLoader { /** Constructs a {@link ClassLoader} which delegates to the given {@link BrooklynClassLoadingContext} */ http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java index cba394c..67e3ab3 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java @@ -43,6 +43,7 @@ import org.apache.brooklyn.api.mgmt.ExecutionContext; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.mgmt.SubscriptionContext; import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.api.mgmt.entitlement.EntitlementManager; import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityManager; import org.apache.brooklyn.api.mgmt.rebind.RebindManager; @@ -65,7 +66,6 @@ import org.apache.brooklyn.core.internal.storage.impl.BrooklynStorageImpl; import org.apache.brooklyn.core.internal.storage.impl.inmemory.InMemoryDataGridFactory; import org.apache.brooklyn.core.location.BasicLocationRegistry; import org.apache.brooklyn.core.mgmt.BrooklynTaskTags; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.entitlement.Entitlements; import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java index 98b5aa2..603f627 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java @@ -35,6 +35,7 @@ import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister.LookupContext; import org.apache.brooklyn.api.objs.Identifiable; import org.apache.brooklyn.api.policy.Policy; @@ -48,7 +49,6 @@ import org.apache.brooklyn.core.effector.BasicParameterType; import org.apache.brooklyn.core.effector.EffectorAndBody; import org.apache.brooklyn.core.effector.EffectorTasks.EffectorBodyTaskFactory; import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContextSequential; import org.apache.brooklyn.core.mgmt.classloading.ClassLoaderFromBrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java index 3655886..5c77753 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java @@ -35,6 +35,7 @@ import org.apache.brooklyn.api.catalog.CatalogItem; 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.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState; import org.apache.brooklyn.api.mgmt.rebind.RebindContext; import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler; @@ -71,7 +72,6 @@ import org.apache.brooklyn.core.entity.EntityInternal; import org.apache.brooklyn.core.feed.AbstractFeed; import org.apache.brooklyn.core.location.AbstractLocation; import org.apache.brooklyn.core.location.internal.LocationInternal; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.internal.BrooklynObjectManagementMode; import org.apache.brooklyn.core.mgmt.internal.BrooklynObjectManagerInternal; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java index e882d79..dfbe1c1 100644 --- a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java +++ b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java @@ -32,12 +32,12 @@ import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.location.PortRange; import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.api.objs.BrooklynType; import org.apache.brooklyn.api.objs.SpecParameter; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.BasicConfigKey; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.text.StringPredicates; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java index 7aef313..002c6b5 100644 --- a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java +++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java @@ -21,11 +21,13 @@ package org.apache.brooklyn.core.plan; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.List; import java.util.ServiceLoader; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.core.typereg.BrooklynTypePlanTransformer; import org.apache.brooklyn.core.typereg.TypePlanTransformers; +import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException; import org.apache.brooklyn.util.guava.Maybe; @@ -38,14 +40,30 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; -/** @deprecated since 0.9.0 use {@link TypePlanTransformers} as part of switch to {@link BrooklynTypePlanTransformer} */ +/** @deprecated since 0.9.0 use {@link TypePlanTransformers} as part of switch to {@link BrooklynTypePlanTransformer}; + * mark transformers as deprecated if there is a preferred corresponding {@link BrooklynTypePlanTransformer} */ @Deprecated public class PlanToSpecFactory { private static final Logger log = LoggerFactory.getLogger(PlanToSpecFactory.class); - private static Collection<PlanToSpecTransformer> getAll() { - return ImmutableList.copyOf(ServiceLoader.load(PlanToSpecTransformer.class)); + private static Collection<PlanToSpecTransformer> getAll(boolean includeDeprecated) { + ServiceLoader<PlanToSpecTransformer> loader = ServiceLoader.load(PlanToSpecTransformer.class); + return ImmutableList.copyOf(includeDeprecated ? loader : filterDeprecated(loader)); + } + + private static Iterable<PlanToSpecTransformer> filterDeprecated(ServiceLoader<PlanToSpecTransformer> loader) { + List<PlanToSpecTransformer> result = MutableList.of(); + for (PlanToSpecTransformer t: loader) { + if (!isDeprecated(t.getClass())) { + result.add(t); + } + } + return result; + } + + private static boolean isDeprecated(Class<? extends PlanToSpecTransformer> c) { + return (c.getAnnotation(Deprecated.class)!=null); } private static Collection<Class<? extends PlanToSpecTransformer>> OVERRIDE; @@ -59,18 +77,22 @@ public class PlanToSpecFactory { } public static Collection<PlanToSpecTransformer> all(ManagementContext mgmt) { + return all(mgmt, true); + } + public static Collection<PlanToSpecTransformer> all(ManagementContext mgmt, boolean includeSuperseded) { Collection<Class<? extends PlanToSpecTransformer>> override = OVERRIDE; Collection<PlanToSpecTransformer> result = new ArrayList<PlanToSpecTransformer>(); if (override!=null) { for (Class<? extends PlanToSpecTransformer> o1: override) { try { - result.add(o1.newInstance()); + if (includeSuperseded || !isDeprecated(o1)) + result.add(o1.newInstance()); } catch (Exception e) { Exceptions.propagate(e); } } } else { - result.addAll(getAll()); + result.addAll(getAll(includeSuperseded)); } for(PlanToSpecTransformer t : result) { t.injectManagementContext(mgmt); @@ -91,8 +113,8 @@ public class PlanToSpecFactory { // TODO primitive loading mechanism, just tries all in order; we'll want something better as we get more plan transformers @Beta - public static <T> Maybe<T> attemptWithLoaders(ManagementContext mgmt, Function<PlanToSpecTransformer,T> f) { - return attemptWithLoaders(all(mgmt), f); + public static <T> Maybe<T> attemptWithLoaders(ManagementContext mgmt, boolean includeDeprecated, Function<PlanToSpecTransformer,T> f) { + return attemptWithLoaders(all(mgmt, includeDeprecated), f); } public static <T> Maybe<T> attemptWithLoaders(Iterable<PlanToSpecTransformer> transformers, Function<PlanToSpecTransformer,T> f) { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/resolve/entity/AbstractEntitySpecResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/AbstractEntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/AbstractEntitySpecResolver.java index ae3ddb2..f3ea9e4 100644 --- a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/AbstractEntitySpecResolver.java +++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/AbstractEntitySpecResolver.java @@ -22,7 +22,7 @@ import java.util.Set; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.util.text.Strings; public abstract class AbstractEntitySpecResolver implements EntitySpecResolver { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/resolve/entity/CatalogEntitySpecResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/CatalogEntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/CatalogEntitySpecResolver.java index 70224aa..eba5201 100644 --- a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/CatalogEntitySpecResolver.java +++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/CatalogEntitySpecResolver.java @@ -21,9 +21,9 @@ package org.apache.brooklyn.core.resolve.entity; import java.util.Set; import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.api.typereg.RegisteredType; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; -import org.apache.brooklyn.core.typereg.RegisteredTypeConstraints; +import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,7 +65,7 @@ public class CatalogEntitySpecResolver extends AbstractEntitySpecResolver { boolean recursiveCall = parentEncounteredTypes.contains(item.getSymbolicName()); if (recursiveCall) return null; return mgmt.getTypeRegistry().createSpec(item, - RegisteredTypeConstraints.alreadyVisited(parentEncounteredTypes), + RegisteredTypeLoadingContexts.alreadyEncountered(parentEncounteredTypes), EntitySpec.class); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/resolve/entity/DelegatingEntitySpecResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/DelegatingEntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/DelegatingEntitySpecResolver.java index 415f209..688c4dd 100644 --- a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/DelegatingEntitySpecResolver.java +++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/DelegatingEntitySpecResolver.java @@ -27,7 +27,7 @@ import java.util.Set; import javax.annotation.Nonnull; import org.apache.brooklyn.api.entity.EntitySpec; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException; import org.slf4j.Logger; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/resolve/entity/EntitySpecResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/EntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/EntitySpecResolver.java index 83e0fab..9fa9fc2 100644 --- a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/EntitySpecResolver.java +++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/EntitySpecResolver.java @@ -24,8 +24,8 @@ import java.util.Set; import javax.annotation.Nullable; import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.ManagementContextInjectable; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; /** * Resolves and decorates {@link EntitySpec entity specifications} based on the {@code serviceType} in a template. http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/resolve/entity/JavaEntitySpecResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/JavaEntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/JavaEntitySpecResolver.java index 047e11d..55cda9f 100644 --- a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/JavaEntitySpecResolver.java +++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/JavaEntitySpecResolver.java @@ -24,8 +24,8 @@ import java.util.Set; import org.apache.brooklyn.api.entity.Application; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.catalog.internal.CatalogUtils; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.javalang.Reflections; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/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 ae2c610..b4d79c2 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 @@ -21,7 +21,7 @@ package org.apache.brooklyn.core.typereg; import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.typereg.RegisteredType; -import org.apache.brooklyn.api.typereg.RegisteredTypeConstraint; +import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.javalang.JavaClassNames; import org.slf4j.Logger; @@ -72,7 +72,7 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra } @Override - public double scoreForType(RegisteredType type, RegisteredTypeConstraint context) { + public double scoreForType(RegisteredType type, RegisteredTypeLoadingContext context) { if (getFormatCode().equals(type.getPlan().getPlanFormat())) return 1; if (type.getPlan().getPlanFormat()==null) return scoreForNullFormat(type.getPlan().getPlanData(), type, context); @@ -80,8 +80,8 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra return scoreForNonmatchingNonnullFormat(type.getPlan().getPlanFormat(), type.getPlan().getPlanData(), type, context); } - protected abstract double scoreForNullFormat(Object planData, RegisteredType type, RegisteredTypeConstraint context); - protected abstract double scoreForNonmatchingNonnullFormat(String planFormat, Object planData, RegisteredType type, RegisteredTypeConstraint context); + protected abstract double scoreForNullFormat(Object planData, RegisteredType type, RegisteredTypeLoadingContext context); + protected abstract double scoreForNonmatchingNonnullFormat(String planFormat, Object planData, RegisteredType type, RegisteredTypeLoadingContext context); /** delegates to more specific abstract create methods, * and performs common validation and customisation of the items created. @@ -90,7 +90,7 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra * <li> setting the {@link AbstractBrooklynObjectSpec#catalogItemId(String)} */ @Override - public Object create(final RegisteredType type, final RegisteredTypeConstraint context) { + public Object create(final RegisteredType type, final RegisteredTypeLoadingContext context) { try { return validate(new RegisteredTypeKindVisitor<Object>() { @Override protected Object visitSpec(RegisteredType type) { @@ -117,14 +117,14 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra } } - protected <T> T validate(T createdObject, RegisteredType type, RegisteredTypeConstraint context) { + protected <T> T validate(T createdObject, RegisteredType type, RegisteredTypeLoadingContext context) { if (createdObject==null) return null; // TODO validation based on the constraint, throw UnsupportedTypePlanException with details if not matched return createdObject; } - protected abstract AbstractBrooklynObjectSpec<?,?> createSpec(RegisteredType type, RegisteredTypeConstraint context) throws Exception; + protected abstract AbstractBrooklynObjectSpec<?,?> createSpec(RegisteredType type, RegisteredTypeLoadingContext context) throws Exception; - protected abstract Object createBean(RegisteredType type, RegisteredTypeConstraint context) throws Exception; + protected abstract Object createBean(RegisteredType type, RegisteredTypeLoadingContext context) throws Exception; } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/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 0ca8bc7..cfb9f9b 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 @@ -26,7 +26,7 @@ import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry; import org.apache.brooklyn.api.typereg.RegisteredType; -import org.apache.brooklyn.api.typereg.RegisteredTypeConstraint; +import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext; import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog; import org.apache.brooklyn.core.catalog.internal.CatalogUtils; import org.apache.brooklyn.util.collections.MutableList; @@ -63,8 +63,8 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry { @SuppressWarnings("deprecation") @Override - public RegisteredType get(String symbolicName, String version, RegisteredTypeConstraint constraint) { - if (constraint==null) constraint = RegisteredTypeConstraints.any(); + public RegisteredType get(String symbolicName, String version, RegisteredTypeLoadingContext constraint) { + if (constraint==null) constraint = RegisteredTypeLoadingContexts.any(); if (version==null) version = BrooklynCatalog.DEFAULT_VERSION; // TODO lookup here, using constraints @@ -81,7 +81,7 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry { } @Override - public RegisteredType get(String symbolicNameWithOptionalVersion, RegisteredTypeConstraint constraint) { + public RegisteredType get(String symbolicNameWithOptionalVersion, RegisteredTypeLoadingContext constraint) { if (CatalogUtils.looksLikeVersionedId(symbolicNameWithOptionalVersion)) { String symbolicName = CatalogUtils.getSymbolicNameFromVersionedId(symbolicNameWithOptionalVersion); String version = CatalogUtils.getVersionFromVersionedId(symbolicNameWithOptionalVersion); @@ -93,26 +93,26 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry { @Override public RegisteredType get(String symbolicNameWithOptionalVersion) { - return get(symbolicNameWithOptionalVersion, (RegisteredTypeConstraint)null); + return get(symbolicNameWithOptionalVersion, (RegisteredTypeLoadingContext)null); } @SuppressWarnings({ "deprecation", "unchecked", "rawtypes" }) @Override - public <SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpec(RegisteredType type, @Nullable RegisteredTypeConstraint constraint, Class<SpecT> specSuperType) { + public <SpecT extends AbstractBrooklynObjectSpec<?,?>> SpecT createSpec(RegisteredType type, @Nullable RegisteredTypeLoadingContext constraint, Class<SpecT> specSuperType) { Preconditions.checkNotNull(type, "type"); if (type.getKind()!=RegisteredTypeKind.SPEC) { throw new IllegalStateException("Cannot create spec from type "+type+" (kind "+type.getKind()+")"); } if (constraint!=null) { - if (constraint.getKind()!=null && constraint.getKind()!=RegisteredTypeKind.SPEC) { + if (constraint.getExpectedKind()!=null && constraint.getExpectedKind()!=RegisteredTypeKind.SPEC) { throw new IllegalStateException("Cannot create spec with constraint "+constraint); } - if (constraint.getEncounteredTypes().contains(type.getSymbolicName())) { + if (constraint.getAlreadyEncounteredTypes().contains(type.getSymbolicName())) { // avoid recursive cycle // TODO implement using java if permitted } } - constraint = RegisteredTypeConstraints.withSpecSuperType(constraint, specSuperType); + constraint = RegisteredTypeLoadingContexts.withSpecSuperType(constraint, specSuperType); Maybe<Object> result = TypePlanTransformers.transform(mgmt, type, constraint); if (result.isPresent()) return (SpecT) result.get(); @@ -121,11 +121,12 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry { // TODO remove once all transformers are available in the new style CatalogItem item = (CatalogItem) mgmt.getCatalog().getCatalogItem(type.getSymbolicName(), type.getVersion()); if (item==null) { - // if not in catalog (because loading new one?) then throw original + // if not in catalog (because loading a new item?) then throw original + // (NB: to support any recursive legacy transformers we might have to create a CI; cross that bridge when we come to it) result.get(); } try { - return (SpecT) BasicBrooklynCatalog.internalCreateSpecWithTransformers(mgmt, item, constraint.getEncounteredTypes()); + return (SpecT) BasicBrooklynCatalog.internalCreateSpecLegacy(mgmt, item, constraint.getAlreadyEncounteredTypes(), false); } catch (Exception e) { Exceptions.propagateIfFatal(e); // for now, combine this failure with the original @@ -137,9 +138,41 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry { // prefer older exception, until the new transformer is the primary pathway throw Exceptions.create("Unable to instantiate "+type, MutableList.of(e, e0)); } - // ultimately swallow the legacy failure, return the original failure (the call below will throw because result is absent) -// return (SpecT) result.get(); } } + @Override + public <SpecT extends AbstractBrooklynObjectSpec<?, ?>> SpecT createSpecFromPlan(String planFormat, Object planData, RegisteredTypeLoadingContext optionalConstraint, Class<SpecT> optionalSpecSuperType) { + return createSpec(RegisteredTypes.spec(null, null, new BasicTypeImplementationPlan(planFormat, planData), null), + optionalConstraint, optionalSpecSuperType); + } + + @Override + public <T> T createBean(RegisteredType type, RegisteredTypeLoadingContext constraint, Class<T> optionalResultSuperType) { + Preconditions.checkNotNull(type, "type"); + if (type.getKind()!=RegisteredTypeKind.SPEC) { + throw new IllegalStateException("Cannot create spec from type "+type+" (kind "+type.getKind()+")"); + } + if (constraint!=null) { + if (constraint.getExpectedKind()!=null && constraint.getExpectedKind()!=RegisteredTypeKind.SPEC) { + throw new IllegalStateException("Cannot create spec with constraint "+constraint); + } + if (constraint.getAlreadyEncounteredTypes().contains(type.getSymbolicName())) { + // avoid recursive cycle + // TODO implement using java if permitted + } + } + constraint = RegisteredTypeLoadingContexts.withBeanSuperType(constraint, optionalResultSuperType); + + @SuppressWarnings("unchecked") + T result = (T) TypePlanTransformers.transform(mgmt, type, constraint).get(); + return result; + } + + @Override + public <T> T createBeanFromPlan(String planFormat, Object planData, RegisteredTypeLoadingContext optionalConstraint, Class<T> optionalBeanSuperType) { + return createBean(RegisteredTypes.bean(null, null, new BasicTypeImplementationPlan(planFormat, planData), null), + optionalConstraint, optionalBeanSuperType); + } + } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java index 96c9cb7..224aca2 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynTypePlanTransformer.java @@ -24,7 +24,7 @@ import java.util.ServiceLoader; import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry; import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind; import org.apache.brooklyn.api.typereg.RegisteredType; -import org.apache.brooklyn.api.typereg.RegisteredTypeConstraint; +import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext; import org.apache.brooklyn.core.mgmt.ManagementContextInjectable; /** @@ -49,18 +49,18 @@ public interface BrooklynTypePlanTransformer extends ManagementContextInjectable * <p> * The framework guarantees arguments are nonnull, and that the {@link RegisteredType#getPlan()} is also not-null. * However the format in that plan may be null. */ - double scoreForType(RegisteredType type, RegisteredTypeConstraint context); + double scoreForType(RegisteredType type, RegisteredTypeLoadingContext context); /** Creates a new instance of the indicated type, or throws if not supported; * this method is used by the {@link BrooklynTypeRegistry} when it creates instances, - * so implementations must respect the {@link RegisteredTypeKind} semantics and the {@link RegisteredTypeConstraint} + * so implementations must respect the {@link RegisteredTypeKind} semantics and the {@link RegisteredTypeLoadingContext} * if they return an instance. * <p> - * The framework guarantees this will only be invoked when {@link #scoreForType(RegisteredType, RegisteredTypeConstraint)} + * The framework guarantees this will only be invoked when {@link #scoreForType(RegisteredType, RegisteredTypeLoadingContext)} * has returned a positive value. * <p> * Implementations should either return null or throw {@link UnsupportedTypePlanException} * if the {@link RegisteredType#getPlan()} is not supported. */ - Object create(RegisteredType type, RegisteredTypeConstraint context); + Object create(RegisteredType type, RegisteredTypeLoadingContext context); double scoreForTypeDefinition(String formatCode, Object catalogData); List<RegisteredType> createFromTypeDefinition(String formatCode, Object catalogData); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/typereg/JavaClassNameTypePlanTransformer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/JavaClassNameTypePlanTransformer.java b/core/src/main/java/org/apache/brooklyn/core/typereg/JavaClassNameTypePlanTransformer.java index a84c9f5..5e6877b 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/JavaClassNameTypePlanTransformer.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/JavaClassNameTypePlanTransformer.java @@ -23,7 +23,7 @@ import java.util.List; import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.api.typereg.RegisteredType; -import org.apache.brooklyn.api.typereg.RegisteredTypeConstraint; +import org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext; import org.apache.brooklyn.util.text.Identifiers; /** @@ -46,7 +46,7 @@ public class JavaClassNameTypePlanTransformer extends AbstractTypePlanTransforme } @Override - protected double scoreForNullFormat(Object planData, RegisteredType type, RegisteredTypeConstraint context) { + protected double scoreForNullFormat(Object planData, RegisteredType type, RegisteredTypeLoadingContext context) { if (type.getPlan().getPlanData() instanceof String && ((String)type.getPlan().getPlanData()).matches(Identifiers.JAVA_BINARY_REGEX)) { return 0.1; @@ -55,22 +55,22 @@ public class JavaClassNameTypePlanTransformer extends AbstractTypePlanTransforme } @Override - protected double scoreForNonmatchingNonnullFormat(String planFormat, Object planData, RegisteredType type, RegisteredTypeConstraint context) { + protected double scoreForNonmatchingNonnullFormat(String planFormat, Object planData, RegisteredType type, RegisteredTypeLoadingContext context) { return 0; } @SuppressWarnings({ "unchecked" }) @Override - protected AbstractBrooklynObjectSpec<?,?> createSpec(RegisteredType type, RegisteredTypeConstraint context) throws Exception { + protected AbstractBrooklynObjectSpec<?,?> createSpec(RegisteredType type, RegisteredTypeLoadingContext context) throws Exception { return RegisteredTypes.newSpecInstance(mgmt, (Class<? extends BrooklynObject>) getType(type, context)); } @Override - protected Object createBean(RegisteredType type, RegisteredTypeConstraint context) throws Exception { + protected Object createBean(RegisteredType type, RegisteredTypeLoadingContext context) throws Exception { return getType(type, context).newInstance(); } - private Class<?> getType(RegisteredType type, RegisteredTypeConstraint context) throws Exception { + private Class<?> getType(RegisteredType type, RegisteredTypeLoadingContext context) throws Exception { return RegisteredTypes.loadActualJavaType((String)type.getPlan().getPlanData(), mgmt, type, context); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e932d5fc/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypeConstraints.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypeConstraints.java b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypeConstraints.java deleted file mode 100644 index 5b4c0cf..0000000 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypeConstraints.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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 groovy.xml.Entity; - -import java.util.Set; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import org.apache.brooklyn.api.entity.EntitySpec; -import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; -import org.apache.brooklyn.api.objs.BrooklynObject; -import org.apache.brooklyn.api.objs.BrooklynObjectType; -import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind; -import org.apache.brooklyn.api.typereg.RegisteredTypeConstraint; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext; -import org.apache.brooklyn.util.collections.MutableSet; -import org.apache.brooklyn.util.javalang.JavaClassNames; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableSet; - -public class RegisteredTypeConstraints { - - private static final Logger log = LoggerFactory.getLogger(RegisteredTypeConstraints.BasicRegisteredTypeConstraint.class); - - /** Immutable (from caller's perspective) record of a constraint */ - public final static class BasicRegisteredTypeConstraint implements RegisteredTypeConstraint { - @Nullable private RegisteredTypeKind kind; - @Nullable private Class<?> javaSuperType; - @Nonnull private Set<String> encounteredTypes = ImmutableSet.of(); - @Nullable BrooklynClassLoadingContext loader; - - private BasicRegisteredTypeConstraint() {} - - public BasicRegisteredTypeConstraint(@Nullable RegisteredTypeConstraint source) { - if (source==null) return; - - this.kind = source.getKind(); - this.javaSuperType = source.getJavaSuperType(); - this.encounteredTypes = source.getEncounteredTypes(); - this.loader = (BrooklynClassLoadingContext) source.getLoader(); - } - - @Override - public RegisteredTypeKind getKind() { - return kind; - } - - @Override - public Class<?> getJavaSuperType() { - if (javaSuperType==null) return Object.class; - return javaSuperType; - } - - @Override - public Set<String> getEncounteredTypes() { - if (encounteredTypes==null) return ImmutableSet.of(); - return ImmutableSet.<String>copyOf(encounteredTypes); - } - - @Override - public BrooklynClassLoadingContext getLoader() { - return loader; - } - - @Override - public String toString() { - return JavaClassNames.cleanSimpleClassName(this)+"["+kind+","+javaSuperType+","+encounteredTypes+"]"; - } - } - - /** returns a constraint which allows anything */ - public static RegisteredTypeConstraint any() { - return new BasicRegisteredTypeConstraint(); - } - - public static RegisteredTypeConstraint alreadyVisited(Set<String> encounteredTypeSymbolicNames) { - BasicRegisteredTypeConstraint result = new BasicRegisteredTypeConstraint(); - result.encounteredTypes = encounteredTypeSymbolicNames == null ? ImmutableSet.<String>of() : ImmutableSet.copyOf(encounteredTypeSymbolicNames); - return result; - } - public static RegisteredTypeConstraint alreadyVisited(Set<String> encounteredTypeSymbolicNames, String anotherEncounteredType) { - BasicRegisteredTypeConstraint result = new BasicRegisteredTypeConstraint(); - MutableSet<String> encounteredTypes = MutableSet.copyOf(encounteredTypeSymbolicNames); - encounteredTypes.addIfNotNull(anotherEncounteredType); - result.encounteredTypes = encounteredTypes.asUnmodifiable(); - return result; - } - - public static RegisteredTypeConstraint alreadyVisited(Set<String> encounteredTypeSymbolicNames, BrooklynClassLoadingContext loader) { - return withLoader(alreadyVisited(encounteredTypeSymbolicNames), loader); - } - - private static RegisteredTypeConstraint of(RegisteredTypeKind kind, Class<? extends BrooklynObject> javaSuperType) { - BasicRegisteredTypeConstraint result = new BasicRegisteredTypeConstraint(); - result.kind = kind; - result.javaSuperType = javaSuperType; - return result; - } - - public static RegisteredTypeConstraint spec(Class<? extends BrooklynObject> javaSuperType) { - return of(RegisteredTypeKind.SPEC, javaSuperType); - } - - public static <T extends AbstractBrooklynObjectSpec<?,?>> RegisteredTypeConstraint withSpecSuperType(@Nullable RegisteredTypeConstraint source, @Nullable Class<T> specSuperType) { - Class<?> superType = lookupTargetTypeForSpec(specSuperType); - BasicRegisteredTypeConstraint constraint = new BasicRegisteredTypeConstraint(source); - if (source==null) source = constraint; - if (source.getJavaSuperType()==null || source.getJavaSuperType().isAssignableFrom( superType )) { - // the constraint was weaker than present; return the new constraint - return constraint; - } - if (superType.isAssignableFrom( source.getJavaSuperType() )) { - // the constraint was already for something more specific; ignore what we've inferred here - return source; - } - // trickier situation; the constraint had a type not compatible with the spec type; log a warning and leave alone - // (e.g. caller specified some java super type which is not a super or sub of the spec target type; - // this may be because the caller specified a Spec as the type supertype, which is wrong; - // or they may have specified an interface along a different hierarchy, which we discouraged - // as it will make filtering/indexing more complex) - log.warn("Ambiguous spec supertypes ("+specSuperType+" for target "+source.getJavaSuperType()+"); " - + "it is recommended that any registered type constraint for a spec be compatible with the spec type"); - return source; - } - - /** given a spec, returns the class of the item it targets, for instance returns {@link Entity} given {@link EntitySpec}; - * see also {@link #lookupSpecTypeForTarget(Class)} */ - static <T extends AbstractBrooklynObjectSpec<?,?>> Class<? extends BrooklynObject> lookupTargetTypeForSpec(Class<T> specSuperType) { - if (specSuperType==null) return BrooklynObject.class; - BrooklynObjectType best = null; - - for (BrooklynObjectType t: BrooklynObjectType.values()) { - if (t.getSpecType()==null) continue; - if (!t.getSpecType().isAssignableFrom(specSuperType)) continue; - // on equality, exit immediately - if (t.getSpecType().equals(specSuperType)) return t.getInterfaceType(); - // else pick which is best - if (best==null) { best = t; continue; } - // if t is more specific, it is better (handles case when e.g. a Policy is a subclass of Entity) - if (best.getSpecType().isAssignableFrom(t.getSpecType())) { best = t; continue; } - } - if (best==null) { - log.warn("Unexpected spec supertype ("+specSuperType+"); treating as any "+BrooklynObject.class, new Throwable("Trace for unexpected spec supertype")); - return BrooklynObject.class; - } - // the spec is more specific, but we're not familiar with it here; return the best - return best.getInterfaceType(); - } - - /** given a {@link BrooklynObject}, returns the spec class which would generate it, for instance returns {@link EntitySpec} given {@link Entity}, - * or null if not known */ - static <BO extends BrooklynObject> Class<? extends AbstractBrooklynObjectSpec<?,?>> lookupSpecTypeForTarget(Class<BO> targetSuperType) { - if (targetSuperType==null) return null; - BrooklynObjectType best = null; - - for (BrooklynObjectType t: BrooklynObjectType.values()) { - if (t.getSpecType()==null) continue; - if (!t.getInterfaceType().isAssignableFrom(targetSuperType)) continue; - // on equality, exit immediately - if (t.getInterfaceType().equals(targetSuperType)) return t.getSpecType(); - // else pick which is best - if (best==null) { best = t; continue; } - // if t is more specific, it is better (handles case when e.g. a Policy is a subclass of Entity) - if (best.getSpecType().isAssignableFrom(t.getSpecType())) { best = t; continue; } - } - if (best==null) { - log.warn("Unexpected target supertype ("+targetSuperType+"); unable to infer spec type"); - return null; - } - // the spec is more specific, but we're not familiar with it here; return the best - return best.getSpecType(); - } - - public static RegisteredTypeConstraint loader(BrooklynClassLoadingContext loader) { - BasicRegisteredTypeConstraint result = new BasicRegisteredTypeConstraint(); - result.loader = loader; - return result; - } - - public static RegisteredTypeConstraint withLoader(RegisteredTypeConstraint constraint, BrooklynClassLoadingContext loader) { - ((BasicRegisteredTypeConstraint)constraint).loader = loader; - return constraint; - } - -}
