refer to RelationshipType rather than Relationship this allows us to reserve Relationships for instances of links which might be BrooklynObjects with config, etc.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/09aab586 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/09aab586 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/09aab586 Branch: refs/heads/master Commit: 09aab586a1cb76dd587b947e3285afa96facce1b Parents: 890c5c0 Author: Alex Heneveld <[email protected]> Authored: Tue Oct 27 12:44:17 2015 +0000 Committer: Alex Heneveld <[email protected]> Committed: Tue Oct 27 12:44:17 2015 +0000 ---------------------------------------------------------------------- .../brooklyn/basic/relations/Relationship.java | 38 ---- .../basic/relations/RelationshipType.java | 38 ++++ .../brooklyn/api/objs/BrooklynObject.java | 21 ++- .../brooklyn/core/entity/EntityRelations.java | 80 +++++--- .../AbstractBrooklynObjectRebindSupport.java | 6 +- .../mgmt/rebind/dto/MementosGenerators.java | 6 +- .../relations/AbstractBasicRelationSupport.java | 14 +- .../relations/ByObjectBasicRelationSupport.java | 16 +- .../core/relations/EmptyRelationSupport.java | 10 +- .../core/relations/RelationshipTypes.java | 188 +++++++++++++++++++ .../brooklyn/core/relations/Relationships.java | 188 ------------------- .../core/relations/RelationshipTest.java | 10 +- 12 files changed, 322 insertions(+), 293 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/api/src/main/java/brooklyn/basic/relations/Relationship.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/brooklyn/basic/relations/Relationship.java b/api/src/main/java/brooklyn/basic/relations/Relationship.java deleted file mode 100644 index bc17e6a..0000000 --- a/api/src/main/java/brooklyn/basic/relations/Relationship.java +++ /dev/null @@ -1,38 +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 brooklyn.basic.relations; - -import brooklyn.basic.relations.Relationship; - - -public interface Relationship<SourceType,TargetType> { - - public String getRelationshipTypeName(); - public Class<SourceType> getSourceType(); - public Class<TargetType> getTargetType(); - - public String getSourceName(); - public String getSourceNamePlural(); - - public String getTargetName(); - public String getTargetNamePlural(); - - public Relationship<TargetType,SourceType> getInverseRelationship(); - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/api/src/main/java/brooklyn/basic/relations/RelationshipType.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/brooklyn/basic/relations/RelationshipType.java b/api/src/main/java/brooklyn/basic/relations/RelationshipType.java new file mode 100644 index 0000000..f7d6abb --- /dev/null +++ b/api/src/main/java/brooklyn/basic/relations/RelationshipType.java @@ -0,0 +1,38 @@ +/* + * 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 brooklyn.basic.relations; + +import brooklyn.basic.relations.RelationshipType; + + +public interface RelationshipType<SourceType,TargetType> { + + public String getRelationshipTypeName(); + public Class<SourceType> getSourceType(); + public Class<TargetType> getTargetType(); + + public String getSourceName(); + public String getSourceNamePlural(); + + public String getTargetName(); + public String getTargetNamePlural(); + + public RelationshipType<TargetType,SourceType> getInverseRelationshipType(); + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObject.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObject.java b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObject.java index 9e1640f..f388bd6 100644 --- a/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObject.java +++ b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObject.java @@ -34,7 +34,7 @@ import org.apache.brooklyn.api.sensor.SensorEventListener; import com.google.common.annotations.Beta; import com.google.common.collect.ImmutableMap; -import brooklyn.basic.relations.Relationship; +import brooklyn.basic.relations.RelationshipType; /** * Super-type of entity, location, policy and enricher. @@ -151,9 +151,20 @@ public interface BrooklynObject extends Identifiable, Configurable { } public interface RelationSupport<T extends BrooklynObject> { - public <U extends BrooklynObject> void add(Relationship<? super T,? super U> relationship, U target); - public <U extends BrooklynObject> void remove(Relationship<? super T,? super U> relationship, U target); - public Set<Relationship<? super T,? extends BrooklynObject>> getRelationships(); - public <U extends BrooklynObject> Set<U> getRelations(Relationship<? super T,U> relationship); + /** Adds a relationship of the given type from this object pointing at the given target, + * and ensures that the inverse relationship (if there is one) is present at the target pointing back at this object. + */ + public <U extends BrooklynObject> void add(RelationshipType<? super T,? super U> relationship, U target); + + /** Removes any and all relationships of the given type from this object pointing at the given target, + * and ensures that the inverse relationships (if there are one) are also removed. + */ + public <U extends BrooklynObject> void remove(RelationshipType<? super T,? super U> relationship, U target); + + /** @return the {@link RelationshipType}s originating from this object */ + public Set<RelationshipType<? super T,? extends BrooklynObject>> getRelationshipTypes(); + + /** @return the {@link BrooklynObject}s which are targets of the given {@link RelationshipType} */ + public <U extends BrooklynObject> Set<U> getRelations(RelationshipType<? super T,U> relationshipType); } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/core/src/main/java/org/apache/brooklyn/core/entity/EntityRelations.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/EntityRelations.java b/core/src/main/java/org/apache/brooklyn/core/entity/EntityRelations.java index 4621a76..6203f22 100644 --- a/core/src/main/java/org/apache/brooklyn/core/entity/EntityRelations.java +++ b/core/src/main/java/org/apache/brooklyn/core/entity/EntityRelations.java @@ -26,14 +26,16 @@ import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.Group; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.objs.BrooklynObject; +import org.apache.brooklyn.api.objs.BrooklynObject.RelationSupport; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.core.objs.BrooklynObjectInternal; -import org.apache.brooklyn.core.relations.Relationships; +import org.apache.brooklyn.core.relations.AbstractBasicRelationSupport; +import org.apache.brooklyn.core.relations.RelationshipTypes; import org.apache.brooklyn.util.collections.MutableMap; import com.google.common.annotations.Beta; -import brooklyn.basic.relations.Relationship; +import brooklyn.basic.relations.RelationshipType; /** TODO these relations are not used yet; see issue where this is introduced and email thread */ @Beta @@ -43,31 +45,31 @@ public class EntityRelations<T extends BrooklynObject> { * in the internal Brooklyn management hierarchy model. * Apart from root {@link Application} entities, every deployed entity must have exactly one manager. * The inverse relationship is {@link #MANAGED_BY}. */ - public static final Relationship<Entity,Entity> MANAGER_OF = Relationships.newRelationshipPair( + public static final RelationshipType<Entity,Entity> MANAGER_OF = RelationshipTypes.newRelationshipPair( "manager", "managers", Entity.class, "manager_of", "managed child", "managed children", Entity.class, "managed_by"); /** Inverse of {@link #MANAGER_OF}. */ - public static final Relationship<Entity,Entity> MANAGED_BY = MANAGER_OF.getInverseRelationship(); + public static final RelationshipType<Entity,Entity> MANAGED_BY = MANAGER_OF.getInverseRelationshipType(); /** {@link #GROUP_CONTAINS} indicates that one entity, typically a {@link Group}, * has zero or more entities which are labelled as "members" of that group entity. * What membership means will depend on the group entity. * An entity may be a member of any number of other entities. * The inverse relationship is {@link #IN_GROUP}. */ - public static final Relationship<Entity,Entity> GROUP_CONTAINS = Relationships.newRelationshipPair( + public static final RelationshipType<Entity,Entity> GROUP_CONTAINS = RelationshipTypes.newRelationshipPair( "group", "groups", Entity.class, "group_contains", "member", "members", Entity.class, "in_group"); /** Inverse of {@link #GROUP_CONTAINS}. */ - public static final Relationship<Entity,Entity> IN_GROUP = GROUP_CONTAINS.getInverseRelationship(); + public static final RelationshipType<Entity,Entity> IN_GROUP = GROUP_CONTAINS.getInverseRelationshipType(); /** {@link #HAS_TARGET} indicates that one entity directs to one or more other entities. * What this targeting relationship means depends on the targetter. * The inverse relationship is {@link #TARGETTED_BY}. */ - public static final Relationship<Entity,Entity> HAS_TARGET = Relationships.newRelationshipPair( + public static final RelationshipType<Entity,Entity> HAS_TARGET = RelationshipTypes.newRelationshipPair( "targetter", "targetters", Entity.class, "has_target", "target", "targets", Entity.class, "targetted_by"); /** Inverse of {@link #HAS_TARGET}. */ - public static final Relationship<Entity,Entity> TARGETTED_BY = HAS_TARGET.getInverseRelationship(); + public static final RelationshipType<Entity,Entity> TARGETTED_BY = HAS_TARGET.getInverseRelationshipType(); /** {@link #ACTIVE_PARENT_OF} indicates that one entity is should be considered as the logical parent of another, * e.g. for presentation purposes to the end user. @@ -86,28 +88,28 @@ public class EntityRelations<T extends BrooklynObject> { * <p> * The inverse relationship is {@link #ACTIVE_CHILD_OF}, * and an entity should normally be an {@link #ACTIVE_CHILD_OF} zero or one entities. */ - public static final Relationship<Entity,Entity> ACTIVE_PARENT_OF = Relationships.newRelationshipPair( + public static final RelationshipType<Entity,Entity> ACTIVE_PARENT_OF = RelationshipTypes.newRelationshipPair( "parent", "parents", Entity.class, "parent_of_active", "active child", "active children", Entity.class, "active_child_of"); /** Inverse of {@link #ACTIVE_PARENT_OF}. */ - public static final Relationship<Entity,Entity> ACTIVE_CHILD_OF = ACTIVE_PARENT_OF.getInverseRelationship(); + public static final RelationshipType<Entity,Entity> ACTIVE_CHILD_OF = ACTIVE_PARENT_OF.getInverseRelationshipType(); /** {@link #HAS_POLICY} indicates that an entity has a policy associated to it. * The inverse relationship is {@link #POLICY_FOR}. */ - public static final Relationship<Entity,Policy> HAS_POLICY = Relationships.newRelationshipPair( + public static final RelationshipType<Entity,Policy> HAS_POLICY = RelationshipTypes.newRelationshipPair( "entity", "entities", Entity.class, "has_policy", "policy", "policies", Policy.class, "policy_for"); /** Inverse of {@link #HAS_POLICY}. */ - public static final Relationship<Policy,Entity> POLICY_FOR = HAS_POLICY.getInverseRelationship(); + public static final RelationshipType<Policy,Entity> POLICY_FOR = HAS_POLICY.getInverseRelationshipType(); // ---- // TODO replace by relations stored in catalog when catalog supports arbitrary types - private static Map<String,Relationship<? extends BrooklynObject, ? extends BrooklynObject>> KNOWN_RELATIONSHIPS = MutableMap.of(); - private static void addRelationship(Relationship<? extends BrooklynObject, ? extends BrooklynObject> r) { + private static Map<String,RelationshipType<? extends BrooklynObject, ? extends BrooklynObject>> KNOWN_RELATIONSHIPS = MutableMap.of(); + private static void addRelationship(RelationshipType<? extends BrooklynObject, ? extends BrooklynObject> r) { KNOWN_RELATIONSHIPS.put(r.getRelationshipTypeName(), r); - if (r.getInverseRelationship()!=null) { - KNOWN_RELATIONSHIPS.put(r.getInverseRelationship().getRelationshipTypeName(), r.getInverseRelationship()); + if (r.getInverseRelationshipType()!=null) { + KNOWN_RELATIONSHIPS.put(r.getInverseRelationshipType().getRelationshipTypeName(), r.getInverseRelationshipType()); } } static { @@ -122,9 +124,9 @@ public class EntityRelations<T extends BrooklynObject> { * it may fail fast or return null or create a poor-man's relationship instance. */ @Beta - public static Relationship<? extends BrooklynObject, ? extends BrooklynObject> lookup(ManagementContext mgmt, String relationshipTypeName) { + public static RelationshipType<? extends BrooklynObject, ? extends BrooklynObject> lookup(ManagementContext mgmt, String relationshipTypeName) { if (relationshipTypeName==null) return null; - Relationship<? extends BrooklynObject, ? extends BrooklynObject> result = KNOWN_RELATIONSHIPS.get(relationshipTypeName); + RelationshipType<? extends BrooklynObject, ? extends BrooklynObject> result = KNOWN_RELATIONSHIPS.get(relationshipTypeName); if (result!=null) return result; /* TODO ultimately we'd like to support arbitrary relationships via persistence and lookup against the catalog; @@ -132,31 +134,47 @@ public class EntityRelations<T extends BrooklynObject> { * we are smart about the relationships defined here, and we return a poor-man's version for items elsewhere. * * for now, a poor-man's relationship; if not in catalog ultimately we should fail. */ - return Relationships.newRelationshipOneway("source", "sources", BrooklynObject.class, relationshipTypeName, "target", "targets", BrooklynObject.class); + return RelationshipTypes.newRelationshipOneway("source", "sources", BrooklynObject.class, relationshipTypeName, "target", "targets", BrooklynObject.class); } + /** + * As {@link RelationSupport#getRelationshipTypes()} for the given object. Callers can use either method. + * See {@link AbstractBasicRelationSupport} for a discussion of why double dispatch is used and both methods are present. + */ @SuppressWarnings({ "rawtypes", "unchecked" }) - public static <T extends BrooklynObject> Set<Relationship<? super T,? extends BrooklynObject>> getRelationships(T source) { - return (Set) ((BrooklynObjectInternal)source).relations().getLocalBackingStore().getRelationships(); + public static <T extends BrooklynObject> Set<RelationshipType<? super T,? extends BrooklynObject>> getRelationshipTypes(T source) { + return (Set) ((BrooklynObjectInternal)source).relations().getLocalBackingStore().getRelationshipTypes(); } + /** + * As {@link RelationSupport#getRelations(RelationshipType)} for the given object. Callers can use either method. + * See {@link AbstractBasicRelationSupport} for a discussion of why double dispatch is used and both methods are present. + */ @SuppressWarnings({ "rawtypes", "unchecked" }) - public static <T extends BrooklynObject,U extends BrooklynObject> Set<U> getRelations(Relationship<? super T,U> relationship, T source) { - return (Set) ((BrooklynObjectInternal)source).relations().getLocalBackingStore().getRelations((Relationship)relationship); + public static <T extends BrooklynObject,U extends BrooklynObject> Set<U> getRelations(RelationshipType<? super T,U> relationship, T source) { + return (Set) ((BrooklynObjectInternal)source).relations().getLocalBackingStore().getRelations((RelationshipType)relationship); } + /** + * As {@link RelationSupport#add(RelationshipType, BrooklynObject)} for the given object. Callers can use either method. + * See {@link AbstractBasicRelationSupport} for a discussion of why double dispatch is used and both methods are present. + */ @SuppressWarnings({ "rawtypes", "unchecked" }) - public static <T extends BrooklynObject,U extends BrooklynObject> void add(T source, Relationship<? super T,? super U> relationship, U target) { - ((BrooklynObjectInternal)source).relations().getLocalBackingStore().add((Relationship)relationship, target); - if (relationship.getInverseRelationship()!=null) - ((BrooklynObjectInternal)target).relations().getLocalBackingStore().add((Relationship)relationship.getInverseRelationship(), source); + public static <T extends BrooklynObject,U extends BrooklynObject> void add(T source, RelationshipType<? super T,? super U> relationship, U target) { + ((BrooklynObjectInternal)source).relations().getLocalBackingStore().add((RelationshipType)relationship, target); + if (relationship.getInverseRelationshipType()!=null) + ((BrooklynObjectInternal)target).relations().getLocalBackingStore().add((RelationshipType)relationship.getInverseRelationshipType(), source); } + /** + * As {@link RelationSupport#remove(RelationshipType, BrooklynObject)} for the given object. Callers can use either method. + * See {@link AbstractBasicRelationSupport} for a discussion of why double dispatch is used and both methods are present. + */ @SuppressWarnings({ "rawtypes", "unchecked" }) - public static <T extends BrooklynObject,U extends BrooklynObject> void remove(T source, Relationship<? super T,? super U> relationship, U target) { - ((BrooklynObjectInternal)source).relations().getLocalBackingStore().remove((Relationship)relationship, target); - if (relationship.getInverseRelationship()!=null) - ((BrooklynObjectInternal)target).relations().getLocalBackingStore().remove((Relationship)relationship.getInverseRelationship(), source); + public static <T extends BrooklynObject,U extends BrooklynObject> void remove(T source, RelationshipType<? super T,? super U> relationship, U target) { + ((BrooklynObjectInternal)source).relations().getLocalBackingStore().remove((RelationshipType)relationship, target); + if (relationship.getInverseRelationshipType()!=null) + ((BrooklynObjectInternal)target).relations().getLocalBackingStore().remove((RelationshipType)relationship.getInverseRelationshipType(), source); } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/AbstractBrooklynObjectRebindSupport.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/AbstractBrooklynObjectRebindSupport.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/AbstractBrooklynObjectRebindSupport.java index b56d8c6..8c5abdf 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/AbstractBrooklynObjectRebindSupport.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/AbstractBrooklynObjectRebindSupport.java @@ -34,7 +34,7 @@ import org.apache.brooklyn.util.text.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.basic.relations.Relationship; +import brooklyn.basic.relations.RelationshipType; public abstract class AbstractBrooklynObjectRebindSupport<T extends Memento> implements RebindSupport<T> { @@ -87,12 +87,12 @@ public abstract class AbstractBrooklynObjectRebindSupport<T extends Memento> imp @SuppressWarnings({ "unchecked", "rawtypes" }) protected void addRelations(RebindContext rebindContext, T memento) { for (Map.Entry<String,Set<String>> rEntry : memento.getRelations().entrySet()) { - Relationship<? extends BrooklynObject, ? extends BrooklynObject> r = EntityRelations.lookup(instance.getManagementContext(), rEntry.getKey()); + RelationshipType<? extends BrooklynObject, ? extends BrooklynObject> r = EntityRelations.lookup(instance.getManagementContext(), rEntry.getKey()); if (r==null) throw new IllegalStateException("Unsupported relationship -- "+rEntry.getKey() + " -- in "+memento); for (String itemId: rEntry.getValue()) { BrooklynObject item = rebindContext.lookup().lookup(null, itemId); if (item != null) { - instance.relations().add((Relationship)r, item); + instance.relations().add((RelationshipType)r, item); } else { LOG.warn("Item not found; discarding item {} relation {} of entity {}({})", new Object[] {itemId, r, memento.getType(), memento.getId()}); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java index 918278c..f0c08a6 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java @@ -68,7 +68,7 @@ import com.google.common.base.Function; import com.google.common.base.Predicates; import com.google.common.collect.Sets; -import brooklyn.basic.relations.Relationship; +import brooklyn.basic.relations.RelationshipType; public class MementosGenerators { @@ -449,9 +449,9 @@ public class MementosGenerators { builder.tags.add(tag); } // CatalogItems return empty support, so this is safe even through they don't support relations - for (Relationship<?,? extends BrooklynObject> relationship: instance.relations().getRelationships()) { + for (RelationshipType<?,? extends BrooklynObject> relationship: instance.relations().getRelationshipTypes()) { @SuppressWarnings({ "unchecked", "rawtypes" }) - Set relations = instance.relations().getRelations((Relationship)relationship); + Set relations = instance.relations().getRelations((RelationshipType)relationship); Set<String> relationIds = Sets.newLinkedHashSet(); for (Object r: relations) relationIds.add( ((BrooklynObject)r).getId() ); builder.relations.put(relationship.getRelationshipTypeName(), relationIds); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/core/src/main/java/org/apache/brooklyn/core/relations/AbstractBasicRelationSupport.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/relations/AbstractBasicRelationSupport.java b/core/src/main/java/org/apache/brooklyn/core/relations/AbstractBasicRelationSupport.java index 6483e97..a76d349 100644 --- a/core/src/main/java/org/apache/brooklyn/core/relations/AbstractBasicRelationSupport.java +++ b/core/src/main/java/org/apache/brooklyn/core/relations/AbstractBasicRelationSupport.java @@ -24,14 +24,14 @@ import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.core.entity.EntityRelations; import org.apache.brooklyn.core.objs.BrooklynObjectInternal.RelationSupportInternal; -import brooklyn.basic.relations.Relationship; +import brooklyn.basic.relations.RelationshipType; /** This abstract impl delegates to {@link EntityRelations} for all changes, routing through a local backing store. * This allows us to make the changes in both directions simultaneously when a relationship is bi-directional, * and should facilitate changing a backing datastore or remote instances when that is supported. * <p> * Currently it can be implemented without it, simplifying things a bit (avoiding the double dispatch) - * apart from the {@link #add(Relationship, BrooklynObject)} method triggering the reverse addition + * apart from the {@link #add(RelationshipType, BrooklynObject)} method triggering the reverse addition * if it isn't already present. TBD which is better (and the internal call to get the backing store is * marked as Beta). */ public abstract class AbstractBasicRelationSupport<SourceType extends BrooklynObject> implements RelationSupportInternal<SourceType> { @@ -41,22 +41,22 @@ public abstract class AbstractBasicRelationSupport<SourceType extends BrooklynOb public AbstractBasicRelationSupport(SourceType source) { this.source = source; } @Override - public Set<Relationship<? super SourceType, ? extends BrooklynObject>> getRelationships() { - return EntityRelations.getRelationships(source); + public Set<RelationshipType<? super SourceType, ? extends BrooklynObject>> getRelationshipTypes() { + return EntityRelations.getRelationshipTypes(source); } @Override - public <U extends BrooklynObject> Set<U> getRelations(Relationship<? super SourceType, U> relationship) { + public <U extends BrooklynObject> Set<U> getRelations(RelationshipType<? super SourceType, U> relationship) { return EntityRelations.getRelations(relationship, source); } @Override - public <U extends BrooklynObject> void add(Relationship<? super SourceType, ? super U> relationship, U target) { + public <U extends BrooklynObject> void add(RelationshipType<? super SourceType, ? super U> relationship, U target) { EntityRelations.add(source, relationship, target); } @Override - public <U extends BrooklynObject> void remove(Relationship<? super SourceType, ? super U> relationship, U target) { + public <U extends BrooklynObject> void remove(RelationshipType<? super SourceType, ? super U> relationship, U target) { EntityRelations.remove(source, relationship, target); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/core/src/main/java/org/apache/brooklyn/core/relations/ByObjectBasicRelationSupport.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/relations/ByObjectBasicRelationSupport.java b/core/src/main/java/org/apache/brooklyn/core/relations/ByObjectBasicRelationSupport.java index 3600640..5e065c0 100644 --- a/core/src/main/java/org/apache/brooklyn/core/relations/ByObjectBasicRelationSupport.java +++ b/core/src/main/java/org/apache/brooklyn/core/relations/ByObjectBasicRelationSupport.java @@ -31,7 +31,7 @@ import com.google.common.base.Supplier; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; -import brooklyn.basic.relations.Relationship; +import brooklyn.basic.relations.RelationshipType; public class ByObjectBasicRelationSupport<SourceType extends BrooklynObject> extends AbstractBasicRelationSupport<SourceType> { @@ -56,7 +56,7 @@ public class ByObjectBasicRelationSupport<SourceType extends BrooklynObject> ext } // TODO for now, relationships are stored here (and persisted); ideally we'd look them up in catalog - private Map<String,Relationship<? super T,? extends BrooklynObject>> relationships = MutableMap.of(); + private Map<String,RelationshipType<? super T,? extends BrooklynObject>> relationshipTypes = MutableMap.of(); private Multimap<String,BrooklynObject> relations = Multimaps.newMultimap(MutableMap.<String,Collection<BrooklynObject>>of(), new Supplier<Collection<BrooklynObject>>() { @@ -65,14 +65,14 @@ public class ByObjectBasicRelationSupport<SourceType extends BrooklynObject> ext } }); - public Set<Relationship<? super T,? extends BrooklynObject>> getRelationships() { + public Set<RelationshipType<? super T,? extends BrooklynObject>> getRelationshipTypes() { synchronized (relations) { - return MutableSet.copyOf(relationships.values()); + return MutableSet.copyOf(relationshipTypes.values()); } } @SuppressWarnings("unchecked") @Override - public <U extends BrooklynObject> Set<U> getRelations(Relationship<? super T, U> relationship) { + public <U extends BrooklynObject> Set<U> getRelations(RelationshipType<? super T, U> relationship) { synchronized (relations) { return (Set<U>)MutableSet.copyOf(relations.get(relationship.getRelationshipTypeName())); } @@ -80,16 +80,16 @@ public class ByObjectBasicRelationSupport<SourceType extends BrooklynObject> ext @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public <U extends BrooklynObject> void add(Relationship<? super T,? super U> relationship, U target) { + public <U extends BrooklynObject> void add(RelationshipType<? super T,? super U> relationship, U target) { synchronized (relations) { - relationships.put(relationship.getRelationshipTypeName(), (Relationship)relationship); + relationshipTypes.put(relationship.getRelationshipTypeName(), (RelationshipType)relationship); relations.put(relationship.getRelationshipTypeName(), target); } onRelationsChanged(); } @Override - public <U extends BrooklynObject> void remove(Relationship<? super T,? super U> relationship, U target) { + public <U extends BrooklynObject> void remove(RelationshipType<? super T,? super U> relationship, U target) { synchronized (relations) { relations.remove(relationship.getRelationshipTypeName(), target); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/core/src/main/java/org/apache/brooklyn/core/relations/EmptyRelationSupport.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/relations/EmptyRelationSupport.java b/core/src/main/java/org/apache/brooklyn/core/relations/EmptyRelationSupport.java index 40b001a..e1e721d 100644 --- a/core/src/main/java/org/apache/brooklyn/core/relations/EmptyRelationSupport.java +++ b/core/src/main/java/org/apache/brooklyn/core/relations/EmptyRelationSupport.java @@ -25,7 +25,7 @@ import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.api.objs.BrooklynObject.RelationSupport; import org.apache.brooklyn.core.objs.BrooklynObjectInternal.RelationSupportInternal; -import brooklyn.basic.relations.Relationship; +import brooklyn.basic.relations.RelationshipType; public final class EmptyRelationSupport<SourceType extends BrooklynObject> implements RelationSupportInternal<SourceType> { @@ -34,22 +34,22 @@ public final class EmptyRelationSupport<SourceType extends BrooklynObject> imple public EmptyRelationSupport(SourceType source) { this.source = source; } @Override - public Set<Relationship<? super SourceType, ? extends BrooklynObject>> getRelationships() { + public Set<RelationshipType<? super SourceType, ? extends BrooklynObject>> getRelationshipTypes() { return Collections.emptySet(); } @Override - public <U extends BrooklynObject> Set<U> getRelations(Relationship<? super SourceType, U> relationship) { + public <U extends BrooklynObject> Set<U> getRelations(RelationshipType<? super SourceType, U> relationship) { return Collections.emptySet(); } @Override - public <U extends BrooklynObject> void add(Relationship<? super SourceType, ? super U> relationship, U target) { + public <U extends BrooklynObject> void add(RelationshipType<? super SourceType, ? super U> relationship, U target) { throw new UnsupportedOperationException("Relations not available on "+source); } @Override - public <U extends BrooklynObject> void remove(Relationship<? super SourceType, ? super U> relationship, U target) { + public <U extends BrooklynObject> void remove(RelationshipType<? super SourceType, ? super U> relationship, U target) { } @Override http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/core/src/main/java/org/apache/brooklyn/core/relations/RelationshipTypes.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/relations/RelationshipTypes.java b/core/src/main/java/org/apache/brooklyn/core/relations/RelationshipTypes.java new file mode 100644 index 0000000..b358039 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/relations/RelationshipTypes.java @@ -0,0 +1,188 @@ +/* + * 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.relations; + +import com.google.common.base.Objects; + +import brooklyn.basic.relations.RelationshipType; + +public class RelationshipTypes { + + private static abstract class AbstractBasicRelationship<SourceType,TargetType> implements RelationshipType<SourceType,TargetType> { + private final String relationshipTypeName; + private final String sourceName; + private final String sourceNamePlural; + private final Class<TargetType> targetType; + + private AbstractBasicRelationship(String relationshipTypeName, String sourceName, String sourceNamePlural, Class<TargetType> targetType) { + this.relationshipTypeName = relationshipTypeName; + this.sourceName = sourceName; + this.sourceNamePlural = sourceNamePlural; + this.targetType = targetType; + } + + @Override + public String getRelationshipTypeName() { + return relationshipTypeName; + } + + @Override + public String getSourceName() { + return sourceName; + } + + @Override + public String getSourceNamePlural() { + return sourceNamePlural; + } + + @Override + public Class<TargetType> getTargetType() { + return targetType; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (!(obj instanceof AbstractBasicRelationship)) return false; + + @SuppressWarnings("rawtypes") + AbstractBasicRelationship other = (AbstractBasicRelationship) obj; + + // only look at type name and class; name of source and target is informational + if (!Objects.equal(relationshipTypeName, other.relationshipTypeName)) return false; + if (!Objects.equal(getSourceType(), other.getSourceType())) return false; + if (!Objects.equal(targetType, other.targetType)) return false; + + if (getInverseRelationshipType() == null) { + // require both null or... + if (other.getInverseRelationshipType() != null) + return false; + } else { + // ... they have same type name + // (don't recurse as that sets up infinite loop) + if (other.getInverseRelationshipType() == null) + return false; + if (!Objects.equal(getInverseRelationshipType().getRelationshipTypeName(), other.getInverseRelationshipType().getRelationshipTypeName())) return false; + } + + return true; + } + + @Override + public int hashCode() { + // comments as per equals + return Objects.hashCode(relationshipTypeName, getSourceType(), targetType, + getInverseRelationshipType()!=null ? getInverseRelationshipType().getRelationshipTypeName() : null); + } + + @Override + public String toString() { + return relationshipTypeName; + } + } + + private static class BasicRelationshipWithInverse<SourceType,TargetType> extends AbstractBasicRelationship<SourceType,TargetType> { + private BasicRelationshipWithInverse<TargetType,SourceType> inverseRelationshipType; + + private BasicRelationshipWithInverse(String relationshipTypeName, String sourceName, String sourceNamePlural, Class<TargetType> targetType) { + super(relationshipTypeName, sourceName, sourceNamePlural, targetType); + } + + @Override + public RelationshipType<TargetType,SourceType> getInverseRelationshipType() { + return inverseRelationshipType; + } + + @Override + public Class<SourceType> getSourceType() { + if (getInverseRelationshipType()==null) return null; + return getInverseRelationshipType().getTargetType(); + } + + @Override + public String getTargetName() { + if (getInverseRelationshipType()==null) return null; + return getInverseRelationshipType().getSourceName(); + } + + @Override + public String getTargetNamePlural() { + if (getInverseRelationshipType()==null) return null; + return getInverseRelationshipType().getSourceNamePlural(); + } + } + + private static class BasicRelationshipOneWay<SourceType,TargetType> extends AbstractBasicRelationship<SourceType,TargetType> { + + private final String targetName; + private final String targetNamePlural; + private final Class<SourceType> sourceType; + + private BasicRelationshipOneWay(String sourceName, String sourceNamePlural, Class<SourceType> sourceType, String toTargetRelationshipTypeName, + String targetName, String targetNamePlural, Class<TargetType> targetType) { + super(toTargetRelationshipTypeName, sourceName, sourceNamePlural, targetType); + this.targetName = targetName; + this.targetNamePlural = targetNamePlural; + this.sourceType = sourceType; + } + + @Override + public Class<SourceType> getSourceType() { + return sourceType; + } + + @Override + public String getTargetName() { + return targetName; + } + + @Override + public String getTargetNamePlural() { + return targetNamePlural; + } + + @Override + public RelationshipType<TargetType, SourceType> getInverseRelationshipType() { + return null; + } + } + + public static <SourceType,TargetType> RelationshipType<SourceType,TargetType> newRelationshipPair( + String sourceName, String sourceNamePlural, Class<SourceType> sourceType, String toTargetRelationshipTypeName, + String targetName, String targetNamePlural, Class<TargetType> targetType, String toSourceRelationshipTypeName) { + BasicRelationshipWithInverse<SourceType, TargetType> r1 = new BasicRelationshipWithInverse<SourceType, TargetType>( + toTargetRelationshipTypeName, sourceName, sourceNamePlural, targetType); + BasicRelationshipWithInverse<TargetType, SourceType> r2 = new BasicRelationshipWithInverse<TargetType, SourceType>( + toSourceRelationshipTypeName, targetName, targetNamePlural, sourceType); + r1.inverseRelationshipType = r2; + r2.inverseRelationshipType = r1; + return r1; + } + + public static <SourceType,TargetType> RelationshipType<SourceType,TargetType> newRelationshipOneway( + String sourceName, String sourceNamePlural, Class<SourceType> sourceType, String toTargetRelationshipTypeName, + String targetName, String targetNamePlural, Class<TargetType> targetType) { + return new BasicRelationshipOneWay<SourceType,TargetType>( + sourceName, sourceNamePlural, sourceType, toTargetRelationshipTypeName, + targetName, targetNamePlural, targetType); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/core/src/main/java/org/apache/brooklyn/core/relations/Relationships.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/relations/Relationships.java b/core/src/main/java/org/apache/brooklyn/core/relations/Relationships.java deleted file mode 100644 index 8f7ad54..0000000 --- a/core/src/main/java/org/apache/brooklyn/core/relations/Relationships.java +++ /dev/null @@ -1,188 +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.relations; - -import com.google.common.base.Objects; - -import brooklyn.basic.relations.Relationship; - -public class Relationships { - - private static abstract class AbstractBasicRelationship<SourceType,TargetType> implements Relationship<SourceType,TargetType> { - private final String relationshipTypeName; - private final String sourceName; - private final String sourceNamePlural; - private final Class<TargetType> targetType; - - private AbstractBasicRelationship(String relationshipTypeName, String sourceName, String sourceNamePlural, Class<TargetType> targetType) { - this.relationshipTypeName = relationshipTypeName; - this.sourceName = sourceName; - this.sourceNamePlural = sourceNamePlural; - this.targetType = targetType; - } - - @Override - public String getRelationshipTypeName() { - return relationshipTypeName; - } - - @Override - public String getSourceName() { - return sourceName; - } - - @Override - public String getSourceNamePlural() { - return sourceNamePlural; - } - - @Override - public Class<TargetType> getTargetType() { - return targetType; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (!(obj instanceof AbstractBasicRelationship)) return false; - - @SuppressWarnings("rawtypes") - AbstractBasicRelationship other = (AbstractBasicRelationship) obj; - - // only look at type name and class; name of source and target is informational - if (!Objects.equal(relationshipTypeName, other.relationshipTypeName)) return false; - if (!Objects.equal(getSourceType(), other.getSourceType())) return false; - if (!Objects.equal(targetType, other.targetType)) return false; - - if (getInverseRelationship() == null) { - // require both null or... - if (other.getInverseRelationship() != null) - return false; - } else { - // ... they have same type name - // (don't recurse as that sets up infinite loop) - if (other.getInverseRelationship() == null) - return false; - if (!Objects.equal(getInverseRelationship().getRelationshipTypeName(), other.getInverseRelationship().getRelationshipTypeName())) return false; - } - - return true; - } - - @Override - public int hashCode() { - // comments as per equals - return Objects.hashCode(relationshipTypeName, getSourceType(), targetType, - getInverseRelationship()!=null ? getInverseRelationship().getRelationshipTypeName() : null); - } - - @Override - public String toString() { - return relationshipTypeName; - } - } - - private static class BasicRelationshipWithInverse<SourceType,TargetType> extends AbstractBasicRelationship<SourceType,TargetType> { - private BasicRelationshipWithInverse<TargetType,SourceType> inverseRelationship; - - private BasicRelationshipWithInverse(String relationshipTypeName, String sourceName, String sourceNamePlural, Class<TargetType> targetType) { - super(relationshipTypeName, sourceName, sourceNamePlural, targetType); - } - - @Override - public Relationship<TargetType,SourceType> getInverseRelationship() { - return inverseRelationship; - } - - @Override - public Class<SourceType> getSourceType() { - if (getInverseRelationship()==null) return null; - return getInverseRelationship().getTargetType(); - } - - @Override - public String getTargetName() { - if (getInverseRelationship()==null) return null; - return getInverseRelationship().getSourceName(); - } - - @Override - public String getTargetNamePlural() { - if (getInverseRelationship()==null) return null; - return getInverseRelationship().getSourceNamePlural(); - } - } - - private static class BasicRelationshipOneWay<SourceType,TargetType> extends AbstractBasicRelationship<SourceType,TargetType> { - - private final String targetName; - private final String targetNamePlural; - private final Class<SourceType> sourceType; - - private BasicRelationshipOneWay(String sourceName, String sourceNamePlural, Class<SourceType> sourceType, String toTargetRelationshipTypeName, - String targetName, String targetNamePlural, Class<TargetType> targetType) { - super(toTargetRelationshipTypeName, sourceName, sourceNamePlural, targetType); - this.targetName = targetName; - this.targetNamePlural = targetNamePlural; - this.sourceType = sourceType; - } - - @Override - public Class<SourceType> getSourceType() { - return sourceType; - } - - @Override - public String getTargetName() { - return targetName; - } - - @Override - public String getTargetNamePlural() { - return targetNamePlural; - } - - @Override - public Relationship<TargetType, SourceType> getInverseRelationship() { - return null; - } - } - - public static <SourceType,TargetType> Relationship<SourceType,TargetType> newRelationshipPair( - String sourceName, String sourceNamePlural, Class<SourceType> sourceType, String toTargetRelationshipTypeName, - String targetName, String targetNamePlural, Class<TargetType> targetType, String toSourceRelationshipTypeName) { - BasicRelationshipWithInverse<SourceType, TargetType> r1 = new BasicRelationshipWithInverse<SourceType, TargetType>( - toTargetRelationshipTypeName, sourceName, sourceNamePlural, targetType); - BasicRelationshipWithInverse<TargetType, SourceType> r2 = new BasicRelationshipWithInverse<TargetType, SourceType>( - toSourceRelationshipTypeName, targetName, targetNamePlural, sourceType); - r1.inverseRelationship = r2; - r2.inverseRelationship = r1; - return r1; - } - - public static <SourceType,TargetType> Relationship<SourceType,TargetType> newRelationshipOneway( - String sourceName, String sourceNamePlural, Class<SourceType> sourceType, String toTargetRelationshipTypeName, - String targetName, String targetNamePlural, Class<TargetType> targetType) { - return new BasicRelationshipOneWay<SourceType,TargetType>( - sourceName, sourceNamePlural, sourceType, toTargetRelationshipTypeName, - targetName, targetNamePlural, targetType); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/09aab586/core/src/test/java/org/apache/brooklyn/core/relations/RelationshipTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/relations/RelationshipTest.java b/core/src/test/java/org/apache/brooklyn/core/relations/RelationshipTest.java index ba114dd..5d73652 100644 --- a/core/src/test/java/org/apache/brooklyn/core/relations/RelationshipTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/relations/RelationshipTest.java @@ -23,16 +23,16 @@ import org.apache.brooklyn.core.test.entity.TestEntity; import org.testng.Assert; import org.testng.annotations.Test; -import brooklyn.basic.relations.Relationship; +import brooklyn.basic.relations.RelationshipType; @Test public class RelationshipTest { - static Relationship<Entity, TestEntity> AUNTIE_OF = Relationships.newRelationshipPair( + static RelationshipType<Entity, TestEntity> AUNTIE_OF = RelationshipTypes.newRelationshipPair( "auntie", "aunties", Entity.class, "auntie_of_nephew", "nephew", "nephews", TestEntity.class, "nephew_of_auntie"); - static Relationship<TestEntity, Entity> NEPHEW_OF = AUNTIE_OF.getInverseRelationship(); + static RelationshipType<TestEntity, Entity> NEPHEW_OF = AUNTIE_OF.getInverseRelationshipType(); public void testFields() { Assert.assertEquals(AUNTIE_OF.getRelationshipTypeName(), "auntie_of_nephew"); @@ -51,8 +51,8 @@ public class RelationshipTest { Assert.assertEquals(NEPHEW_OF.getSourceNamePlural(), "nephews"); Assert.assertEquals(NEPHEW_OF.getTargetNamePlural(), "aunties"); - Assert.assertEquals(NEPHEW_OF.getInverseRelationship(), AUNTIE_OF); - Assert.assertEquals(AUNTIE_OF.getInverseRelationship(), NEPHEW_OF); + Assert.assertEquals(NEPHEW_OF.getInverseRelationshipType(), AUNTIE_OF); + Assert.assertEquals(AUNTIE_OF.getInverseRelationshipType(), NEPHEW_OF); } }
