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. |