From: <lh...@us...> - 2008-05-07 11:33:48
|
Revision: 56 http://tinytim.svn.sourceforge.net/tinytim/?rev=56&view=rev Author: lheuer Date: 2008-05-07 04:33:54 -0700 (Wed, 07 May 2008) Log Message: ----------- - Initial TopicMapImporter import - Support for "untyped" names in the MapInputHandler - Check for scope constraints in the MapInputHandler - More tests Modified Paths: -------------- tinytim-mio/trunk/src/main/java/org/tinytim/mio/MapInputHandler.java tinytim-mio/trunk/src/test/java/org/tinytim/mio/TestMapInputHandler.java Added Paths: ----------- tinytim-mio/trunk/src/main/java/org/tinytim/mio/TopicMapImporter.java Modified: tinytim-mio/trunk/src/main/java/org/tinytim/mio/MapInputHandler.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/mio/MapInputHandler.java 2008-05-07 11:31:20 UTC (rev 55) +++ tinytim-mio/trunk/src/main/java/org/tinytim/mio/MapInputHandler.java 2008-05-07 11:33:54 UTC (rev 56) @@ -21,6 +21,7 @@ package org.tinytim.mio; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.logging.Logger; @@ -28,6 +29,7 @@ import org.tinytim.ITyped; import org.tinytim.TopicMapImpl; import org.tinytim.TypeInstanceConverter; +import org.tinytim.voc.TMDM; import org.tmapi.core.Association; import org.tmapi.core.AssociationRole; import org.tmapi.core.Locator; @@ -77,10 +79,13 @@ /** * Sets the topic map instance to operate on. * - * @param tm The topic map. + * @param topicMap The topic map. */ - public void setTopicMap(TopicMap tm) { - _tm = (TopicMapImpl) tm; + public void setTopicMap(TopicMap topicMap) { + if (topicMap == null) { + throw new IllegalArgumentException("The topic map must not be null"); + } + _tm = (TopicMapImpl) topicMap; } /* (non-Javadoc) @@ -189,7 +194,11 @@ * @see com.semagia.mio.IMapHandler#endName() */ public void endName() throws MIOException { + TopicName name = (TopicName) _peekConstruct(); _leaveStatePopConstruct(State.NAME); + if (name.getType() == null) { + name.setType(_topicBySubjectIdentifier(TMDM.TOPIC_NAME)); + } } /* (non-Javadoc) @@ -203,8 +212,14 @@ /* (non-Javadoc) * @see com.semagia.mio.IMapHandler#endVariant() */ + @SuppressWarnings("unchecked") public void endVariant() throws MIOException { + Variant variant = (Variant) _peekConstruct(); _leaveStatePopConstruct(State.VARIANT); + Collection<Topic> scope = variant.getScope(); + if (scope.isEmpty() || variant.getTopicName().getScope().equals(scope)) { + throw new MIOException("The variant has no scope"); + } } /* (non-Javadoc) Added: tinytim-mio/trunk/src/main/java/org/tinytim/mio/TopicMapImporter.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/mio/TopicMapImporter.java (rev 0) +++ tinytim-mio/trunk/src/main/java/org/tinytim/mio/TopicMapImporter.java 2008-05-07 11:33:54 UTC (rev 56) @@ -0,0 +1,222 @@ +/* + * 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.mio; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.tmapi.core.TMAPIRuntimeException; +import org.tmapi.core.TopicMap; + +import org.xml.sax.InputSource; + +import com.semagia.mio.DeserializerRegistry; +import com.semagia.mio.IDeserializer; +import com.semagia.mio.MIOException; +import com.semagia.mio.Syntax; + +/** + * Functions to import serialized topic maps. + * + * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a> + * @version $Rev:$ - $Date:$ + */ +public final class TopicMapImporter { + + private TopicMapImporter() { + // noop. + } + + /** + * Reads a XML topic map from <code>input</code> and adds the content to the + * specified <code>topicMap</code>. The <code>docIRI</code> is used to + * resolve IRIs against. + * + * @param topicMap The topic map instance which receives the + * Topic Maps constructs. + * @param docIRI The IRI which is used to resolve IRIs against. + * @param input The stream to read the serialized topic map from. + * @throws IOException If an error occurs. + */ + public static void importInto(TopicMap topicMap, String docIRI, InputStream input) throws IOException { + _import(Syntax.XTM, topicMap, docIRI, input); + } + + /** + * Reads a XML topic map from <code>input</code> and adds the content to the + * specified <code>topicMap</code>. The <code>docIRI</code> is used to + * resolve IRIs against. + * + * @param topicMap The topic map instance which receives the + * Topic Maps constructs. + * @param docIRI The IRI which is used to resolve IRIs against. + * @param input The source to read the serialized topic map from. + * @throws IOException If an error occurs. + */ + public static void importInto(TopicMap topicMap, String docIRI, InputSource input) throws IOException { + _import(Syntax.XTM, topicMap, docIRI, input); + } + + /** + * Reads a topic map from <code>file</code> and adds the content to the + * specified <code>topicMap</code>. The <code>docIRI</code> is used to + * resolve IRIs against. + * + * The syntax of the serialized topic map is guessed by the file name. If + * the file extension gives no indication of the used syntax, XTM is + * assumed. + * + * @param topicMap The topic map instance which receives the + * Topic Maps constructs. + * @param docIRI The IRI which is used to resolve IRIs against. + * @param file The file to read the serialized topic map from. + * @throws IOException If an error occurs. + */ + public static void importInto(TopicMap topicMap, String docIRI, File file) throws IOException { + _import(_guessSyntax(file), topicMap, docIRI, new FileInputStream(file)); + } + + /** + * Reads a topic map from <code>file</code> and adds the content to the + * specified <code>topicMap</code>. The <code>docIRI</code> is used to + * resolve IRIs against. + * + * The <code>syntax</code> is a string with the abbreviated Topic Maps syntax + * name; i.e. "xtm", "ltm", "ctm". The name is matched case-insensitve, that + * means "xtm" is the same as "xTm", "XTM" etc. + * + * @param topicMap The topic map instance which receives the + * Topic Maps constructs. + * @param docIRI The IRI which is used to resolve IRIs against. + * @param file The file to read the serialized topic map from. + * @param syntax The name of the syntax of the encoded topic map. I.e. "xtm". + * @throws IOException If an error occurs. + */ + public static void importInto(TopicMap topicMap, String docIRI, File file, String syntax) throws IOException { + importInto(topicMap, docIRI, new FileInputStream(file), syntax); + } + + /** + * Reads a topic map from <code>input</code> and adds the content to the + * specified <code>topicMap</code>. The <code>docIRI</code> is used to + * resolve IRIs against. + * + * The <code>syntax</code> is a string with the abbreviated Topic Maps syntax + * name; i.e. "xtm", "ltm", "ctm". The name is matched case-insensitve, that + * means "xtm" is the same as "xTm", "XTM" etc. + * + * @param topicMap The topic map instance which receives the + * Topic Maps constructs. + * @param docIRI The IRI which is used to resolve IRIs against. + * @param input The stream to read the serialized topic map from. + * @param syntax The name of the syntax of the encoded topic map. I.e. "xtm". + * @throws IOException If an error occurs. + */ + public static void importInto(TopicMap topicMap, String docIRI, InputStream input, String syntax) throws IOException { + importInto(topicMap, docIRI, new InputSource(input), syntax); + } + + /** + * Reads a topic map from <code>input</code> and adds the content to the + * specified <code>topicMap</code>. The <code>docIRI</code> is used to + * resolve IRIs against. + * + * The <code>syntax</code> is a string with the abbreviated Topic Maps syntax + * name; i.e. "xtm", "ltm", "ctm". The name is matched case-insensitve, that + * means "xtm" is the same as "xTm", "XTM" etc. + * + * @param topicMap The topic map instance which receives the + * Topic Maps constructs. + * @param docIRI The IRI which is used to resolve IRIs against. + * @param input The source to read the serialized topic map from. + * @param syntax The name of the syntax of the encoded topic map. I.e. "xtm". + * @throws IOException If an error occurs. + */ + public static void importInto(TopicMap topicMap, String docIRI, InputSource input, String syntax) throws IOException { + Syntax syntax_ = Syntax.valueOf(syntax); + if (syntax_ == null) { + throw new RuntimeException("The syntax '" + syntax + "' is unknown"); + } + _import(syntax_, topicMap, docIRI, input); + } + + /** + * Returns a {@link Syntax} instance. + * + * @param file The file to guess the syntax from. + * @return A syntax which matches the file extension or {@link Syntax#XTM} + * if the file extension is not available or gives no indication + * about the used syntax. + */ + private static Syntax _guessSyntax(File file) { + String name = file.getName(); + int i = name.lastIndexOf('.'); + return i == -1 ? Syntax.XTM + : Syntax.forFileExtension(name.substring(i+1), Syntax.XTM); + } + + /** + * Reads a topic map from <code>input</code> and adds the content to the + * <code>topicMap</code>. + * + * @param syntax A syntax instance. + * @param topicMap A topic map instance. + * @param docIRI The IRI which is used to resolve locators against. + * @param input The source to read the topic map from. + * @throws IOException If an error occurs. + */ + private static void _import(Syntax syntax, TopicMap topicMap, String docIRI, + InputStream input) throws IOException { + _import(syntax, topicMap, docIRI, new InputSource(input)); + } + + /** + * Reads a topic map from <code>input</code> and adds the content to the + * <code>topicMap</code>. + * + * @param syntax A syntax instance. + * @param topicMap A topic map instance. + * @param docIRI The IRI which is used to resolve locators against. + * @param input The source to read the topic map from. + * @throws IOException If an error occurs. + */ + private static void _import(Syntax syntax, TopicMap topicMap, String docIRI, + InputSource input) throws IOException { + IDeserializer deser = DeserializerRegistry.createDeserializer(syntax); + if (deser == null) { + throw new IOException("No deserializer found for the syntax '" + syntax.getName() + "'"); + } + deser.setMapHandler(new MapInputHandler(topicMap)); + try { + deser.parse(input, docIRI); + } + catch (MIOException ex) { + if (ex.getException() instanceof IOException) { + throw (IOException) ex.getException(); + } + else { + throw new TMAPIRuntimeException(ex); + } + } + } +} Property changes on: tinytim-mio/trunk/src/main/java/org/tinytim/mio/TopicMapImporter.java ___________________________________________________________________ Name: svn:keywords + Rev Date Id Name: svn:eol-style + native Modified: tinytim-mio/trunk/src/test/java/org/tinytim/mio/TestMapInputHandler.java =================================================================== --- tinytim-mio/trunk/src/test/java/org/tinytim/mio/TestMapInputHandler.java 2008-05-07 11:31:20 UTC (rev 55) +++ tinytim-mio/trunk/src/test/java/org/tinytim/mio/TestMapInputHandler.java 2008-05-07 11:33:54 UTC (rev 56) @@ -22,6 +22,7 @@ import org.tinytim.Property; import org.tinytim.TopicMapImpl; +import org.tinytim.voc.TMDM; import org.tmapi.core.Locator; import org.tmapi.core.Occurrence; import org.tmapi.core.Topic; @@ -29,6 +30,7 @@ import org.tmapi.core.TopicMapSystemFactory; import org.tmapi.core.TopicName; +import com.semagia.mio.MIOException; import com.semagia.mio.helpers.Ref; import junit.framework.TestCase; @@ -126,9 +128,9 @@ _handler.startTopic(Ref.createItemIdentifier(itemIdent)); _handler.itemIdentifier(ref); _handler.endTopic(); - _handler.startName(); - _handler.value("tinyTiM"); - _handler.endName(); + _handler.startOccurrence(); + _handler.value("tinyTiM", _XSD_STRING); + _handler.endOccurrence(); _handler.endTopic(); _handler.endTopicMap(); assertEquals(1, _tm.getTopics().size()); @@ -136,9 +138,9 @@ assertNotNull(topic); assertEquals(topic, _tm.getObjectByItemIdentifier(_tm.createLocator(ref))); assertEquals(topic, _tm.getObjectByItemIdentifier(_tm.createLocator(itemIdent))); - assertEquals(1, topic.getTopicNames().size()); - TopicName name = (TopicName)topic.getTopicNames().iterator().next(); - assertEquals("tinyTiM", name.getValue()); + assertEquals(1, topic.getOccurrences().size()); + Occurrence occ = (Occurrence) topic.getOccurrences().iterator().next(); + assertEquals("tinyTiM", occ.getValue()); } /** @@ -231,4 +233,79 @@ assertEquals(val, occ.getResource().getReference()); } + /** + * Tests if the name type is automatically set. + */ + public void testDefaultNameType() throws Exception { + String ref = "http://sf.net/projects/tinytim/test#1"; + String val = "tinyTiM"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createSubjectIdentifier(ref)); + _handler.startName(); + _handler.value(val); + _handler.endName(); + _handler.endTopic(); + _handler.endTopicMap(); + Topic topic = _tm.getTopicBySubjectIdentifier(_tm.createLocator(ref)); + assertNotNull(topic); + TopicName name = (TopicName) topic.getTopicNames().iterator().next(); + assertEquals(val, name.getValue()); + assertNotNull(name.getType()); + assertTrue(name.getType().getSubjectIdentifiers().contains(TMDM.TOPIC_NAME)); + } + + /** + * Tests if a variant with no scope is reported as error. + */ + public void testVariantNoScopeError() throws Exception { + String ref = "http://sf.net/projects/tinytim/test#1"; + String val = "tinyTiM"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createSubjectIdentifier(ref)); + _handler.startName(); + _handler.value(val); + _handler.startVariant(); + _handler.value(val, _XSD_STRING); + try { + _handler.endVariant(); + fail("A variant with no scope shouldn't be allowed"); + } + catch (MIOException ex) { + // noop. + } + } + + /** + * Tests if a variant with a scope equals to the parent's scope is rejected. + */ + public void testVariantNoScopeError2() throws Exception { + String ref = "http://sf.net/projects/tinytim/test#1"; + String theme = "http://sf.net/projects/tinytim/test#theme"; + String val = "tinyTiM"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createSubjectIdentifier(ref)); + _handler.startName(); + _handler.startScope(); + _handler.startTheme(); + _handler.topicRef(Ref.createItemIdentifier(theme)); + _handler.endTheme(); + _handler.endScope(); + _handler.value(val); + + _handler.startVariant(); + _handler.value(val, _XSD_STRING); + _handler.startScope(); + _handler.startTheme(); + _handler.topicRef(Ref.createItemIdentifier(theme)); + _handler.endTheme(); + _handler.endScope(); + try { + _handler.endVariant(); + fail("A variant with a scope equals to the parent's scope shouldn't be allowed"); + } + catch (MIOException ex) { + // noop. + } + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |