/* * 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.objs.proxy; import java.util.Map; 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.objs.EntityAdjunct; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.api.sensor.Enricher; import org.apache.brooklyn.api.sensor.EnricherSpec; import org.apache.brooklyn.api.sensor.Feed; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigConstraints; import org.apache.brooklyn.core.enricher.AbstractEnricher; import org.apache.brooklyn.core.entity.AbstractEntity; import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.core.policy.AbstractPolicy; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.core.config.ConfigBag; import org.apache.brooklyn.util.exceptions.Exceptions; /** * Creates policies of required types. * * This is an internal class for use by core-brooklyn. End-users are strongly discouraged from * using this class directly. * * Note that calling policies by their constructors has not been "deprecated" (yet!). We just * support both mechanisms, so one can supply PolicySpec in an EntitySpec. * * @author aled */ public class InternalPolicyFactory extends InternalFactory { /** * Returns true if this is a "new-style" policy (i.e. where not expected to call the constructor to instantiate it). * * @param managementContext * @param clazz * * @deprecated since 0.7.0; use {@link InternalFactory#isNewStyle(Class)} */ @Deprecated public static boolean isNewStylePolicy(ManagementContext managementContext, Class<?> clazz) { try { return isNewStylePolicy(clazz); } catch (IllegalArgumentException e) { return false; } } /** * @deprecated since 0.7.0; use {@link InternalFactory#isNewStyle(Class)} */ @Deprecated public static boolean isNewStylePolicy(Class<?> clazz) { if (!Policy.class.isAssignableFrom(clazz)) { throw new IllegalArgumentException("Class "+clazz+" is not a policy"); } return InternalFactory.isNewStyle(clazz); } /** * @deprecated since 0.7.0; use {@link InternalFactory#isNewStyle(Class)} */ @Deprecated public static boolean isNewStyleEnricher(Class<?> clazz) { if (!Enricher.class.isAssignableFrom(clazz)) { throw new IllegalArgumentException("Class "+clazz+" is not an enricher"); } return InternalFactory.isNewStyle(clazz); } public InternalPolicyFactory(ManagementContextInternal managementContext) { super(managementContext); } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T extends Policy> T createPolicy(PolicySpec<T> spec) { if (spec.getFlags().containsKey("parent")) { throw new IllegalArgumentException("Spec's flags must not contain parent; use spec.parent() instead for "+spec); } try { Class<? extends T> clazz = spec.getType(); T pol = construct(clazz, spec.getFlags()); if (spec.getDisplayName()!=null) { ((AbstractPolicy)pol).setDisplayName(spec.getDisplayName()); } if (spec.getCatalogItemId()!=null) { ((AbstractPolicy)pol).setCatalogItemId(spec.getCatalogItemId()); } pol.tags().addTags(spec.getTags()); if (isNewStyle(clazz)) { ((AbstractPolicy)pol).setManagementContext(managementContext); Map<String, Object> config = ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig(); ((AbstractPolicy)pol).configure(MutableMap.copyOf(config)); // TODO AbstractPolicy.configure modifies the map } // TODO Can we avoid this for "new-style policies"? Should we just trust the configure() method, // which the user may have overridden? // Also see InternalLocationFactory for same issue, which this code is based on. for (Map.Entry<ConfigKey<?>, Object> entry : spec.getConfig().entrySet()) { pol.config().set((ConfigKey)entry.getKey(), entry.getValue()); } ConfigConstraints.assertValid(pol); ((AbstractPolicy)pol).init(); return pol; } catch (Exception e) { throw Exceptions.propagate(e); } } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T extends Enricher> T createEnricher(EnricherSpec<T> spec) { if (spec.getFlags().containsKey("parent")) { throw new IllegalArgumentException("Spec's flags must not contain parent; use spec.parent() instead for "+spec); } try { Class<? extends T> clazz = spec.getType(); T enricher = construct(clazz, spec.getFlags()); if (spec.getDisplayName()!=null) ((AbstractEnricher)enricher).setDisplayName(spec.getDisplayName()); if (spec.getCatalogItemId()!=null) { ((AbstractEnricher)enricher).setCatalogItemId(spec.getCatalogItemId()); } enricher.tags().addTags(spec.getTags()); if (isNewStyle(clazz)) { ((AbstractEnricher)enricher).setManagementContext(managementContext); Map<String, Object> config = ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig(); ((AbstractEnricher)enricher).configure(MutableMap.copyOf(config)); // TODO AbstractEnricher.configure modifies the map } // TODO Can we avoid this for "new-style policies"? Should we just trust the configure() method, // which the user may have overridden? // Also see InternalLocationFactory for same issue, which this code is based on. for (Map.Entry<ConfigKey<?>, Object> entry : spec.getConfig().entrySet()) { enricher.config().set((ConfigKey)entry.getKey(), entry.getValue()); } ConfigConstraints.assertValid(enricher); ((AbstractEnricher)enricher).init(); return enricher; } catch (Exception e) { throw Exceptions.propagate(e); } } /** * Constructs a new-style policy (fails if no no-arg constructor). */ public <T extends Policy> T constructPolicy(Class<T> clazz) { return super.constructNewStyle(clazz); } /** * Constructs a new-style enricher (fails if no no-arg constructor). */ public <T extends Enricher> T constructEnricher(Class<T> clazz) { return super.constructNewStyle(clazz); } /** * Constructs a new-style feed (fails if no no-arg constructor). */ public <T extends Feed> T constructFeed(Class<T> clazz) { return super.constructNewStyle(clazz); } }