From: <lh...@us...> - 2009-03-06 11:49:47
|
Revision: 279 http://tinytim.svn.sourceforge.net/tinytim/?rev=279&view=rev Author: lheuer Date: 2009-03-06 11:49:34 +0000 (Fri, 06 Mar 2009) Log Message: ----------- - Variant reifier is now part of the output - Java Docs Modified Paths: -------------- tinytim-mio/trunk/src/main/java/org/tinytim/mio/CTMTopicMapWriter.java Modified: tinytim-mio/trunk/src/main/java/org/tinytim/mio/CTMTopicMapWriter.java =================================================================== --- tinytim-mio/trunk/src/main/java/org/tinytim/mio/CTMTopicMapWriter.java 2009-03-05 15:34:47 UTC (rev 278) +++ tinytim-mio/trunk/src/main/java/org/tinytim/mio/CTMTopicMapWriter.java 2009-03-06 11:49:34 UTC (rev 279) @@ -62,7 +62,7 @@ * representation. * * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a> - * @version $Rev:$ - $Date:$ + * @version $Rev$ - $Date$ */ public class CTMTopicMapWriter implements TopicMapWriter { @@ -70,11 +70,11 @@ private static final Pattern _ID_PATTERN = Pattern.compile("[A-Za-z_](\\.*[\\-A-Za-z_0-9])*"); private final Writer _out; -// private final String _baseIRI; + private final String _baseIRI; private final String _encoding; private Topic _defaultNameType; //TODO: Add setters/getters - private boolean _exportIIDs = false; + private boolean _exportIIDs = true; private boolean _prettify = true; private String _title; private String _author; @@ -92,20 +92,20 @@ private final Map<Topic, TopicReference> _topic2Reference; - public CTMTopicMapWriter(final OutputStream out) throws IOException { - this(out, "utf-8"); + public CTMTopicMapWriter(final OutputStream out, final String baseIRI) throws IOException { + this(out, baseIRI, "utf-8"); } - public CTMTopicMapWriter(final OutputStream out, final String encoding) throws IOException { - this(new OutputStreamWriter(out, encoding), encoding); + public CTMTopicMapWriter(final OutputStream out, final String baseIRI, final String encoding) throws IOException { + this(new OutputStreamWriter(out, encoding), baseIRI, encoding); } - private CTMTopicMapWriter(final Writer writer, final String encoding) { + private CTMTopicMapWriter(final Writer writer, final String baseIRI, final String encoding) { _out = writer; -// if (baseIRI == null) { -// throw new IllegalArgumentException("The base IRI must not be null"); -// } -// _baseIRI = baseIRI; + if (baseIRI == null) { + throw new IllegalArgumentException("The base IRI must not be null"); + } + _baseIRI = baseIRI; if (encoding == null) { throw new IllegalArgumentException("The encoding must not be null"); } @@ -212,21 +212,10 @@ _newline(); _out.write("%version 1.0"); _writeFileHeader(); - _out.write(")#"); + _out.write("%prefix xsd <" + Namespace.XSD + "> # Default prefix"); _newline(); - _newline(); - _writeSection("Prefixes"); - _out.write("%prefix xsd <" + Namespace.XSD + ">"); - _newline(); Collection<Topic> topics = new ArrayList<Topic>(topicMap.getTopics()); - final boolean removeDefaultNameType = _defaultNameType != null - && _defaultNameType.getSubjectIdentifiers().size() == 1 - && _defaultNameType.getSubjectLocators().size() == 0 - && _defaultNameType.getTypes().size() == 0 - && _defaultNameType.getNames().size() == 0 - && _defaultNameType.getOccurrences().size() == 0 - && _defaultNameType.getRolesPlayed().size() == 0 - && _defaultNameType.getReified() == null; + final boolean removeDefaultNameType = _shouldStandardTopicExported(_defaultNameType); if (removeDefaultNameType) { topics.remove(_defaultNameType); } @@ -273,8 +262,26 @@ _out.write("# Thanks for using tinyTiM -- http://tinytim.sourceforge.net/ :)"); _newline(); _out.flush(); + _topic2Reference.clear(); } + private boolean _shouldStandardTopicExported(Topic topic) { + return topic != null + && topic.getSubjectIdentifiers().size() == 1 + && topic.getSubjectLocators().size() == 0 + && topic.getTypes().size() == 0 + && topic.getNames().size() == 0 + && topic.getOccurrences().size() == 0 + && topic.getRolesPlayed().size() == 0 + && topic.getReified() == null; + } + + /** + * Writes the header comment with the optional title, author, license etc. + * information. + * + * @throws IOException In case of an error. + */ private void _writeFileHeader() throws IOException { _newline(); _newline(); @@ -301,16 +308,19 @@ _out.write("Generated by tinyTiM -- http://tinytim.sourceforge.net/"); _newline(); _newline(); + _out.write(")#"); + _newline(); + _newline(); } /** * If <tt>topics</tt> is not empty, the topics will be removed from * <tt>allTopics</tt> and written out under the specified section <tt>title</tt>. * - * @param topics - * @param allTopics - * @param title - * @throws IOException + * @param topics The topics to serialize. + * @param allTopics A collection of topics where the <tt>topics</tt> should be removed from. + * @param title The title of the ontology section. + * @throws IOException In case of an error. */ private void _writeOntologyTypes(Collection<Topic> topics, Collection<Topic> allTopics, String title) throws IOException { if (topics.isEmpty()) { @@ -322,10 +332,10 @@ } /** - * Sorts the specified collection and serializes the topics. + * Sorts the specified collection of topics and serializes it. * * @param topics An unordered collection of topics. - * @throws IOException If an error occurs. + * @throws IOException In case of an error. */ private void _writeTopics(Collection<Topic> topics) throws IOException { Topic[] topicArray = topics.toArray(new Topic[topics.size()]); @@ -335,15 +345,16 @@ } } + /** + * Serializes a the specified topic. + * + * @param topic The topic to serialize. + * @throws IOException In case of an error. + */ private void _writeTopic(Topic topic) throws IOException { - final TopicReference mainIdentity = _getTopicReference(topic); -// if ((ref.type == TopicReference.ID -// || ref.type == TopicReference.IID) -// && _hasNoCharacteristics(topic)) { -// return; -// } _newline(); boolean wantSemicolon = false; + final TopicReference mainIdentity = _getTopicReference(topic); _writeTopicRef(mainIdentity); _out.write(' '); for (Topic type: topic.getTypes()) { @@ -383,17 +394,10 @@ if (wantSemicolon) { _out.write(' '); } - _out.write("."); + _out.write('.'); _newline(); } -// private boolean _hasNoCharacteristics(Topic topic) { -// return topic.getTypes().isEmpty() -// && topic.getNames().isEmpty() -// && topic.getOccurrences().isEmpty() -// && !(_exportIIDs || topic.getItemIdentifiers().isEmpty()); -// } - private TopicReference[] _getSubjectIdentifiers(Topic topic) { return _getLocators(topic, TopicReference.SID, topic.getSubjectIdentifiers()); } @@ -432,6 +436,12 @@ return refArray; } + /** + * Returns a sorted array of names for the specified topic. + * + * @param topic The topic to retrieve the names from. + * @return A sorted array of names. + */ private Name[] _getNames(Topic topic) { Set<Name> names_ = topic.getNames(); Name[] names = names_.toArray(new Name[names_.size()]); @@ -440,10 +450,10 @@ } /** - * + * Returns a sorted array of occurrences for the specified topic. * - * @param topic - * @return + * @param topic The topic to retrieve the occurrences from. + * @return A sorted array of occurrences. */ private Occurrence[] _getOccurrences(Topic topic) { Set<Occurrence> occs_ = topic.getOccurrences(); @@ -452,6 +462,13 @@ return occs; } + /** + * + * + * @param type + * @param wantSemicolon Indicates if a semicolon should be written. + * @throws IOException In case of an error. + */ private void _writeTypeInstance(Topic type, boolean wantSemicolon) throws IOException { _writeSemicolon(wantSemicolon); _out.write("isa "); @@ -464,6 +481,13 @@ // _writeTopicRef(supertype); // } + /** + * Serializes the specified occurrence. + * + * @param occ The occurrence to serialize + * @param wantSemicolon Indicates if a semicolon should be written. + * @throws IOException In case of an error. + */ private void _writeOccurrence(IOccurrence occ, boolean wantSemicolon) throws IOException { _writeSemicolon(wantSemicolon); _writeTopicRef(occ.getType()); @@ -473,6 +497,13 @@ _writeReifier(occ); } + /** + * Serializes the specified name. + * + * @param name The name to serialize. + * @param wantSemicolon Indicates if a semicolon should be written. + * @throws IOException In case of an error. + */ private void _writeName(IName name, boolean wantSemicolon) throws IOException { _writeSemicolon(wantSemicolon); _out.write("- "); @@ -491,27 +522,45 @@ } } + /** + * Serializes the specified variant. + * + * @param variant The variant to serialize. + * @throws IOException In case of an error. + */ private void _writeVariant(IVariant variant) throws IOException { _out.write(" ("); _writeLiteral(variant.getLiteral()); _writeScope(variant); + _writeReifier(variant); _out.write(')'); } + /** + * Serializes the specified association. + * + * @param assoc The association to serialize. + * @throws IOException In case of an error. + */ private void _writeAssociation(Association assoc) throws IOException { _newline(); _writeTopicRef(assoc.getType()); _out.write('('); Role[] roles = assoc.getRoles().toArray(new Role[0]); Arrays.sort(roles, _roleComparator); + boolean wantComma = false; for (Role role: roles) { + if (wantComma) { + _out.write(", "); + } _writeTopicRef(role.getType()); _out.write(": "); _writeTopicRef(role.getPlayer()); if (role.getReifier() != null) { - _out.write(" #( If you found a reason why a role should be reified, write us )# "); _writeReifier(role); + _out.write(" #( Great, you found a reason why a role should be reified, please tell us about it :) )# "); } + wantComma = true; } _out.write(')'); _writeScope((IScoped) assoc); @@ -519,6 +568,17 @@ _newline(); } + /** + * Writes a semicolon and a newline character iff <tt>wantSemicolon</tt> is + * <tt>true</tt>. + * <p> + * If a semicolon is written, optional whitespaces are written to ident the + * next statement. + * </p> + * + * @param wantSemicolon Indicates if a semicolon should be written. + * @throws IOException In case of an error. + */ private void _writeSemicolon(boolean wantSemicolon) throws IOException { if (wantSemicolon) { _out.write(';'); @@ -530,10 +590,11 @@ } /** - * + * Serializes the scope of the scoped construct if the scope is not + * unconstrained. * - * @param scoped - * @throws IOException + * @param scoped The scoped construct from which the scope should be written. + * @throws IOException In case of an error. */ private void _writeScope(IScoped scoped) throws IOException { IScope scope = scoped.getScopeObject(); @@ -553,19 +614,83 @@ } /** + * Writes the reifier if <tt>reifiable</tt> is reified. + * + * @param reifiable The reifiable construct. + * @throws IOException If an error occurs. + */ + private void _writeReifier(Reifiable reifiable) throws IOException { + Topic reifier = reifiable.getReifier(); + if (reifier == null) { + return; + } + _out.write(" ~ "); + _writeTopicRef(reifier); + } + + /** + * Writes a literal. * + * If the datatype is xsd:anyURI or xsd:string, the datatype is omitted. + * If the datatype is natively supported by CTM (like xsd:integer, xsd:decimal) + * the quotes and the datatype are omitted. * + * @param lit The literal to serialize. + * @throws IOException In case of an error. + */ + private void _writeLiteral(ILiteral lit) throws IOException { + final Locator datatype = lit.getDatatype(); + final String value = lit.getValue(); + if (XSD.ANY_URI.equals(datatype)) { + _writeLocator(value); + } + else if (XSD.STRING.equals(datatype)) { + _writeString(value); + } + else if (_isNativelySupported(lit)) { + _out.write(value); + } + else { + _writeString(value); + _out.write("^^"); + String datatypeIRI = datatype.toExternalForm(); + if (datatypeIRI.startsWith(Namespace.XSD)) { + _out.write("xsd:"); + _out.write(datatypeIRI.substring(datatypeIRI.lastIndexOf('#')+1)); + } + else { + _writeLocator(datatypeIRI); + } + } + } + + /** + * + * * @param topic - * @throws IOException + * @throws IOException In case of an error. */ private void _writeTopicRef(Topic topic) throws IOException { _writeTopicRef(_getTopicReference(topic)); } + /** + * + * + * @param topicRef + * @throws IOException In case of an error. + */ private void _writeTopicRef(TopicReference topicRef) throws IOException { _writeTopicRef(topicRef, false); } + /** + * + * + * @param topicRef + * @param wantSemicolon Indicates if a semicolon should be written. + * @throws IOException In case of an error. + */ private void _writeTopicRef(TopicReference topicRef, boolean wantSemicolon) throws IOException { _writeSemicolon(wantSemicolon); switch (topicRef.type) { @@ -586,10 +711,24 @@ _writeLocator(topicRef.reference); } + /** + * + * + * @param string + * @throws IOException + */ private void _writeString(String string) throws IOException { - //TODO: Escape _out.write('"'); - _out.write(string); + char[] ch = string.toCharArray(); + for (int i=0; i<ch.length; i++) { + switch (ch[i]) { + case '"': + case '\\': + _out.write("\\"); + default: + _out.write(ch[i]); + } + } _out.write('"'); } @@ -614,7 +753,7 @@ if (ref == null) { if (topic.getItemIdentifiers().size() == 1) { final String iid = topic.getItemIdentifiers().iterator().next().toExternalForm(); - int idx = iid.lastIndexOf('#'); + int idx = !iid.startsWith(_baseIRI) ? -1 : iid.lastIndexOf('#'); if (idx > 0) { String id = iid.substring(idx + 1); ref = _isValidId(id) ? TopicReference.createId(id) @@ -652,42 +791,6 @@ return _ID_PATTERN.matcher(id).matches(); } - /** - * Writes a literal. - * - * If the datatype is xsd:anyURI or xsd:string, the datatype is omitted. - * If the datatype is natively supported by CTM (like xsd:integer, xsd:decimal) - * the quotes and the datatype are omitted. - * - * @param lit The literal to serialize. - * @throws IOException In case of an error. - */ - private void _writeLiteral(ILiteral lit) throws IOException { - final Locator datatype = lit.getDatatype(); - final String value = lit.getValue(); - if (XSD.ANY_URI.equals(datatype)) { - _writeLocator(value); - } - else if (!XSD.STRING.equals(datatype) - && _isNativelySupported(lit)) { - _out.write(value); - } - else { - _writeString(value); - if (!XSD.STRING.equals(datatype)) { - _out.write("^^"); - String datatypeIRI = datatype.toExternalForm(); - if (datatypeIRI.startsWith(Namespace.XSD)) { - _out.write("xsd:"); - _out.write(datatypeIRI.substring(datatypeIRI.lastIndexOf('#')+1)); - } - else { - _writeLocator(datatypeIRI); - } - } - } - } - private boolean _isNativelySupported(ILiteral literal) { Locator datatype = literal.getDatatype(); return XSD.STRING.equals(datatype) @@ -701,21 +804,6 @@ || "-INF".equals(literal.getValue())); } - /** - * Writes the reifier if <tt>reifiable</tt> is reified. - * - * @param reifiable The reifiable construct. - * @throws IOException If an error occurs. - */ - private void _writeReifier(Reifiable reifiable) throws IOException { - Topic reifier = reifiable.getReifier(); - if (reifier == null) { - return; - } - _out.write(" ~ "); - _writeTopicRef(reifier); - } - private void _newline() throws IOException { _out.write('\n'); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |