ar.com.tadp.xml.rinzo.core.resources.validation.XMLStringValidator.java Source code

Java tutorial

Introduction

Here is the source code for ar.com.tadp.xml.rinzo.core.resources.validation.XMLStringValidator.java

Source

/*****************************************************************************
 * This file is part of Rinzo
 *
 * Author: Claudio Cancinos
 * WWW: https://sourceforge.net/projects/editorxml
 * Copyright (C): 2008, Claudio Cancinos
 * 
 * This program 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 2
 * of the License, or (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; If not, see <http://www.gnu.org/licenses/>
 ****************************************************************************/
package ar.com.tadp.xml.rinzo.core.resources.validation;

import java.io.StringReader;
import java.net.URI;
import java.util.Collection;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.apache.commons.lang.StringUtils;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import ar.com.tadp.xml.rinzo.XMLEditorPlugin;
import ar.com.tadp.xml.rinzo.core.RinzoXMLEditor;
import ar.com.tadp.xml.rinzo.core.resources.cache.DocumentCache;
import ar.com.tadp.xml.rinzo.core.resources.cache.DocumentStructureDeclaration;
import ar.com.tadp.xml.rinzo.core.utils.FileUtils;

/**
 * Validates if the content of an editor is a well formed XML file.
 * If the file defines a DTD or XSD the file is validated against it.
 *  
 * @author ccancinos
 */
public class XMLStringValidator implements XmlValidator {
    private MarkersErrorHandler errorHandler;
    private ExternalResolver resolver = new ExternalResolver();

    public void validate(RinzoXMLEditor editor) {
        this.errorHandler = new MarkersErrorHandler(editor);
        this.errorHandler.setFile(editor.getEditorInputIFile());

        String fileName = editor.getFileName();
        String fileContent = editor.getSourceViewerEditor().getDocument().get();
        if (!StringUtils.isEmpty(fileContent.trim())) {
            Collection<DocumentStructureDeclaration> schemaDefinitions = editor.getModel().getSchemaDefinitions();
            if (schemaDefinitions != null && !schemaDefinitions.isEmpty()) {
                this.saxSchemaValidate(fileName, fileContent, schemaDefinitions);
            } else {
                DocumentStructureDeclaration dtdDefinition = editor.getModel().getDTDDefinition();
                if (dtdDefinition != null) {
                    this.saxDTDValidate(fileName, fileContent, dtdDefinition);
                } else {
                    this.plainTextValidate(fileName, fileContent);
                }
            }
        }
    }

    private void plainTextValidate(String fileName, String fileContent) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(true);
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            builder.setErrorHandler(this.errorHandler);
            builder.parse(new InputSource(new StringReader(fileContent)));
        } catch (Exception e) {
            //Do nothing because the errorHandler informs the error
        }
    }

    private void saxDTDValidate(String fileName, String fileContent,
            DocumentStructureDeclaration structureDeclaration) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(true);
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            URI resolverURI = FileUtils.resolveURI(fileName, structureDeclaration.getSystemId());
            if (resolverURI != null) {
                this.resolver.setBaseURL(fileName);
                this.resolver.setSystemId(structureDeclaration.getSystemId());
                builder.setEntityResolver(this.resolver);
            }
            builder.setErrorHandler(this.errorHandler);
            builder.parse(new InputSource(new StringReader(fileContent)));
        } catch (Exception e) {
            //Do nothing because the errorHandler informs the error
        }
    }

    private void saxSchemaValidate(String fileName, String fileContent,
            Collection<DocumentStructureDeclaration> schemaDefinitions) {
        try {
            Validator validator;
            Map<Collection<DocumentStructureDeclaration>, Validator> schemaValidatorsCache = XMLEditorPlugin
                    .getDefault().getSchemaValidatorsCache();

            validator = schemaValidatorsCache.get(schemaDefinitions);
            if (validator == null) {
                StreamSource[] sources = new StreamSource[schemaDefinitions.size()];
                int pos = 0;
                Map<String, String> fileLocations = DocumentCache.getInstance().getAllLocations(schemaDefinitions,
                        fileName);
                for (Map.Entry<String, String> fileLocation : fileLocations.entrySet()) {
                    StreamSource streamSource = new StreamSource(fileLocation.getValue());
                    streamSource.setPublicId(fileLocation.getKey());
                    sources[pos++] = streamSource;
                }
                validator = this.createValidator(sources);
                schemaValidatorsCache.put(schemaDefinitions, validator);
            }

            validator.reset();
            validator.setErrorHandler(this.errorHandler);
            validator.validate(new StreamSource(new StringReader(fileContent)));
        } catch (SAXParseException saxE) {
            try {
                this.errorHandler.error(saxE);
            } catch (SAXException e) {
            }
        } catch (Exception exception) {
            //Do nothing because the errorHandler informs the error
        }
    }

    private Validator createValidator(StreamSource[] sources) throws Exception {
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        sf.setFeature("http://apache.org/xml/features/xinclude", true);
        Schema schema = sf.newSchema(sources);
        return schema.newValidator();
    }

    /**
     * @return Returns the errorHandler.
     */
    public ErrorHandler getErrorHandler() {
        return this.errorHandler;
    }

    /**
     * @param errorHandler The errorHandler to set.
     */
    public void setErrorHandler(MarkersErrorHandler errorHandler) {
        this.errorHandler = errorHandler;
    }

}