org.betaconceptframework.astroboa.engine.definition.xsom.CmsEntityResolverForValidation.java Source code

Java tutorial

Introduction

Here is the source code for org.betaconceptframework.astroboa.engine.definition.xsom.CmsEntityResolverForValidation.java

Source

/*
 * Copyright (C) 2005-2012 BetaCONCEPT Limited
 *
 * This file is part of Astroboa.
 *
 * Astroboa is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Astroboa 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Astroboa.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.betaconceptframework.astroboa.engine.definition.xsom;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.betaconceptframework.astroboa.util.CmsConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Used to resolve imports from definition xsd files
 * and mainly to provide the right xsd definition file
 * when validating definition files. 
 * 
 * This resolver must have all definitions inside a map.
 * 
 * 
 * @author Gregory Chomatas (gchomatas@betaconcept.com)
 * @author Savvas Triantafyllou (striantafyllou@betaconcept.com)
 * 
 */
public class CmsEntityResolverForValidation implements EntityResolver {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private Map<String, String> definitionSources = new HashMap<String, String>();

    private List<InputStream> openStreams = new ArrayList<InputStream>();

    private EntityResolverForBuiltInSchemas entityResolverForBuiltInSchemas;

    @Override
    /**
     * According to XSOM library 
     * By setting EntityResolver to XSOMParser, you can redirect <xs:include>s and <xs:import>s to different resources.
     * For imports, the namespace URI of the target schema is passed as the public ID,
     * and the absolutized value of the schemaLocation attribute will be passed as the system ID. 
     */
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {

        if (systemId != null) {

            try {

                String schemaFilename = systemId;

                //We are only interested in file name
                if (schemaFilename.contains(File.separator)) {
                    schemaFilename = StringUtils.substringAfterLast(systemId, File.separator);
                } else if (!File.separator.equals(schemaFilename.contains(CmsConstants.FORWARD_SLASH))
                        && schemaFilename.contains(CmsConstants.FORWARD_SLASH)) {
                    //Perform the extra check in case File.separator is not '/' and it 
                    //does not exist in the schema filename.
                    //This case usually appears in a windows environment.
                    schemaFilename = StringUtils.substringAfterLast(systemId, CmsConstants.FORWARD_SLASH);
                }

                if (definitionSources.containsKey(schemaFilename)) {
                    InputStream inputStream = IOUtils.toInputStream(definitionSources.get(schemaFilename), "UTF-8");
                    openStreams.add(inputStream);

                    InputSource inputSource = new InputSource(inputStream);

                    inputSource.setPublicId(publicId);
                    inputSource.setSystemId(schemaFilename);

                    return inputSource;
                }

                return entityResolverForBuiltInSchemas.resolveEntity(publicId, systemId);

            } catch (Exception e) {
                throw new IOException(e);
            }
        }

        //Returning null allow XSD Parser to continue with default behavior
        //and will try to resolve entity using its own implementation
        return null;
    }

    public void clearDefinitions() {

        if (!openStreams.isEmpty()) {
            for (InputStream openStream : openStreams) {
                IOUtils.closeQuietly(openStream);
            }
        }

        definitionSources.clear();
        openStreams.clear();
    }

    public void addExternalDefinition(File definitionFile) throws IOException {
        if (definitionFile != null) {
            definitionSources.put(definitionFile.getName(), FileUtils.readFileToString(definitionFile, "UTF-8"));
        }
    }

    public void addDefinition(String definitionName, String definition) throws IOException {
        if (definitionName != null && definition != null) {

            if (definitionName.contains(CmsConstants.FORWARD_SLASH)) {
                definitionSources.put(StringUtils.substringAfterLast(definitionName, CmsConstants.FORWARD_SLASH),
                        definition);
            } else {
                definitionSources.put(definitionName, definition);
            }
        }

    }

    public Map<String, String> getDefinitionSources() {
        return definitionSources;
    }

    public void setBuiltInEntityResolver(EntityResolverForBuiltInSchemas entityResolverForBuiltInSchemas) {
        this.entityResolverForBuiltInSchemas = entityResolverForBuiltInSchemas;

    }
}