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