From: <lh...@us...> - 2008-08-16 17:00:45
|
Revision: 128 http://tinytim.svn.sourceforge.net/tinytim/?rev=128&view=rev Author: lheuer Date: 2008-08-16 17:00:53 +0000 (Sat, 16 Aug 2008) Log Message: ----------- - Removed stopgab TopicMapImporter in favour of several specialized Readers - Added ITopicMapReader / ITopicMapWriter - Moved Canonicalizer from the .cxtm package into the .mio package (CXTMWriter) Modified Paths: -------------- tinytim-mio/trunk/src/main/java/org/tinytim/core/AbstractMapInputHandler.java Added Paths: ----------- tinytim-mio/trunk/src/main/java/org/tinytim/mio/AbstractTopicMapReader.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/BTMReader.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/CTMReader.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/CXTMWriter.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/ITopicMapReader.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/ITopicMapWriter.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/LTMReader.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/SnelloReader.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/TMXMLReader.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/XMLC14NWriter.java tinytim-mio/trunk/src/main/java/org/tinytim/mio/XTMReader.java Removed Paths: ------------- tinytim-mio/trunk/src/main/java/org/tinytim/mio/TopicMapImporter.java Modified: tinytim-mio/trunk/src/main/java/org/tinytim/core/AbstractMapInputHandler.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/core/AbstractMapInputHandler.java 2008-08-15 12:10:43 UTC (rev 127) +++ tinytim-mio/trunk/src/main/java/org/tinytim/core/AbstractMapInputHandler.java 2008-08-16 17:00:53 UTC (rev 128) @@ -48,23 +48,23 @@ public abstract class AbstractMapInputHandler implements IMapHandler { private final int - INITIAL = 0, - TOPIC = 1, - ASSOCIATION = 2, - ROLE = 3, - OCCURRENCE = 4, - NAME = 5, - VARIANT = 6, - SCOPE = 7, - THEME = 8, - REIFIER = 9, - PLAYER = 10, - ISA = 11, - TYPE = 12; + INITIAL = 1, + TOPIC = 2, + ASSOCIATION = 3, + ROLE = 4, + OCCURRENCE = 5, + NAME = 6, + VARIANT = 7, + SCOPE = 8, + THEME = 9, + REIFIER = 10, + PLAYER = 11, + ISA = 12, + TYPE = 13; private final int _CONSTRUCTS = 6; - private final int _STATES = 8; - private final int _SCOPE = 4; + private final int _STATES = 10; + private final int _SCOPE = 6; private TopicMapImpl _tm; private int[] _stateStack; @@ -388,7 +388,7 @@ */ private void _enterState(int state) { if (_stateSize + 1 > _stateStack.length) { - int[] states = new int[_stateSize*2]; + int[] states = new int[Math.min(_stateSize*2, Integer.MAX_VALUE)]; System.arraycopy(_stateStack, 0, states, 0, _stateSize); _stateStack = states; } @@ -406,7 +406,7 @@ private void _enterState(int state, IConstruct tmo) { _enterState(state); if (_constructSize + 1 > _constructStack.length) { - IConstruct[] constructs = new IConstruct[_constructSize*2]; + IConstruct[] constructs = new IConstruct[Math.min(_constructSize*2, Integer.MAX_VALUE)]; System.arraycopy(_constructStack, 0, constructs, 0, _constructSize); _constructStack = constructs; } Added: tinytim-mio/trunk/src/main/java/org/tinytim/mio/AbstractTopicMapReader.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/mio/AbstractTopicMapReader.java (rev 0) +++ tinytim-mio/trunk/src/main/java/org/tinytim/mio/AbstractTopicMapReader.java 2008-08-16 17:00:53 UTC (rev 128) @@ -0,0 +1,92 @@ +/* + * 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; + +/** + * Base class for {@link ITopicMapReader} implementations. + * + * This class provides a layer to <tt>com.semagia.mio</tt> and handles + * the discovery of an appropriate deserializer transparently. + * + * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a> + * @version $Rev:$ - $Date:$ + */ +abstract class AbstractTopicMapReader implements ITopicMapReader { + + protected IDeserializer _deserializer; + + AbstractTopicMapReader(final TopicMap topicMap, final Syntax syntax) { + _deserializer = DeserializerRegistry.createDeserializer(syntax); + if (_deserializer == null) { + throw new TMAPIRuntimeException("Appropriate deserializer not found for syntax " + syntax.getName()); + } + _deserializer.setMapHandler(new MapInputHandler(topicMap)); + } + + /* (non-Javadoc) + * @see org.tinytim.mio.ITopicMapReader#read(java.io.File, java.lang.String) + */ + public void read(File source, String baseIRI) throws IOException { + read(new FileInputStream(source), baseIRI); + } + + /* (non-Javadoc) + * @see org.tinytim.mio.ITopicMapReader#read(java.io.InputStream, java.lang.String) + */ + public void read(InputStream source, String baseIRI) throws IOException { + read(new InputSource(source), baseIRI); + } + + /* (non-Javadoc) + * @see org.tinytim.mio.ITopicMapReader#read(org.xml.sax.InputSource, java.lang.String) + */ + public void read(InputSource source, String baseIRI) throws IOException { + try { + _deserializer.parse(source, baseIRI); + } + catch (MIOException ex) { + if (ex.getException() instanceof IOException) { + throw (IOException) ex.getException(); + } + else { + throw new TMAPIRuntimeException(ex); + } + } + finally { + _deserializer = null; + } + } + +} Property changes on: tinytim-mio/trunk/src/main/java/org/tinytim/mio/AbstractTopicMapReader.java ___________________________________________________________________ Added: svn:keywords + Rev Date Id Added: svn:eol-style + native Added: tinytim-mio/trunk/src/main/java/org/tinytim/mio/BTMReader.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/mio/BTMReader.java (rev 0) +++ tinytim-mio/trunk/src/main/java/org/tinytim/mio/BTMReader.java 2008-08-16 17:00:53 UTC (rev 128) @@ -0,0 +1,45 @@ +/* + * 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 org.tmapi.core.TopicMap; + +import com.semagia.mio.Syntax; + +/** + * {@link ITopicMapReader} implementation that is able to deserialize + * <a href="http://www.semagia.com/tr/btm/1.0/">Binary Topic Maps (BTM) 1.0</a>. + * + * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a> + * @version $Rev:$ - $Date:$ + */ +public final class BTMReader extends AbstractTopicMapReader { + + /** + * Constructs a new instance. + * + * @param topicMap The topic map to which the content is added to. + */ + public BTMReader(final TopicMap topicMap) { + super(topicMap, Syntax.BTM); + } + +} Property changes on: tinytim-mio/trunk/src/main/java/org/tinytim/mio/BTMReader.java ___________________________________________________________________ Added: svn:keywords + Rev Date Id Added: svn:eol-style + native Added: tinytim-mio/trunk/src/main/java/org/tinytim/mio/CTMReader.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/mio/CTMReader.java (rev 0) +++ tinytim-mio/trunk/src/main/java/org/tinytim/mio/CTMReader.java 2008-08-16 17:00:53 UTC (rev 128) @@ -0,0 +1,48 @@ +/* + * 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 org.tmapi.core.TopicMap; + +import com.semagia.mio.Syntax; + +/** + * {@link ITopicMapReader} implementation that is able to deserialize + * <a href="http://www.isotopicmaps.org/ctm">Compact Topic Maps (CTM) 1.0</a>. + * <p> + * Note that this reader implements the CTM draft dtd. 2008-05-15. + * </p> + * + * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a> + * @version $Rev:$ - $Date:$ + */ +public final class CTMReader extends AbstractTopicMapReader { + + /** + * Constructs a new instance. + * + * @param topicMap The topic map to which the content is added to. + */ + public CTMReader(final TopicMap topicMap) { + super(topicMap, Syntax.CTM); + } + +} Property changes on: tinytim-mio/trunk/src/main/java/org/tinytim/mio/CTMReader.java ___________________________________________________________________ Added: svn:keywords + Rev Date Id Added: svn:eol-style + native Added: tinytim-mio/trunk/src/main/java/org/tinytim/mio/CXTMWriter.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/mio/CXTMWriter.java (rev 0) +++ tinytim-mio/trunk/src/main/java/org/tinytim/mio/CXTMWriter.java 2008-08-16 17:00:53 UTC (rev 128) @@ -0,0 +1,1233 @@ +/* + * 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.IOException; +import java.io.OutputStream; +import java.util.AbstractSet; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.logging.Logger; + +import org.tinytim.core.TopicMapImpl; +import org.tinytim.internal.utils.CollectionFactory; +import org.tinytim.utils.DuplicateRemovalUtils; +import org.tinytim.voc.TMDM; +import org.tinytim.voc.XSD; +import org.tmapi.core.Association; +import org.tmapi.core.Construct; +import org.tmapi.core.DatatypeAware; +import org.tmapi.core.Locator; +import org.tmapi.core.Name; +import org.tmapi.core.Occurrence; +import org.tmapi.core.Reifiable; +import org.tmapi.core.Role; +import org.tmapi.core.Scoped; +import org.tmapi.core.Topic; +import org.tmapi.core.TopicInUseException; +import org.tmapi.core.TopicMap; +import org.tmapi.core.Typed; +import org.tmapi.core.Variant; +import org.tmapi.index.TypeInstanceIndex; + +import org.xml.sax.Attributes; +import org.xml.sax.helpers.AttributesImpl; + +/** + * Provides serialization of topic maps into Canonical XTM (CXTM). + * <p> + * CXTM is a format that guarantees that two equivalent Topic Maps Data Model + * instances [ISO/IEC 13250-2] will always produce byte-by-byte identical + * serializations, and that non-equivalent instances will always produce + * different serializations. + * </p> + * <p> + * See <a href="http://www.isotopicmaps.org/cxtm/">http://www.isotopicmaps.org/cxtm/</a> + * for details. + * </p> + * <p> + * <em>CAUTION</em>: This class implements the + * <a href="http://www.isotopicmaps.org/cxtm/">CXTM draft dtd. 2008-05-15</a>, + * the output may change in the future. + * </p> + * + * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a> + * @version $Rev$ - $Date$ + */ +public final class CXTMWriter implements ITopicMapWriter { + + private static final Logger LOG = Logger.getLogger(CXTMWriter.class.getName()); + + private static final Role[] _EMPTY_ROLES = new Role[0]; + + private Topic _type; + private Topic _instance; + private Topic _typeInstance; + + private XMLC14NWriter _out; + private final String _normBase; + private Map<Construct, Integer> _construct2Id; + private Map<Topic, List<Role>> _topic2Roles; + private Map<Locator, String> _locator2Norm; + + private Comparator<Topic> _topicComparator; + private Comparator<Association> _assocComparator; + private Comparator<Role> _roleComparator; + private Comparator<Occurrence> _occComparator; + private Comparator<Name> _nameComparator; + private Comparator<Variant> _variantComparator; + private Comparator<Set<Locator>> _locSetComparator; + private Comparator<Locator> _locComparator; + private Comparator<Set<Topic>> _scopeComparator; + + private Map<Association, Role[]> _assoc2Roles; + + /** + * Creates a canonicalizer. + * + * @param out The stream the CXTM is written onto. + * @param baseLocator The base locator which is used to resolve IRIs against. + * @throws IOException If an error occurs. + */ + public CXTMWriter(OutputStream out, String baseLocator) throws IOException { + if (baseLocator == null) { + throw new IllegalArgumentException("The base locator must not be null"); + } + _out = new XMLC14NWriter(out); + _normBase = _normalizeBaseLocator(baseLocator); + _topicComparator = new TopicComparator(); + _assocComparator = new AssociationComparator(); + _roleComparator = new RoleComparator(); + _occComparator = new OccurrenceComparator(); + _nameComparator = new NameComparator(); + _variantComparator = new VariantComparator(); + _locSetComparator = new LocatorSetComparator(); + _locComparator = new LocatorComparator(); + _scopeComparator = new ScopeComparator(); + } + + /** + * Serializes the specified <tt>topicMap</tt> into the CXTM format. + * <p> + * <em>CAUTION</em>: This method MAY modify the topic map since duplicate + * Topic Maps constructs (if any) are removed in advance. + * </p> + * + * @param topicMap The topic map to serialize. + * @throws IOException If an error occurs. + */ + public void write(TopicMap topicMap) throws IOException { + DuplicateRemovalUtils.removeDuplicates(topicMap); + _construct2Id = CollectionFactory.createIdentityMap(); + _locator2Norm = CollectionFactory.createIdentityMap(); + _assoc2Roles = CollectionFactory.createIdentityMap(); + _topic2Roles = CollectionFactory.createIdentityMap(); + TypeInstanceIndex typeInstanceIndex = ((TopicMapImpl) topicMap).getIndexManager().getTypeInstanceIndex(); + if (!typeInstanceIndex.isAutoUpdated()) { + typeInstanceIndex.reindex(); + } + Topic[] topics = _fetchTopics(topicMap, typeInstanceIndex); + Association[] assocs = _fetchAssociations(topicMap, typeInstanceIndex); + typeInstanceIndex.close(); + _createIndex(topics, assocs); + _out.startDocument(); + AttributesImpl attrs = new AttributesImpl(); + _addReifier(attrs, topicMap); + _out.startElement("topicMap", attrs); + _out.newline(); + _writeItemIdentifiers(topicMap); + for (Topic topic: topics) { + _writeTopic(topic); + } + for (Association assoc: assocs) { + _writeAssociation(assoc); + } + _out.endElement("topicMap"); + _out.newline(); + _out.endDocument(); + _out = null; + _construct2Id = null; + _locator2Norm = null; + _assoc2Roles = null; + _topic2Roles = null; + } + + /** + * Returns an unsorted array of topics which should be included into + * the output. + * + * This method may return more topics than {@link TopicMap#getTopics()} + * since this method creates virtual topics to model type-instance + * relationships properly. + * + * @param topicMap The topic map from which the topic should be serialized. + * @param idx A (upto date) type instance index. + * @return All topics which must be included into the output. + */ + private Topic[] _fetchTopics(final TopicMap topicMap, final TypeInstanceIndex idx) { + Collection<Topic> types = idx.getTopicTypes(); + if (types.isEmpty()) { + Set<Topic> topics = topicMap.getTopics(); + return topics.toArray(new Topic[topics.size()]); + } + else { + List<Topic> topics = CollectionFactory.createList(topicMap.getTopics()); + _typeInstance = _getTopicBySubjectIdentifier(topicMap, topics, TMDM.TYPE_INSTANCE); + _type = _getTopicBySubjectIdentifier(topicMap, topics, TMDM.TYPE); + _instance = _getTopicBySubjectIdentifier(topicMap, topics, TMDM.INSTANCE); + return topics.toArray(new Topic[topics.size()]); + } + } + + /** + * Returns a topic by its subject identifier. If the topic is null, a + * {@link TypeInstanceTopic} is created, added to the <tt>topics</tt> + * and returned. + * + * @param tm The topic map to fetch the topic from. + * @param topics A modifiable collection of topics. + * @param sid The subject identifier. + * @return A topic with the specified subject identifier. + */ + private Topic _getTopicBySubjectIdentifier(TopicMap tm, Collection<Topic> topics, Locator sid) { + Topic topic = tm.getTopicBySubjectIdentifier(sid); + if (topic == null) { + topic = new TypeInstanceTopic(sid); + topics.add(topic); + } + return topic; + } + + /** + * Returns an unsorted array of associations which should be serialized. + * + * This method may return more association than {@link TopicMap#getAssociations()} + * since this method may create virtual associations which are used to + * model type-instance relationships properly. + * + * @param tm The topic map from which the associations should be serialized. + * @param idx A (upto date) type instance index. + * @return An unsorted array of associations which must be included into the output. + */ + private Association[] _fetchAssociations(final TopicMap tm, final TypeInstanceIndex idx) { + Collection<Topic> types = idx.getTopicTypes(); + if (types.isEmpty()) { + Set<Association> assocs = tm.getAssociations(); + return assocs.toArray(new Association[assocs.size()]); + } + else { + List<Association> assocs = CollectionFactory.createList(tm.getAssociations()); + for (Topic type: types) { + for (Topic instance: idx.getTopics(type)) { + assocs.add(new TypeInstanceAssociation(type, instance)); + } + } + return assocs.toArray(new Association[assocs.size()]); + } + } + + /** + * Creates the index on which the canonicalizer operates. + * + * As sideeffect, the provided topic and association arrays get sorted. + * + * @param topics An array of topics. + * @param assocs An array of associations. + */ + private void _createIndex(Topic[] topics, Association[] assocs) { + Arrays.sort(topics, _topicComparator); + Topic topic = null; + for (int i=0; i < topics.length; i++) { + topic = topics[i]; + _construct2Id.put(topic, Integer.valueOf(i+1)); + } + Arrays.sort(assocs, _assocComparator); + Association assoc = null; + for (int i=0; i < assocs.length; i++) { + assoc = assocs[i]; + _construct2Id.put(assoc, Integer.valueOf(i+1)); + Set<Role> roles_ = assoc.getRoles(); + Role[] roles = roles_.toArray(new Role[roles_.size()]); + Arrays.sort(roles, _roleComparator); + _assoc2Roles.put(assoc, roles); + for (int j=0; j < roles.length; j++) { + _construct2Id.put(roles[j], Integer.valueOf(j+1)); + } + } + } + + /** + * Returns a sorted array of roles of the provided association. + * + * @param assoc The association to retrieve the roles from. + * @return A (maybe empty) sorted array of roles. + */ + private Role[] _getRoles(final Association assoc) { + Role[] roles = _assoc2Roles.get(assoc); + return roles != null ? roles : _EMPTY_ROLES; + } + + /** + * Returns a sorted array of names of the provided topic. + * + * @param topic The topic to retrieve the names from. + * @return A (maybe empty) sorted array of names. + */ + private Name[] _getNames(final Topic topic) { + Set<Name> names_ = topic.getNames(); + Name[] names = names_.toArray(new Name[names_.size()]); + Arrays.sort(names, _nameComparator); + return names; + } + + /** + * Returs a sorted array of variants of the provided name. + * + * @param name The name to retrieve the variants from. + * @return A (maybe empty) sorted array of variants. + */ + private Variant[] _getVariants(final Name name) { + Set<Variant> variants_ = name.getVariants(); + Variant[] variants = variants_.toArray(new Variant[variants_.size()]); + Arrays.sort(variants, _variantComparator); + return variants; + } + + /** + * Returns a sorted array of occurrences of the provided topic. + * + * @param topic The topic to retrieve the occurrences from. + * @return A (maybe emtpy) sorted array of occurrences. + */ + private Occurrence[] _getOccurrences(final Topic topic) { + Set<Occurrence> occs_ = topic.getOccurrences(); + Occurrence[] occs = occs_.toArray(new Occurrence[occs_.size()]); + Arrays.sort(occs, _occComparator); + return occs; + } + + /** + * Returns the index of the provided Topic Maps construct. + * + * The "index" is <cite>"[...] the string encoding of the position of this + * information item in the canonically ordered list of the values from + * that set".</cite> (CXTM 3.20 Constructing the number attribute). + * + * @param tmo The Topic Maps construct to return the index of. + * @return The index of the Topic Maps construct. + */ + private int _indexOf(final Construct tmo) { + return _construct2Id.get(tmo).intValue(); + } + + /** + * Serializes the <tt>topic</tt>. + * + * @param topic The topic to serialize. + * @throws IOException If an error occurs. + */ + private void _writeTopic(final Topic topic) throws IOException { + AttributesImpl attrs = new AttributesImpl(); + attrs.addAttribute("", "number", null, null, "" +_indexOf(topic)); + _out.startElement("topic", attrs); + _out.newline(); + _writeLocatorSet("subjectIdentifiers", topic.getSubjectIdentifiers()); + _writeLocatorSet("subjectLocators", topic.getSubjectLocators()); + _writeItemIdentifiers(topic); + Name[] names = _getNames(topic); + for (int i=0; i < names.length; i++) { + _writeName(names[i], i+1); + } + Occurrence[] occs = _getOccurrences(topic); + for (int i=0; i < occs.length; i++) { + _writeOccurrence(occs[i], i+1); + } + List<Role> roles_ = CollectionFactory.createList(topic.getRolesPlayed()); + List<Role> alienRoles = _topic2Roles.get(topic); + if (alienRoles != null) { + roles_.addAll(alienRoles); + } + Role[] roles = roles_.toArray(new Role[roles_.size()]); + Arrays.sort(roles, _roleComparator); + AttributesImpl roleAttrs = new AttributesImpl(); + StringBuilder sb = new StringBuilder(20); + for (int i=0; i < roles.length; i++) { + sb.append("association.") + .append(_indexOf(roles[i].getParent())) + .append(".role.") + .append(_indexOf(roles[i])); + roleAttrs.addAttribute("", "ref", null, null, sb.toString()); + _out.startElement("rolePlayed", roleAttrs); + _out.endElement("rolePlayed"); + _out.newline(); + sb.setLength(0); + roleAttrs.clear(); + } + _out.endElement("topic"); + _out.newline(); + } + + /** + * Serializes an association. + * + * @param assoc The association to serialize. + * @throws IOException If an error occurs. + */ + private void _writeAssociation(final Association assoc) throws IOException { + _out.startElement("association", _attributes(assoc, _indexOf(assoc))); + _out.newline(); + _writeType(assoc); + for (Role role: _getRoles(assoc)) { + _out.startElement("role", _attributes(role, _indexOf(role))); + _out.newline(); + _out.startElement("player", _topicRef(role.getPlayer())); + _out.endElement("player"); + _out.newline(); + _writeType(role); + _writeItemIdentifiers(role); + _out.endElement("role"); + _out.newline(); + } + _writeScope(assoc); + _writeItemIdentifiers(assoc); + _out.endElement("association"); + _out.newline(); + } + + /** + * Serializes an occurrence. + * + * @param occ The occurrence to serialize. + * @param pos The position of the occurrence within the parent container. + * @throws IOException If an error occurs. + */ + private void _writeOccurrence(final Occurrence occ, int pos) throws IOException { + _out.startElement("occurrence", _attributes(occ, pos)); + _out.newline(); + _writeDatatyped(occ); + _writeType(occ); + _writeScope(occ); + _writeItemIdentifiers(occ); + _out.endElement("occurrence"); + _out.newline(); + } + + /** + * Writes the value/datatype pair of an occurrence or variant. + * + * @param obj The construct to serialize. + * @throws IOException If an error occurs. + */ + private void _writeDatatyped(final DatatypeAware obj) throws IOException { + final String value = XSD.ANY_URI.equals(obj.getDatatype()) + ? _normalizeLocator(obj.locatorValue()) + : obj.getValue(); + _out.startElement("value"); + _out.characters(value); + _out.endElement("value"); + _out.newline(); + _out.startElement("datatype"); + _out.characters(_normalizeLocator(obj.getDatatype())); + _out.endElement("datatype"); + _out.newline(); + } + + /** + * Serializes a topic name. + * + * @param name The name to serialize. + * @param pos The position of the name within the parent container. + * @throws IOException If an error occurs. + */ + private void _writeName(final Name name, int pos) throws IOException { + _out.startElement("name", _attributes(name, pos)); + _out.newline(); + _out.startElement("value"); + _out.characters(name.getValue()); + _out.endElement("value"); + _out.newline(); + _writeType(name); + _writeScope(name); + Variant[] variants = _getVariants(name); + Variant variant = null; + for (int i=0; i<variants.length; i++) { + variant = variants[i]; + _out.startElement("variant", _attributes(variant, i+1)); + _out.newline(); + _writeDatatyped(variant); + _writeScope(variant); + _writeItemIdentifiers(variant); + _out.endElement("variant"); + _out.newline(); + } + _writeItemIdentifiers(name); + _out.endElement("name"); + _out.newline(); + } + + /** + * Serializes the type of a typed Topic Maps construct. + * + * @param typed The typed Topic Maps construct from which the type should be + * serialized. + * @throws IOException If an error occurs. + */ + private void _writeType(final Typed typed) throws IOException { + _out.startElement("type", _topicRef(typed.getType())); + _out.endElement("type"); + _out.newline(); + } + + /** + * Serializes the scope of a scoped Topic Maps construct. + * + * If the scope is unconstrained, this method does nothing. + * + * @param scoped The scoped Topic Maps construct. + * @throws IOException If an error occurs. + */ + private void _writeScope(final Scoped scoped) throws IOException { + Set<Topic> scope = scoped.getScope(); + if (scope.isEmpty()) { + return; + } + _out.startElement("scope"); + _out.newline(); + Topic[] themes = scope.toArray(new Topic[scope.size()]); + Arrays.sort(themes, _topicComparator); + for (int i=0; i < themes.length; i++) { + _out.startElement("scopingTopic", _topicRef(themes[i])); + _out.endElement("scopingTopic"); + _out.newline(); + } + _out.endElement("scope"); + _out.newline(); + } + + /** + * Serializes a locator. + * + * A normalized locator value is created which is serialized. + * + * @param loc The locator to serialize. + * @throws IOException If an error occurs. + */ + private void _writeLocator(final Locator loc) throws IOException { + _out.startElement("locator"); + _out.characters(_normalizeLocator(loc)); + _out.endElement("locator"); + _out.newline(); + } + + /** + * Serializes the item identifiers of the specified Topic Maps construct. + * + * @param tmo The Topic Maps construct to take the item identifiers from. + * @throws IOException If an error occurs. + */ + private void _writeItemIdentifiers(final Construct tmo) throws IOException { + _writeLocatorSet("itemIdentifiers", tmo.getItemIdentifiers()); + } + + /** + * Serializes the <tt>locators</tt> using the <tt>localName</tt> as + * element name. + * + * If the set of <tt>locators</tt> is empty, this method does nothing. + * + * @param localName The element's name. + * @param locators The locators to serialize. + * @throws IOException If an error occurs. + */ + private void _writeLocatorSet(final String localName, final Set<Locator> locators) throws IOException { + if (locators.isEmpty()) { + return; + } + Locator[] locs = locators.toArray(new Locator[locators.size()]); + Arrays.sort(locs, _locComparator); + _out.startElement(localName); + _out.newline(); + for (int i=0; i < locs.length; i++) { + _writeLocator(locs[i]); + } + _out.endElement(localName); + _out.newline(); + } + + /** + * Returns attributes which contains a reference to the provided topic. + * + * @param topic The topic to which the reference should point to. + * @return Attributes with a topic reference. + */ + private Attributes _topicRef(final Topic topic) { + if (topic == null) { + _reportInvalid("The topic reference is null"); + return XMLC14NWriter.EMPTY_ATTRS; + } + AttributesImpl attrs = new AttributesImpl(); + attrs.addAttribute("", "topicref", null, null, "" + _indexOf(topic)); + return attrs; + } + + /** + * Returns attributes which contain the reifier (if any) and the number + * of the provided Topic Maps construct (not a topic). + * + * @param reifiable The Topic Maps construct. + * @param The position of the reifiable within the parent container. + * @return Attributes which contain a reference to the reifier (if any) and + * the number of the provided Topic Maps construct. + */ + private Attributes _attributes(final Reifiable reifiable, int i) { + AttributesImpl attrs = new AttributesImpl(); + _addReifier(attrs, reifiable); + attrs.addAttribute("", "number", null, null, "" + i); + return attrs; + } + + /** + * Adds a reference to the reifier of the Topic Maps construct to the + * provided attributes. If the Topic Maps construct has no reifier, the + * provided attributes are not modified. + * + * @param attrs The attributes. + * @param reifiable The reifiable Topic Maps construct. + */ + private void _addReifier(final AttributesImpl attrs, final Reifiable reifiable) { + Topic reifier = reifiable.getReifier(); + if (reifier != null) { + attrs.addAttribute("", "reifier", null, null, "" + _indexOf(reifier)); + } + } + + /** + * Normalizes the locator according to CXTM 3.19. + * + * @param locator The locator to normalize. + * @return A normalized representation of the locator. + */ + private String _normalizeLocator(final Locator locator) { + String normLoc = _locator2Norm.get(locator); + if (normLoc != null) { + return normLoc; + } + normLoc = locator.getReference(); + if (normLoc.startsWith(_normBase)) { + normLoc = normLoc.substring(_normBase.length()); + } + else { + int i = 0; + int slashPos = -1; + final int max = Math.min(_normBase.length(), normLoc.length()); + while(i < max && _normBase.charAt(i) == normLoc.charAt(i)) { + if (_normBase.charAt(i) == '/') { + slashPos = i; + } + i++; + } + if (slashPos > -1) { + normLoc = normLoc.substring(slashPos); + } + } + if (normLoc.startsWith("/")) { + normLoc = normLoc.substring(1); + } + _locator2Norm.put(locator, normLoc); + return normLoc; + } + + /** + * Normalizes the base locator according to the following procedure + * (CXTM 3.19 - 1.): + * <cite>[...] the base locator with any fragment identifier and query + * removed and any trailing "/" character removed.[...]</cite> + * + * @param baseLocator + * @return + */ + private static String _normalizeBaseLocator(final String baseLocator) { + String loc = baseLocator; + int i = loc.indexOf('#'); + if (i > 0) { + loc = loc.substring(0, i); + } + i = loc.indexOf('?'); + if (i > 0) { + loc = loc.substring(0, i); + } + if (loc.endsWith("/")) { + loc = loc.substring(0, loc.length()-1); + } + return loc; + } + + /** + * Writes a warning msg to the log. + * + * This method is used to inform the user that the serialized topic map + * is not valid acc. to CXTM. + * + * @param msg The warning message. + */ + private static void _reportInvalid(final String msg) { + LOG.warning("Invalid CXTM: '" + msg + "'"); + } + + + /* + * Comparators. + */ + + private final class TopicComparator implements Comparator<Topic> { + + public int compare(Topic o1, Topic o2) { + if (o1 == o2) { + return 0; + } + if (o1 != null && o2 == null) { + _reportInvalid("Comparing topics where one topic is null"); + return +1; + } + else if (o1 == null && o2 != null) { + _reportInvalid("Comparing topics where one topic is null"); + return -1; + } + int res = _locSetComparator.compare(o1.getSubjectIdentifiers(), o2.getSubjectIdentifiers()); + if (res == 0) { + res = _locSetComparator.compare(o1.getSubjectLocators(), o2.getSubjectLocators()); + if (res == 0) { + res = _locSetComparator.compare(o1.getItemIdentifiers(), o2.getItemIdentifiers()); + } + } + return res; + } + } + + /** + * Abstract comparator that provides some utility methods which handle common + * comparisons. + */ + private abstract class AbstractComparator<T> implements Comparator<T> { + int compareString(String o1, String o2) { + if (o1 == null && o2 != null) { + _reportInvalid("The first string value is null"); + return -1; + } + if (o1 != null && o2 == null) { + _reportInvalid("The second string value is null"); + return +1; + } + return o1.compareTo(o2); + } + /** + * Extracts the type of the typed Topic Maps constructs and compares + * the topics. + * + * @param o1 The first typed Topic Maps construct. + * @param o2 The second typed Topic Maps construct. + * @return A negative integer, zero, or a positive integer as the + * first argument is less than, equal to, or greater than the + * second. + */ + int compareType(Typed o1, Typed o2) { + return _topicComparator.compare(o1.getType(), o2.getType()); + } + /** + * Extracts the scope of the scoped Topic Maps constructs and compares + * them. + * + * @param o1 The first scoped Topic Maps construct. + * @param o2 The second scoped Topic Maps construct. + * @return A negative integer, zero, or a positive integer as the + * first argument is less than, equal to, or greater than the + * second. + */ + int compareScope(Scoped o1, Scoped o2) { + return _scopeComparator.compare(o1.getScope(), o2.getScope()); + } + } + + /** + * Enhances the {@link AbstractComparator} with a method to compare the + * value and datatype of an occurrence or variant. + */ + private abstract class AbstractDatatypeAwareComparator<T> extends AbstractComparator<T> { + /** + * Compares the value and datatype of the occurrences / variants. + * + * @param o1 The first occurrence / variant. + * @param o2 The second occurrence / variant. + * @return A negative integer, zero, or a positive integer as the + * first argument is less than, equal to, or greater than the + * second. + */ + int _compareValueDatatype(DatatypeAware o1, DatatypeAware o2) { + int res = compareString(o1.getValue(), o2.getValue()); + if (res == 0) { + res = compareString(o1.getDatatype().getReference(), o2.getDatatype().getReference()); + } + return res; + } + } + + /** + * Canonical sort order: + * 1. [type] + * 2. [roles] + * 3. [scope] + * 4. [parent] + */ + private final class AssociationComparator extends AbstractComparator<Association> { + + private Comparator<Set<Role>> _roleSetComparator; + + AssociationComparator() { + _roleSetComparator = new RoleSetComparator(); + } + + public int compare(Association o1, Association o2) { + if (o1 == o2) { + return 0; + } + int res = compareType(o1, o2); + if (res == 0) { + res = _roleSetComparator.compare(o1.getRoles(), o2.getRoles()); + if (res == 0) { + res = compareScope(o1, o2); + } + } + return res; + } + } + + /** + * Role comparator which ignores the parent association. This comparator + * is meant to be used for roles where the parent is known to be equal or + * unequal. + */ + private class RoleIgnoreParentComparator extends AbstractComparator<Role> { + + public int compare(Role o1, Role o2) { + if (o1 == o2) { + return 0; + } + int res = _topicComparator.compare(o1.getPlayer(), o2.getPlayer()); + if (res == 0) { + res = compareType(o1, o2); + } + return res; + } + } + + /** + * Canonical sort order: + * 1. [player] + * 2. [type] + * 3. [parent] + */ + private final class RoleComparator extends RoleIgnoreParentComparator { + + public int compare(Role o1, Role o2) { + if (o1 == o2) { + return 0; + } + int res = super.compare(o1, o2); + if (res == 0) { + res = _assocComparator.compare(o1.getParent(), o2.getParent()); + } + return res; + } + } + + /** + * Canonical sort order: + * 1. [value] + * 2. [datatype] + * 3. [type] + * 4. [scope] + * 5. [parent] + */ + private final class OccurrenceComparator extends AbstractDatatypeAwareComparator<Occurrence> { + + public int compare(Occurrence o1, Occurrence o2) { + if (o1 == o2) { + return 0; + } + int res = _compareValueDatatype(o1, o2); + if (res == 0) { + res = compareType(o1, o2); + if (res == 0) { + res = compareScope(o1, o2); + } + } + return res; + } + + } + + /** + * Canonical sort order: + * 1. [value] + * 2. [type] + * 3. [scope] + * 4. [parent] + */ + private final class NameComparator extends AbstractComparator<Name> { + + public int compare(Name o1, Name o2) { + if (o1 == o2) { + return 0; + } + int res = compareString(o1.getValue(), o2.getValue()); + if (res == 0) { + res = compareType(o1, o2); + if (res == 0) { + res = compareScope(o1, o2); + } + } + return res; + } + } + + /** + * Canonical sort order: + * 1. [value] + * 2. [datatype] + * 3. [scope] + * 4. [parent] + */ + private final class VariantComparator extends AbstractDatatypeAwareComparator<Variant> { + + public int compare(Variant o1, Variant o2) { + if (o1 == o2) { + return 0; + } + int res = _compareValueDatatype(o1, o2); + if (res == 0) { + res = compareScope(o1, o2); + } + return res; + } + } + + /** + * Comparator which compares the size of the provided set. + * + * Iff the size of the sets are equal, another comparison method is used + * to compare the content of the sets. + */ + private abstract class AbstractSetComparator<T> implements Comparator<Set<T>> { + + public int compare(Set<T> o1, Set<T> o2) { + int s1 = o1.size(); + int s2 = o2.size(); + int res = s1 - s2; + if (res == 0) { + res = compareContent(o1, o2, s1); + } + return res; + } + + /** + * Called iff the size of the sets is equal. + * + * This method is used to compare the content of the sets. + * + * @param o1 The first set. + * @param o2 The second set. + * @param size The size of the set(s). + * @return A negative integer, zero, or a positive integer as the + * first argument is less than, equal to, or greater than the + * second. + */ + abstract int compareContent(Set<T> o1, Set<T> o2, int size); + } + + /** + * Compares role sets. The parent of the roles is ignored! + */ + private final class RoleSetComparator extends AbstractSetComparator<Role> { + + private RoleIgnoreParentComparator _roleCmp; + + RoleSetComparator() { + _roleCmp = new RoleIgnoreParentComparator(); + } + + @Override + int compareContent(Set<Role> o1, Set<Role> o2, + int size) { + int res = 0; + Role[] roles1 = o1.toArray(new Role[size]); + Role[] roles2 = o2.toArray(new Role[size]); + Arrays.sort(roles1, _roleCmp); + Arrays.sort(roles2, _roleCmp); + for (int i=0; i < size && res == 0; i++) { + res = _roleCmp.compare(roles1[i], roles2[i]); + } + return res; + } + + } + + /** + * Compares the scope of two scoped Topic Maps constructs. + */ + private final class ScopeComparator extends AbstractSetComparator<Topic> { + + @Override + int compareContent(Set<Topic> o1, Set<Topic> o2, int size) { + int res = 0 ; + Topic[] topics1 = o1.toArray(new Topic[size]); + Topic[] topics2 = o2.toArray(new Topic[size]); + Arrays.sort(topics1, _topicComparator); + Arrays.sort(topics2, _topicComparator); + for (int i=0; i < size && res == 0; i++) { + res = _topicComparator.compare(topics1[i], topics2[i]); + } + return res; + } + + } + + /** + * Comparator for sets of {@link org.tmapi.core.Locator}s. + */ + private final class LocatorSetComparator extends AbstractSetComparator<Locator> { + + @Override + int compareContent(Set<Locator> o1, Set<Locator> o2, int size) { + int res = 0; + Locator[] locs1 = o1.toArray(new Locator[size]); + Locator[] locs2 = o2.toArray(new Locator[size]); + Arrays.sort(locs1, _locComparator); + Arrays.sort(locs2, _locComparator); + for (int i=0; i < size && res == 0; i++) { + res = _locComparator.compare(locs1[i], locs2[i]); + } + return res; + } + } + + /** + * Compares {@link org.tmapi.core.Locator}s. + */ + private final class LocatorComparator implements Comparator<Locator> { + + public int compare(Locator o1, Locator o2) { + if (o1 == o2) { + return 0; + } + return _normalizeLocator(o1).compareTo(_normalizeLocator(o2)); + } + + } + + + /* + * Helper classes to treat type-instance relationships, modelled as property + * of a topic, as associations. + */ + + private final class TypeInstanceTopic implements Topic { + + private final Set<Locator> _sids; + + TypeInstanceTopic(Locator sid) { + _sids = Collections.singleton(sid); + } + + public Set<Locator> getSubjectIdentifiers() { + return _sids; + } + + public void addItemIdentifier(Locator arg0) { } + public void addSubjectIdentifier(Locator arg0) {} + public void addSubjectLocator(Locator arg0) {} + public void addType(Topic arg0) {} + public Set<Occurrence> getOccurrences() { return Collections.emptySet(); } + public Reifiable getReified() { return null; } + public Set<Role> getRolesPlayed() { return Collections.emptySet(); } + public Set<Locator> getSubjectLocators() { return Collections.emptySet(); } + public Set<Name> getNames() { return Collections.emptySet(); } + public Set<Topic> getTypes() { return null; } + public void mergeIn(Topic arg0) { } + public void remove() throws TopicInUseException { } + public void removeSubjectIdentifier(Locator arg0) { } + public void removeSubjectLocator(Locator arg0) { } + public void removeType(Topic arg0) { } + public String getId() { return null; } + public Set<Locator> getItemIdentifiers() { return Collections.emptySet(); } + public TopicMap getTopicMap() { return null; } + public void removeItemIdentifier(Locator arg0) { } + public Name createName(String value, Collection<Topic> scope) { return null; } + public Name createName(String value, Topic... scope) {return null;} + public Name createName(Topic type, String value, Collection<Topic> scope) { return null; } + public Name createName(Topic type, String value, Topic... scope) { return null; } + public Occurrence createOccurrence(Topic type, Locator value, Collection<Topic> scope) { return null;} + public Occurrence createOccurrence(Topic type, Locator value, Topic... scope) {return null;} + public Occurrence createOccurrence(Topic type, String value, Collection<Topic> scope) { return null; } + public Occurrence createOccurrence(Topic type, String value, Locator datatype, Collection<Topic> scope) { return null; } + public Occurrence createOccurrence(Topic type, String value, Locator datatype, Topic... scope) { return null; } + public Occurrence createOccurrence(Topic type, String value, Topic... scope) { return null; } + public Set<Name> getNames(Topic type) { return null; } + public Set<Occurrence> getOccurrences(Topic type) { return null;} + public TopicMap getParent() { return null; } + public Set<Role> getRolesPlayed(Topic type, Topic assocType) { return null; } + public Set<Role> getRolesPlayed(Topic type) { return null; } + + } + + /** + * Used to represent type-instance relationships which are modelled as + * [type] property of topics. + */ + private final class TypeInstanceAssociation implements Association { + + final Set<Role> _roles; + + TypeInstanceAssociation(Topic type, Topic instance) { + Role typeRole = new TypeInstanceRole(this, _type, type); + Role instanceRole = new TypeInstanceRole(this, _instance, instance); + _roles = new TypeInstanceRoleSet(typeRole, instanceRole); + } + + public Set<Role> getRoles() { + return _roles; + } + + public Topic getType() { + return _typeInstance; + } + + public Set<Topic> getRoleTypes() { return null; } + public Set<Role> getRoles(Topic type) { return null; } + public void setReifier(Topic reifier) { } + public void addItemIdentifier(Locator itemIdentifier) { } + public Set<Locator> getItemIdentifiers() { return Collections.emptySet(); } + public TopicMap getParent() { return null; } + public void removeItemIdentifier(Locator itemIdentifier) { } + public Role createRole(Topic arg0, Topic arg1) { return null; } + public Topic getReifier() { return null; } + public void remove() {} + public void setType(Topic arg0) {} + public void addTheme(Topic arg0) {} + public Set<Topic> getScope() { return Collections.emptySet(); } + public void removeTheme(Topic arg0) {} + public String getId() { return null; } + public TopicMap getTopicMap() { return null; } + } + + /** + * Immutable association role. + */ + private class TypeInstanceRole implements Role { + private final Topic _type; + private final Topic _player; + private final Association _parent; + + TypeInstanceRole(Association parent, Topic type, Topic player) { + _type = type; + _player = player; + _parent = parent; + List<Role> roles = _topic2Roles.get(player); + if (roles == null) { + roles = CollectionFactory.createList(); + _topic2Roles.put(player, roles); + } + roles.add(this); + } + + public Topic getType() { + return _type; + } + + public Topic getPlayer() { + return _player; + } + + public void setReifier(Topic reifier) { } + public void addItemIdentifier(Locator itemIdentifier) { } + public Set<Locator> getItemIdentifiers() { return Collections.emptySet(); } + public Association getParent() { return _parent; } + public void removeItemIdentifier(Locator itemIdentifier) { } + public Association getAssociation() { return _parent; } + public Topic getReifier() { return null; } + public void remove() {} + public void setPlayer(Topic arg0) {} + public void setType(Topic arg0) {} + public String getId() { return null; } + public TopicMap getTopicMap() { return null; } + } + + /** + * Immutable 'set' of two roles. + */ + private static class TypeInstanceRoleSet extends AbstractSet<Role> { + + private final Role _role1; + private final Role _role2; + + TypeInstanceRoleSet(Role role1, Role role2) { + _role1 = role1; + _role2 = role2; + } + + @Override + public Iterator<Role> iterator() { + return new TypeInstanceRoleSetIterator(); + } + + @Override + public int size() { + return 2; + } + + private class TypeInstanceRoleSetIterator implements Iterator<Role> { + + private int _idx; + + public boolean hasNext() { + return _idx < 2; + } + + public Role next() { + if (_idx > 1) { + throw new NoSuchElementException(); + } + return 0 == _idx++ ? _role1 : _role2; + } + + public void remove() { + new UnsupportedOperationException(); + } + } + } + +} Property changes on: tinytim-mio/trunk/src/main/java/org/tinytim/mio/CXTMWriter.java ___________________________________________________________________ Added: svn:keywords + Rev Date Id Added: svn:eol-style + native Added: tinytim-mio/trunk/src/main/java/org/tinytim/mio/ITopicMapReader.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/mio/ITopicMapReader.java (rev 0) +++ tinytim-mio/trunk/src/main/java/org/tinytim/mio/ITopicMapReader.java 2008-08-16 17:00:53 UTC (rev 128) @@ -0,0 +1,71 @@ +/* + * 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.IOException; +import java.io.InputStream; + +import org.xml.sax.InputSource; + +/** + * This interface represents a reader to deserialize a topic map from a source. + * <p> + * The reader is not meant to be reused and should be thrown away once one + * of the <tt>read</tt> methods were invoked. + * </p> + * + * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a> + * @version $Rev:$ - $Date:$ + */ +public interface ITopicMapReader { + + /** + * Reads a topic map from <tt>source</tt> using the provided <tt>docIRI</tt> + * to resolve IRIs against. + * + * @param source The source to read the serialized topic map from. + * @param docIRI The IRI which is used to resolve IRIs against. + * @throws IOException If an error occurs. + */ + public void read(InputSource source, String docIRI) throws IOException; + + /** + * Reads a topic map from <tt>source</tt> using the provided <tt>docIRI</tt> + * to resolve IRIs against. + * + * @param source The file to read the serialized topic map from. + * @param docIRI The IRI which is used to resolve IRIs against. + * @throws IOException If an error occurs. + */ + public void read(File source, String docIRI)throws IOException; + + /** + * Reads a topic map from <tt>source</tt> using the provided <tt>docIRI</tt> + * to resolve IRIs against. + * + * @param source The stream to read the serialized topic map from. + * @param docIRI The IRI which is used to resolve IRIs against. + * @throws IOException If an error occurs. + */ + public void read(InputStream source, String docIRI)throws IOException; + +} Property changes on: tinytim-mio/trunk/src/main/java/org/tinytim/mio/ITopicMapReader.java ___________________________________________________________________ Added: svn:keywords + Rev Date Id Added: svn:eol-style + native Added: tinytim-mio/trunk/src/main/java/org/tinytim/mio/ITopicMapWriter.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/mio/ITopicMapWriter.java ... [truncated message content] |