Java tutorial
/** * Copyright 2011 Vecna Technologies, Inc. * * 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.vecna.maven.hibernate; import java.io.File; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.util.Properties; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.PropertyUtils; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.NamingStrategy; import com.vecna.maven.commons.BuildClassPathMojo; /** * Base Mojo for manipulating Hibernate schema (generation, updates, validation). * Features: * * <ul> * <li>Multiple configuration files</li> * <li>Multiple property files</li> * <li>Properties supplied as Mojo parameters</li> * <li>Classes supplied as Mojo parameters</li> * <li>Mappings supplied as Mojo parameters</li> * </ul> * * @author ogolberg@vecna.com */ public abstract class HibernateSchemaMojo extends BuildClassPathMojo { /** * Reference to the maven project. Internal. * @parameter expression="${project}" * @required * @readonly */ private MavenProject project; /** * Hibernate config (hibernate.cfg.xml) files. Can be filesystem or classpath resources. * @parameter */ private String[] configFiles; /** * Hibernate property (hibernate.properties) files. Can be filesystem or classpath resources. * @parameter */ private String[] propertyFiles; /** * Additional mapping resources (hbm.xml). * @parameter */ private String[] additionalMappings; /** * Additional classes to be mapped (in addition to the ones specified in Hibernate configuration files). * @parameter */ private String[] additionalClasses; /** * Hibernate properties (override properties retrieved from property files). * @parameter */ private Properties properties; /** * The naming strategy to use (class name). * @parameter */ private String namingStrategy; /** * Disable auto-detection of Envers. * @parameter */ private boolean disableEnvers; /** * Skip execution * @parameter */ private boolean skip; /** * {@inheritDoc} */ @Override protected MavenProject getProject() { return project; } /** * Resolves a filesystem or classpath URL from a string. Classpath resources are resolved using * the current thread's context classloader (to play nice with Maven). * @param string the string to resolve. * @return a valid filesystem or classpath resource <code>string</code> points to. * @throws MojoExecutionException if the argument does not point to a valid filesystem of classpath resource */ private URL getURL(String string) throws MojoExecutionException { File file = new File(string); if (file.exists()) { try { return file.toURL(); } catch (MalformedURLException e) { throw new MojoExecutionException(file + " cannot be converted to a URL", e); } } else { URL url = Thread.currentThread().getContextClassLoader().getResource(string); if (url == null) { throw new MojoExecutionException(string + " is not a valid file or classpath resource"); } return url; } } /** * Create mapping metadata from provided Hibernate configuration * @return mapping metadata * @throws MojoExecutionException if a mapping class cannot be resolved or if the naming strategy cannot be instantiated */ protected Configuration createMappings() throws MojoExecutionException { Configuration configuration = new AnnotationConfiguration(); if (configFiles != null) { for (String configFile : configFiles) { if (configFile != null && !configFile.equals("")) { configuration.configure(getURL(configFile)); } } } if (additionalClasses != null) { for (String additionalClass : additionalClasses) { try { configuration.addClass(Class.forName(additionalClass)); } catch (ClassNotFoundException e) { throw new MojoExecutionException("coudn't add additional classes", e); } } } if (additionalMappings != null) { for (String mapping : additionalMappings) { configuration.addURL(getURL(mapping)); } } if (propertyFiles != null) { for (String propertyFile : propertyFiles) { URL url = getURL(propertyFile); Properties properties = PropertyUtils.loadProperties(url); configuration.addProperties(properties); } } if (properties != null) { configuration.addProperties(properties); } if (namingStrategy != null) { try { @SuppressWarnings("unchecked") Class nsClass = Thread.currentThread().getContextClassLoader().loadClass(namingStrategy); configuration.setNamingStrategy((NamingStrategy) nsClass.newInstance()); } catch (Exception e) { throw new MojoExecutionException(namingStrategy + " is not a valid naming strategy", e); } } configuration.buildMappings(); if (!disableEnvers) { if (tryEnableEnvers(configuration)) { getLog().info("Detected Envers"); } } return configuration; } /** * Add Envers mappings if Envers is present on the classpath */ protected boolean tryEnableEnvers(Configuration configuration) throws MojoExecutionException { Class<?> enversConfigClass; try { final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); enversConfigClass = classLoader.loadClass("org.hibernate.envers.configuration.AuditConfiguration"); } catch (ClassNotFoundException e) { return false; } try { Method getFor = enversConfigClass.getMethod("getFor", Configuration.class); getFor.invoke(null, configuration); } catch (Exception e) { throw new MojoExecutionException("Unexpected error while creating the Envers configuration", e); } return true; } /** * {@inheritDoc} */ @Override protected final void executeWithClassLoader() throws MojoExecutionException, MojoFailureException { if (!skip) { Configuration configuration = createMappings(); executeWithMappings(configuration); } else { getLog().info("skipping execution"); } } /** * This method will be executed in the build classpath classloader context after the mapping metadata is built. * @param configuration mapping metadata. * @throws MojoExecutionException on execution exception * @throws MojoFailureException on execution failure */ protected abstract void executeWithMappings(Configuration configuration) throws MojoExecutionException, MojoFailureException; }