/* * #! * 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.util.HashSet; import java.util.Set; import junit.framework.Assert; import net.ontopia.infoset.impl.basic.URILocator; 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.TypedIF; import net.ontopia.topicmaps.impl.basic.InMemoryTopicMapStore; import org.junit.Test; public class Issue409Test { /** * Merges a topicmap with occurrences into an empty topicmap. The occurrences have a type with a * name, but no psi. During merging, a new empty topic is created as type for each of the * occurrences in the source. */ @Test public void testOccsWithoutPSI() { mergeTypedIF(new TypedIFCreator() { public void createTypedIFs(TopicMapBuilderIF builder, TopicIF type) { builder.makeOccurrence(builder.makeTopic(), type, "foo1"); builder.makeOccurrence(builder.makeTopic(), type, "foo2"); builder.makeOccurrence(builder.makeTopic(), type, "foo3"); } public TypedIF getTyped(TopicIF topic) { if (topic.getOccurrences().size() == 0) { return null; } return topic.getOccurrences().iterator().next(); } }); } /** * Same as testOccsWithoutPSI, except this time the occurrence type has a psi. This test passes */ @Test public void testOccsWithPSI() { mergeTypedIF(new TypedIFCreator() { public void createTypedIFs(TopicMapBuilderIF builder, TopicIF type) { type.addSubjectIdentifier(URILocator.create("foo:bar")); builder.makeOccurrence(builder.makeTopic(), type, "foo1"); builder.makeOccurrence(builder.makeTopic(), type, "foo2"); builder.makeOccurrence(builder.makeTopic(), type, "foo3"); } public TypedIF getTyped(TopicIF topic) { if (topic.getOccurrences().size() == 0) { return null; } return topic.getOccurrences().iterator().next(); } }); } /** * Same as testOccsWithoutPSI, but now with a name and a nametype. */ @Test public void testNamesWithoutPSI() { mergeTypedIF(new TypedIFCreator() { public void createTypedIFs(TopicMapBuilderIF builder, TopicIF type) { builder.makeTopicName(builder.makeTopic(), type, "foo1"); builder.makeTopicName(builder.makeTopic(), type, "foo2"); builder.makeTopicName(builder.makeTopic(), type, "foo3"); } public TypedIF getTyped(TopicIF topic) { if (topic.getTopicNames().size() == 0) { return null; } TopicNameIF name = topic.getTopicNames().iterator().next(); if (name.getType().getSubjectIdentifiers().contains(PSI.getSAMNameType())) { return null; } return name; } }); } /** * Same as testOccsWithPSI, but now with a name and a nametype. */ @Test public void testNamesWithPSI() { mergeTypedIF(new TypedIFCreator() { public void createTypedIFs(TopicMapBuilderIF builder, TopicIF type) { type.addSubjectIdentifier(URILocator.create("foo:bar")); builder.makeTopicName(builder.makeTopic(), type, "foo1"); builder.makeTopicName(builder.makeTopic(), type, "foo2"); builder.makeTopicName(builder.makeTopic(), type, "foo3"); } public TypedIF getTyped(TopicIF topic) { if (topic.getTopicNames().size() == 0) { return null; } TopicNameIF name = topic.getTopicNames().iterator().next(); if (name.getType().getSubjectIdentifiers().contains(PSI.getSAMNameType())) { return null; } return name; } }); } private void mergeTypedIF(TypedIFCreator creator) { TopicMapIF source = new InMemoryTopicMapStore().getTopicMap(); TopicMapBuilderIF builder = source.getBuilder(); TopicIF type = builder.makeTopic(); builder.makeTopicName(type, "Type"); creator.createTypedIFs(builder, type); TopicMapIF target = new InMemoryTopicMapStore().getTopicMap(); MergeUtils.mergeInto(target, source); // collect the types after the merge. The bug causes duplication of types as no-name topics Set<TopicIF> types = new HashSet<TopicIF>(); for (TopicIF topic : target.getTopics()) { TypedIF typed = creator.getTyped(topic); if (typed != null) { types.add(typed.getType()); } } // if correct, there should be 1 type Assert.assertEquals("There were duplicate types created during merge", 1, types.size()); // ... and that type should have a name for (TopicIF t : types) { Assert.assertEquals("OT did not have a name post-merge", 1, t.getTopicNames().size()); } } interface TypedIFCreator { void createTypedIFs(TopicMapBuilderIF builder, TopicIF type); TypedIF getTyped(TopicIF topic); } }