|
From: <lh...@us...> - 2008-04-21 14:59:07
|
Revision: 26
http://tinytim.svn.sourceforge.net/tinytim/?rev=26&view=rev
Author: lheuer
Date: 2008-04-21 07:59:01 -0700 (Mon, 21 Apr 2008)
Log Message:
-----------
- Initial import of the core and some indexes
- CopyUtils is not ready yet
Modified Paths:
--------------
tinytim/trunk/src/main/java/org/tinytim/TopicUtils.java
tinytim/trunk/src/main/java/org/tinytim/index/IndexFlagsImpl.java
Added Paths:
-----------
tinytim/trunk/src/main/java/org/tinytim/AssociationImpl.java
tinytim/trunk/src/main/java/org/tinytim/AssociationRoleImpl.java
tinytim/trunk/src/main/java/org/tinytim/CopyUtils.java
tinytim/trunk/src/main/java/org/tinytim/DatatypeAwareConstruct.java
tinytim/trunk/src/main/java/org/tinytim/IDatatypeAwareConstruct.java
tinytim/trunk/src/main/java/org/tinytim/IdentityManager.java
tinytim/trunk/src/main/java/org/tinytim/MergeUtils.java
tinytim/trunk/src/main/java/org/tinytim/OccurrenceImpl.java
tinytim/trunk/src/main/java/org/tinytim/TopicImpl.java
tinytim/trunk/src/main/java/org/tinytim/TopicNameImpl.java
tinytim/trunk/src/main/java/org/tinytim/VariantImpl.java
tinytim/trunk/src/main/java/org/tinytim/index/IndexManager.java
tinytim/trunk/src/main/java/org/tinytim/index/ScopedIndex.java
tinytim/trunk/src/main/java/org/tinytim/index/TypeInstanceIndex.java
Added: tinytim/trunk/src/main/java/org/tinytim/AssociationImpl.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/AssociationImpl.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/AssociationImpl.java 2008-04-21 14:59:01 UTC (rev 26)
@@ -0,0 +1,133 @@
+/*
+ * This is tinyTiM, a tiny Topic Maps engine.
+ *
+ * Copyright (C) 2008 Lars Heuer (heuer[at]semagia.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+package org.tinytim;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Set;
+
+import org.tmapi.core.Association;
+import org.tmapi.core.AssociationRole;
+import org.tmapi.core.TMAPIException;
+import org.tmapi.core.Topic;
+
+/**
+ * {@link org.tmapi.core.Association} implementation.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+public final class AssociationImpl extends Scoped implements Association,
+ IReifiable, ITyped, IScoped {
+
+ private Set<AssociationRole> _roles;
+ private Topic _type;
+
+ AssociationImpl(TopicMapImpl topicMap) {
+ super(topicMap, null);
+ _roles = topicMap.getCollectionFactory().createSet(2);
+ }
+
+ /**
+ * Adds a role to this association.
+ *
+ * @param role The role to add.
+ */
+ void addRole(AssociationRole role) {
+ AssociationRoleImpl r = (AssociationRoleImpl) role;
+ if (r._parent == this) {
+ return;
+ }
+ assert r._parent == null;
+ _fireEvent(Event.ADD_ROLE, null, r);
+ _roles.add(r);
+ r._parent = this;
+ TopicImpl player = (TopicImpl) r.getPlayer();
+ if (player != null) {
+ player.addRolePlayed(r);
+ }
+ }
+
+ /**
+ * Removes a role from this association.
+ *
+ * @param role The role to remove.
+ */
+ void removeRole(AssociationRole role) {
+ AssociationRoleImpl r = (AssociationRoleImpl) role;
+ if (r._parent != this) {
+ return;
+ }
+ _fireEvent(Event.REMOVE_ROLE, r, null);
+ _roles.remove(role);
+ r._parent = null;
+ TopicImpl player = (TopicImpl) r.getPlayer();
+ if (player != null) {
+ player.removeRolePlayed(r);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Association#createAssociationRole(org.tmapi.core.Topic, org.tmapi.core.Topic)
+ */
+ public AssociationRole createAssociationRole(Topic player, Topic type) {
+ AssociationRoleImpl role = new AssociationRoleImpl(_tm, type, player);
+ addRole(role);
+ return role;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Association#getAssociationRoles()
+ */
+ public Set<AssociationRole> getAssociationRoles() {
+ return Collections.unmodifiableSet(_roles);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Association#getType()
+ */
+ public Topic getType() {
+ return _type;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Association#setType(org.tmapi.core.Topic)
+ */
+ public void setType(Topic type) {
+ if (_type == type) {
+ return;
+ }
+ _fireEvent(Event.SET_TYPE, _type, type);
+ _type = type;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.TopicMapObject#remove()
+ */
+ public void remove() throws TMAPIException {
+ _tm.removeAssociation(this);
+ for (AssociationRole role: new ArrayList<AssociationRole>(_roles)) {
+ role.remove();
+ }
+ _roles = null;
+ super.dispose();
+ }
+}
Property changes on: tinytim/trunk/src/main/java/org/tinytim/AssociationImpl.java
___________________________________________________________________
Name: svn:keywords
+ Rev Date Id
Name: svn:eol-style
+ native
Added: tinytim/trunk/src/main/java/org/tinytim/AssociationRoleImpl.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/AssociationRoleImpl.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/AssociationRoleImpl.java 2008-04-21 14:59:01 UTC (rev 26)
@@ -0,0 +1,83 @@
+/*
+ * This is tinyTiM, a tiny Topic Maps engine.
+ *
+ * Copyright (C) 2008 Lars Heuer (heuer[at]semagia.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+package org.tinytim;
+
+import org.tmapi.core.Association;
+import org.tmapi.core.AssociationRole;
+import org.tmapi.core.TMAPIException;
+import org.tmapi.core.Topic;
+
+/**
+ * {@link org.tmapi.core.AssociationRole} implementation.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+public final class AssociationRoleImpl extends Typed implements AssociationRole,
+ ITyped {
+
+ private Topic _player;
+
+ AssociationRoleImpl(TopicMapImpl tm, Topic type, Topic player) {
+ super(tm, type, null);
+ _player = player;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.AssociationRole#getAssociation()
+ */
+ public Association getAssociation() {
+ return (Association) _parent;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.AssociationRole#getPlayer()
+ */
+ public Topic getPlayer() {
+ return _player;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.AssociationRole#setPlayer(org.tmapi.core.Topic)
+ */
+ public void setPlayer(Topic player) {
+ if (_player == player) {
+ return;
+ }
+ _fireEvent(Event.SET_PLAYER, _player, player);
+ if (_player != null) {
+ ((TopicImpl)_player).removeRolePlayed(this);
+ }
+ _player = player;
+ if (player != null) {
+ ((TopicImpl) player).addRolePlayed(this);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.tinytim.TopicMapObjectImpl#remove()
+ */
+ public void remove() throws TMAPIException {
+ ((AssociationImpl) _parent).removeRole(this);
+ super.dispose();
+ }
+
+}
Property changes on: tinytim/trunk/src/main/java/org/tinytim/AssociationRoleImpl.java
___________________________________________________________________
Name: svn:keywords
+ Rev Date Id
Name: svn:eol-style
+ native
Added: tinytim/trunk/src/main/java/org/tinytim/CopyUtils.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/CopyUtils.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/CopyUtils.java 2008-04-21 14:59:01 UTC (rev 26)
@@ -0,0 +1,171 @@
+/*
+ * This is tinyTiM, a tiny Topic Maps engine.
+ *
+ * Copyright (C) 2008 Lars Heuer (heuer[at]semagia.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+package org.tinytim;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.tmapi.core.Locator;
+import org.tmapi.core.Occurrence;
+import org.tmapi.core.Topic;
+import org.tmapi.core.TopicMap;
+import org.tmapi.core.TopicMapObject;
+
+/**
+ * This class provides methods to copy Topic Maps constructs from one
+ * topic map to another without creating duplicates.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+final class CopyUtils {
+
+ /**
+ * Copies the topics and associations from the <code>source</code> to the
+ * <code>target</code> topic map.
+ *
+ * @param source The topic map to take the topics and associations from.
+ * @param target The topic map which should receive the topics and associations.
+ */
+ public static void copy(TopicMap source, TopicMap target) {
+ _copy((TopicMapImpl) source, (TopicMapImpl) target);
+ }
+
+ /**
+ * @see #copy(TopicMap, TopicMap)
+ */
+ @SuppressWarnings("unchecked")
+ private static void _copy(TopicMapImpl source, TopicMapImpl target) {
+ if (source == null || target == null) {
+ throw new IllegalArgumentException("Neither the source topic map nor the target topic map must be null");
+ }
+ if (source == target) {
+ return;
+ }
+ Map<Topic, Topic> mergeMap = target.getCollectionFactory().createMap();
+ Topic existing = null;
+ TopicMapObject existingConstruct = null;
+ for (Topic topic: source.getTopics()) {
+ for (Iterator<Locator> iter = topic.getSubjectLocators().iterator(); iter.hasNext();) {
+ existing = target.getTopicBySubjectLocator(iter.next());
+ if (existing != null) {
+ _addMerge(topic, existing, mergeMap);
+ }
+ }
+ for (Iterator<Locator> iter = topic.getSubjectIdentifiers().iterator(); iter.hasNext();) {
+ Locator sid = iter.next();
+ existing = target.getTopicBySubjectIdentifier(sid);
+ if (existing != null) {
+ _addMerge(topic, existing, mergeMap);
+ }
+ existingConstruct = target.getObjectByItemIdentifier(sid);
+ if (existingConstruct instanceof Topic) {
+ _addMerge(topic, (Topic) existingConstruct, mergeMap);
+ }
+ }
+ for (Iterator<Locator> iter = topic.getSourceLocators().iterator(); iter.hasNext();) {
+ Locator iid = iter.next();
+ existingConstruct = target.getObjectByItemIdentifier(iid);
+ if (existingConstruct instanceof Topic) {
+ _addMerge(topic, (Topic) existingConstruct, mergeMap);
+ }
+ existing = target.getTopicBySubjectIdentifier(iid);
+ if (existing != null) {
+ _addMerge(topic, existing, mergeMap);
+ }
+ }
+ }
+ if (source.getReifier() != null && target.getReifier() != null) {
+ _addMerge(source.getReifier(), target.getReifier(), mergeMap);
+ }
+ for (Topic topic: source.getTopics()) {
+ if (!mergeMap.containsKey(topic)) {
+ _copyTopic(topic, target, mergeMap);
+ }
+ }
+ for (Topic topic: mergeMap.keySet()) {
+ Topic targetTopic = mergeMap.get(topic);
+ _copyIdentities(topic, targetTopic);
+ _copyTypes(topic, targetTopic, mergeMap);
+ _copyCharacteristics(topic, (TopicImpl)targetTopic, mergeMap);
+ }
+ }
+
+ private static Topic _copyTopic(Topic topic, TopicMap target,
+ Map<Topic, Topic> mergeMap) {
+ Topic targetTopic = target.createTopic();
+ _copyIdentities(topic, targetTopic);
+ _copyTypes(topic, targetTopic, mergeMap);
+ _copyCharacteristics(topic, (TopicImpl)targetTopic, mergeMap);
+ return targetTopic;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void _copyIdentities(Topic topic, Topic targetTopic) {
+ for(Iterator<Locator> iter = topic.getSubjectIdentifiers().iterator(); iter.hasNext();) {
+ targetTopic.addSubjectIdentifier(iter.next());
+ }
+ for(Iterator<Locator> iter = topic.getSubjectLocators().iterator(); iter.hasNext();) {
+ targetTopic.addSubjectLocator(iter.next());
+ }
+ _copyItemIdentifiers((IConstruct)topic, (IConstruct)targetTopic);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void _copyTypes(Topic topic, Topic targetTopic,
+ Map<Topic, Topic> mergeMap) {
+ for (Iterator<Topic> iter = topic.getTypes().iterator(); iter.hasNext();) {
+ Topic type = iter.next();
+ Topic targetType = mergeMap.get(type);
+ if (targetType == null) {
+ targetType = _copyTopic(type, targetTopic.getTopicMap(), mergeMap);
+ }
+ targetTopic.addType(targetType);
+ }
+ }
+
+ private static void _copyCharacteristics(Topic topic, TopicImpl targetTopic,
+ Map<Topic, Topic> mergeMap) {
+ Map<String, IReifiable> sigs = ((TopicMapImpl) targetTopic.getTopicMap()).getCollectionFactory().<String, IReifiable>createMap();
+ for (Occurrence occ: targetTopic.getOccurrences()) {
+ sigs.put(SignatureGenerator.generateSignature(occ), (IReifiable)occ);
+ }
+ }
+
+ private static void _copyItemIdentifiers(IConstruct source, IConstruct target) {
+ for(Locator iid: source.getItemIdentifiers()) {
+ target.addSourceLocator(iid);
+ }
+ }
+
+ private static void _addMerge(Topic source, Topic target, Map<Topic, Topic> mergeMap) {
+ Topic prevTarget = mergeMap.get(source);
+ if (prevTarget != null) {
+ if (!prevTarget.equals(target)) {
+ MergeUtils.merge(target, prevTarget);
+ }
+ }
+ else {
+ mergeMap.put(source, target);
+ }
+ }
+
+}
Property changes on: tinytim/trunk/src/main/java/org/tinytim/CopyUtils.java
___________________________________________________________________
Name: svn:keywords
+ Rev Date Id
Name: svn:eol-style
+ native
Added: tinytim/trunk/src/main/java/org/tinytim/DatatypeAwareConstruct.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/DatatypeAwareConstruct.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/DatatypeAwareConstruct.java 2008-04-21 14:59:01 UTC (rev 26)
@@ -0,0 +1,117 @@
+/*
+ * This is tinyTiM, a tiny Topic Maps engine.
+ *
+ * Copyright (C) 2008 Lars Heuer (heuer[at]semagia.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+package org.tinytim;
+
+import java.util.Collection;
+
+import org.tmapi.core.Locator;
+import org.tmapi.core.Topic;
+
+/**
+ * Implementation of {@link org.tinytim.IDatatypeAwareConstruct}.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+abstract class DatatypeAwareConstruct extends Typed implements
+ IDatatypeAwareConstruct, IScoped {
+
+ private String _value;
+ private Locator _resource;
+
+ DatatypeAwareConstruct(TopicMapImpl topicMap, Topic type, String value, Collection<Topic> scope) {
+ super(topicMap, type, scope);
+ _value = value;
+ }
+
+ DatatypeAwareConstruct(TopicMapImpl topicMap, Topic type, Locator value, Collection<Topic> scope) {
+ super(topicMap, type, scope);
+ _resource = value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tinytim.IDatatypeAwareConstruct#getValue2()
+ */
+ public String getValue2() {
+ if (_value != null) {
+ return _value;
+ }
+ return _resource != null ? _resource.getReference() : "";
+ }
+
+ /**
+ *
+ *
+ * @param value
+ */
+ public void setValue(String value) {
+ _fireEvent(Event.SET_VALUE, _value, value);
+ _resource = null;
+ _value = value;
+ }
+
+ /**
+ *
+ *
+ * @return
+ */
+ public String getValue() {
+ return _value;
+ }
+
+ /**
+ *
+ *
+ * @return
+ */
+ public Locator getResource() {
+ return _resource;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Occurrence#setResource(org.tmapi.core.Locator)
+ */
+ public void setResource(Locator value) {
+ _fireEvent(Event.SET_VALUE, _value, value);
+ _value = null;
+ _resource = value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tinytim.IDatatypeAwareConstruct#getDatatype()
+ */
+ public Locator getDatatype() {
+ if (_value != null || _resource == null) {
+ return STRING;
+ }
+ return ANY_URI;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tinytim.Construct#dispose()
+ */
+ @Override
+ protected void dispose() {
+ _value = null;
+ _resource = null;
+ super.dispose();
+ }
+}
Property changes on: tinytim/trunk/src/main/java/org/tinytim/DatatypeAwareConstruct.java
___________________________________________________________________
Name: svn:keywords
+ Rev Date Id
Name: svn:eol-style
+ native
Added: tinytim/trunk/src/main/java/org/tinytim/IDatatypeAwareConstruct.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/IDatatypeAwareConstruct.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/IDatatypeAwareConstruct.java 2008-04-21 14:59:01 UTC (rev 26)
@@ -0,0 +1,56 @@
+/*
+ * This is tinyTiM, a tiny Topic Maps engine.
+ *
+ * Copyright (C) 2008 Lars Heuer (heuer[at]semagia.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+package org.tinytim;
+
+import org.tmapi.core.Locator;
+
+/**
+ * Indicates that a Topic Maps construct has a value and a datatype.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+interface IDatatypeAwareConstruct extends IConstruct {
+
+ static final String _XSD_BASE = "http://www.w3.org/2001/XMLSchema#";
+ static final Locator STRING = new IRI(_XSD_BASE + "string");
+ static final Locator ANY_URI = new IRI(_XSD_BASE + "anyURI");
+
+ /**
+ * The value of this Topic Maps construct.
+ *
+ * This method differs from TMAPI: This method MUST return the value OR the
+ * locator as string. This method should be removed if we have TMAPI 2.0
+ * (maybe the whole interface should be removed).
+ * Currently, the {@link SignatureGenerator} needs it.
+ *
+ * @return The value.
+ */
+ public String getValue2();
+
+ /**
+ * Returns the datatype of this Topic Maps construct.
+ *
+ * @return The datatype.
+ */
+ public Locator getDatatype();
+
+}
Property changes on: tinytim/trunk/src/main/java/org/tinytim/IDatatypeAwareConstruct.java
___________________________________________________________________
Name: svn:keywords
+ Rev Date Id
Name: svn:eol-style
+ native
Added: tinytim/trunk/src/main/java/org/tinytim/IdentityManager.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/IdentityManager.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/IdentityManager.java 2008-04-21 14:59:01 UTC (rev 26)
@@ -0,0 +1,250 @@
+/*
+ * This is tinyTiM, a tiny Topic Maps engine.
+ *
+ * Copyright (C) 2008 Lars Heuer (heuer[at]semagia.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+package org.tinytim;
+
+import java.util.Map;
+
+import org.tmapi.core.DuplicateSourceLocatorException;
+import org.tmapi.core.Locator;
+import org.tmapi.core.ModelConstraintException;
+import org.tmapi.core.Topic;
+import org.tmapi.core.TopicsMustMergeException;
+
+/**
+ * The identity manager takes care about the TMDM identity constraints and
+ * provides an index to get Topic Maps constructs by their identity.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+final class IdentityManager {
+
+ private long _nextId;
+ private Map<Locator, Topic> _sid2Topic;
+ private Map<Locator, Topic> _slo2Topic;
+ private Map<Locator, IConstruct> _iid2Construct;
+ private Map<String, IConstruct> _id2Construct;
+
+ IdentityManager(TopicMapImpl tm) {
+ ICollectionFactory collFactory = tm.getCollectionFactory();
+ _id2Construct = collFactory.<String, IConstruct>createMap();
+ _sid2Topic = collFactory.<Locator, Topic>createMap();
+ _slo2Topic = collFactory.<Locator, Topic>createMap();
+ _iid2Construct = collFactory.<Locator, IConstruct>createMap();
+ _subscribe(tm);
+ _register(tm);
+ }
+
+ private void _subscribe(IEventPublisher publisher) {
+ IEventHandler handler = new TopicMapsConstructAddHandler();
+ publisher.subscribe(Event.ADD_TOPIC, handler);
+ publisher.subscribe(Event.ADD_ASSOCIATION, handler);
+ publisher.subscribe(Event.ADD_ROLE, handler);
+ publisher.subscribe(Event.ADD_OCCURRENCE, handler);
+ publisher.subscribe(Event.ADD_NAME, handler);
+ publisher.subscribe(Event.ADD_VARIANT, handler);
+ handler = new TopicMapsConstructRemoveHandler();
+ publisher.subscribe(Event.REMOVE_TOPIC, handler);
+ publisher.subscribe(Event.REMOVE_ASSOCIATION, handler);
+ publisher.subscribe(Event.REMOVE_ROLE, handler);
+ publisher.subscribe(Event.REMOVE_OCCURRENCE, handler);
+ publisher.subscribe(Event.REMOVE_NAME, handler);
+ publisher.subscribe(Event.REMOVE_VARIANT, handler);
+ handler = new AddItemIdentifierHandler();
+ publisher.subscribe(Event.ADD_IID, handler);
+ handler = new RemoveItemIdentifierHandler();
+ publisher.subscribe(Event.REMOVE_IID, handler);
+ handler = new AddSubjectIdentifierHandler();
+ publisher.subscribe(Event.ADD_SID, handler);
+ handler = new RemoveSubjectIdentifierHandler();
+ publisher.subscribe(Event.REMOVE_SID, handler);
+ handler = new AddSubjectLocatorHandler();
+ publisher.subscribe(Event.ADD_SLO, handler);
+ handler = new RemoveSubjectLocatorHandler();
+ publisher.subscribe(Event.REMOVE_SLO, handler);
+ handler = new ReifierConstraintHandler();
+ publisher.subscribe(Event.SET_REIFIER, handler);
+ }
+
+ private void _register(IConstruct construct) {
+ Construct c = (Construct) construct;
+ if (c._id == null) {
+ c._id = "" + _nextId++;
+ }
+ if (!_id2Construct.containsKey(c)) {
+ _id2Construct.put(c._id, c);
+ }
+ }
+
+ private void _unregister(IConstruct construct) {
+ _id2Construct.remove(((Construct) construct)._id);
+ }
+
+ public IConstruct getConstructById(String id) {
+ return _id2Construct.get(id);
+ }
+
+ public Topic getTopicBySubjectIdentifier(Locator sid) {
+ return _sid2Topic.get(sid);
+ }
+
+ public Topic getTopicBySubjectLocator(Locator slo) {
+ return _slo2Topic.get(slo);
+ }
+
+ public IConstruct getConstructByItemIdentifier(Locator iid) {
+ return _iid2Construct.get(iid);
+ }
+
+ public void close() {
+ _id2Construct = null;
+ _iid2Construct = null;
+ _sid2Topic = null;
+ _slo2Topic = null;
+ }
+
+ private class TopicMapsConstructAddHandler implements IEventHandler {
+ public void handleEvent(Event evt, IConstruct sender, Object oldValue,
+ Object newValue) {
+ _register((IConstruct)newValue);
+ }
+ }
+
+ private class TopicMapsConstructRemoveHandler implements IEventHandler {
+ public void handleEvent(Event evt, IConstruct sender, Object oldValue,
+ Object newValue) {
+ _unregister((IConstruct)oldValue);
+ }
+ }
+
+ /**
+ * Checks identity constraints and adds the Topic Maps construct and the
+ * item identifier to the index.
+ */
+ private class AddItemIdentifierHandler implements IEventHandler {
+ public void handleEvent(Event evt, IConstruct sender, Object oldValue,
+ Object newValue) {
+ Locator iid = (Locator) newValue;
+ IConstruct existing = _iid2Construct.get(iid);
+ if (existing != null) {
+ if (existing != sender) {
+ if (sender instanceof Topic && existing instanceof Topic) {
+ throw new TopicsMustMergeException((Topic) sender, (Topic) existing, "A topic with the same item identifier '" + iid.getReference() + "' exists");
+ }
+ throw new DuplicateSourceLocatorException(sender, existing, iid, "A Topic Maps construct with the same item identifier '" + iid.getReference() + "' exists");
+ }
+ }
+ if (sender instanceof Topic) {
+ Topic existingTopic = _sid2Topic.get(iid);
+ if (existingTopic != null && existingTopic != sender) {
+ throw new TopicsMustMergeException((Topic) sender, existingTopic, "A topic with a subject identifier equals to the item identifier '" + iid.getReference() + "' exists");
+ }
+ }
+ _iid2Construct.put(iid, sender);
+ }
+ }
+
+ /**
+ * Removes an item identifier and its Topic Maps constructs from the index.
+ */
+ private class RemoveItemIdentifierHandler implements IEventHandler {
+ public void handleEvent(Event evt, IConstruct sender, Object oldValue,
+ Object newValue) {
+ _iid2Construct.remove(oldValue);
+ }
+ }
+
+ /**
+ * Checks identity constraints and adds the topic and the
+ * subject identifier to the index.
+ */
+ private class AddSubjectIdentifierHandler implements IEventHandler {
+ public void handleEvent(Event evt, IConstruct sender, Object oldValue,
+ Object newValue) {
+ Topic topic = (Topic) sender;
+ Locator sid = (Locator) newValue;
+ IConstruct existing = (IConstruct) _sid2Topic.get(sid);
+ if (existing != null && existing != topic) {
+ throw new TopicsMustMergeException(topic, (Topic) existing, "A topic with the same subject identifier '" + sid.getReference() + "' exists");
+ }
+ existing = _iid2Construct.get(sid);
+ if (existing != null && existing instanceof Topic && existing != topic) {
+ throw new TopicsMustMergeException(topic, (Topic) existing, "A topic with an item identifier equals to the subject identifier '" + sid.getReference() + "' exists");
+ }
+ _sid2Topic.put(sid, topic);
+ }
+ }
+
+ /**
+ * Removes a subject identifier and its topic from the index.
+ */
+ private class RemoveSubjectIdentifierHandler implements IEventHandler {
+ public void handleEvent(Event evt, IConstruct sender, Object oldValue,
+ Object newValue) {
+ Locator slo = (Locator) oldValue;
+ _sid2Topic.remove(slo);
+ }
+ }
+
+ /**
+ * Checks identity constraints and adds the topic and the
+ * subject locator to the index.
+ */
+ private class AddSubjectLocatorHandler implements IEventHandler {
+ public void handleEvent(Event evt, IConstruct sender, Object oldValue,
+ Object newValue) {
+ Topic topic = (Topic) sender;
+ Locator slo = (Locator) newValue;
+ Topic existing = _slo2Topic.get(slo);
+ if (existing != null && existing != topic) {
+ throw new TopicsMustMergeException(topic, existing, "A topic with the same subject locator '" + slo.getReference() + "' exists");
+ }
+ _slo2Topic.put(slo, topic);
+ }
+ }
+
+ /**
+ * Removes a subject locator and its topic from the index.
+ */
+ private class RemoveSubjectLocatorHandler implements IEventHandler {
+ public void handleEvent(Event evt, IConstruct sender, Object oldValue,
+ Object newValue) {
+ Locator slo = (Locator) oldValue;
+ _slo2Topic.remove(slo);
+ }
+ }
+
+ /**
+ * Checks if setting the reifier is allowed.
+ */
+ private static class ReifierConstraintHandler implements IEventHandler {
+ public void handleEvent(Event evt, IConstruct sender, Object oldValue,
+ Object newValue) {
+ if (newValue == null) {
+ return;
+ }
+ IReifiable currentReified = ((TopicImpl) newValue)._reified;
+ if (currentReified != null && currentReified != sender) {
+ throw new ModelConstraintException(sender, "The topic reifies another Topic Maps construct");
+ }
+ }
+ }
+}
Property changes on: tinytim/trunk/src/main/java/org/tinytim/IdentityManager.java
___________________________________________________________________
Name: svn:keywords
+ Rev Date Id
Name: svn:eol-style
+ native
Added: tinytim/trunk/src/main/java/org/tinytim/MergeUtils.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/MergeUtils.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/MergeUtils.java 2008-04-21 14:59:01 UTC (rev 26)
@@ -0,0 +1,339 @@
+/*
+ * This is tinyTiM, a tiny Topic Maps engine.
+ *
+ * Copyright (C) 2008 Lars Heuer (heuer[at]semagia.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+package org.tinytim;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.tinytim.index.IScopedIndex;
+import org.tinytim.index.ITypeInstanceIndex;
+import org.tinytim.index.IndexManager;
+import org.tmapi.core.Association;
+import org.tmapi.core.AssociationRole;
+import org.tmapi.core.Locator;
+import org.tmapi.core.ModelConstraintException;
+import org.tmapi.core.Occurrence;
+import org.tmapi.core.TMAPIException;
+import org.tmapi.core.TMAPIRuntimeException;
+import org.tmapi.core.Topic;
+import org.tmapi.core.TopicMap;
+import org.tmapi.core.TopicName;
+import org.tmapi.core.Variant;
+
+/**
+ * This class does provides functions to merge topic maps and topics.
+ *
+ * This class relies on the implementation of tinyTiM, if the implementation
+ * changes, check the <code>==</code> comparisons.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+final class MergeUtils {
+
+ private MergeUtils() {
+ // noop.
+ }
+
+ /**
+ * Merges two topic maps.
+ *
+ * @param source The source topic map.
+ * @param target The target topic map which receives all
+ * topics / associations from <code>source</code>.
+ */
+ public static void merge(TopicMap source, TopicMap target) {
+ CopyUtils.copy(source, target);
+ }
+
+ /**
+ * Merges two topics.
+ *
+ * The topics MUST belong to the same topic map. The <code>source</code>
+ * will be removed from the topic map and <code>target</code> takes all
+ * characteristics of the <code>source</code>.
+ *
+ * @param source The source topic.
+ * @param target The target topic which receives all characteristics from
+ * <code>source</code>.
+ */
+ public static void merge(Topic source, Topic target) {
+ _merge((TopicImpl) source, (TopicImpl) target);
+ }
+
+ /**
+ * @see #merge(Topic, Topic)
+ */
+ private static void _merge(TopicImpl source, TopicImpl target) {
+ if (source == null || target == null) {
+ throw new IllegalArgumentException("Neither the source topic nor the target topic must be null");
+ }
+ if (source == target) {
+ return;
+ }
+ if (source.getTopicMap() != target.getTopicMap()) {
+ throw new IllegalArgumentException("The topics must belong to the same topic map");
+ }
+ IReifiable sourceReifiable = source._reified;
+ if (sourceReifiable != null && target._reified != null) {
+ // This should be enforced by the model
+ assert sourceReifiable != target._reified;
+ throw new ModelConstraintException(target, "The topics cannot be merged. They reify different Topic Maps constructs");
+ }
+ _moveItemIdentifiers((IConstruct)source, (IConstruct)target);
+ if (sourceReifiable != null) {
+ sourceReifiable.setReifier(target);
+ }
+ List<Locator> locs = new ArrayList<Locator>(source.getSubjectIdentifiers());
+ for (Locator sid: locs) {
+ source.removeSubjectIdentifier(sid);
+ target.addSubjectIdentifier(sid);
+ }
+ locs = new ArrayList<Locator>(source.getSubjectLocators());
+ for (Locator slo: locs) {
+ source.removeSubjectLocator(slo);
+ target.addSubjectLocator(slo);
+ }
+ _replaceTopics(source, target);
+ for(Topic type: source.getTypes()) {
+ target.addType(type);
+ }
+ Map<String, IReifiable> sigs = ((TopicMapImpl) source.getTopicMap()).getCollectionFactory().<String, IReifiable>createMap();
+ for (Occurrence occ: target.getOccurrences()) {
+ sigs.put(SignatureGenerator.generateSignature(occ), (IReifiable)occ);
+ }
+ IReifiable existing = null;
+ for (Occurrence occ: new ArrayList<Occurrence>(source.getOccurrences())) {
+ existing = sigs.get(SignatureGenerator.generateSignature(occ));
+ if (existing != null) {
+ handleExistingConstruct((IReifiable) occ, existing);
+ removeConstruct((IConstruct)occ);
+ }
+ else {
+ source.removeOccurrence(occ);
+ target.addOccurrence(occ);
+ }
+ }
+ sigs.clear();
+ for (TopicName name: target.getTopicNames()) {
+ sigs.put(SignatureGenerator.generateSignature(name), (IReifiable) name);
+ }
+ for (TopicName name: new ArrayList<TopicName>(source.getTopicNames())) {
+ existing = sigs.get(SignatureGenerator.generateSignature(name));
+ if (existing != null) {
+ handleExistingConstruct((IReifiable) name, existing);
+ moveVariants((TopicNameImpl)name, (TopicNameImpl) existing);
+ removeConstruct((IConstruct) name);
+ }
+ else {
+ source.removeName(name);
+ target.addName(name);
+ }
+ }
+ sigs.clear();
+ for (AssociationRole role: target.getRolesPlayed()) {
+ Association parent = role.getAssociation();
+ sigs.put(SignatureGenerator.generateSignature(parent), (IReifiable) parent);
+ }
+ for (AssociationRole role: new ArrayList<AssociationRole>(source.getRolesPlayed())) {
+ role.setPlayer(target);
+ Association parent = role.getAssociation();
+ existing = sigs.get(SignatureGenerator.generateSignature(parent));
+ if (existing != null) {
+ handleExistingConstruct((IReifiable)parent, existing);
+ _moveRoleCharacteristics(parent, (Association)existing);
+ removeConstruct((IConstruct)parent);
+ }
+ }
+ removeConstruct(source);
+ }
+
+ /**
+ * Removes a Topic Maps construct.
+ *
+ * If the construct is not removable, a runtime exception is thrown.
+ *
+ * @param construct The construct to remove.
+ */
+ static void removeConstruct(IConstruct construct) {
+ try {
+ construct.remove();
+ }
+ catch (TMAPIException ex) {
+ throw new TMAPIRuntimeException("Unexpected exception while Topic Maps construct removal", ex);
+ }
+ }
+
+ /**
+ * Moves role item identifiers and reifier from the <code>source</code> to
+ * the <code>target</code>'s equivalent role.
+ *
+ * @param source The association to remove the characteristics from.
+ * @param target The association which takes the role characteristics.
+ */
+ @SuppressWarnings("unchecked")
+ private static void _moveRoleCharacteristics(Association source, Association target) {
+ Map<String, AssociationRole> sigs = ((TopicMapImpl) target.getTopicMap()).getCollectionFactory().<String, AssociationRole>createMap();
+ for (AssociationRole role: ((AssociationImpl)target).getAssociationRoles()) {
+ sigs.put(SignatureGenerator.generateSignature(role), role);
+ }
+ List<AssociationRole> roles = new ArrayList<AssociationRole>(source.getAssociationRoles());
+ for (AssociationRole role: roles) {
+ handleExistingConstruct((IReifiable)role, (IReifiable)sigs.get(SignatureGenerator.generateSignature(role)));
+ removeConstruct((IConstruct)role);
+ }
+ }
+
+ /**
+ * Moves the variants from <code>source</code> to <code>target</code>.
+ *
+ * @param source The name to take the variants from.
+ * @param target The target to add the variants to.
+ */
+ static void moveVariants(TopicNameImpl source, TopicNameImpl target) {
+ Map<String, Variant> sigs = ((TopicMapImpl) target.getTopicMap()).getCollectionFactory().<String, Variant>createMap();
+ for (Variant var: target.getVariants()) {
+ sigs.put(SignatureGenerator.generateSignature(var), var);
+ }
+ Variant existing = null;
+ for (Variant var: new ArrayList<Variant>(source.getVariants())) {
+ existing = sigs.get(SignatureGenerator.generateSignature(var));
+ if (existing != null) {
+ handleExistingConstruct((IReifiable) var, (IReifiable) existing);
+ removeConstruct((IConstruct)var);
+ }
+ else {
+ source.removeVariant(var);
+ target.addVariant(var);
+ }
+ }
+ }
+
+ /**
+ * Moves the item identifiers and reifier from <code>source</code> to
+ * <code>target</code>.
+ *
+ * If the <code>source</code> is reified, the <code>target</code>'s reifier
+ * is set to the source reifier unless the target is also reified.
+ * If <code>source</code> and <code>target</code> are reified, the reifiers
+ * are merged.
+ *
+ * @param source The source Topic Maps construct.
+ * @param target The target Topic Maps construct.
+ */
+ static void handleExistingConstruct(IReifiable source, IReifiable target) {
+ _moveItemIdentifiers(source, target);
+ if (source.getReifier() == null) {
+ return;
+ }
+ if (target.getReifier() != null) {
+ Topic reifier = source.getReifier();
+ source.setReifier(null);
+ merge(reifier, target.getReifier());
+ }
+ else {
+ Topic reifier = source.getReifier();
+ source.setReifier(null);
+ target.setReifier(reifier);
+ }
+ }
+
+ /**
+ * Replaces the <code>source</code> topic with the <code>replacement</code>
+ * everywhere where <code>source</code> is used as type or theme.
+ *
+ * @param source The topic to replace.
+ * @param replacement The topic which replaces the <code>source</code>.
+ */
+ private static void _replaceTopics(Topic source, Topic replacement) {
+ TopicMapImpl tm = (TopicMapImpl) replacement.getTopicMap();
+ IndexManager idxMan = tm.getIndexManager();
+ ITypeInstanceIndex typeInstanceIndex = idxMan.getTypeInstanceIndex();
+ if (!typeInstanceIndex.isAutoUpdated()) {
+ typeInstanceIndex.reindex();
+ }
+ List<Topic> topics = new ArrayList<Topic>(typeInstanceIndex.getTopics(source));
+ for (Topic topic: topics) {
+ topic.removeType(source);
+ topic.addType(replacement);
+ }
+ Collection<ITyped> typed = new ArrayList<ITyped>(typeInstanceIndex.getAssociations(source));
+ _replaceTopicAsType(typed, replacement);
+ typed = new ArrayList<ITyped>(typeInstanceIndex.getRoles(source));
+ _replaceTopicAsType(typed, replacement);
+ typed = new ArrayList<ITyped>(typeInstanceIndex.getOccurrences(source));
+ _replaceTopicAsType(typed, replacement);
+ typed = new ArrayList<ITyped>(typeInstanceIndex.getNames(source));
+ _replaceTopicAsType(typed, replacement);
+ typeInstanceIndex.close();
+ IScopedIndex scopedIndex = idxMan.getScopedIndex();
+ if (!scopedIndex.isAutoUpdated()) {
+ scopedIndex.reindex();
+ }
+ Collection<IScoped> scoped = new ArrayList<IScoped>(scopedIndex.getAssociationsByTheme(source));
+ _replaceTopicAsTheme(scoped, source, replacement);
+ scoped = new ArrayList<IScoped>(scopedIndex.getOccurrencesByTheme(source));
+ _replaceTopicAsTheme(scoped, source, replacement);
+ scoped = new ArrayList<IScoped>(scopedIndex.getNamesByTheme(source));
+ _replaceTopicAsTheme(scoped, source, replacement);
+ scoped = new ArrayList<IScoped>(scopedIndex.getVariantsByTheme(source));
+ _replaceTopicAsTheme(scoped, source, replacement);
+ scopedIndex.close();
+ }
+
+ /**
+ * Sets <code>replacement</code> as type of each typed Topic Maps construct.
+ *
+ * @param typedConstructs A collection of typed constructs.
+ * @param replacement The type.
+ */
+ private static void _replaceTopicAsType(Collection<ITyped> typedConstructs,
+ Topic replacement) {
+ for (ITyped typed: typedConstructs) {
+ typed.setType(replacement);
+ }
+ }
+
+ private static void _replaceTopicAsTheme(Collection<IScoped> scopedCollection,
+ Topic oldTheme, Topic newTheme) {
+ for (IScoped scoped: scopedCollection) {
+ scoped.removeTheme(oldTheme);
+ scoped.addTheme(newTheme);
+ }
+ }
+
+ /**
+ * Moves the item identifiers from <code>source</code> to <code>target</code>.
+ *
+ * @param source The source to remove the item identifiers from.
+ * @param target The target which get the item identifiers.
+ */
+ private static void _moveItemIdentifiers(IConstruct source, IConstruct target) {
+ List<Locator> iids = new ArrayList<Locator>(source.getItemIdentifiers());
+ for (Locator iid: iids) {
+ source.removeItemIdentifier(iid);
+ target.addItemIdentifier(iid);
+ }
+ }
+
+}
Property changes on: tinytim/trunk/src/main/java/org/tinytim/MergeUtils.java
___________________________________________________________________
Name: svn:keywords
+ Rev Date Id
Name: svn:eol-style
+ native
Added: tinytim/trunk/src/main/java/org/tinytim/OccurrenceImpl.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/OccurrenceImpl.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/OccurrenceImpl.java 2008-04-21 14:59:01 UTC (rev 26)
@@ -0,0 +1,62 @@
+/*
+ * This is tinyTiM, a tiny Topic Maps engine.
+ *
+ * Copyright (C) 2008 Lars Heuer (heuer[at]semagia.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+package org.tinytim;
+
+import java.util.Collection;
+
+import org.tmapi.core.Locator;
+import org.tmapi.core.Occurrence;
+import org.tmapi.core.TMAPIException;
+import org.tmapi.core.Topic;
+
+/**
+ * {@link org.tmapi.core.Occurrence} implementation.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+public final class OccurrenceImpl extends DatatypeAwareConstruct implements
+ Occurrence, ITyped {
+
+ OccurrenceImpl(TopicMapImpl topicMap, Topic type, String value, Collection<Topic> scope) {
+ super(topicMap, type, value, scope);
+ }
+
+ OccurrenceImpl(TopicMapImpl topicMap, Topic type, Locator value, Collection<Topic> scope) {
+ super(topicMap, type, value, scope);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Occurrence#getTopic()
+ */
+ public Topic getTopic() {
+ return (Topic) _parent;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.TopicMapObject#remove()
+ */
+ public void remove() throws TMAPIException {
+ ((TopicImpl) _parent).removeOccurrence(this);
+ super.dispose();
+ }
+
+}
Property changes on: tinytim/trunk/src/main/java/org/tinytim/OccurrenceImpl.java
___________________________________________________________________
Name: svn:keywords
+ Rev Date Id
Name: svn:eol-style
+ native
Added: tinytim/trunk/src/main/java/org/tinytim/TopicImpl.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/TopicImpl.java (rev 0)
+++ tinytim/trunk/src/main/java/org/tinytim/TopicImpl.java 2008-04-21 14:59:01 UTC (rev 26)
@@ -0,0 +1,317 @@
+/*
+ * This is tinyTiM, a tiny Topic Maps engine.
+ *
+ * Copyright (C) 2008 Lars Heuer (heuer[at]semagia.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+package org.tinytim;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+import org.tmapi.core.AssociationRole;
+import org.tmapi.core.Locator;
+import org.tmapi.core.MergeException;
+import org.tmapi.core.ModelConstraintException;
+import org.tmapi.core.Occurrence;
+import org.tmapi.core.Topic;
+import org.tmapi.core.TopicInUseException;
+import org.tmapi.core.TopicMapObject;
+import org.tmapi.core.TopicName;
+
+/**
+ * {@link org.tmapi.core.Topic} implementation.
+ *
+ * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
+ * @version $Rev:$ - $Date:$
+ */
+public final class TopicImpl extends Construct implements Topic {
+
+ private Set<AssociationRole> _rolesPlayed;
+ IReifiable _reified;
+ private Set<Topic> _types;
+ private Set<Locator> _sids;
+ private Set<Locator> _slos;
+ private Set<Occurrence> _occs;
+ private Set<TopicName> _names;
+
+ TopicImpl(TopicMapImpl topicMap) {
+ super(topicMap);
+ ICollectionFactory collFactory = topicMap.getCollectionFactory();
+ _sids = collFactory.<Locator>createSet(2);
+ _occs = collFactory.<Occurrence>createSet(2);
+ _names = collFactory.<TopicName>createSet(2);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#getSubjectIdentifiers()
+ */
+ public Set<Locator> getSubjectIdentifiers() {
+ return Collections.unmodifiableSet(_sids);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#addSubjectIdentifier(org.tmapi.core.Locator)
+ */
+ public void addSubjectIdentifier(Locator sid) throws MergeException {
+ if (_sids.contains(sid)) {
+ return;
+ }
+ _fireEvent(Event.ADD_SID, null, sid);
+ _sids.add(sid);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#removeSubjectIdentifier(org.tmapi.core.Locator)
+ */
+ public void removeSubjectIdentifier(Locator sid) {
+ if (!_sids.contains(sid)) {
+ return;
+ }
+ _fireEvent(Event.REMOVE_SID, sid, null);
+ _sids.remove(sid);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#getSubjectLocators()
+ */
+ public Set<Locator> getSubjectLocators() {
+ return _slos == null ? Collections.<Locator>emptySet()
+ : Collections.unmodifiableSet(_slos);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#addSubjectLocator(org.tmapi.core.Locator)
+ */
+ public void addSubjectLocator(Locator slo) throws MergeException,
+ ModelConstraintException {
+ if (_slos != null && _sids.contains(slo)) {
+ return;
+ }
+ _fireEvent(Event.ADD_SLO, null, slo);
+ if (_slos == null) {
+ _slos = _tm.getCollectionFactory().createSet();
+ }
+ _slos.add(slo);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#removeSubjectLocator(org.tmapi.core.Locator)
+ */
+ public void removeSubjectLocator(Locator slo) {
+ if (_slos == null || !_slos.contains(slo)) {
+ return;
+ }
+ _fireEvent(Event.REMOVE_SLO, slo, null);
+ _sids.remove(slo);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#getOccurrences()
+ */
+ public Set<Occurrence> getOccurrences() {
+ return Collections.unmodifiableSet(_occs);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#createOccurrence(java.lang.String, org.tmapi.core.Topic, java.util.Collection)
+ */
+ @SuppressWarnings("unchecked")
+ public Occurrence createOccurrence(String value, Topic type, Collection scope) {
+ Occurrence occ = new OccurrenceImpl(_tm, type, value, scope);
+ addOccurrence(occ);
+ return occ;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#createOccurrence(org.tmapi.core.Locator, org.tmapi.core.Topic, java.util.Collection)
+ */
+ @SuppressWarnings("unchecked")
+ public Occurrence createOccurrence(Locator value, Topic type, Collection scope) {
+ Occurrence occ = new OccurrenceImpl(_tm, type, value, scope);
+ addOccurrence(occ);
+ return occ;
+ }
+
+ /**
+ * Adds an occurrence to the [occurrences] property.
+ *
+ * @param occ The occurrence to add.
+ */
+ void addOccurrence(Occurrence occ) {
+ OccurrenceImpl o = (OccurrenceImpl) occ;
+ if (o._parent == this) {
+ return;
+ }
+ _fireEvent(Event.ADD_OCCURRENCE, null, o);
+ o._parent = this;
+ _occs.add(o);
+ }
+
+ /**
+ * Removes an occurrence from the [occurrences] property.
+ *
+ * @param occ The occurrence to remove.
+ */
+ void removeOccurrence(Occurrence occ) {
+ OccurrenceImpl o = (OccurrenceImpl) occ;
+ if (o._parent != this) {
+ return;
+ }
+ _fireEvent(Event.REMOVE_OCCURRENCE, o, null);
+ _occs.remove(o);
+ o._parent = null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#getTopicNames()
+ */
+ public Set<TopicName> getTopicNames() {
+ return Collections.unmodifiableSet(_names);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#createTopicName(java.lang.String, java.util.Collection)
+ */
+ @SuppressWarnings("unchecked")
+ public TopicName createTopicName(String value, Collection scope)
+ throws MergeException {
+ return createTopicName(value, null, scope);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#createTopicName(java.lang.String, org.tmapi.core.Topic, java.util.Collection)
+ */
+ @SuppressWarnings("unchecked")
+ public TopicName createTopicName(String value, Topic type, Collection scope)
+ throws UnsupportedOperationException, MergeException {
+ TopicNameImpl name = new TopicNameImpl(_tm, type, value, scope);
+ addName(name);
+ return name;
+ }
+
+ void addName(TopicName name) {
+ TopicNameImpl n = (TopicNameImpl) name;
+ if (n._parent == this) {
+ return;
+ }
+ assert n._parent == null;
+ _fireEvent(Event.ADD_NAME, null, n);
+ n._parent = this;
+ _names.add(n);
+ }
+
+ void removeName(TopicName name) {
+ TopicNameImpl n = (TopicNameImpl) name;
+ if (n._parent != this) {
+ return;
+ }
+ _fireEvent(Event.REMOVE_NAME, n, null);
+ _names.remove(n);
+ n._parent = null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#getReified()
+ */
+ public Set<TopicMapObject> getReified() {
+ return _reified != null ? Collections.<TopicMapObject>singleton(_reified)
+ : Collections.<TopicMapObject>emptySet();
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#getRolesPlayed()
+ */
+ public Set<AssociationRole> getRolesPlayed() {
+ return _rolesPlayed == null ? Collections.<AssociationRole>emptySet()
+ : Collections.unmodifiableSet(_rolesPlayed);
+ }
+
+ void addRolePlayed(AssociationRole role) {
+ if (_rolesPlayed == null) {
+ _rolesPlayed = _tm.getCollectionFactory().createSet(4);
+ }
+ _rolesPlayed.add(role);
+ }
+
+ void removeRolePlayed(AssociationRole role) {
+ if (_rolesPlayed == null) {
+ return;
+ }
+ _rolesPlayed.remove(role);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#getTypes()
+ */
+ public Set<Topic> getTypes() {
+ return _types == null ? Collections.<Topic>emptySet()
+ : Collections.unmodifiableSet(_types);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#addType(org.tmapi.core.Topic)
+ */
+ public void addType(Topic type) {
+ if (_types != null && _types.contains(type)) {
+ return;
+ }
+ _fireEvent(Event.ADD_TYPE, null, type);
+ if (_types == null) {
+ _types = _tm.getCollectionFactory().createSet();
+ }
+ _types.add(type);
+ }
+
+ /* (non-Javadoc)
+ * @see org.tmapi.core.Topic#removeType(org.tmapi.core.Topic)
+ */
+ public void removeType(Topic type) {
+ if (_types ==...
[truncated message content] |