|
From: <lh...@us...> - 2009-03-26 09:24:59
|
Revision: 293
http://tinytim.svn.sourceforge.net/tinytim/?rev=293&view=rev
Author: lheuer
Date: 2009-03-26 09:24:44 +0000 (Thu, 26 Mar 2009)
Log Message:
-----------
Added utility class to fetch the super-/subtypes of a topic and to check if a topic is an instance of another topic (supertypes / subtypes are taken into account)
Added Paths:
-----------
tinytim/trunk/src/main/java/org/tinytim/utils/TypeInstanceUtils.java
tinytim/trunk/src/test/java/org/tinytim/utils/TestTypeInstanceUtils.java
Added: tinytim/trunk/src/main/java/org/tinytim/utils/TypeInstanceUtils.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/utils/TypeInstanceUtils.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/utils/TypeInstanceUtils.java 2009-03-26 09:24:44 UTC (rev 293)
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2009 Lars Heuer (heuer[at]semagia.com). All rights reserved.
+ *
+ * Licensed 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.tinytim.utils;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.tinytim.internal.api.IAssociation;
+import org.tinytim.voc.TMDM;
+import org.tmapi.core.Locator;
+import org.tmapi.core.Role;
+import org.tmapi.core.Topic;
+import org.tmapi.core.TopicMap;
+import org.tmapi.core.Typed;
+
+/**
+ * Utility functions to retrieve the supertypes / subtypes of a topic and
+ * to check if a topic is an instance of another topic.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+public class TypeInstanceUtils {
+
+ private static final RolePlayerWalker _SUPERTYPES_WALKER = new RolePlayerWalker(TMDM.SUPERTYPE_SUBTYPE, TMDM.SUBTYPE, TMDM.SUPERTYPE);
+ private static final RolePlayerWalker _SUBTYPES_WALKER = new RolePlayerWalker(TMDM.SUPERTYPE_SUBTYPE, TMDM.SUPERTYPE, TMDM.SUBTYPE);
+
+ private TypeInstanceUtils() {
+ // noop
+ }
+
+ /**
+ * Returns if <tt>instance</tt> is an instance of <tt>type</tt>.
+ * <p>
+ * The typed construct is an instance of <tt>type</tt> if {@link Typed#getType()}
+ * is equal to the provided <tt>type</tt> or if <tt>type</tt> is a supertype
+ * of {@link Typed#getType()}.
+ * </p>
+ *
+ * @param instance The instance.
+ * @param type The type.
+ * @return <tt>true</tt> if the typed construct is an instance of <tt>type</tt>,
+ * otherwise <tt>false</tt>.
+ */
+ public static boolean isInstanceOf(Typed instance, Topic type) {
+ if (instance == null) {
+ throw new IllegalArgumentException("The instance must not be null");
+ }
+ if (type == null) {
+ throw new IllegalArgumentException("The type must not be null");
+ }
+ return instance.getType().equals(type)
+ || _SUPERTYPES_WALKER.isAssociated(instance.getType(), type);
+ }
+
+ /**
+ * Returns if <tt>instance</tt> is an instance of <tt>type</tt>.
+ * <p>
+ * The topic is an instance of <tt>type</tt> if {@link Topic#getTypes()}
+ * contains <tt>type</tt> or if one of the topics returned by {@link Topic#getTypes()}
+ * is a subtype of <tt>type</tt>.
+ * </p>
+ *
+ * @param instance The instance.
+ * @param type The type.
+ * @return <tt>true</tt> if the topic is an instance of <tt>type</tt>,
+ * otherwise <tt>false</tt>.
+ */
+ public static boolean isInstanceOf(Topic instance, Topic type) {
+ if (instance == null) {
+ throw new IllegalArgumentException("The instance must not be null");
+ }
+ if (type == null) {
+ throw new IllegalArgumentException("The type must not be null");
+ }
+ Collection<Topic> types = instance.getTypes();
+ if (types.contains(type)) {
+ return true;
+ }
+ for (Topic topicType: types) {
+ if (_SUPERTYPES_WALKER.isAssociated(topicType, type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the supertypes of <tt>subtype</tt>.
+ * <p>
+ * If <tt>subtype</tt> does not participate in a supertype-subtype association,
+ * the returned collection is empty.
+ * </p>
+ *
+ * @param subtype The subtype.
+ * @return A (maybe empty) collection of supertypes.
+ */
+ public static Collection<Topic> getSupertypes(Topic subtype) {
+ if (subtype == null) {
+ throw new IllegalArgumentException("The subtype must not be null");
+ }
+ return _SUPERTYPES_WALKER.walk(subtype);
+ }
+
+ /**
+ * Returns the subtypes of <tt>supertype</tt>.
+ * <p>
+ * If <tt>supertype</tt> does not participate in a supertype-subtype association,
+ * the returned collection is empty.
+ * </p>
+ *
+ * @param supertype The supertype.
+ * @return A (maybe empty) collection of subtypes.
+ */
+ public static Collection<Topic> getSubtypes(Topic supertype) {
+ if (supertype == null) {
+ throw new IllegalArgumentException("The supertype must not be null");
+ }
+ return _SUBTYPES_WALKER.walk(supertype);
+ }
+
+
+ private static class RolePlayerWalker {
+
+ private final Locator _assocTypeLoc;
+ private final Locator _rolePlayingTypeLoc;
+ private final Locator _otherRoleTypeLoc;
+
+ public RolePlayerWalker(Locator associationType, Locator rolePlayingType, Locator otherRoleType) {
+ _assocTypeLoc = associationType;
+ _rolePlayingTypeLoc = rolePlayingType;
+ _otherRoleTypeLoc = otherRoleType;
+ }
+
+ /**
+ * Walks through the association players and reports those which are
+ * playing the counterpart role.
+ *
+ * @param start The starting point.
+ * @return A colleciton of topics.
+ */
+ public Set<Topic> walk(Topic start) {
+ return _walk(start, null);
+ }
+
+ /**
+ * Returns if <tt>start</tt> is associated with <tt>end</tt>.
+ *
+ * @param start The starting point.
+ * @param end The end point.
+ * @return <tt>true</tt> if the start topic is associated with the end topic.
+ */
+ public boolean isAssociated(Topic start, Topic end) {
+ return _walk(start, end).contains(end);
+ }
+
+ /**
+ * Walks through the players.
+ *
+ * @param start The starting topic, must not be <tt>null</tt>.
+ * @param end The end topic, maybe <tt>null</tt>.
+ * @return A collection of topics.
+ */
+ public Set<Topic> _walk(Topic start, Topic end) {
+ final TopicMap tm = start.getTopicMap();
+ final Topic assocType = tm.getTopicBySubjectIdentifier(_assocTypeLoc);
+ final Topic rolePlayingType = tm.getTopicBySubjectIdentifier(_rolePlayingTypeLoc);
+ final Topic otherRoleType = tm.getTopicBySubjectIdentifier(_otherRoleTypeLoc);
+ if (assocType == null
+ || rolePlayingType == null
+ || otherRoleType == null) {
+ return Collections.emptySet();
+ }
+ Set<Topic> players = new HashSet<Topic>();
+ _walk(start, players, end, assocType, rolePlayingType, otherRoleType);
+ return players;
+ }
+
+ private void _walk(Topic start, Set<Topic> result, Topic goal, Topic assocType, Topic rolePlayingType, Topic otherRoleType) {
+ for (Role role: start.getRolesPlayed(rolePlayingType, assocType)) {
+ IAssociation parent = (IAssociation) role.getParent();
+ if (!parent.getScopeObject().isUnconstrained()) {
+ continue;
+ }
+ Set<Role> roles = role.getParent().getRoles();
+ if (roles.size() != 2) {
+ continue;
+ }
+ for (Role r: roles) {
+ if (!r.getType().equals(otherRoleType)) {
+ continue;
+ }
+ Topic player = r.getPlayer();
+ if (goal != null && player.equals(goal)) {
+ result.add(goal);
+ // No need to walk further
+ return;
+ }
+ else if (!result.contains(player)) {
+ result.add(player);
+ _walk(player, result, goal, assocType, rolePlayingType, otherRoleType);
+ }
+ }
+ }
+ }
+ }
+
+
+}
Property changes on: tinytim/trunk/src/main/java/org/tinytim/utils/TypeInstanceUtils.java
___________________________________________________________________
Added: svn:keywords
+ Rev Date Id
Added: svn:eol-style
+ native
Added: tinytim/trunk/src/test/java/org/tinytim/utils/TestTypeInstanceUtils.java
===================================================================
--- tinytim/trunk/src/test/java/org/tinytim/utils/TestTypeInstanceUtils.java (rev 0)
+++ tinytim/trunk/src/test/java/org/tinytim/utils/TestTypeInstanceUtils.java 2009-03-26 09:24:44 UTC (rev 293)
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2008 - 2009 Lars Heuer (heuer[at]semagia.com). All rights reserved.
+ *
+ * Licensed 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.tinytim.utils;
+
+import java.util.Collection;
+
+import org.tinytim.core.TinyTimTestCase;
+import org.tinytim.voc.TMDM;
+
+import org.tmapi.core.Association;
+import org.tmapi.core.Topic;
+import org.tmapi.core.Typed;
+
+/**
+ * Tests against the {@link TypeInstanceUtils}.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+public class TestTypeInstanceUtils extends TinyTimTestCase {
+
+ private void _testTypedInstanceOf(final Typed typed) {
+ assertNotNull(typed.getType());
+ final Topic origType = typed.getType();
+ final Topic newType = createTopic();
+ assertTrue(TypeInstanceUtils.isInstanceOf(typed, origType));
+ assertFalse(TypeInstanceUtils.isInstanceOf(typed, newType));
+ typed.setType(newType);
+ assertFalse(TypeInstanceUtils.isInstanceOf(typed, origType));
+ assertTrue(TypeInstanceUtils.isInstanceOf(typed, newType));
+ final Topic supertype = createTopic();
+ assertFalse(TypeInstanceUtils.isInstanceOf(typed, supertype));
+ _makeSupertypeSubtype(newType, supertype);
+ assertTrue(TypeInstanceUtils.isInstanceOf(typed, supertype));
+ final Topic supersupertype = createTopic();
+ assertFalse(TypeInstanceUtils.isInstanceOf(typed, supersupertype));
+ _makeSupertypeSubtype(supertype, supersupertype);
+ assertTrue(TypeInstanceUtils.isInstanceOf(typed, supersupertype));
+ }
+
+ private void _makeSupertypeSubtype(Topic subtype, Topic supertype) {
+ Association assoc = _tm.createAssociation(_tm.createTopicBySubjectIdentifier(TMDM.SUPERTYPE_SUBTYPE));
+ assoc.createRole(_tm.createTopicBySubjectIdentifier(TMDM.SUPERTYPE), supertype);
+ assoc.createRole(_tm.createTopicBySubjectIdentifier(TMDM.SUBTYPE), subtype);
+ }
+
+ public void testAssociation() {
+ _testTypedInstanceOf(createAssociation());
+ }
+
+ public void testRole() {
+ _testTypedInstanceOf(createRole());
+ }
+
+ public void testOccurrence() {
+ _testTypedInstanceOf(createOccurrence());
+ }
+
+ public void testName() {
+ _testTypedInstanceOf(createName());
+ }
+
+ /**
+ * Tests if a topic is an instance of itself.
+ */
+ public void testIsInstanceOfSelf() {
+ final Topic topic = createTopic();
+ assertFalse(TypeInstanceUtils.isInstanceOf(topic, topic));
+ }
+
+ /**
+ * Tests if a topic is an instance of the types returned by
+ * {@link Topic#getTypes()}.
+ */
+ public void testIsInstanceOfTypes() {
+ final Topic topic = createTopic();
+ final Topic type = createTopic();
+ topic.addType(type);
+ assertTrue(topic.getTypes().contains(type));
+ assertTrue(TypeInstanceUtils.isInstanceOf(topic, type));
+ }
+
+ public void testTopicIsInstanceOf() {
+ final Topic topic = createTopic();
+ final Topic type1 = createTopic();
+ final Topic type2 = createTopic();
+ topic.addType(type1);
+ assertTrue(topic.getTypes().contains(type1));
+ assertFalse(topic.getTypes().contains(type2));
+ assertTrue(TypeInstanceUtils.isInstanceOf(topic, type1));
+ assertFalse(TypeInstanceUtils.isInstanceOf(topic, type2));
+ _makeSupertypeSubtype(type1, type2);
+ assertTrue(TypeInstanceUtils.isInstanceOf(topic, type2));
+ final Topic type3 = createTopic();
+ assertFalse(TypeInstanceUtils.isInstanceOf(topic, type3));
+ _makeSupertypeSubtype(type2, type3);
+ assertTrue(TypeInstanceUtils.isInstanceOf(topic, type3));
+ }
+
+ public void testGetSupertypesSubtypes() {
+ final Topic sub = createTopic();
+ final Topic super1 = createTopic();
+ final Topic super2 = createTopic();
+ Collection<Topic> supertypes = TypeInstanceUtils.getSupertypes(sub);
+ Collection<Topic> subtypes1 = TypeInstanceUtils.getSubtypes(super1);
+ Collection<Topic> subtypes2 = TypeInstanceUtils.getSubtypes(super2);
+ assertEquals(0, supertypes.size());
+ assertEquals(0, subtypes1.size());
+ assertEquals(0, subtypes2.size());
+ // sub ako super1
+ _makeSupertypeSubtype(sub, super1);
+ supertypes = TypeInstanceUtils.getSupertypes(sub);
+ subtypes1 = TypeInstanceUtils.getSubtypes(super1);
+ subtypes2 = TypeInstanceUtils.getSubtypes(super2);
+ assertEquals(1, supertypes.size());
+ assertTrue(supertypes.contains(super1));
+ assertEquals(1, subtypes1.size());
+ assertTrue(subtypes1.contains(sub));
+ assertEquals(0, subtypes2.size());
+ // super1 ako super2
+ _makeSupertypeSubtype(super1, super2);
+ supertypes = TypeInstanceUtils.getSupertypes(sub);
+ subtypes1 = TypeInstanceUtils.getSubtypes(super1);
+ subtypes2 = TypeInstanceUtils.getSubtypes(super2);
+ assertEquals(2, supertypes.size());
+ assertTrue(supertypes.contains(super1));
+ assertTrue(supertypes.contains(super2));
+ assertEquals(1, subtypes1.size());
+ assertTrue(subtypes1.contains(sub));
+ assertEquals(2, subtypes2.size());
+ assertTrue(subtypes2.contains(sub));
+ assertTrue(subtypes2.contains(super1));
+ }
+
+}
Property changes on: tinytim/trunk/src/test/java/org/tinytim/utils/TestTypeInstanceUtils.java
___________________________________________________________________
Added: svn:keywords
+ Rev Date Id
Added: svn:eol-style
+ native
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|