From: <lh...@us...> - 2008-05-08 12:11:30
|
Revision: 63 http://tinytim.svn.sourceforge.net/tinytim/?rev=63&view=rev Author: lheuer Date: 2008-05-08 05:11:31 -0700 (Thu, 08 May 2008) Log Message: ----------- - Moved .mio into .io Added Paths: ----------- tinytim-io/trunk/src/main/java/org/tinytim/io/ tinytim-io/trunk/src/main/java/org/tinytim/io/MapInputHandler.java tinytim-io/trunk/src/main/java/org/tinytim/io/TopicMapImporter.java tinytim-io/trunk/src/test/java/org/tinytim/io/ tinytim-io/trunk/src/test/java/org/tinytim/io/TestMapInputHandler.java Removed Paths: ------------- tinytim-io/trunk/src/main/java/org/tinytim/mio/ tinytim-io/trunk/src/test/java/org/tinytim/mio/ Added: tinytim-io/trunk/src/main/java/org/tinytim/io/MapInputHandler.java =================================================================== --- tinytim-io/trunk/src/main/java/org/tinytim/io/MapInputHandler.java (rev 0) +++ tinytim-io/trunk/src/main/java/org/tinytim/io/MapInputHandler.java 2008-05-08 12:11:31 UTC (rev 63) @@ -0,0 +1,601 @@ +/* + * 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.io; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.logging.Logger; + +import org.tinytim.IReifiable; +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; +import org.tmapi.core.Occurrence; +import org.tmapi.core.ScopedObject; +import org.tmapi.core.Topic; +import org.tmapi.core.TopicMap; +import org.tmapi.core.TopicMapObject; +import org.tmapi.core.TopicName; +import org.tmapi.core.Variant; + +import com.semagia.mio.IMapHandler; +import com.semagia.mio.IRef; +import com.semagia.mio.MIOException; + +/** + * {@link com.semagia.mio.IMapHandler} implementation. + * + * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a> + * @version $Rev$ - $Date$ + */ +public class MapInputHandler implements IMapHandler { + + private enum State { + INITIAL, TOPIC, ASSOCIATION, ROLE, OCCURRENCE, NAME, VARIANT, + SCOPE, THEME, REIFIER, PLAYER, ISA, TYPE; + } + + private static final String _XSD_STRING = "http://www.w3.org/2001/XMLSchema#string"; + private static final String _XSD_ANY_URI = "http://www.w3.org/2001/XMLSchema#anyURI"; + + private static final Logger LOG = Logger.getLogger(MapInputHandler.class.getName()); + + private TopicMapImpl _tm; + private State[] _stateStack; + private int _stackPointer; + private List<TopicMapObject> _constructStack; + + public MapInputHandler() { + } + + public MapInputHandler(TopicMap topicMap) { + this(); + setTopicMap(topicMap); + } + + /** + * Sets the topic map instance to operate on. + * + * @param topicMap The topic map. + */ + public void setTopicMap(TopicMap topicMap) { + if (topicMap == null) { + throw new IllegalArgumentException("The topic map must not be null"); + } + _tm = (TopicMapImpl) topicMap; + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startTopicMap() + */ + public void startTopicMap() throws MIOException { + _constructStack = new ArrayList<TopicMapObject>(); + _stateStack = new State[15]; + _stackPointer = -1; + _enterState(State.INITIAL, _tm); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endTopicMap() + */ + public void endTopicMap() throws MIOException { + TypeInstanceConverter.convertAssociationsToTypes(_tm); + _constructStack = null; + _stateStack = null; + _tm = null; + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startTopic(com.semagia.mio.IRef) + */ + public void startTopic(IRef identity) throws MIOException { + _enterState(State.TOPIC, _createTopic(identity)); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endTopic() + */ + public void endTopic() throws MIOException { + Topic topic = _peekTopic(); + _leaveStatePopConstruct(State.TOPIC); + _handleTopic(topic); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startAssociation() + */ + public void startAssociation() throws MIOException { + _enterState(State.ASSOCIATION, _tm.createAssociation()); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endAssociation() + */ + public void endAssociation() throws MIOException { + _leaveStatePopConstruct(State.ASSOCIATION); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startRole() + */ + public void startRole() throws MIOException { + assert _state() == State.ASSOCIATION; + _enterState(State.ROLE, ((Association) _peekConstruct()).createAssociationRole(null, null)); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endRole() + */ + public void endRole() throws MIOException { + _leaveStatePopConstruct(State.ROLE); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startPlayer() + */ + public void startPlayer() throws MIOException { + assert _state() == State.ROLE; + _enterState(State.PLAYER); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endPlayer() + */ + public void endPlayer() throws MIOException { + _leaveState(State.PLAYER); + assert _state() == State.ROLE; + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startOccurrence() + */ + public void startOccurrence() throws MIOException { + _enterState(State.OCCURRENCE, _peekTopic().createOccurrence((Locator) null, null, null)); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endOccurrence() + */ + public void endOccurrence() throws MIOException { + _leaveStatePopConstruct(State.OCCURRENCE); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startName() + */ + public void startName() throws MIOException { + _enterState(State.NAME, _peekTopic().createTopicName(null, null)); + } + + /* (non-Javadoc) + * @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) + * @see com.semagia.mio.IMapHandler#startVariant() + */ + public void startVariant() throws MIOException { + assert _state() == State.NAME; + _enterState(State.VARIANT, ((TopicName) _peekConstruct()).createVariant((Locator) null, null)); + } + + /* (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) + * @see com.semagia.mio.IMapHandler#startType() + */ + public void startType() throws MIOException { + assert _peekConstruct() instanceof ITyped; + _enterState(State.TYPE); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endType() + */ + public void endType() throws MIOException { + _leaveState(State.TYPE); + assert _peekConstruct() instanceof ITyped; + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startScope() + */ + public void startScope() throws MIOException { + assert _peekConstruct() instanceof ScopedObject; + _enterState(State.SCOPE); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endScope() + */ + public void endScope() throws MIOException { + _leaveState(State.SCOPE); + assert _peekConstruct() instanceof ScopedObject; + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startTheme() + */ + public void startTheme() throws MIOException { + assert _state() == State.SCOPE; + _enterState(State.THEME); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endTheme() + */ + public void endTheme() throws MIOException { + _leaveState(State.THEME); + assert _state() == State.SCOPE; + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#subjectIdentifier(java.lang.String) + */ + public void subjectIdentifier(String subjectIdentifier) throws MIOException { + Locator sid = _tm.createLocator(subjectIdentifier); + Topic topic = _peekTopic(); + Topic existing = _tm.getTopicBySubjectIdentifier(sid); + if (existing != null && !existing.equals(topic)) { + _merge(existing, topic); + } + else { + TopicMapObject tmo = _tm.getObjectByItemIdentifier(sid); + if (tmo != null && tmo instanceof Topic && !tmo.equals(topic)) { + _merge((Topic) tmo, topic); + } + } + topic.addSubjectIdentifier(sid); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#subjectLocator(java.lang.String) + */ + public void subjectLocator(String subjectLocator) throws MIOException { + Locator slo = _tm.createLocator(subjectLocator); + Topic topic = _peekTopic(); + Topic existing = _tm.getTopicBySubjectLocator(slo); + if (existing != null && !existing.equals(topic)) { + _merge(existing, topic); + } + topic.addSubjectLocator(slo); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#itemIdentifier(java.lang.String) + */ + public void itemIdentifier(String itemIdentifier) throws MIOException { + Locator iid = _tm.createLocator(itemIdentifier); + TopicMapObject tmo = _peekConstruct(); + if (_state() == State.TOPIC) { + TopicMapObject existing = _tm.getObjectByItemIdentifier(iid); + if (existing != null && existing instanceof Topic && !existing.equals(tmo)) { + _merge((Topic) existing, (Topic) tmo); + } + else { + Topic topic = _tm.getTopicBySubjectIdentifier(iid); + if (topic != null && !topic.equals(tmo)) { + _merge(topic, (Topic) tmo); + } + } + } + tmo.addSourceLocator(iid); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startIsa() + */ + public void startIsa() throws MIOException { + assert _state() == State.TOPIC; + _enterState(State.ISA); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endIsa() + */ + public void endIsa() throws MIOException { + _leaveState(State.ISA); + assert _state() == State.TOPIC; + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#startReifier() + */ + public void startReifier() throws MIOException { + assert _peekConstruct() instanceof IReifiable; + _enterState(State.REIFIER); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#endReifier() + */ + public void endReifier() throws MIOException { + _leaveState(State.REIFIER); + assert _peekConstruct() instanceof IReifiable; + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#topicRef(com.semagia.mio.IRef) + */ + public void topicRef(IRef identity) throws MIOException { + _handleTopic(_createTopic(identity)); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#value(java.lang.String) + */ + public void value(String value) throws MIOException { + assert _state() == State.NAME; + ((TopicName) _peekConstruct()).setValue(value); + } + + /* (non-Javadoc) + * @see com.semagia.mio.IMapHandler#value(java.lang.String, java.lang.String) + */ + public void value(String value, String datatype) throws MIOException { + boolean isLocator = _XSD_ANY_URI.equals(datatype); + if (!isLocator && !_XSD_STRING.equals(datatype)) { + LOG.warning("The datatype '" + datatype + "' was converted into xsd:string"); + } + if (_state() == State.OCCURRENCE) { + Occurrence occ = (Occurrence) _peekConstruct(); + if (isLocator) { + occ.setResource(_tm.createLocator(value)); + } + else { + occ.setValue(value); + } + } + else { + assert _state() == State.VARIANT; + Variant variant = (Variant) _peekConstruct(); + if (isLocator) { + variant.setResource(_tm.createLocator(value)); + } + else { + variant.setValue(value); + } + } + } + + /** + * Enters a state. + * + * @param state The state to push ontop of the state stack. + */ + private void _enterState(State state) { + _stateStack[++_stackPointer] = state; + } + + /** + * Enters a state and pushes the Topic Maps construct ontop of the construct + * stack. + * + * @param state The state to enter. + * @param tmo The Topic Maps construct which should be pushed to the stack. + */ + private void _enterState(State state, TopicMapObject tmo) { + _enterState(state); + _constructStack.add(tmo); + } + + /** + * Leaves a state. + * + * @param state The state to leave. + * @throws MIOException If the state is not equals to the current state. + */ + private void _leaveState(State state) throws MIOException { + if (!(state == _stateStack[_stackPointer])) { + _reportError("Unexpected state: " + _stateStack[_stackPointer] + ", expected: " + state); + } + --_stackPointer; + } + + /** + * Leaves a state and removed the Topic Maps construct from the top of the + * construct stack. + * + * @param state The state to leave. + * @throws MIOException If the state is not equals to the current state. + */ + private void _leaveStatePopConstruct(State state) throws MIOException { + _leaveState(state); + _constructStack.remove(_constructStack.size()-1); + } + + /** + * Returns the Topic Maps construct on top of the stack. + * + * @return The Topic Maps construct. + */ + private TopicMapObject _peekConstruct() { + return _constructStack.get(_constructStack.size()-1); + } + + /** + * Returns the topic on top of the stack. + * + * @return The topic. + */ + private Topic _peekTopic() { + return (Topic) _peekConstruct(); + } + + /** + * Returns the current state. + * + * @return The current state. + */ + private State _state() { + return _stateStack[_stackPointer]; + } + + /** + * Handles the topic dependent on the current state. + * + * @param topic The topic to handle. + */ + private void _handleTopic(Topic topic) { + switch (_state()) { + case ISA: _peekTopic().addType(topic); break; + case TYPE: ((ITyped) _peekConstruct()).setType(topic); break; + case PLAYER: ((AssociationRole) _peekConstruct()).setPlayer(topic); break; + case THEME: ((ScopedObject) _peekConstruct()).addScopingTopic(topic); break; + case REIFIER: ((IReifiable) _peekConstruct()).setReifier(topic); break; + } + } + + /** + * Merges the <code>source</code> topic with the <code>target</code>. + * + * Further, this method ensures that the construct stack stays valid: If + * the <code>source</code> is part of the stack, it is replaced with + * <code>target</code>. + * + * @param source The source topic (will be removed). + * @param target The target topic. + */ + private void _merge(Topic source, Topic target) { + int i = _constructStack.indexOf(source); + while (i > -1) { + _constructStack.set(i, target); + i = _constructStack.indexOf(source); + } + target.mergeIn(source); + } + + /** + * Returns either an existing topic with the specified identity or creates + * a topic with the given identity. + * + * @param ref The identity of the topic. + * @return A topic instance. + * @throws MIOException + */ + private Topic _createTopic(IRef ref) throws MIOException { + Locator loc = _tm.createLocator(ref.getIRI()); + switch (ref.getType()) { + case IRef.ITEM_IDENTIFIER: return _topicByItemIdentifier(loc); + case IRef.SUBJECT_IDENTIFIER: return _topicBySubjectIdentifier(loc); + case IRef.SUBJECT_LOCATOR: return _topicBySubjectLocator(loc); + default: _reportError("Unknown reference type " + ref.getType()); + } + // Never returned, an exception was thrown + return null; + } + + /** + * Returns either an existing topic with the specified item identfier, + * or creates a topic with the given item identifier. + * + * @param iid The item identifier of the topic. + * @return A topic instance. + */ + private Topic _topicByItemIdentifier(Locator iid) { + TopicMapObject tmo = _tm.getObjectByItemIdentifier(iid); + Topic topic = (tmo instanceof Topic) ? (Topic) tmo : null; + if (topic == null) { + topic = _tm.getTopicBySubjectIdentifier(iid); + if (topic != null) { + topic.addSourceLocator(iid); + } + } + if (topic == null) { + topic = _tm.createTopic(); + topic.addSourceLocator(iid); + } + return topic; + } + + /** + * Returns either an existing topic with the specified subject identfier, + * or creates a topic with the given subject identifier. + * + * @param sid The subject identifier of the topic. + * @return A topic instance. + */ + private Topic _topicBySubjectIdentifier(Locator sid) { + Topic topic = _tm.getTopicBySubjectIdentifier(sid); + if (topic == null) { + TopicMapObject tmo = _tm.getObjectByItemIdentifier(sid); + if (tmo instanceof Topic) { + topic = (Topic) tmo; + topic.addSubjectIdentifier(sid); + } + } + if (topic == null) { + topic = _tm.createTopic(); + topic.addSubjectIdentifier(sid); + } + return topic; + } + + /** + * Returns either an existing topic with the specified subject locator, + * or creates a topic with the given subject locator. + * + * @param slo The subject locator of the topic. + * @return A topic instance. + */ + private Topic _topicBySubjectLocator(Locator slo) { + Topic topic = _tm.getTopicBySubjectLocator(slo); + if (topic == null) { + topic = _tm.createTopic(); + topic.addSubjectLocator(slo); + } + return topic; + } + + /** + * Reports an error. + * + * @param msg The error message. + * @throws MIOException Thrown in any case. + */ + private static void _reportError(String msg) throws MIOException { + throw new MIOException(msg); + } + +} Property changes on: tinytim-io/trunk/src/main/java/org/tinytim/io/MapInputHandler.java ___________________________________________________________________ Name: svn:keywords + Rev Date Id Name: svn:eol-style + native Added: tinytim-io/trunk/src/main/java/org/tinytim/io/TopicMapImporter.java =================================================================== --- tinytim-io/trunk/src/main/java/org/tinytim/io/TopicMapImporter.java (rev 0) +++ tinytim-io/trunk/src/main/java/org/tinytim/io/TopicMapImporter.java 2008-05-08 12:11:31 UTC (rev 63) @@ -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.io; + +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-io/trunk/src/main/java/org/tinytim/io/TopicMapImporter.java ___________________________________________________________________ Name: svn:keywords + Rev Date Id Name: svn:eol-style + native Added: tinytim-io/trunk/src/test/java/org/tinytim/io/TestMapInputHandler.java =================================================================== --- tinytim-io/trunk/src/test/java/org/tinytim/io/TestMapInputHandler.java (rev 0) +++ tinytim-io/trunk/src/test/java/org/tinytim/io/TestMapInputHandler.java 2008-05-08 12:11:31 UTC (rev 63) @@ -0,0 +1,311 @@ +/* + * 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.io; + +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; +import org.tmapi.core.TopicMapSystem; +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; + +/** + * Tests against the {@link org.tinytim.io.MapInputHandler}. + * + * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a> + * @version $Rev$ - $Date$ + */ +public class TestMapInputHandler extends TestCase { + + private static final String _XSD_STRING = "http://www.w3.org/2001/XMLSchema#string"; + private static final String _XSD_ANY_URI = "http://www.w3.org/2001/XMLSchema#anyURI"; + + private TopicMapImpl _tm; + private MapInputHandler _handler; + + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception { + TopicMapSystemFactory tmSysFactory = TopicMapSystemFactory.newInstance(); + tmSysFactory.setProperty(Property.XTM10_REIFICATION, "false"); + TopicMapSystem tmSys = tmSysFactory.newTopicMapSystem(); + _tm = (TopicMapImpl) tmSys.createTopicMap("http://sf.net/projects/tinytim/test"); + _handler = new MapInputHandler(); + _handler.setTopicMap(_tm); + } + + /** + * Simple startTopicMap, followed by an endTopicMap event. + */ + public void testEmpty() throws Exception { + assertEquals(0, _tm.getTopics().size()); + assertEquals(0, _tm.getAssociations().size()); + _handler.startTopicMap(); + _handler.endTopicMap(); + assertEquals(0, _tm.getTopics().size()); + assertEquals(0, _tm.getAssociations().size()); + } + + /** + * Tests topic creation with an item identifier. + */ + public void testTopicIdentityItemIdentifier() throws Exception { + String itemIdent = "http://sf.net/projects/tinytim/test#1"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createItemIdentifier(itemIdent)); + _handler.endTopic(); + _handler.endTopicMap(); + assertEquals(1, _tm.getTopics().size()); + Topic topic = (Topic) _tm.getObjectByItemIdentifier(_tm.createLocator(itemIdent)); + assertNotNull(topic); + } + + /** + * Tests topic creation with a subject identifier. + */ + public void testTopicIdentitySubjectIdentifier() throws Exception { + String subjIdent = "http://sf.net/projects/tinytim/test#1"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createSubjectIdentifier(subjIdent)); + _handler.endTopic(); + _handler.endTopicMap(); + assertEquals(1, _tm.getTopics().size()); + Topic topic = _tm.getTopicBySubjectIdentifier(_tm.createLocator(subjIdent)); + assertNotNull(topic); + } + + /** + * Tests topic creation with a subject locator. + */ + public void testTopicIdentitySubjectLocator() throws Exception { + String subjLoc = "http://sf.net/projects/tinytim/test#1"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createSubjectLocator(subjLoc)); + _handler.endTopic(); + _handler.endTopicMap(); + assertEquals(1, _tm.getTopics().size()); + Topic topic = _tm.getTopicBySubjectLocator(_tm.createLocator(subjLoc)); + assertNotNull(topic); + } + + /** + * Tests transparent merging. + */ + public void testTopicMerging() throws Exception { + String ref = "http://sf.net/projects/tinytim/test#1"; + String itemIdent = "http://example.org/1"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createSubjectIdentifier(ref)); + // Topic in topic event + _handler.startTopic(Ref.createItemIdentifier(itemIdent)); + _handler.itemIdentifier(ref); + _handler.endTopic(); + _handler.startOccurrence(); + _handler.value("tinyTiM", _XSD_STRING); + _handler.endOccurrence(); + _handler.endTopic(); + _handler.endTopicMap(); + assertEquals(1, _tm.getTopics().size()); + Topic topic = _tm.getTopicBySubjectIdentifier(_tm.createLocator(ref)); + assertNotNull(topic); + assertEquals(topic, _tm.getObjectByItemIdentifier(_tm.createLocator(ref))); + assertEquals(topic, _tm.getObjectByItemIdentifier(_tm.createLocator(itemIdent))); + assertEquals(1, topic.getOccurrences().size()); + Occurrence occ = (Occurrence) topic.getOccurrences().iterator().next(); + assertEquals("tinyTiM", occ.getValue()); + } + + /** + * Tests assigning identities to a topic. + */ + public void testTopicIdentities1() throws Exception { + String ref = "http://sf.net/projects/tinytim/test#1"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createSubjectIdentifier(ref)); + _handler.itemIdentifier(ref); + _handler.endTopic(); + _handler.endTopicMap(); + assertEquals(1, _tm.getTopics().size()); + Locator loc = _tm.createLocator(ref); + Topic topic = _tm.getTopicBySubjectIdentifier(loc); + assertNotNull(topic); + assertEquals(topic, _tm.getObjectByItemIdentifier(loc)); + } + + /** + * Tests assigning identities to a topic. + */ + public void testTopicIdentities2() throws Exception { + String ref = "http://sf.net/projects/tinytim/test#1"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createItemIdentifier(ref)); + _handler.subjectIdentifier(ref); + _handler.endTopic(); + _handler.endTopicMap(); + assertEquals(1, _tm.getTopics().size()); + Locator loc = _tm.createLocator(ref); + Topic topic = _tm.getTopicBySubjectIdentifier(loc); + assertNotNull(topic); + assertEquals(topic, _tm.getObjectByItemIdentifier(loc)); + } + + /** + * Tests reifying the topic map. + */ + public void testTopicMapReifier() throws Exception { + String ref = "http://sf.net/projects/tinytim/test#1"; + _handler.startTopicMap(); + _handler.startReifier(); + _handler.startTopic(Ref.createSubjectIdentifier(ref)); + _handler.endTopic(); + _handler.endReifier(); + _handler.endTopicMap(); + assertNotNull(_tm.getReifier()); + Topic topic = _tm.getTopicBySubjectIdentifier(_tm.createLocator(ref)); + assertNotNull(topic); + assertEquals(topic, _tm.getReifier()); + } + + /** + * Tests occurrence creation with a value of datatype xsd:string. + */ + public void testOccurrenceValueString() throws Exception { + String ref = "http://sf.net/projects/tinytim/test#1"; + String val = "tinyTiM"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createSubjectIdentifier(ref)); + _handler.startOccurrence(); + _handler.value(val, _XSD_STRING); + _handler.endOccurrence(); + _handler.endTopic(); + _handler.endTopicMap(); + Topic topic = _tm.getTopicBySubjectIdentifier(_tm.createLocator(ref)); + assertNotNull(topic); + Occurrence occ = (Occurrence) topic.getOccurrences().iterator().next(); + assertEquals(val, occ.getValue()); + } + + /** + * Tests occurrence creation with a value of datatype xsd:anyURI. + */ + public void testOccurrenceValueURI() throws Exception { + String ref = "http://sf.net/projects/tinytim/test#1"; + String val = "http://sf.net/projects/tinytim"; + _handler.startTopicMap(); + _handler.startTopic(Ref.createSubjectIdentifier(ref)); + _handler.startOccurrence(); + _handler.value(val, _XSD_ANY_URI); + _handler.endOccurrence(); + _handler.endTopic(); + _handler.endTopicMap(); + Topic topic = _tm.getTopicBySubjectIdentifier(_tm.createLocator(ref)); + assertNotNull(topic); + Occurrence occ = (Occurrence) topic.getOccurrences().iterator().next(); + assertNull(occ.getValue()); + 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. + } + } + +} Property changes on: tinytim-io/trunk/src/test/java/org/tinytim/io/TestMapInputHandler.java ___________________________________________________________________ Name: svn:keywords + Rev Date Id Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |