All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.maritimecloud.msdl.MsdlProcessor Maven / Gradle / Ivy

There is a newer version: 0.3
Show newest version
/* Copyright (c) 2011 Danish Maritime Authority.
 *
 * 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.maritimecloud.msdl;

import static java.util.Objects.requireNonNull;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import net.maritimecloud.internal.msdl.parser.ParsedProject;
import net.maritimecloud.msdl.model.Project;

/**
 * A processor of MSDL plugins.
 *
 * @author Kasper Nielsen
 */
public class MsdlProcessor {

    final List dependencyDirectories = new ArrayList<>();

    /** The files that be processed by each plugin. */
    final Set files = new LinkedHashSet<>();

    MsdlLogger logger;

    /** A list of all plugins that should be processed. */
    final List plugins = new ArrayList<>();

    Path sourceDirectory;

    public MsdlProcessor() {
        sourceDirectory = Paths.get("").toAbsolutePath(); // current working directory
    }

    public MsdlProcessor addDependencyDirectory(Path p) {
        dependencyDirectories.add(p);
        return this;
    }

    /**
     * Adds a .MSDL file.
     *
     * @param path
     *            the path of the file
     */
    public MsdlProcessor addFile(Path path) {
        files.add(requireNonNull(path));
        return this;
    }

    public MsdlProcessor addFile(String path) {
        return addFile(Paths.get(path));
    }

    /**
     * Adds a plugin that should be processed
     *
     * @param plugin
     *            the plugin to add to the processing chain
     * @return this processor
     * @throws NullPointerException
     *             if the specified plugin is null
     */
    public MsdlProcessor addPlugin(MsdlPlugin plugin) {
        plugins.add(requireNonNull(plugin));
        return this;
    }

    private Map checkFiles(MsdlLogger logger) {
        LinkedHashMap m = new LinkedHashMap<>();
        for (Path p : getFiles()) {
            if (p.isAbsolute()) {
                if (!Files.exists(p)) {
                    logger.error("Could not find file " + p);
                }
                Path parent = p.getParent();
                while (parent != null) {
                    if (parent.equals(getSourceDirectory())) {
                        m.put(getSourceDirectory().relativize(p).toString(), p);
                        break;
                    }
                    parent = parent.getParent();
                }
                if (parent == null) {
                    logger.error("All .msdl files must must be located in " + getSourceDirectory() + ", was " + p);
                }
            } else {
                Path file = getSourceDirectory().resolve(p);
                if (!Files.exists(file)) {
                    logger.error("Could not find file " + p + " at " + file);
                }
                m.put(getSourceDirectory().relativize(file).toString(), file.toAbsolutePath());
                logger.debug("Found file: " + file.toAbsolutePath());
            }
        }
        return m;
    }

    public MsdlProcessorResult executePlugins() {
        if (plugins.size() == 0) {
            throw new IllegalStateException("No plugins have been registered for execution");
        }
        MsdlLogger log = logger;
        if (log == null) {
            Logger lo = Logger.getLogger("msdl");
            for (Handler h : lo.getParent().getHandlers()) {
                h.setLevel(Level.FINE);
                h.setFormatter(new SimpleFormatter() {
                    public String format(LogRecord record) {
                        String throwable = "";
                        if (record.getThrown() != null) {
                            StringWriter sw = new StringWriter();
                            try (PrintWriter pw = new PrintWriter(sw)) {
                                record.getThrown().printStackTrace(pw);
                            }
                            throwable = sw.toString();
                        }
                        return new java.util.Date() + " " + record.getLevel() + " " + record.getMessage() + "\r\n"
                        + throwable;
                    }
                });
            }
            log = MsdlLogger.wrapJUL(lo);
        }

        AtomicInteger errorCounter = new AtomicInteger();
        log = MsdlLogger.errorCountingLogger(log, errorCounter);

        Map sourceFiles = checkFiles(log);
        if (errorCounter.get() > 0) {
            return new MsdlProcessorResult("One or more files could not be found");
        }

        // Parse all files and resolve imports
        ParsedProject pp = new ParsedProject(sourceFiles, dependencyDirectories, log);
        Project p = pp.parse();
        if (errorCounter.get() > 0 || p == null) {
            return new MsdlProcessorResult("Failed to properly parse MSDL files");
        }

        // Invoke each plugin
        for (MsdlPlugin plugin : plugins) {
            plugin.logger = log;
            log.info("Processing plugin: " + plugin.getClass().getSimpleName());
            try {
                plugin.process(p);
            } catch (MsdlPluginException e) {
                return new MsdlProcessorResult("Plugin failed");
            } catch (Exception e) {
                log.error("Plugin failed", e);
                // return new MsdlProcessorResult("Plugin failed");
            }
            if (errorCounter.get() > 0) {
                return new MsdlProcessorResult("Plugin failed");
            }
        }
        return new MsdlProcessorResult(null); // success
    }

    public List getDependencyDirectories() {
        return dependencyDirectories;
    }

    public Collection getFiles() {
        return files;
    }

    /**
     * @return the logger
     */
    public MsdlLogger getLogger() {
        return logger;
    }

    /**
     * @return the sourceDirectory
     */
    public Path getSourceDirectory() {
        return sourceDirectory;
    }

    public MsdlProcessor setLogger(MsdlLogger logger) {
        this.logger = requireNonNull(logger);
        return this;
    }

    public MsdlProcessor setSourceDirectory(Path p) {
        this.sourceDirectory = p.toAbsolutePath();
        return this;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy