/* * 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.lang.reflect.InvocationTargetException; import java.util.Map; import java.util.Map.Entry; 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.config.ConfigKey; import org.apache.brooklyn.core.location.AbstractLocation; import org.apache.brooklyn.core.location.internal.LocationInternal; import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager; import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.util.core.config.ConfigBag; import org.apache.brooklyn.util.core.flags.FlagUtils; import org.apache.brooklyn.util.exceptions.Exceptions; import com.google.common.collect.ImmutableMap; /** * Creates locations of required types. * * This is an internal class for use by core-brooklyn. End-users are strongly discouraged from * using this class directly. * * @author aled */ public class InternalLocationFactory extends InternalFactory { /** * Returns true if this is a "new-style" location (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 isNewStyleLocation(ManagementContext managementContext, Class<?> clazz) { try { return isNewStyleLocation(clazz); } catch (IllegalArgumentException e) { return false; } } /** * @deprecated since 0.7.0; use {@link InternalFactory#isNewStyle(Class)} */ @Deprecated public static boolean isNewStyleLocation(Class<?> clazz) { if (!Location.class.isAssignableFrom(clazz)) { throw new IllegalArgumentException("Class "+clazz+" is not an location"); } return InternalFactory.isNewStyle(clazz); } public InternalLocationFactory(ManagementContextInternal managementContext) { super(managementContext); } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T extends Location> T createLocation(LocationSpec<T> spec) { if (spec.getFlags().containsKey("parent")) { throw new IllegalArgumentException("Spec's flags must not contain parent; use spec.parent() instead for "+spec); } if (spec.getFlags().containsKey("id")) { throw new IllegalArgumentException("Spec's flags must not contain id; use spec.id() instead for "+spec); } if (spec.getId() != null && ((LocalLocationManager)managementContext.getLocationManager()).isKnownLocationId(spec.getId())) { throw new IllegalArgumentException("Entity with id "+spec.getId()+" already exists; cannot create new entity with this explicit id from spec "+spec); } try { Class<? extends T> clazz = spec.getType(); T loc = construct(clazz, spec.getFlags()); if (spec.getId() != null) { FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", spec.getId()), loc); } managementContext.prePreManage(loc); if (spec.getDisplayName()!=null) ((AbstractLocation)loc).setDisplayName(spec.getDisplayName()); if (spec.getCatalogItemId()!=null) { ((AbstractLocation)loc).setCatalogItemId(spec.getCatalogItemId()); } loc.tags().addTags(spec.getTags()); if (isNewStyle(clazz)) { ((AbstractLocation)loc).setManagementContext(managementContext); ((AbstractLocation)loc).configure(ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig()); } for (Map.Entry<ConfigKey<?>, Object> entry : spec.getConfig().entrySet()) { ((AbstractLocation)loc).config().set((ConfigKey)entry.getKey(), entry.getValue()); } for (Entry<Class<?>, Object> entry : spec.getExtensions().entrySet()) { ((LocationInternal)loc).addExtension((Class)entry.getKey(), entry.getValue()); } ((AbstractLocation)loc).init(); Location parent = spec.getParent(); if (parent != null) { loc.setParent(parent); } return loc; } catch (Exception e) { throw Exceptions.propagate(e); } } /** * Constructs a new-style entity (fails if no no-arg constructor). */ public <T extends Location> T constructLocation(Class<T> clazz) { return super.constructNewStyle(clazz); } @Override protected <T> T constructOldStyle(Class<T> clazz, Map<String,?> flags) throws InstantiationException, IllegalAccessException, InvocationTargetException { if (flags.containsKey("parent") || flags.containsKey("owner")) { throw new IllegalArgumentException("Spec's flags must not contain parent or owner; use spec.parent() instead for "+clazz); } return super.constructOldStyle(clazz, flags); } }