/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
package net.ontopia.topicmaps.utils.ltm;
import antlr.RecognitionException;
import antlr.TokenStreamException;
import antlr.TokenStreamIOException;
import antlr.TokenStreamRecognitionException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.MalformedURLException;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.infoset.impl.basic.URILocator;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.topicmaps.core.TopicMapStoreFactoryIF;
import net.ontopia.topicmaps.core.TopicMapStoreIF;
import net.ontopia.topicmaps.impl.utils.AbstractTopicMapReader;
import net.ontopia.topicmaps.utils.ClassInstanceUtils;
import net.ontopia.utils.OntopiaRuntimeException;
import net.ontopia.utils.URIUtils;
import org.xml.sax.InputSource;
/**
* PUBLIC: This TopicMapReader can read topic maps from LTM files.
* @since 1.1
*/
public class LTMTopicMapReader extends AbstractTopicMapReader {
/**
* PUBLIC: Creates a topic map reader bound to the URL given in the
* arguments.
* @param url The URL of the LTM file.
*/
public LTMTopicMapReader(String url) throws MalformedURLException {
this(new InputSource(new URILocator(url).getExternalForm()),
new URILocator(url));
}
/**
* PUBLIC: Creates a topic map reader bound to the reader given in
* the arguments.
* @param reader The reader from which the topic map is to be read.
* @param base_address The base address to be used for resolving
* relative references.
*/
public LTMTopicMapReader(Reader reader, LocatorIF base_address) {
this(new InputSource(reader), base_address);
}
/**
* PUBLIC: Creates a topic map reader bound to the input stream
* given in the arguments.
* @param stream The input stream from which the topic map is to be read.
* @param base_address The base address to be used for resolving
* relative references.
*/
public LTMTopicMapReader(InputStream stream, LocatorIF base_address) {
this(new InputSource(stream), base_address);
}
/**
* PUBLIC: Creates a topic map reader bound to the file given in the
* arguments.
* @param file The file object from which to read the topic map.
*/
public LTMTopicMapReader(File file) throws IOException {
try {
if (!file.exists())
throw new FileNotFoundException(file.toString());
this.base_address = new URILocator(URIUtils.toURL(file));
this.source = new InputSource(base_address.getExternalForm());
}
catch (java.net.MalformedURLException e) {
throw new OntopiaRuntimeException("Internal error. File " + file + " had "
+ "invalid URL representation.");
}
}
/**
* PUBLIC: Creates a topic map reader bound to the input source
* given in the arguments.
* @param source The SAX input source from which the topic map is to be read.
* @param base_address The base address to be used for resolving
* relative references.
*/
public LTMTopicMapReader(InputSource source, LocatorIF base_address) {
this.source = source;
this.base_address = base_address;
}
/**
* PUBLIC: Creates a topic map reader bound to the URL given in the
* arguments.
* @param url The URL of the topic map document.
* @since 2.0
*/
public LTMTopicMapReader(LocatorIF url) {
this(new InputSource(url.getExternalForm()), url);
}
// ==== READER IMPLEMENTATION ====
protected TopicMapIF read(TopicMapStoreFactoryIF store_factory)
throws IOException {
TopicMapStoreIF store = store_factory.createStore();
TopicMapIF topicmap = store.getTopicMap();
// Set base address on in-memory store
if ((store instanceof net.ontopia.topicmaps.impl.utils.AbstractTopicMapStore) &&
store.getBaseAddress() == null)
((net.ontopia.topicmaps.impl.utils.AbstractTopicMapStore)store)
.setBaseAddress(getBaseAddress());
// Parse!
Reader reader = null;
try {
reader = makeReader(source, new LTMEncodingSniffer());
LTMLexer lexer = new LTMLexer(reader);
LTMParser parser = new LTMParser(lexer);
parser.setBase(getBaseAddress());
parser.setTopicMap(topicmap);
parser.init();
parser.topicmap();
reader.close();
} catch (AntlrWrapException ex) {
throw (IOException) ex.getException();
} catch (RecognitionException ex) {
throw new IOException("Lexical error at " + getBaseAddress().getAddress()
+ ":" + ex.line + ":" + ex.column + ": "+ ex.getMessage());
} catch (TokenStreamRecognitionException e) {
RecognitionException ex = e.recog;
throw new IOException("Lexical error at " + getBaseAddress().getAddress()
+ ":" + ex.line + ":" + ex.column + ": "+ ex.getMessage());
} catch (TokenStreamIOException ex) {
throw ex.io;
} catch (TokenStreamException ex) {
throw new IOException("Lexical error: " + ex.getMessage());
} catch (java.io.CharConversionException e) {
throw new IOException("Problem decoding character encoding."
+ "Did you declare the right encoding?");
} finally {
if (reader != null)
reader.close();
}
// Process class-instance associations
ClassInstanceUtils.resolveAssociations1(topicmap);
return topicmap;
}
}