|
From: <lh...@us...> - 2009-07-23 12:26:39
|
Revision: 329
http://tinytim.svn.sourceforge.net/tinytim/?rev=329&view=rev
Author: lheuer
Date: 2009-07-23 12:26:38 +0000 (Thu, 23 Jul 2009)
Log Message:
-----------
Fixes #2824837 and the remaining problem with the VariantReifier3 test
Modified Paths:
--------------
tinytim/trunk/CHANGES.txt
tinytim/trunk/src/main/java/org/tinytim/core/AssociationImpl.java
tinytim/trunk/src/main/java/org/tinytim/mio/TinyTimMapInputHandler.java
tinytim/trunk/src/test/java/org/tinytim/mio/TestTinyTimMapInputHandler.java
Modified: tinytim/trunk/CHANGES.txt
===================================================================
--- tinytim/trunk/CHANGES.txt 2009-07-23 12:21:03 UTC (rev 328)
+++ tinytim/trunk/CHANGES.txt 2009-07-23 12:26:38 UTC (rev 329)
@@ -9,11 +9,11 @@
Bugfixes:
---------
-* Bug #2812460 -- Port the Check class from Ontopia back to
- tinyTiM
+* Bug #2812460 -- Port the Check class from Ontopia back to tinyTiM
* Bug #2809821 -- Ensure same topic map constraint
* Bug #2561306 -- Move TinyTimMapInputHandler to the core
* Bug #2824834 -- Reifier at duplicate construct fails
+* Bug #2824837 -- Same iid at a duplicate statement does not work
2.0.0 a4 (06.12.2008)
Modified: tinytim/trunk/src/main/java/org/tinytim/core/AssociationImpl.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/core/AssociationImpl.java 2009-07-23 12:21:03 UTC (rev 328)
+++ tinytim/trunk/src/main/java/org/tinytim/core/AssociationImpl.java 2009-07-23 12:26:38 UTC (rev 329)
@@ -19,13 +19,13 @@
import java.util.Set;
import org.tinytim.internal.api.Event;
+import org.tinytim.internal.api.IAssociation;
import org.tinytim.internal.api.IConstant;
import org.tinytim.internal.api.IScope;
import org.tinytim.internal.api.ITopicMap;
import org.tinytim.internal.utils.Check;
import org.tinytim.internal.utils.CollectionFactory;
-import org.tmapi.core.Association;
import org.tmapi.core.Role;
import org.tmapi.core.Topic;
import org.tmapi.core.TopicMap;
@@ -36,7 +36,7 @@
* @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
* @version $Rev$ - $Date$
*/
-final class AssociationImpl extends ScopedImpl implements Association {
+final class AssociationImpl extends ScopedImpl implements IAssociation {
private Set<Role> _roles;
Modified: tinytim/trunk/src/main/java/org/tinytim/mio/TinyTimMapInputHandler.java
===================================================================
--- tinytim/trunk/src/main/java/org/tinytim/mio/TinyTimMapInputHandler.java 2009-07-23 12:21:03 UTC (rev 328)
+++ tinytim/trunk/src/main/java/org/tinytim/mio/TinyTimMapInputHandler.java 2009-07-23 12:26:38 UTC (rev 329)
@@ -17,9 +17,11 @@
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.tinytim.core.Scope;
import org.tinytim.core.value.Literal;
+import org.tinytim.internal.api.IAssociation;
import org.tinytim.internal.api.IConstruct;
import org.tinytim.internal.api.IConstructFactory;
import org.tinytim.internal.api.ILiteralAware;
@@ -35,15 +37,14 @@
import org.tinytim.utils.TypeInstanceConverter;
import org.tinytim.voc.TMDM;
-import org.tmapi.core.Association;
import org.tmapi.core.Construct;
import org.tmapi.core.Locator;
import org.tmapi.core.Reifiable;
import org.tmapi.core.Role;
-import org.tmapi.core.Scoped;
import org.tmapi.core.Topic;
import org.tmapi.core.TopicMap;
import org.tmapi.core.Typed;
+import org.tmapi.core.Variant;
import com.semagia.mio.IMapHandler;
import com.semagia.mio.IRef;
@@ -76,11 +77,13 @@
private static final int _STATE_SIZE = 10;
private static final int _SCOPE_SIZE = 6;
private static final int _DELAYED_REIFICATION_SIZE = 2;
+ private static final int _DELAYED_ITEM_IDENTIFIER_SIZE = 2;
private final IConstructFactory _factory;
private final ITopicMap _tm;
private final List<Topic> _scope;
- private final Map<Reifiable, Topic> _delayedReification;
+ private final Map<Reifiable, ITopic> _delayedReification;
+ private final Map<IConstruct, Set<Locator>> _delayedItemIdentifiers;
private byte[] _stateStack;
private int _stateSize;
private IConstruct[] _constructStack;
@@ -94,6 +97,7 @@
_factory = _tm.getConstructFactory();
_scope = CollectionFactory.createList(_SCOPE_SIZE);
_delayedReification = CollectionFactory.createIdentityMap(_DELAYED_REIFICATION_SIZE);
+ _delayedItemIdentifiers = CollectionFactory.createIdentityMap(_DELAYED_ITEM_IDENTIFIER_SIZE);
}
/* (non-Javadoc)
@@ -114,6 +118,12 @@
@Override
public void endTopicMap() throws MIOException {
TypeInstanceConverter.convertAssociationsToTypes(_tm);
+ if (!_delayedReification.isEmpty()) {
+ throw new MIOException("ERROR: Unhandled reifications");
+ }
+ if (!_delayedItemIdentifiers.isEmpty()) {
+ throw new MIOException("ERROR: Unhandled item identifiers");
+ }
_constructStack = null;
_stateStack = null;
_scope.clear();
@@ -148,7 +158,7 @@
*/
@Override
public void endAssociation() throws MIOException {
- _leaveStatePopReifiable(ASSOCIATION);
+ _handleDelayedEvents(_leaveStatePopConstruct(ASSOCIATION));
}
/* (non-Javadoc)
@@ -157,7 +167,7 @@
@Override
public void startRole() throws MIOException {
assert _state() == ASSOCIATION;
- _enterState(ROLE, _factory.createRole((Association) _peekConstruct()));
+ _enterState(ROLE, _factory.createRole((IAssociation) _peekConstruct()));
}
/* (non-Javadoc)
@@ -199,7 +209,7 @@
*/
@Override
public void endOccurrence() throws MIOException {
- _leaveStatePopReifiable(OCCURRENCE);
+ _handleDelayedEvents(_leaveStatePopConstruct(OCCURRENCE));
}
/* (non-Javadoc)
@@ -222,7 +232,7 @@
if (name.getType() == null) {
name.setType(_tm.createTopicBySubjectIdentifier(TMDM.TOPIC_NAME));
}
- _handleDelayedReifier(name);
+ _handleDelayedEvents(name);
}
/* (non-Javadoc)
@@ -273,7 +283,7 @@
*/
@Override
public void startScope() throws MIOException {
- assert _peekConstruct() instanceof Scoped;
+ assert _peekConstruct() instanceof IScoped;
_enterState(SCOPE);
}
@@ -346,8 +356,8 @@
public void itemIdentifier(String itemIdentifier) throws MIOException {
Locator iid = _tm.createLocator(itemIdentifier);
IConstruct tmo = _peekConstruct();
+ IConstruct existing = (IConstruct) _tm.getConstructByItemIdentifier(iid);
if (_state() == TOPIC) {
- IConstruct existing = (IConstruct) _tm.getConstructByItemIdentifier(iid);
if (existing != null && existing.isTopic() && !existing.equals(tmo)) {
_merge((Topic) existing, (ITopic) tmo);
}
@@ -357,8 +367,24 @@
_merge(topic, (ITopic) tmo);
}
}
+ tmo.addItemIdentifier(iid);
}
- tmo.addItemIdentifier(iid);
+ else if (existing != null && !existing.equals(tmo)) {
+ if (!_areMergable(tmo, existing)) {
+ throw new MIOException("A Topic Maps construct with the item identifier '" + itemIdentifier + "' exists already");
+ }
+ else {
+ Set<Locator> iids = _delayedItemIdentifiers.get(tmo);
+ if (iids == null) {
+ iids = CollectionFactory.createIdentitySet();
+ }
+ iids.add(iid);
+ _delayedItemIdentifiers.put(tmo, iids);
+ }
+ }
+ else {
+ tmo.addItemIdentifier(iid);
+ }
}
/* (non-Javadoc)
@@ -481,10 +507,6 @@
return construct;
}
- private Reifiable _leaveStatePopReifiable(byte state) throws MIOException {
- return _handleDelayedReifier((Reifiable) _leaveStatePopConstruct(state));
- }
-
/**
* Returns the Topic Maps construct on top of the stack.
*
@@ -495,75 +517,88 @@
}
/**
- *
+ * Issues the delayed item identifier and reifier events.
*
- * @param reifiable
- * @return
- * @throws MIOException
+ * @param construct
*/
- private Reifiable _handleDelayedReifier(final Reifiable reifiable) throws MIOException {
- Topic reifier = _delayedReification.remove(reifiable);
- final IConstruct c = (IConstruct) reifiable;
- if (reifier != null) {
- return _handleDelayedReifier(reifiable, reifier);
+ private void _handleDelayedEvents(IConstruct tmc) throws MIOException {
+ IConstruct existing = _processDelayedEvents(tmc);
+ if (tmc.isAssociation()) {
+ IAssociation existingAssoc = (IAssociation) existing;
+ IConstruct existingRole = null;
+ for (Role role: ((IAssociation) tmc).getRoles()) {
+ existingRole = _processDelayedEvents((IConstruct) role);
+ if (existingRole != null && existingAssoc == null) {
+ existingAssoc = (IAssociation) existingRole.getParent();
+ }
+ }
+ if (existingAssoc != null && !existingAssoc.equals(tmc)) {
+ MergeUtils.moveRoleCharacteristics((IAssociation) tmc, existingAssoc);
+ existing = existingAssoc;
+ }
}
- List<? extends Reifiable> reifiables = null;
- if (c.isAssociation()) {
- reifiables = CollectionFactory.createList(((Association) c).getRoles());
+ else if (tmc.isName()) {
+ IName existingName = (IName) existing;
+ IConstruct existingVariant = null;
+ for (Variant role: ((IName) tmc).getVariants()) {
+ existingVariant = _processDelayedEvents((IConstruct) role);
+ if (existingVariant != null && existingName == null) {
+ existingName = (IName) existingVariant.getParent();
+ }
+ }
+ if (existingName != null && !existingName.equals(tmc)) {
+ MergeUtils.moveVariants((IName) tmc, existingName);
+ existing = existingName;
+ }
}
- else if (c.isName()) {
- reifiables = CollectionFactory.createList(((IName) c).getVariants());
+ if (existing != null && !existing.equals(tmc)) {
+ tmc.remove();
}
- if (reifiables == null || _delayedReification.isEmpty()) {
- return reifiable;
+ }
+
+ private IConstruct _processDelayedEvents(IConstruct tmc) throws MIOException {
+ IConstruct existing = null;
+ Set<Locator> iids = _delayedItemIdentifiers.remove(tmc);
+ Topic reifier = _delayedReification.remove(tmc);
+ final int signature = SignatureGenerator.generateSignature(tmc);
+ if (iids != null) {
+ existing = _handleItemIdentifiers(signature, tmc, iids);
}
- boolean foundReifier = false;
- final int parentSignature = SignatureGenerator.generateSignature(c);
- for (Reifiable r: reifiables) {
- reifier = _delayedReification.remove(r);
- if (reifier == null) {
- continue;
- }
- if (parentSignature == SignatureGenerator.generateSignature((IConstruct) reifier.getReified().getParent())) {
- _handleDelayedReifier(r, reifier);
- foundReifier = !c.equals(reifier.getReified().getParent());
- }
- else {
- throw new MIOException("The topic '" + reifier + "' reifies another construct");
- }
+ if (reifier != null) {
+ existing = _handleReification(signature, tmc, reifier);
}
- if (foundReifier) {
- c.remove();
+ return existing;
+ }
+
+ private IConstruct _handleReification(int signature, IConstruct tmc,
+ Topic reifier) throws MIOException {
+ final IConstruct existing = (IConstruct) reifier.getReified();
+ final boolean checkParent = tmc.isRole() || tmc.isVariant();
+ final int parentSignature = checkParent ? SignatureGenerator.generateSignature((IConstruct)tmc.getParent())
+ : -1;
+ if (signature != SignatureGenerator.generateSignature(existing)
+ || (checkParent && parentSignature != SignatureGenerator.generateSignature((IConstruct) existing.getParent()))) {
+ throw new MIOException("The topic '" + reifier + "' reifies another construct");
}
- return reifiable;
+ MergeUtils.moveItemIdentifiers(tmc, existing);
+ return existing;
}
- /**
- *
- *
- * @param reifiable
- * @param reifier
- * @return
- * @throws MIOException
- */
- private Reifiable _handleDelayedReifier(final Reifiable reifiable, final Topic reifier) throws MIOException {
- IConstruct c = (IConstruct) reifiable;
- IConstruct reified = (IConstruct) reifier.getReified();
- if (SignatureGenerator.generateSignature(c) ==
- SignatureGenerator.generateSignature(reified)) {
- MergeUtils.moveItemIdentifiers(reifiable, reifier.getReified());
- if (c.isAssociation()) {
- MergeUtils.moveRoleCharacteristics((Association) c, (Association) reifier.getReified());
+ private IConstruct _handleItemIdentifiers(int signature, IConstruct tmc,
+ Set<Locator> iids) throws MIOException {
+ IConstruct existing = null;
+ final boolean checkParent = tmc.isRole() || tmc.isVariant();
+ final int parentSignature = checkParent ? SignatureGenerator.generateSignature((IConstruct)tmc.getParent())
+ : -1;
+ for (Locator iid: iids) {
+ existing = (IConstruct) _tm.getConstructByItemIdentifier(iid);
+ if (signature != SignatureGenerator.generateSignature(existing)
+ || (checkParent && parentSignature != SignatureGenerator.generateSignature((IConstruct) existing.getParent()))) {
+ throw new MIOException("The item identifier '" + iid + "' is already assigned");
}
- else if (c.isName()) {
- MergeUtils.moveVariants((IName)c, (IName) reified);
- }
- reifiable.remove();
- return reifier.getReified();
+ MergeUtils.moveItemIdentifiers(tmc, existing);
}
- else {
- throw new MIOException("The topic " + reifier + " reifies another construct");
- }
+ return existing;
}
/**
@@ -596,7 +631,7 @@
case TYPE: ((Typed) _peekConstruct()).setType(topic); break;
case PLAYER: ((Role) _peekConstruct()).setPlayer(topic); break;
case THEME: _scope.add(topic); break;
- case REIFIER: _handleReifier((Reifiable) _peekConstruct(), topic); break;
+ case REIFIER: _handleReifier((Reifiable) _peekConstruct(), (ITopic) topic); break;
}
}
@@ -607,7 +642,7 @@
* @param reifier
* @throws MIOException
*/
- private void _handleReifier(Reifiable reifiable, Topic reifier) throws MIOException {
+ private void _handleReifier(Reifiable reifiable, ITopic reifier) throws MIOException {
final Reifiable reified = reifier.getReified();
if (reified != null && !reifiable.equals(reified)) {
if (!_areMergable((IConstruct) reifiable, (IConstruct) reified)) {
@@ -644,8 +679,8 @@
private boolean _areMergable(IConstruct a, IConstruct b) {
return _sameConstructKind(a, b)
- && (a.isRole() && b.isRole()
- || (a.isVariant() && b.isVariant() && a.getParent().getParent().equals(b.getParent().getParent()))
+ && (a.isRole()
+ || (a.isVariant() && a.getParent().getParent().equals(b.getParent().getParent()))
|| a.getParent().equals(b.getParent()));
}
Modified: tinytim/trunk/src/test/java/org/tinytim/mio/TestTinyTimMapInputHandler.java
===================================================================
--- tinytim/trunk/src/test/java/org/tinytim/mio/TestTinyTimMapInputHandler.java 2009-07-23 12:21:03 UTC (rev 328)
+++ tinytim/trunk/src/test/java/org/tinytim/mio/TestTinyTimMapInputHandler.java 2009-07-23 12:26:38 UTC (rev 329)
@@ -51,74 +51,74 @@
_handler = new TinyTimMapInputHandler(_tm);
}
-// public void testVariantNoValue() throws Exception {
-// final IRef theTopic = Ref.createItemIdentifier("http://test.semagia.com/the-topic");
-// final IRef theme = Ref.createItemIdentifier("http://test.semagia.com/theme");
-// TinyTimMapInputHandler handler = _handler;
-// handler.startTopicMap();
-// handler.startTopic(theTopic);
-// handler.startName();
-// handler.value("Semagia");
-// handler.startVariant();
-// handler.startScope();
-// handler.startTheme();
-// handler.topicRef(theme);
-// handler.endTheme();
-// handler.endScope();
-// try {
-// handler.endVariant();
-// fail("Expected an error since the variant has no value");
-// }
-// catch (MIOException ex) {
-// // noop.
-// }
-// }
-//
-// public void testNameNoValue() throws Exception {
-// final IRef theTopic = Ref.createItemIdentifier("http://test.semagia.com/the-topic");
-// TinyTimMapInputHandler handler = _handler;
-// handler.startTopicMap();
-// handler.startTopic(theTopic);
-// handler.startName();
-// try {
-// handler.endName();
-// fail("Expected an error since the name has no value");
-// }
-// catch (MIOException ex) {
-// // noop.
-// }
-// }
-//
-// /**
-// * <a href="http://code.google.com/p/mappa/issues/detail?id=23">http://code.google.com/p/mappa/issues/detail?id=23</a>
-// */
-// public void testMappaIssue23() throws Exception {
-// String iid = "http://mappa.semagia.com/issue-23";
-// String iid2 = "http://mappa.semagia.com/issue-23_";
-// final IRef TOPIC_NAME = Ref.createSubjectIdentifier(TMDM.TOPIC_NAME.getReference());
-// TinyTimMapInputHandler handler = _handler;
-// handler.startTopicMap();
-// handler.startTopic(Ref.createItemIdentifier(iid));
-// handler.startName();
-// handler.value("test");
-// handler.startType();
-// handler.topicRef(TOPIC_NAME);
-// handler.endType();
-// handler.endName();
-// handler.endTopic();
-// handler.startTopic(Ref.createItemIdentifier(iid2));
-// handler.startName();
-// handler.value("a test");
-// handler.startType();
-// handler.topicRef(TOPIC_NAME);
-// handler.endType();
-// handler.endName();
-// handler.subjectIdentifier(TOPIC_NAME.getIRI());
-// handler.endTopic();
-// handler.endTopicMap();
-// }
+ public void testVariantNoValue() throws Exception {
+ final IRef theTopic = Ref.createItemIdentifier("http://test.semagia.com/the-topic");
+ final IRef theme = Ref.createItemIdentifier("http://test.semagia.com/theme");
+ TinyTimMapInputHandler handler = _handler;
+ handler.startTopicMap();
+ handler.startTopic(theTopic);
+ handler.startName();
+ handler.value("Semagia");
+ handler.startVariant();
+ handler.startScope();
+ handler.startTheme();
+ handler.topicRef(theme);
+ handler.endTheme();
+ handler.endScope();
+ try {
+ handler.endVariant();
+ fail("Expected an error since the variant has no value");
+ }
+ catch (MIOException ex) {
+ // noop.
+ }
+ }
+ public void testNameNoValue() throws Exception {
+ final IRef theTopic = Ref.createItemIdentifier("http://test.semagia.com/the-topic");
+ TinyTimMapInputHandler handler = _handler;
+ handler.startTopicMap();
+ handler.startTopic(theTopic);
+ handler.startName();
+ try {
+ handler.endName();
+ fail("Expected an error since the name has no value");
+ }
+ catch (MIOException ex) {
+ // noop.
+ }
+ }
+
/**
+ * <a href="http://code.google.com/p/mappa/issues/detail?id=23">http://code.google.com/p/mappa/issues/detail?id=23</a>
+ */
+ public void testMappaIssue23() throws Exception {
+ String iid = "http://mappa.semagia.com/issue-23";
+ String iid2 = "http://mappa.semagia.com/issue-23_";
+ final IRef TOPIC_NAME = Ref.createSubjectIdentifier(TMDM.TOPIC_NAME.getReference());
+ TinyTimMapInputHandler handler = _handler;
+ handler.startTopicMap();
+ handler.startTopic(Ref.createItemIdentifier(iid));
+ handler.startName();
+ handler.value("test");
+ handler.startType();
+ handler.topicRef(TOPIC_NAME);
+ handler.endType();
+ handler.endName();
+ handler.endTopic();
+ handler.startTopic(Ref.createItemIdentifier(iid2));
+ handler.startName();
+ handler.value("a test");
+ handler.startType();
+ handler.topicRef(TOPIC_NAME);
+ handler.endType();
+ handler.endName();
+ handler.subjectIdentifier(TOPIC_NAME.getIRI());
+ handler.endTopic();
+ handler.endTopicMap();
+ }
+
+ /**
* <a href="http://code.google.com/p/ontopia/issues/detail?id=84">http://code.google.com/p/ontopia/issues/detail?id=84</a>
* <a href="http://code.google.com/p/ontopia/issues/detail?id=77">http://code.google.com/p/ontopia/issues/detail?id=77</a>
*/
@@ -494,6 +494,50 @@
}
}
+ public void testSameIIDIssueAssociation() throws Exception {
+ TinyTimMapInputHandler handler = _handler;
+ final IRef assocType = Ref.createItemIdentifier("http://test.semagia.com/assoc-type");
+ final IRef roleType = Ref.createItemIdentifier("http://test.semagia.com/role-type");
+ final IRef rolePlayer = Ref.createItemIdentifier("http://test.semagia.com/role-player");
+ final String iid = "http://test.semagia.com/iid";
+ handler.startTopicMap();
+ handler.startAssociation();
+ handler.itemIdentifier(iid);
+ handler.startType();
+ handler.topicRef(assocType);
+ handler.endType();
+ handler.startRole();
+ handler.startType();
+ handler.topicRef(roleType);
+ handler.endType();
+ handler.startPlayer();
+ handler.topicRef(rolePlayer);
+ handler.endPlayer();
+ handler.endRole();
+ handler.endAssociation();
+
+ handler.startAssociation();
+ handler.itemIdentifier(iid);
+ handler.startType();
+ handler.topicRef(assocType);
+ handler.endType();
+ handler.startRole();
+ handler.startType();
+ handler.topicRef(roleType);
+ handler.endType();
+ handler.startPlayer();
+ handler.topicRef(rolePlayer);
+ handler.endPlayer();
+ handler.endRole();
+ handler.endAssociation();
+ handler.endTopicMap();
+ assertEquals(1, _tm.getAssociations().size());
+ final Association assoc = _tm.getAssociations().iterator().next();
+ final Construct tmc = _tm.getConstructByItemIdentifier(createLocator(iid));
+ assertNotNull(tmc);
+ assertEquals(assoc, tmc);
+ }
+
/**
* Simple startTopicMap, followed by an endTopicMap event.
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|