/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
package net.ontopia.topicmaps.utils;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.net.MalformedURLException;
import junit.framework.TestCase;
import net.ontopia.topicmaps.impl.basic.InMemoryTopicMapStore;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.infoset.impl.basic.URILocator;
import net.ontopia.topicmaps.core.AssociationIF;
import net.ontopia.topicmaps.core.AssociationRoleIF;
import net.ontopia.topicmaps.core.ConstraintViolationException;
import net.ontopia.topicmaps.core.OccurrenceIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TopicMapBuilderIF;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.topicmaps.core.TopicNameIF;
import net.ontopia.topicmaps.core.VariantNameIF;
import net.ontopia.topicmaps.xml.XTMTopicMapReader;
import net.ontopia.topicmaps.xml.CanonicalTopicMapWriter;
import net.ontopia.utils.ObjectUtils;
import net.ontopia.utils.FileUtils;
import net.ontopia.utils.TestFileUtils;
import net.ontopia.utils.URIUtils;
public class MergeTest extends TestCase {
protected TopicMapIF topicmap1;
protected TopicMapIF topicmap2;
protected TopicMapBuilderIF builder1;
protected TopicMapBuilderIF builder2;
public MergeTest(String name) {
super(name);
}
public void setUp() {
topicmap1 = makeTopicMap();
topicmap2 = makeTopicMap();
builder1 = topicmap1.getBuilder();
builder2 = topicmap2.getBuilder();
}
// intended to be overridden
protected TopicMapIF makeTopicMap() {
InMemoryTopicMapStore store = new InMemoryTopicMapStore();
return store.getTopicMap();
}
public URILocator makeLocator(String uri) {
try {
return new URILocator(uri);
}
catch (java.net.MalformedURLException e) {
fail("malformed URL given" + e.getMessage());
return null; // never executed...
}
}
// --- Test cases for shouldMerge
public void testShouldEmptyTopics() {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder2.makeTopic();
assertTrue("claims empty topics should be merged",
!MergeUtils.shouldMerge(t1, t2));
}
public void testShouldNullSubject() {
try {
TopicIF t1 = builder1.makeTopic();
t1.addSubjectLocator(makeLocator("http://www.ontopia.net"));
TopicIF t2 = builder2.makeTopic();
assertTrue("claims topics with different subjects should merge",
!MergeUtils.shouldMerge(t1, t2));
}
catch (ConstraintViolationException e) {
fail("(INTERNAL) " + e.getMessage());
}
}
public void testShouldSameSubject() {
try {
TopicIF t1 = builder1.makeTopic();
t1.addSubjectLocator(makeLocator("http://www.ontopia.net"));
TopicIF t2 = builder2.makeTopic();
t2.addSubjectLocator(makeLocator("http://www.ontopia.net"));
assertTrue("claims topics with same subjects should not merge",
MergeUtils.shouldMerge(t1, t2));
}
catch (ConstraintViolationException e) {
fail("(INTERNAL) " + e.getMessage());
}
}
public void testShouldSameSubjectIndicator() {
try {
TopicIF t1 = builder1.makeTopic();
t1.addSubjectIdentifier(makeLocator("http://www.ontopia.net"));
TopicIF t2 = builder2.makeTopic();
t2.addSubjectIdentifier(makeLocator("http://www.ontopia.net"));
assertTrue("claims topics with same subjects indicator should not merge",
MergeUtils.shouldMerge(t1, t2));
}
catch (ConstraintViolationException e) {
fail("(INTERNAL) " + e.getMessage());
}
}
public void testShouldSameTopicName() {
TopicIF t1 = builder1.makeTopic();
builder1.makeTopicName(t1, "Ontopia");
TopicIF t2 = builder2.makeTopic();
builder2.makeTopicName(t2, "Ontopia");
assertTrue("claims topics with same base name in unconstrained scope should merge",
!MergeUtils.shouldMerge(t1, t2));
}
public void testShouldTopicIsSubjectIndicator() {
TopicIF t1 = builder1.makeTopic();
t1.addItemIdentifier(makeLocator("http://www.ontopia.net"));
TopicIF t2 = builder2.makeTopic();
t2.addSubjectIdentifier(makeLocator("http://www.ontopia.net"));
assertTrue("claims topics should not merge when one is subject indicator of other",
MergeUtils.shouldMerge(t1, t2));
}
public void testShouldTopicIsSubjectIndicatorReverse() {
TopicIF t1 = builder1.makeTopic();
t1.addItemIdentifier(makeLocator("http://www.ontopia.net"));
TopicIF t2 = builder2.makeTopic();
t2.addSubjectIdentifier(makeLocator("http://www.ontopia.net"));
assertTrue("claims topics should not merge when one is subject indicator of other",
MergeUtils.shouldMerge(t2, t1));
}
public void testSeveralTopicNames() {
TopicIF dummy1 = builder1.makeTopic();
TopicIF dummy2 = builder1.makeTopic();
TopicIF t1 = builder1.makeTopic();
TopicNameIF bn1 = builder1.makeTopicName(t1, "Ontopia");
bn1.addTheme(t1);
TopicNameIF bn2 = builder1.makeTopicName(t1, "Ontopia");
bn2.addTheme(dummy1);
TopicNameIF bn3 = builder1.makeTopicName(t1, "Ontopia");
bn3.addTheme(dummy2);
TopicNameIF bn4 = builder1.makeTopicName(t1, "Ontopia");
bn4.addTheme(dummy1);
bn4.addTheme(dummy2);
TopicNameIF bn5 = builder1.makeTopicName(t1, "Ontopia");
TopicIF t2 = builder2.makeTopic();
builder2.makeTopicName(t2, "Ontopia");
assertTrue("claims topics should merge when they have same BN in unconstrained scope",
!MergeUtils.shouldMerge(t1, t2));
}
// --- Test cases for mergeInto(TopicIF, TopicIF)
public void testMergeEmptyTopics() {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
try {
MergeUtils.mergeInto(t1, t2);
assertTrue("source topic not removed from topic map!",
t2.getTopicMap() == null);
}
catch (Exception e) {
throw new RuntimeException(e.toString());
}
}
public void testMergeDifferentSubjects1() {
try {
TopicIF t1 = builder1.makeTopic();
t1.addSubjectLocator(makeLocator("http://www.ontopia.net"));
TopicIF t2 = builder1.makeTopic();
MergeUtils.mergeInto(t1, t2);
assertTrue("subject was lost during merge",
t1.getSubjectLocators().contains(makeLocator("http://www.ontopia.net")));
}
catch (ConstraintViolationException e) {
fail("didn't accept merging when only one topic had a subject" + e.getMessage());
}
}
public void testMergeDifferentSubjects2() { // F.5.1, 4
try {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
t2.addSubjectLocator(makeLocator("http://www.ontopia.net"));
MergeUtils.mergeInto(t1, t2);
assertTrue("subject was lost during merge",
t1.getSubjectLocators().contains(makeLocator("http://www.ontopia.net")));
}
catch (ConstraintViolationException e) {
fail("didn't accept merging when only one topic had a subject" + e.getMessage());
}
}
public void testMergeDifferentSubjects3() {
try {
TopicIF t1 = builder1.makeTopic();
t1.addSubjectLocator(makeLocator("http://www.ontopia.net"));
TopicIF t2 = builder1.makeTopic();
t2.addSubjectLocator(makeLocator("ftp://www.ontopia.net"));
MergeUtils.mergeInto(t1, t2);
}
catch (ConstraintViolationException e) {
fail("merge of topics with different subjects not accepted");
}
}
public void testMergeSubjectIndicators() { // F.5.1, 3
try {
TopicIF t1 = builder1.makeTopic();
URILocator loc1 = makeLocator("http://www.ontopia.net");
t1.addSubjectIdentifier(loc1);
TopicIF t2 = builder1.makeTopic();
URILocator loc2 = makeLocator("ftp://www.ontopia.net");
t2.addSubjectIdentifier(loc2);
URILocator loc3 = makeLocator("http://www.ontopia.no");
t2.addSubjectIdentifier(loc3);
MergeUtils.mergeInto(t1, t2);
assertTrue("wrong number of subject indicators after merge",
t1.getSubjectIdentifiers().size() == 3);
assertTrue("original subject indicator lost",
t1.getSubjectIdentifiers().contains(loc1));
assertTrue("source subject indicator not copied",
t1.getSubjectIdentifiers().contains(loc2) &&
t1.getSubjectIdentifiers().contains(loc3));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeTopicNames() { // F.5.1, 2
try {
TopicIF t1 = builder1.makeTopic();
TopicNameIF bn1 = builder1.makeTopicName(t1, "bn1");
TopicIF t2 = builder1.makeTopic();
TopicNameIF bn2 = builder1.makeTopicName(t2, "bn2");
MergeUtils.mergeInto(t1, t2);
assertTrue("wrong number of base names after merge",
t1.getTopicNames().size() == 2);
assertTrue("original base name lost",
t1.getTopicNames().contains(bn1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeTopicNameDuplicates() { // bug #228
try {
TopicIF t1 = builder1.makeTopic();
TopicNameIF bn1 = builder1.makeTopicName(t1, "bn");
TopicIF t2 = builder1.makeTopic();
TopicNameIF bn2 = builder1.makeTopicName(t2, "bn");
MergeUtils.mergeInto(t1, t2);
assertTrue("base name duplicates not suppressed",
t1.getTopicNames().size() == 1);
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
try {
TopicIF tt1 = builder1.makeTopic();
TopicIF tt2 = builder1.makeTopic();
TopicIF t1 = builder1.makeTopic();
TopicNameIF bn1 = builder1.makeTopicName(t1, "bn");
bn1.addTheme(tt1);
bn1.addTheme(tt2);
TopicIF t2 = builder1.makeTopic();
TopicNameIF bn2 = builder1.makeTopicName(t2, "bn");
bn2.addTheme(tt1);
bn2.addTheme(tt2);
MergeUtils.mergeInto(t1, t2);
assertTrue("base name duplicates not suppressed",
t1.getTopicNames().size() == 1);
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeTopicNameDuplicatesWithVariants() {
TopicIF t1 = builder1.makeTopic();
TopicNameIF bn1 = builder1.makeTopicName(t1, "bn");
VariantNameIF vn1 = builder1.makeVariantName(bn1, "vn");
TopicIF t2 = builder1.makeTopic();
TopicNameIF bn2 = builder1.makeTopicName(t2, "bn");
VariantNameIF vn2 = builder1.makeVariantName(bn2, "vn");
MergeUtils.mergeInto(t1, t2);
assertTrue("base name duplicates not suppressed",
t1.getTopicNames().size() == 1);
}
public void testMergeOccurrences() { // F.5.1, 6
try {
TopicIF t1 = builder1.makeTopic();
URILocator loc1 = makeLocator("http://www.ontopia.net");
TopicIF ot1 = builder1.makeTopic();
OccurrenceIF oc1 = builder1.makeOccurrence(t1, ot1, loc1);
TopicIF t2 = builder1.makeTopic();
URILocator loc2 = makeLocator("ftp://www.ontopia.net");
TopicIF ot2 = builder1.makeTopic();
OccurrenceIF oc2 = builder1.makeOccurrence(t2, ot2, loc2);
MergeUtils.mergeInto(t1, t2);
assertTrue("wrong number of occurrences after merge",
t1.getOccurrences().size() == 2);
assertTrue("original occurrence lost",
t1.getOccurrences().contains(oc1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeOccurrenceDuplicates() {
try {
TopicIF t1 = builder1.makeTopic();
URILocator loc1 = makeLocator("http://www.ontopia.net");
TopicIF ot1 = builder1.makeTopic();
OccurrenceIF oc1 = builder1.makeOccurrence(t1, ot1, loc1);
TopicIF t2 = builder1.makeTopic();
OccurrenceIF oc2 = builder1.makeOccurrence(t2, ot1, loc1);
MergeUtils.mergeInto(t1, t2);
assertTrue("occurrence duplicates not suppressed",
t1.getOccurrences().size() == 1);
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
try {
TopicIF tt1 = builder1.makeTopic();
TopicIF tt2 = builder1.makeTopic();
TopicIF t1 = builder1.makeTopic();
URILocator loc1 = makeLocator("http://www.ontopia.net");
TopicIF ot1 = builder1.makeTopic();
OccurrenceIF oc1 = builder1.makeOccurrence(t1, ot1, loc1);
oc1.addTheme(tt1);
oc1.addTheme(tt2);
TopicIF t2 = builder1.makeTopic();
OccurrenceIF oc2 = builder1.makeOccurrence(t2, ot1, loc1);
oc2.addTheme(tt1);
oc2.addTheme(tt2);
MergeUtils.mergeInto(t1, t2);
assertTrue("occurrence duplicates not suppressed",
t1.getOccurrences().size() == 1);
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeTypes() {
try {
TopicIF tt1 = builder1.makeTopic();
TopicIF tt2 = builder1.makeTopic();
TopicIF t1 = builder1.makeTopic();
t1.addType(tt1);
TopicIF t2 = builder1.makeTopic();
t2.addType(tt2);
MergeUtils.mergeInto(t1, t2);
assertTrue("wrong number of types after merge",
t1.getTypes().size() == 2);
assertTrue("original type lost",
t1.getTypes().contains(tt1));
assertTrue("source type not copied",
t1.getTypes().contains(tt2));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeRoles() { // F.5.1, 5
try {
TopicIF atype = builder1.makeTopic();
AssociationIF assoc1 = builder1.makeAssociation(atype);
AssociationIF assoc2 = builder1.makeAssociation(atype);
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicIF type1 = builder1.makeTopic();
TopicIF type2 = builder1.makeTopic();
AssociationRoleIF ar1 = builder1.makeAssociationRole(assoc1, type1, t1);
AssociationRoleIF ar2 = builder1.makeAssociationRole(assoc2, type2, t2);
MergeUtils.mergeInto(t1, t2);
assertTrue("wrong number of roles after merge",
t1.getRoles().size() == 2);
assertTrue("original role lost",
t1.getRoles().contains(ar1));
assertTrue("source role not copied",
t1.getRoles().contains(ar2));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeTopicTypeUse() {
try {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicIF t3 = builder1.makeTopic();
t3.addType(t2);
MergeUtils.mergeInto(t1, t2);
assertTrue("types of unrelated topic corrupted",
t3.getTypes().size() == 1);
assertTrue("topic type replacement not done correctly",
t3.getTypes().contains(t1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeAssociationRoleTypeUse() {
try {
TopicIF atype = builder1.makeTopic();
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicIF player = builder1.makeTopic();
AssociationIF assoc1 = builder1.makeAssociation(atype);
AssociationRoleIF ar1 = builder1.makeAssociationRole(assoc1, t2, player);
MergeUtils.mergeInto(t1, t2);
assertTrue("association role type replacement not done correctly",
ar1.getType().equals(t1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeAssociationTypeUse() {
try {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
AssociationIF assoc1 = builder1.makeAssociation(t2);
MergeUtils.mergeInto(t1, t2);
assertTrue("association type replacement not done correctly",
assoc1.getType().equals(t1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeTopicNameTypeUse() {
try {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicNameIF bn = builder1.makeTopicName(t1, t2, "");
MergeUtils.mergeInto(t1, t2);
assertTrue("basename type replacement not done correctly",
bn.getType().equals(t1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeOccurrenceTypeUse() {
try {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
OccurrenceIF occ = builder1.makeOccurrence(t1, t2, "");
MergeUtils.mergeInto(t1, t2);
assertTrue("occurrence type replacement not done correctly",
occ.getType().equals(t1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeAssociationScopeUse() {
try {
TopicIF atype = builder1.makeTopic();
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
AssociationIF assoc = builder1.makeAssociation(atype);
assoc.addTheme(t2);
MergeUtils.mergeInto(t1, t2);
assertTrue("association scope corrupted",
assoc.getScope().size() == 1);
assertTrue("association theme replacement not done correctly",
assoc.getScope().contains(t1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeTopicNameScopeUse() {
try {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicNameIF bn = builder1.makeTopicName(t1, "");
bn.addTheme(t2);
MergeUtils.mergeInto(t1, t2);
assertTrue("base name scope corrupted",
bn.getScope().size() == 1);
assertTrue("base name theme replacement not done correctly",
bn.getScope().contains(t1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeOccurrenceScopeUse() {
try {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicIF ot = builder1.makeTopic();
OccurrenceIF occ = builder1.makeOccurrence(t1, ot, "");
occ.addTheme(t2);
MergeUtils.mergeInto(t1, t2);
assertTrue("occurrence scope corrupted",
occ.getScope().size() == 1);
assertTrue("occurrence theme replacement not done correctly",
occ.getScope().contains(t1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeVariantNameScopeUse() {
try {
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicNameIF bn = builder1.makeTopicName(t1, "");
VariantNameIF vn = builder1.makeVariantName(bn, "");
vn.addTheme(t2);
MergeUtils.mergeInto(t1, t2);
assertTrue("variant name scope corrupted",
vn.getScope().size() == 1);
assertTrue("variant name theme replacement not done correctly",
vn.getScope().contains(t1));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
}
public void testMergeDuplicateAssociations() throws IOException {
TopicMapIF tm = ImportExportUtils.getReader(TestFileUtils.getTestInputFile("various", "merge-duplicate-assoc.ltm")).read();
LocatorIF base = tm.getStore().getBaseAddress();
TopicIF puccini1 = (TopicIF) tm.getObjectByItemIdentifier(base.resolveAbsolute("#puccini1"));
TopicIF puccini2 = (TopicIF) tm.getObjectByItemIdentifier(base.resolveAbsolute("#puccini2"));
MergeUtils.mergeInto(puccini1, puccini2);
// the new puccini should have only a single place of birth; in
// fact, only a single association
assertTrue("Merge did not remove duplicate associations",
puccini1.getRoles().size() == 1);
}
// FIXME: must test duplicates
public void testMergeSelf() throws IOException {
TopicMapIF tm1 = ImportExportUtils.getReader(TestFileUtils.getTestInputFile("query", "jill.xtm")).read();
TopicMapIF tm2 = ImportExportUtils.getReader(TestFileUtils.getTestInputFile("query", "jill.xtm")).read();
MergeUtils.mergeInto(tm1, tm2);
}
public void testMergeReified() {
// build TM
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
OccurrenceIF occ = builder1.makeOccurrence(t1, t2, "");
occ.setReifier(t2);
// merge
MergeUtils.mergeInto(t1, t2);
// check
assertTrue("Occurrence lost reifier on merge",
occ.getReifier() == t1);
assertTrue("Topic lost reified on merge",
t1.getReified() == occ);
}
public void testMergeReified2() {
// build TM
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicIF t3 = builder1.makeTopic();
OccurrenceIF occ = builder1.makeOccurrence(t3, t2, "");
occ.setReifier(t2);
// merge
MergeUtils.mergeInto(t2, t1);
// check
assertTrue("Occurrence lost reifier on merge",
occ.getReifier() == t2);
assertTrue("Topic lost reified on merge",
t2.getReified() == occ);
}
public void testMergeReified3() {
// build TM
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicIF t3 = builder1.makeTopic();
OccurrenceIF occ1 = builder1.makeOccurrence(t3, t2, "x");
occ1.setReifier(t2);
OccurrenceIF occ2 = builder1.makeOccurrence(t3, t2, "y");
occ2.setReifier(t1);
// merge
try {
MergeUtils.mergeInto(t2, t1);
fail("Successfully merged topics which reify different objects");
} catch (ConstraintViolationException e) {
}
}
public void testMergeReifiedTargetTopicMap() {
// build TMs
TopicIF reifier = builder1.makeTopic();
topicmap1.setReifier(reifier);
// merge
MergeUtils.mergeInto(topicmap1, topicmap2);
// previous line checks if moving topicmap causes it to lose
// its reifier
// check
assertTrue("Topic map lost reifier on merge",
topicmap1.getReifier() == reifier);
assertTrue("Topic lost reified on merge",
reifier.getReified() == topicmap1);
}
public void testMergeReifiedSourceTopicMap() {
// build TMs
TopicIF reifier1 = builder1.makeTopic();
reifier1.addSubjectIdentifier(URILocator.create("test:reifier"));
TopicIF reifier2 = builder2.makeTopic();
reifier2.addSubjectIdentifier(URILocator.create("test:reifier"));
topicmap2.setReifier(reifier2);
// merge
MergeUtils.mergeInto(topicmap1, topicmap2);
// previous line checks if moving topicmap causes it to lose
// its reifier (which it should)
// check
assertTrue("Topic map did not lose reifier on merge",
topicmap1.getReifier() == null);
assertTrue("Topic did become reifier on merge",
reifier1.getReified() == null);
}
public void testMergeReifiedTopicMaps() {
// build TMs
TopicIF reifier1 = builder1.makeTopic();
reifier1.addSubjectIdentifier(URILocator.create("test:reifier"));
topicmap1.setReifier(reifier1);
TopicIF reifier2 = builder2.makeTopic();
reifier2.addSubjectIdentifier(URILocator.create("test:reifier"));
topicmap2.setReifier(reifier2);
// merge
MergeUtils.mergeInto(topicmap1, topicmap2);
// previous line checks if moving topicmap causes it to lose
// its reifier
// check
assertTrue("Topic map lost reifier on merge",
topicmap1.getReifier() == reifier1);
assertTrue("Topic did become reifier on merge",
reifier1.getReified() == topicmap1);
}
public void testMergeReifiedBasename() {
// build TM
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicIF t3 = builder1.makeTopic();
TopicNameIF bn = builder1.makeTopicName(t3, t2, "");
bn.setReifier(t2);
// merge
MergeUtils.mergeInto(t1, t3);
// previous line checks if moving bn from t3 to t1 causes it to lose
// its reifier
// check
TopicNameIF newbn = (TopicNameIF)t1.getTopicNames().iterator().next();
assertTrue("Basename lost reifier on merge",
newbn.getReifier() == t2);
assertTrue("Topic lost reified on merge",
t2.getReified() == newbn);
}
public void testMergeReifiedOccurrence() {
// build TM
TopicIF t1 = builder1.makeTopic();
TopicIF t2 = builder1.makeTopic();
TopicIF t3 = builder1.makeTopic();
OccurrenceIF occ = builder1.makeOccurrence(t3, t2, "");
occ.setReifier(t2);
// merge
MergeUtils.mergeInto(t1, t3);
// previous line checks if moving occ from t3 to t1 causes it to lose
// its reifier
// check
OccurrenceIF newocc = (OccurrenceIF)t1.getOccurrences().iterator().next();
assertTrue("Occurrence lost reifier on merge",
newocc.getReifier() == t2);
assertTrue("Topic lost reified on merge",
t2.getReified() == newocc);
}
public void testMergeReifiedAssociation() {
// build TM
TopicIF reifier = builder1.makeTopic();
TopicIF at = builder1.makeTopic();
TopicIF nrt = builder1.makeTopic();
TopicIF nrp = builder1.makeTopic();
TopicIF drt = builder1.makeTopic();
TopicIF drp = builder1.makeTopic();
TopicIF target = builder1.makeTopic();
AssociationIF assoc = builder1.makeAssociation(at);
AssociationRoleIF nrole = builder1.makeAssociationRole(assoc, nrt, nrp);
AssociationRoleIF drole = builder1.makeAssociationRole(assoc, drt, drp);
assoc.setReifier(reifier);
// merge
MergeUtils.mergeInto(target, nrp);
// previous line checks if moving association from nrp to target causes it to lose
// its reifier
// check
AssociationRoleIF newrole = (AssociationRoleIF)target.getRoles().iterator().next();
AssociationIF newassoc = newrole.getAssociation();
assertTrue("Association lost reifier on merge",
newassoc.getReifier() == reifier);
assertTrue("Topic lost reified on merge",
reifier.getReified() == newassoc);
}
public void testMergeReifiedNearRole() {
// build TM
TopicIF reifier = builder1.makeTopic();
TopicIF at = builder1.makeTopic();
TopicIF nrt = builder1.makeTopic();
TopicIF nrp = builder1.makeTopic();
TopicIF drt = builder1.makeTopic();
TopicIF drp = builder1.makeTopic();
TopicIF target = builder1.makeTopic();
AssociationIF assoc = builder1.makeAssociation(at);
AssociationRoleIF nrole = builder1.makeAssociationRole(assoc, nrt, nrp);
AssociationRoleIF drole = builder1.makeAssociationRole(assoc, drt, drp);
nrole.setReifier(reifier);
// merge
MergeUtils.mergeInto(target, nrp);
// previous line checks if moving association from nrp to target causes it to lose
// its reifier
// check
AssociationRoleIF newnrole = (AssociationRoleIF)target.getRoles().iterator().next();
assertTrue("Near role lost reifier on merge",
newnrole.getReifier() == reifier);
assertTrue("Topic lost reified on merge",
reifier.getReified() == newnrole);
}
public void testMergeReifiedDistantRole() {
// build TM
TopicIF reifier = builder1.makeTopic();
TopicIF at = builder1.makeTopic();
TopicIF nrt = builder1.makeTopic();
TopicIF nrp = builder1.makeTopic();
TopicIF drt = builder1.makeTopic();
TopicIF drp = builder1.makeTopic();
TopicIF target = builder1.makeTopic();
AssociationIF assoc = builder1.makeAssociation(at);
AssociationRoleIF nrole = builder1.makeAssociationRole(assoc, nrt, nrp);
AssociationRoleIF drole = builder1.makeAssociationRole(assoc, drt, drp);
drole.setReifier(reifier);
// merge
MergeUtils.mergeInto(target, nrp);
// previous line checks if moving association from nrp to target causes it to lose
// its reifier
// check
AssociationRoleIF newnrole = (AssociationRoleIF)target.getRoles().iterator().next();
// locate distant role
AssociationRoleIF newdrole = null;
Iterator iter = newnrole.getAssociation().getRoles().iterator();
while (iter.hasNext()) {
AssociationRoleIF role = (AssociationRoleIF)iter.next();
if (ObjectUtils.different(newnrole, role)) {
newdrole = role;
break;
}
}
assertTrue("Distant role lost reifier on merge",
newdrole.getReifier() == reifier);
assertTrue("Topic lost reified on merge",
reifier.getReified() == newdrole);
}
// --- Test cases for mergeInto(TopicMapIF, TopicIF)
public void testMergeDuplicateSourceLocator() {
try {
TopicIF t1 = builder1.makeTopic();
t1.addItemIdentifier(new URILocator("http://www.example.com"));
TopicNameIF bn1 = builder1.makeTopicName(t1, "boodoo");
bn1.addItemIdentifier(new URILocator("http://www.example.com/#1"));
TopicIF t2 = builder2.makeTopic();
t2.addItemIdentifier(new URILocator("http://www.example.com"));
TopicNameIF bn2 = builder2.makeTopicName(t2, "boodoo");
bn2.addItemIdentifier(new URILocator("http://www.example.com/#1"));
MergeUtils.mergeInto(topicmap1, t2);
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
catch (java.net.MalformedURLException e) {
fail("URI literals malformed" + e.getMessage());
}
}
public void testMergeDuplicateSourceLocator2() {
// this test differs from the previous one in that the base names
// are not equal, and so should not be merged
try {
TopicIF t1 = builder1.makeTopic();
t1.addItemIdentifier(new URILocator("http://www.example.com"));
TopicNameIF bn1 = builder1.makeTopicName(t1, "boodoo");
bn1.addItemIdentifier(new URILocator("http://www.example.com/#1"));
TopicIF t2 = builder2.makeTopic();
t2.addItemIdentifier(new URILocator("http://www.example.com"));
TopicNameIF bn2 = builder2.makeTopicName(t2, "boovoo");
bn2.addItemIdentifier(new URILocator("http://www.example.com/#1"));
MergeUtils.mergeInto(topicmap1, t2);
fail("merge succeeded, even though duplicates did not match");
}
catch (ConstraintViolationException e) {
}
catch (java.net.MalformedURLException e) {
fail("URI literals malformed" + e.getMessage());
}
}
public void testMergeReifyingTopic() {
try {
TopicIF t1 = builder2.makeTopic();
TopicNameIF bn1 = builder2.makeTopicName(t1, "famous misspelling");
TopicIF t2 = builder2.makeTopic();
TopicNameIF bn2 = builder2.makeTopicName(t2, "boodoo");
bn2.addItemIdentifier(new URILocator("http://www.example.com/#1"));
bn2.setReifier(t1);
MergeUtils.mergeInto(topicmap1, t2);
assertTrue("reifying topic was not included",
topicmap1.getTopics().size() >= 2);
TopicNameIF bn = (TopicNameIF) topicmap1.getObjectByItemIdentifier(new URILocator("http://www.example.com/#1"));
TopicIF reifier = bn.getReifier();
assertTrue("reification link was broken", reifier != null);
assertTrue("reifier base name not copied", !reifier.getTopicNames().isEmpty());
bn = (TopicNameIF) reifier.getTopicNames().iterator().next();
assertTrue("reifier base name not copied correctly",
bn.getValue().equals("famous misspelling"));
}
catch (ConstraintViolationException e) {
fail("merge of topics unaccountably failed" + e.getMessage());
}
catch (MalformedURLException e) {
fail("URI literals malformed" + e.getMessage());
}
}
public void testMergeAllTopics() throws MalformedURLException, IOException {
String sep = File.separator;
String root = TestFileUtils.getTestdataOutputDirectory();
TestFileUtils.verifyDirectory(root, "canonical", "out");
String file = TestFileUtils.getTestInputFile("various", "houdini.xtm");
String outfile = root + sep + "canonical" + sep + "out" + sep + "houdini.xtm";
String baseline = TestFileUtils.getTestInputFile("various", "baseline-houdini.xtm");
TopicMapIF topicmap = new XTMTopicMapReader(URIUtils.getURI(file)).read();
// save
InMemoryTopicMapStore store = new InMemoryTopicMapStore();
TopicMapIF newtm = store.getTopicMap();
Iterator iterator = topicmap.getTopics().iterator();
while (iterator.hasNext()) {
TopicIF topic = (TopicIF) iterator.next();
MergeUtils.mergeInto(newtm, topic);
}
new CanonicalTopicMapWriter(outfile).write(newtm);
assertTrue("Topic map created by merging over topics not equal to original",
FileUtils.compareFileToResource(outfile, baseline));
}
public void testMergeReifiedNames() {
TopicIF t1 = builder1.makeTopic();
TopicNameIF bn1 = builder1.makeTopicName(t1, "bn1");
TopicIF r1 = builder1.makeTopic();
bn1.setReifier(r1);
builder1.makeTopicName(r1, "reifier1");
TopicIF t2 = builder1.makeTopic();
TopicNameIF bn2 = builder1.makeTopicName(t2, "bn1");
TopicIF r2 = builder1.makeTopic();
bn2.setReifier(r2);
builder1.makeTopicName(r2, "reifier2");
MergeUtils.mergeInto(t1, t2);
assertTrue("wrong number of base names after merge",
t1.getTopicNames().size() == 1);
assertTrue("original base name lost",
t1.getTopicNames().contains(bn1));
bn1 = (TopicNameIF) t1.getTopicNames().iterator().next();
r1 = bn1.getReifier();
assertTrue("reifier lost", r1 != null);
assertTrue("wrong number of names on reifier: " + r1.getTopicNames().size(),
r1.getTopicNames().size() == 2);
}
public void testMergeReifiedOccurrences() {
TopicIF occtype = builder1.makeTopic();
TopicIF t1 = builder1.makeTopic();
OccurrenceIF occ1 = builder1.makeOccurrence(t1, occtype, "occ1");
TopicIF r1 = builder1.makeTopic();
occ1.setReifier(r1);
builder1.makeTopicName(r1, "reifier1");
TopicIF t2 = builder1.makeTopic();
OccurrenceIF occ2 = builder1.makeOccurrence(t2, occtype, "occ1");
TopicIF r2 = builder1.makeTopic();
occ2.setReifier(r2);
builder1.makeTopicName(r2, "reifier2");
MergeUtils.mergeInto(t1, t2);
assertTrue("wrong number of occurrences after merge",
t1.getOccurrences().size() == 1);
assertTrue("original occurrence lost",
t1.getOccurrences().contains(occ1));
occ1 = (OccurrenceIF) t1.getOccurrences().iterator().next();
r1 = occ1.getReifier();
assertTrue("reifier lost", r1 != null);
assertTrue("wrong number of names on reifier: " + r1.getTopicNames().size(),
r1.getTopicNames().size() == 2);
}
public void testMergeAssociationReifiers() {
// the idea here is: what happens if you attempt to merge two topics
// which reify duplicate associations?
TopicIF atype = builder1.makeTopic();
AssociationIF assoc1 = builder1.makeAssociation(atype);
AssociationIF assoc2 = builder1.makeAssociation(atype);
TopicIF player = builder1.makeTopic();
TopicIF type = builder1.makeTopic();
AssociationRoleIF ar1 = builder1.makeAssociationRole(assoc1, type, player);
AssociationRoleIF ar2 = builder1.makeAssociationRole(assoc2, type, player);
// the two associations should be equal
TopicIF r1 = builder1.makeTopic();
assoc1.setReifier(r1);
TopicIF r2 = builder1.makeTopic();
assoc2.setReifier(r2);
MergeUtils.mergeInto(r1, r2);
assertTrue("wrong number of roles after merge",
player.getRoles().size() == 1);
}
}