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

com.edugility.jpa.maven.plugin.AbstractJPAMojo Maven / Gradle / Ivy

The newest version!
/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil -*-
 *
 * $Id$
 *
 * Copyright (c) 2011 Edugility LLC.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * The original copy of this license is available at
 * http://www.opensource.org/license/mit-license.html.
 */
package com.edugility.jpa.maven.plugin;

import java.lang.reflect.Field;

import java.net.URISyntaxException;
import java.net.URL;

import java.io.File;
import java.io.IOException;

import java.util.Map;
import java.util.Set;

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.plugin.logging.Log;

import org.apache.maven.model.Build; // for javadoc only

import org.apache.maven.project.MavenProject;

import org.scannotation.archiveiterator.DirectoryIteratorFactory;
import org.scannotation.archiveiterator.FileIterator;
import org.scannotation.archiveiterator.FileProtocolIteratorFactory;
import org.scannotation.archiveiterator.Filter;
import org.scannotation.archiveiterator.IteratorFactory;
import org.scannotation.archiveiterator.JarIterator;
import org.scannotation.archiveiterator.StreamIterator;

/**
 * An {@link AbstractMojo} that provides support for scanning a set of
 * {@link URL}s and reporting back on the annotated classnames found
 * there.
 *
 * @author Laird Nelson
 *
 * @since 1.0-SNAPSHOT
 */
public abstract class AbstractJPAMojo extends AbstractMojo {

  /**
   * Static initializer; works around Scannotation
   * bug #3134533 by installing a patched {@link
   * FileProtocolIteratorFactory} into the {@link IteratorFactory}
   * class' {@link IteratorFactory#registry} field.
   *
   * @see Scannotation
   * bug #3134533
   */
  static {
    Field field = null;
    try {
      field = IteratorFactory.class.getDeclaredField("registry");
      assert field != null;
      field.setAccessible(true);
      @SuppressWarnings("unchecked")
      final Map registry = (Map)field.get(null);
      assert registry != null;
      assert registry.containsKey("file");
      final Object old = registry.put("file", new FileProtocolIteratorFactory() {
          @Override
          public StreamIterator create(final URL url, final Filter filter) throws IOException {
            StreamIterator returnValue = null;
            if (url != null) {
              // See http://sourceforge.net/tracker/?func=detail&aid=3134533&group_id=214374&atid=1029423
              File file;
              try {
                file = new File(url.toURI());
              } catch (final URISyntaxException e) {
                file = new File(url.getPath());
              }
              if (file.isDirectory()) {
                returnValue = new FileIterator(file, filter);
              } else {
                returnValue = new JarIterator(url.openStream(), filter);
              }
            }
            return returnValue;
          }
        });
      assert old != null;
    } catch (final Exception ohWell) {
      ohWell.printStackTrace();
    }
  }

  /**
   * The {@link MavenProject} usually injected by the Maven runtime.
   * Used for the return value of its {@link
   * MavenProject#getTestClasspathElements()
   * getTestClasspathElements()} method and its associated {@link
   * Build}'s {@link Build#getTestOutputDirectory()
   * getTestOutputDirectory()} method.  This field may be {@code null}
   * when this {@link AbstractJPAMojo} is not configured
   * by Maven.
   *
   * @parameter default-value="${project}" property="project"
   *
   * @readonly
   *
   * @required
   *
   * @see Guide
   * to Configuring Plug-ins
   */
  private MavenProject project;

  /**
   * The {@link AnnotationDB} that will be {@linkplain
   * #cloneAnnotationDB() cloned} for use by this {@link
   * AbstractJPAMojo}.  This field may be {@code null} at any point,
   * and may be populated by either Maven,
   * the {@link #setAnnotationDB(AnnotationDB)} method or the {@link
   * #createAnnotationDB()} method.
   *
   * @parameter alias="db" property="annotationDB"
   *
   * @see #cloneAnnotationDB()
   *
   * @see #createAnnotationDB()
   *
   * @see #setAnnotationDB(AnnotationDB)
   *
   * @see Guide
   * to Configuring Plug-ins
   */
  private AnnotationDB db;

  /**
   * A {@link URLFilter} that will be used to construct the {@link
   * Set} of {@link URL}s that will be scanned by this {@link
   * AbstractJPAMojo}.  This field may be {@code null} at any point
   * and may be populated by either Maven
   * or the {@link #setURLFilter(URLFilter)} method.
   *
   * @parameter property="URLFilter"
   *
   * @see #getURLFilter()
   *
   * @see #setURLFilter(URLFilter)
   *
   * @see Guide
   * to Configuring Plug-ins
   */
  private URLFilter urlFilter;

  /**
   * Constructs a new {@link AbstractJPAMojo}.  No configuration
   * automatic or otherwise will have taken place as a result of
   * calling this constructor.
   */
  protected AbstractJPAMojo() {
    super();
  }

  /**
   * Creates a new {@link AnnotationDB} in the (common) case where a
   * user has not supplied this {@link AbstractJPAMojo} with a
   * pre-configured {@link AnnotationDB}.
   *
   * 

This method never returns {@code null}. Subclasses overriding * this method must ensure that their overridden implementation * never returns {@code null}.

* * @return a new {@link AnnotationDB}; never {@code null} * * @see AnnotationDB * * @see org.scannotation.AnnotationDB */ protected AnnotationDB createAnnotationDB() { return new AnnotationDB(); } /** * Returns this {@link AbstractJPAMojo}'s associated {@link * URLFilter}, or {@code null} if no such {@link URLFilter} exists. * *

This method may return {@code null}.

* * @return the {@link URLFilter} used by this {@link * AbstractJPAMojo}, or {@code null} * * @see #setURLFilter(URLFilter) * * @see URLFilter */ public URLFilter getURLFilter() { return this.urlFilter; } /** * Sets this {@link AbstractJPAMojo}'s associated {@link URLFilter}. * {@code null} is permitted as a parameter value. * * @param filter the {@link URLFilter} to set; may be {@code null} * * @see #getURLFilter() * * @see URLFilter */ public void setURLFilter(final URLFilter filter) { this.urlFilter = filter; } /** * Returns the {@link MavenProject} that Maven customarily injects * into this mojo, or {@code null} if no such {@link MavenProject} * has been set. * *

This method may return {@code null}.

* * @return the {@link MavenProject} associated with this mojo, or * {@code null} */ public MavenProject getProject() { return this.project; } /** * Installs the {@link MavenProject} for use by this mojo during its * run. * * @param project the {@link MavenProject} to use; may be {@code * null} */ public void setProject(final MavenProject project) { this.project = project; } /** * Returns a {@linkplain AnnotationDB#clone() clone} of this {@link * AbstractJPAMojo}'s {@linkplain #setAnnotationDB(AnnotationDB) * associated AnnotationDB}. * *

A clone is returned because {@link * org.scannotation.AnnotationDB} retains state after {@linkplain * org.scannotation.AnnotationDB#scanArchives(URL[]) scanning}, and * Maven plugins have no contractually defined lifecycle semantics. * Consequently it is unknown how long-lived this {@link * AbstractJPAMojo}'s {@link #db} reference might be.

* *

This method may return {@code null}.

* * @return a {@linkplain AnnotationDB#clone() clone} of this {@link * AbstractJPAMojo}'s {@linkplain #setAnnotationDB(AnnotationDB) * associated AnnotationDB}, or {@code null} if no such * {@link AnnotationDB} could be cloned * * @see #setAnnotationDB(AnnotationDB) * * @see AnnotationDB * * @see AnnotationDB#clone() * * @see org.scannotation.AnnotationDB * * @see org.scannotation.AnnotationDB#annotationIndex * * @see org.scannotation.AnnotationDB#classIndex */ public final AnnotationDB cloneAnnotationDB() { if (this.db == null) { this.db = this.createAnnotationDB(); } if (this.db == null) { return null; } return this.db.clone(); } /** * Sets the {@link AnnotationDB} that will be used by this {@link * AbstractJPAMojo}'s {@link #cloneAnnotationDB()} method. {@code * null} is permitted as a parameter value. * * @param db the {@link AnnotationDB} to set; may be {@code null} * * @see #cloneAnnotationDB() * * @see AnnotationDB */ public void setAnnotationDB(final AnnotationDB db) { this.db = db; } /** * Scans the supplied {@link Set} of {@link URL}s and returns the * {@link AnnotationDB} that contains the scanned annotation * information. * *

This method may return {@code null} in exceptional * circumstances.

* * @param urls the {@link Set} of {@link URL}s to scan; if {@code * null}, then no scanning operation will take place * * @return the {@link AnnotationDB} that was used to perform the * scan, or {@code null} if no {@link AnnotationDB} could be * {@linkplain #cloneAnnotationDB() found} * * @exception IOException if an error occurs during scanning * * @see #cloneAnnotationDB() * * @see org.scannotation.AnnotationDB#scanArchives(URL[]) */ protected final AnnotationDB scan(final Set urls) throws IOException { final AnnotationDB db = this.cloneAnnotationDB(); final AnnotationDB result = this.scan(db, urls); assert result == db; return result; } /** * Scans the supplied {@link Set} of {@link URL}s and as a * convenience returns the supplied {@link AnnotationDB} that * contains the scanned annotation information. * *

This method may return {@code null} if the supplied {@code db} * is {@code null}.

* * @param db the {@link AnnotationDB} used to {@linkplain * org.scannotation.AnnotationDB#scanArchives(URL[]) perform the * scan}; if {@code null} then no scanning operation will take place * * @param urls the {@link Set} of {@link URL}s to scan; if {@code * null}, then no scanning operation will take place * * @return the {@code db} parameter * * @exception IOException if an error occurs during scanning * * @see org.scannotation.AnnotationDB#scanArchives(URL[]) */ private final AnnotationDB scan(AnnotationDB db, final Set urls) throws IOException { if (db != null && urls != null && !urls.isEmpty()) { final Log log = this.getLog(); if (log != null && log.isDebugEnabled()) { log.debug("Scanning the following URLs: " + urls); } db.clear(); db.scanArchives(urls.toArray(new URL[urls.size()])); } return db; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy