/*
* Copyright (c) 2013-2015 Josef Hardi <josef.hardi@gmail.com>
*
* 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 com.obidea.semantika.mapping.parser.termalxml;
import static com.obidea.semantika.mapping.parser.termalxml.TermalVocabulary.COMMENT;
import static com.obidea.semantika.mapping.parser.termalxml.TermalVocabulary.LOGICAL_TABLE;
import static com.obidea.semantika.mapping.parser.termalxml.TermalVocabulary.MAPPING;
import static com.obidea.semantika.mapping.parser.termalxml.TermalVocabulary.PREDICATE_OBJECT_MAP;
import static com.obidea.semantika.mapping.parser.termalxml.TermalVocabulary.PREFIX;
import static com.obidea.semantika.mapping.parser.termalxml.TermalVocabulary.PROGRAM;
import static com.obidea.semantika.mapping.parser.termalxml.TermalVocabulary.SUBJECT_MAP;
import static com.obidea.semantika.mapping.parser.termalxml.TermalVocabulary.URI_TEMPLATE;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.obidea.semantika.database.IDatabaseMetadata;
import com.obidea.semantika.expression.ExpressionObjectFactory;
import com.obidea.semantika.mapping.IMappingSet;
import com.obidea.semantika.mapping.IMetaModel;
import com.obidea.semantika.mapping.MappingObjectFactory;
import com.obidea.semantika.mapping.MutableMappingSet;
import com.obidea.semantika.mapping.exception.MappingParserException;
import com.obidea.semantika.mapping.parser.MappingParserConfiguration;
import com.obidea.semantika.ontology.IOntology;
import com.obidea.semantika.ontology.owlapi.AbstractOwlOntology;
import com.obidea.semantika.util.StringUtils;
public class TermalXmlParserHandler extends DefaultHandler
{
private MutableMappingSet mMappingSet;
private IDatabaseMetadata mDatabaseMetadata;
private AbstractOwlOntology mOntology;
private MappingParserConfiguration mConfiguration;
private Locator mLocator;
private Map<String, String> mPrefixMapper;
private Map<String, String> mUriTemplateMapper;
private Map<String, AbstractTermalElementHandlerFactory> mHandlerMap;
private Stack<AbstractTermalElementHandler> mHandlerStack;
public TermalXmlParserHandler(IMappingSet mappingSet, IMetaModel metaModel, MappingParserConfiguration configuration) throws MappingParserException
{
mMappingSet = (MutableMappingSet) mappingSet;
mConfiguration = configuration;
mDatabaseMetadata = metaModel.getDatabaseMetadata();
mOntology = owlOntology(metaModel.getOntology());
mPrefixMapper = new HashMap<String, String>();
mUriTemplateMapper = new HashMap<String, String>();
mHandlerMap = new HashMap<String, AbstractTermalElementHandlerFactory>();
mHandlerStack = new Stack<AbstractTermalElementHandler>();
addFactory(new AbstractTermalElementHandlerFactory(PROGRAM)
{
@Override
public AbstractTermalElementHandler createElementHandler(TermalXmlParserHandler handler) {
return new ProgramElementHandler(handler);
}
});
addFactory(new AbstractTermalElementHandlerFactory(MAPPING)
{
@Override
public AbstractTermalElementHandler createElementHandler(TermalXmlParserHandler handler) {
return new MappingElementHandler(handler);
}
});
addFactory(new AbstractTermalElementHandlerFactory(LOGICAL_TABLE)
{
@Override
public AbstractTermalElementHandler createElementHandler(TermalXmlParserHandler handler) {
return new LogicalTableElementHandler(handler);
}
});
addFactory(new AbstractTermalElementHandlerFactory(SUBJECT_MAP)
{
@Override
public AbstractTermalElementHandler createElementHandler(TermalXmlParserHandler handler) {
return new SubjectMapElementHandler(handler);
}
});
addFactory(new AbstractTermalElementHandlerFactory(PREDICATE_OBJECT_MAP)
{
@Override
public AbstractTermalElementHandler createElementHandler(TermalXmlParserHandler handler) {
return new PredicateObjectMapElementHandler(handler);
}
});
}
private static AbstractOwlOntology owlOntology(IOntology ontology) throws MappingParserException
{
if (!(ontology instanceof AbstractOwlOntology)) {
throw new MappingParserException("Mapping parser requires OWL ontology object"); //$NON-NLS-1$
}
return (AbstractOwlOntology) ontology;
}
public boolean isStrictParsing()
{
return mConfiguration.isStrictParsing();
}
public IDatabaseMetadata getDatabaseMetadata()
{
return mDatabaseMetadata;
}
public AbstractOwlOntology getOntology()
{
return mOntology;
}
public MutableMappingSet getMappingSet()
{
return mMappingSet;
}
public ExpressionObjectFactory getExpressionObjectFactory()
{
return ExpressionObjectFactory.getInstance();
}
public MappingObjectFactory getMappingObjectFactory()
{
return MappingObjectFactory.getInstance();
}
@Override
public void setDocumentLocator(Locator locator)
{
super.setDocumentLocator(locator);
mLocator = locator;
}
public int getLineNumber()
{
if (mLocator != null) {
return mLocator.getLineNumber();
}
else {
return -1;
}
}
public int getColumnNumber()
{
if (mLocator != null) {
return mLocator.getColumnNumber();
}
else {
return -1;
}
}
public Map<String, String> getPrefixMapper()
{
return mPrefixMapper;
}
public Map<String, String> getUriTemplateMapper()
{
return mUriTemplateMapper;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
try {
if (localName.equals(COMMENT.getLocalName())) {
return; // skip it
}
// Collect the prefix declarations
if (localName.equals(PREFIX.getLocalName())) {
String prefixName = attributes.getValue(TermalVocabulary.NAME.getQName());
String namespaceUri = attributes.getValue(TermalVocabulary.NAMESPACE.getQName());
if (!StringUtils.isEmpty(namespaceUri)) {
mPrefixMapper.put(prefixName, namespaceUri);
}
return;
}
// Collect the identifier-template declarations
if (localName.equals(URI_TEMPLATE.getLocalName())) {
String templateName = attributes.getValue(TermalVocabulary.NAME.getQName());
String templateString = attributes.getValue(TermalVocabulary.VALUE.getQName());
if (!StringUtils.isEmpty(templateName) && !StringUtils.isEmpty(templateString)) {
mUriTemplateMapper.put(templateName, templateString);
}
return;
}
AbstractTermalElementHandlerFactory handlerFactory = mHandlerMap.get(localName);
if (handlerFactory != null) {
AbstractTermalElementHandler handler = handlerFactory.createElementHandler(this);
if (!mHandlerStack.isEmpty()) {
AbstractTermalElementHandler topElement = mHandlerStack.peek();
handler.setParentElement(topElement);
}
mHandlerStack.push(handler);
for (int i = 0; i < attributes.getLength(); i++) {
handler.attribute(attributes.getQName(i), attributes.getValue(i));
}
handler.startElement(localName);
}
else {
throw new UnknownXmlElementException("Unknown XML element \"<" + localName + ">\"", //$NON-NLS-1$ //$NON-NLS-2$
getLineNumber(), getColumnNumber());
}
}
catch (MappingParserException e) {
throw new SAXException(e);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
try {
if (localName.equals(PREFIX.getLocalName())) {
return; // ignore this tag
}
if (localName.equals(URI_TEMPLATE.getLocalName())) {
return; // ignore this tag
}
if (localName.equals(COMMENT.getLocalName())) {
return; // ignore this tag
}
if (!mHandlerStack.isEmpty()) {
AbstractTermalElementHandler handler = mHandlerStack.pop();
handler.endElement();
}
}
catch (MappingParserException e) {
throw new SAXException(e);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
try {
if (!mHandlerStack.isEmpty()) {
AbstractTermalElementHandler handler = mHandlerStack.peek();
String localName = handler.getElementName();
if (localName.equals(LOGICAL_TABLE.getLocalName())) {
handler.characters(ch, start, length);
}
}
}
catch (MappingParserException e) {
throw new SAXException(e);
}
}
private void addFactory(AbstractTermalElementHandlerFactory factory, String... legacyElementNames)
{
mHandlerMap.put(factory.getElementName(), factory);
for (String elementName : legacyElementNames) {
mHandlerMap.put(elementName, factory);
}
}
}