com.c4om.xsdfriendlyvalidator.XSDFriendlyValidatorLauncher.java Source code

Java tutorial

Introduction

Here is the source code for com.c4om.xsdfriendlyvalidator.XSDFriendlyValidatorLauncher.java

Source

/*
Copyright 2014 Universidad Politcnica de Madrid - Center for Open Middleware (http://www.centeropenmiddleware.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.c4om.xsdfriendlyvalidator;

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

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;

import static com.c4om.utils.xmlutils.JavaXMLUtils.*;

/**
 * Class that launches the XSD friendly validator from a command line.
 * 
 */
public class XSDFriendlyValidatorLauncher {

    private static final String COMMAND_LINE_SYNTAX = "java -jar XSDFriendlyValidator.jar { --help | --inputFiles inputFile1[,...,inputFileN] [--schemas ns1URI,ns1XSD.xsd,...,nsNURI,nsNXSD.xsd[,noNsXSD.xsd]]";

    /**
     * Long name of the {@link Option} 'inputFiles', which is used to provide the input candidate files.
     */
    private static final String OPTION_LONG_NAME_INPUT_FILES = "inputFiles";

    /**
     * Long name of the {@link Option} 'schemas', which is used to provide the input schemas.
     */
    private static final String OPTION_LONG_NAME_SCHEMAS = "schemas";

    /**
     * Short name of the {@link Option} 'schemas', which is used to provide the input schemas.
     */
    private static final String OPTION_NAME_SCHEMAS = "sch";

    /**
     * Short name of the {@link Option} 'inputFiles', which is used to provide the input candidate files.
     */
    private static final String OPTION_NAME_INPUT_FILES = "in";

    /**
     * Short name of the {@link Option} 'help', which is used to provide the input schemas.
     */
    private static final String OPTION_NAME_HELP = "h";

    /**
     * Long name of the {@link Option} 'help', which is used to provide the input candidate files.
     */
    private static final String OPTION_LONG_NAME_HELP = "help";

    /**
     * The admitted command line options.
     */
    private static final Options OPTIONS;

    static {
        @SuppressWarnings("static-access")
        Option schemasOption = OptionBuilder.withValueSeparator(',').hasArgs().withLongOpt(OPTION_LONG_NAME_SCHEMAS)
                .isRequired(false)
                .withDescription(
                        "A comma-separated list of pairs of namespace URIs and paths to their respective schemas. The format is \"--schemas ns1URI,ns1XSD.xsd,...,nsNURI,nsNXSD.xsd[,noNsXSD.xsd]\"")
                .create(OPTION_NAME_SCHEMAS);
        @SuppressWarnings("static-access")
        Option filesOption = OptionBuilder.withValueSeparator(',').hasArgs()
                .withLongOpt(OPTION_LONG_NAME_INPUT_FILES)
                //.isRequired(true)
                .isRequired(false).withDescription("A comma-separated list of paths to files")
                .create(OPTION_NAME_INPUT_FILES);
        @SuppressWarnings("static-access")
        Option helpOption = OptionBuilder.withLongOpt(OPTION_LONG_NAME_HELP).create(OPTION_NAME_HELP);
        OPTIONS = new Options();
        OPTIONS.addOption(filesOption);
        OPTIONS.addOption(schemasOption);
        OPTIONS.addOption(helpOption);
    }

    /**
     * Private constructor to prevent instantiation.
     */
    private XSDFriendlyValidatorLauncher() {
    }

    /**
     * This method parses an array of "schemas" command line option values to get a {@link Map} between namespace URIs and the XSDs that describe them. 
     * Such a {@link Map} is suitable as input parameter for {@link XSDFriendlyValidator#validate(Document, Map)} and {@link XSDFriendlyValidator#validate(List, Map)}. 
     * Null, empty and whitespace values are ignored.
     * @param commandLineOptionValues the array of command line option values
     * @return A {@link Map} between URIs and XSD documents, suitable to be used as input in a {@link XSDFriendlyValidator}
     * @throws IOException If there are problems related to I/O
     * @throws SAXException If there are problems at XML parsing
     * @throws ParserConfigurationException If there are problems at XML parsing 
     * @throws IllegalArgumentException if the array is empty or only contains null, empty or whitespace values.
     * 
     */
    private static Map<String, Document> getSchemaFilesFromCommandLine(String[] commandLineOptionValues)
            throws IOException, ParserConfigurationException, SAXException {
        Map<String, Document> result = new HashMap<>();
        if (commandLineOptionValues.length == 0) {
            throw new IllegalArgumentException("Empty array");
        }
        for (int i = 0; i < commandLineOptionValues.length; i++) {
            while (commandLineOptionValues[i] == null || commandLineOptionValues[i].trim().equals("")) {
                i++;
            }
            if (i >= commandLineOptionValues.length) {
                throw new IllegalArgumentException("Array only with empty or null values");
            }
            if (!(i == (commandLineOptionValues.length - 1))) {
                String uri = commandLineOptionValues[i];
                i++;
                String filePath = commandLineOptionValues[i];
                File file = new File(filePath);
                if (!file.exists()) {
                    throw new FileNotFoundException("File '" + filePath + "' does not exist.");
                } else if (!file.isFile()) {
                    throw new IOException("'" + filePath + "' is not a file.");
                }
                Document schemaDocument = loadW3CDocumentFromInputFile(file);
                result.put(uri, schemaDocument);
            } else {
                String filePath = commandLineOptionValues[i];
                File file = new File(filePath);
                if (!file.exists()) {
                    throw new FileNotFoundException("File '" + filePath + "' does not exist.");
                } else if (!file.isFile()) {
                    throw new IOException("'" + filePath + "' is not a file.");
                }
                Document schemaDocument = loadW3CDocumentFromInputFile(file);
                result.put("", schemaDocument);
            }

        }
        return result;
    }

    /**
     * This method parses an array of command line option values to get a {@link List} of {@link Document} objects with the contents 
     * of the XML files pointed by the paths present at that {@link String} array.
     * @param commandLineOptionValues an array of command line option values
     * @return a {@link List} of {@link Document} objects  with the contents of the XML files pointed by the paths present at <code>commandLineOptionValues</code>
     * @throws IOException if there are problems accessing a document file (including a {@link FileNotFoundException} if it is not found).
     * @throws ParserConfigurationException if the parser is bad configured (this should not normally happen).
     * @throws SAXException if there are parsing problems (non well-formed XML, invalid characters etc.)
     */
    private static List<Document> getListOfInputDocumentsFromCommandLine(String[] commandLineOptionValues)
            throws IOException, ParserConfigurationException, SAXException {
        List<Document> result = new ArrayList<>(commandLineOptionValues.length);
        for (int i = 0; i < commandLineOptionValues.length; i++) {
            String filePath = commandLineOptionValues[i];
            File file = new File(filePath);
            if (!file.exists()) {
                throw new FileNotFoundException("File '" + filePath + "' does not exist.");
            } else if (!file.isFile()) {
                throw new IOException("'" + filePath + "' is not a file.");
            }
            Document currentDocument = loadW3CDocumentFromInputFile(file);
            result.add(currentDocument);
        }
        return result;
    }

    /**
     * Method called at application start.
     * 
     * @param args command line args
     */
    public static void main(String[] args) throws Exception {
        CommandLineParser parser = new BasicParser();
        CommandLine commandLine1 = parser.parse(OPTIONS, args);
        CommandLine commandLine = commandLine1;
        if (commandLine.hasOption(OPTION_NAME_HELP)) {
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp(COMMAND_LINE_SYNTAX, OPTIONS);
            System.exit(0);
        } else if (!commandLine.hasOption(OPTION_NAME_INPUT_FILES)) {
            System.err.println("You must specify input files. Invoke with --help to see how.");
            System.exit(1);
        }
        String[] inputFileOptionValues = commandLine.getOptionValues(OPTION_NAME_INPUT_FILES);
        List<Document> inputFilesList = getListOfInputDocumentsFromCommandLine(inputFileOptionValues);
        String[] schemasOptionValues = commandLine.getOptionValues(OPTION_NAME_SCHEMAS);
        Map<String, Document> schemasMap = getSchemaFilesFromCommandLine(schemasOptionValues);
        XSDFriendlyValidator validator = new XSDFriendlyValidatorImpl();
        ValidationResults validationResults = validator.validate(inputFilesList,
                Arrays.asList(inputFileOptionValues), schemasMap);
        System.out.println(validationResults.toString());
    }
}