Package org.apache.isis.tool.mavenplugin

Source Code of org.apache.isis.tool.mavenplugin.ValidateMojo

package org.apache.isis.tool.mavenplugin;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.
*/

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.codehaus.classworlds.ClassRealm;
import org.codehaus.classworlds.ClassWorld;
import org.codehaus.classworlds.DuplicateRealmException;
import org.codehaus.plexus.util.xml.Xpp3Dom;

import org.apache.isis.core.metamodel.runtimecontext.noruntime.RuntimeContextNoRuntime;
import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
import org.apache.isis.core.metamodel.app.IsisMetaModel;
import org.apache.isis.progmodels.dflt.ProgrammingModelFacetsJava5;
import org.apache.isis.tool.mavenplugin.util.ClassRealms;
import org.apache.isis.tool.mavenplugin.util.ClassWorlds;
import org.apache.isis.tool.mavenplugin.util.IsisMetaModels;
import org.apache.isis.tool.mavenplugin.util.Log4j;
import org.apache.isis.tool.mavenplugin.util.MavenProjects;
import org.apache.isis.tool.mavenplugin.util.Xpp3Doms;

/**
*
*
*
*/
@Mojo(name = "validate", defaultPhase = LifecyclePhase.TEST, requiresProject = true, requiresDependencyResolution = ResolutionScope.COMPILE, requiresDependencyCollection = ResolutionScope.COMPILE)
public class ValidateMojo extends AbstractMojo {

    private static final String CURRENT_PLUGIN_KEY = "org.apache.isis.tools:isis-maven-plugin";
    private static final String ISIS_REALM = "isis";

    @Component
    protected MavenProject mavenProject;

    public void execute() throws MojoExecutionException, MojoFailureException {

        Log4j.configureIfRequired();

        ValidationFailures validationFailures = bootIsisThenShutdown();

        if (validationFailures.occurred()) {
            throwFailureException(validationFailures.getNumberOfMessages() + " problems found.", validationFailures.getMessages());
        }
    }

    private ValidationFailures bootIsisThenShutdown() throws MojoExecutionException, MojoFailureException {
        ClassWorld classWorld = null;
        IsisMetaModel isisMetaModel = null;
        try {
            classWorld = new ClassWorld();
            final ClassRealm isisRealm = classWorld.newRealm(ISIS_REALM);

            addClassesToRealm(isisRealm);

            List<Object> serviceList = createServicesFromConfiguration(isisRealm);

            isisMetaModel = bootstrapIsis(isisRealm, serviceList);
            return isisMetaModel.getValidationFailures();

        } catch (DuplicateRealmException e) {
            throwExecutionException("Error building classworld", e);
            return null; // never reached, since exception thrown above
        } finally {
            ClassWorlds.disposeSafely(classWorld, ISIS_REALM);
            IsisMetaModels.disposeSafely(isisMetaModel);
        }
    }

    @SuppressWarnings("unchecked")
    private void addClassesToRealm(final ClassRealm isisRealm) throws MojoExecutionException {

        // first add all dependencies (including transitive)...
        Set<Artifact> artifacts = mavenProject.getArtifacts();
        for (Artifact artifact : artifacts) {
            File file = artifact.getFile();
            try {
                ClassRealms.addFileToRealm(isisRealm, file, getLog());
            } catch (MalformedURLException e) {
                throwExecutionException("Error adding classes for artifact '" + artifact + "' to class realm", e);
            } catch (IOException e) {
                throwExecutionException("Error adding classes for artifact '" + artifact + "' to class realm", e);
            }
        }

        // ... then all classpath elements
        // (there is substantial overlap with getArtifacts() here, but neither
        // appears to
        // provide the comprehensive set of class path elements).
        List<String> classpathElements;
        try {
            classpathElements = mavenProject.getRuntimeClasspathElements();
        } catch (DependencyResolutionRequiredException e) {
            throwExecutionException("Error obtaining runtime classpath", e);
            return;
        }
        for (String classpathElement : classpathElements) {
            final File file = new File(classpathElement);
            try {
                ClassRealms.addFileToRealm(isisRealm, file, getLog());
            } catch (MalformedURLException e) {
                throwExecutionException("Error adding classes for classpath element '" + classpathElement + "' to class realm", e);
            } catch (IOException e) {
                throwExecutionException("Error adding classes for classpath element '" + classpathElement + "' to class realm", e);
            }
        }
    }

    private List<Object> createServicesFromConfiguration(final ClassRealm isisRealm) throws MojoFailureException {
        final List<String> serviceEls = getServiceClassNamesFromConfiguration();
        return createServiceInstances(isisRealm, serviceEls);
    }

    private List<String> getServiceClassNamesFromConfiguration() throws MojoFailureException {
        final Xpp3Dom configuration = (Xpp3Dom) MavenProjects.lookupPlugin(mavenProject, CURRENT_PLUGIN_KEY).getConfiguration();
        if (configuration == null) {
            throwFailureException("Configuration error", "No <configuration> element found");
        }
        final Xpp3Dom servicesEl = configuration.getChild("services");
        if (servicesEl == null) {
            throwFailureException("Configuration error", "No <configuration>/<services> element found");
        }
        final Xpp3Dom[] serviceEls = servicesEl.getChildren("service");
        if (serviceEls == null || serviceEls.length == 0) {
            throwFailureException("Configuration error", "No <configuration>/<services>/<service> elements found");
        }
        return Lists.transform(Arrays.asList(serviceEls), Xpp3Doms.GET_VALUE);
    }

    private List<Object> createServiceInstances(final ClassRealm isisRealm, final List<String> serviceClassNames) throws MojoFailureException {
        final List<Object> serviceList = Lists.newArrayList();
        final Set<String> logMessages = Sets.newLinkedHashSet();
        for (String serviceClassName : serviceClassNames) {
            try {
                serviceList.add(isisRealm.loadClass(serviceClassName).newInstance());
            } catch (ClassNotFoundException e) {
                logMessages.add("Error loading class '" + serviceClassName + "' from classrealm");
            } catch (InstantiationException e) {
                logMessages.add("Error instantiating loaded class '" + serviceClassName + "'");
            } catch (IllegalAccessException e) {
                logMessages.add("Error instantiating loaded class '" + serviceClassName + "'");
            }
        }
        if (!logMessages.isEmpty()) {
            throwFailureException("Unable to load configured services", logMessages);
        }
        return serviceList;
    }

    private static IsisMetaModel bootstrapIsis(final ClassRealm isisRealm, List<Object> serviceList) {
        Thread.currentThread().setContextClassLoader(isisRealm.getClassLoader());

        IsisMetaModel isisMetaModel = IsisMetaModel.builder(new RuntimeContextNoRuntime(), new ProgrammingModelFacetsJava5()).withServices(serviceList).build();
        isisMetaModel.init();

        return isisMetaModel;
    }

    private void throwFailureException(String errorMessage, Set<String> logMessages) throws MojoFailureException {
        logErrors(logMessages);
        throw new MojoFailureException(errorMessage);
    }

    private void throwFailureException(String errorMessage, String... logMessages) throws MojoFailureException {
        logErrors(logMessages);
        throw new MojoFailureException(errorMessage);
    }

    private void throwExecutionException(String errorMessage, Exception e) throws MojoExecutionException {
        logErrors(errorMessage);
        throw new MojoExecutionException(errorMessage, e);
    }

    private void logErrors(String... logMessages) {
        getLog().error("");
        for (String logMessage : logMessages) {
            getLog().error(logMessage);
        }
        getLog().error("");
    }

    private void logErrors(Set<String> logMessages) {
        logErrors(logMessages.toArray(new String[] {}));
    }

}
TOP

Related Classes of org.apache.isis.tool.mavenplugin.ValidateMojo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.