| /* |
| * 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. |
| */ |
| package org.apache.uima.pear.tools; |
| |
| import java.io.File; |
| import java.io.FileFilter; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.Properties; |
| import java.util.Set; |
| |
| import org.apache.commons.io.FileUtils; |
| import org.apache.maven.plugin.AbstractMojo; |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.plugin.logging.Log; |
| 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.Parameter; |
| import org.apache.maven.project.MavenProject; |
| import org.apache.uima.UIMAFramework; |
| import org.apache.uima.util.Level; |
| |
| /** |
| * PearPackagingMojo which generates an UIMA PEAR package. All the necessary |
| * information from the UIMA nature is gathered and added to the PEAR package. |
| * Additionally the generated jar file from the Maven build is added with the |
| * according classpath information. |
| */ |
| @Mojo(name = "package", defaultPhase = LifecyclePhase.PACKAGE) |
| public class PearPackagingMojo extends AbstractMojo { |
| |
| /** |
| * Main component directory of the UIMA project that contains the UIMA nature. |
| */ |
| @Parameter(defaultValue = "${basedir}", property = "basedir", required = true) |
| private String mainComponentDir = null; |
| |
| /** |
| * Required classpath settings for the PEAR package. |
| */ |
| @Parameter(defaultValue = "${pear.classpath}", property = "pear.classpath") |
| private String classpath = null; |
| |
| /** |
| * Main Component Descriptor path relative to the main component directory |
| */ |
| @Parameter(defaultValue = "${pear.mainComponentDesc}", property = "pear.mainComponentDesc", required = true) |
| private String mainComponentDesc = null; |
| |
| /** |
| * PEAR package component ID |
| */ |
| @Parameter(defaultValue = "${pear.componentId}", property = "pear.componentId", required = true) |
| private String componentId = null; |
| |
| /** |
| * Target directory for the PEAR package |
| */ |
| @Parameter(defaultValue = "${basedir}/target", required = true) |
| private String targetDir = null; |
| |
| /** |
| * Required UIMA datapath settings for the PEAR package |
| */ |
| @Parameter(defaultValue = "$main_root/resources") |
| private String datapath = null; |
| |
| /** |
| * Required environment variables for the PEAR package |
| * |
| * |
| */ |
| @Parameter |
| private Properties props = null; |
| |
| /** |
| * The maven project. |
| */ |
| @Parameter( defaultValue = "${project}", readonly = true ) |
| private MavenProject project; |
| |
| // the PEAR packaging directory contains all the stuff that is added to |
| // the PEAR |
| private File pearPackagingDir; |
| |
| private ArrayList<String> classpathsInOrder; |
| |
| private Set<String> classpathsDefined; |
| |
| private Log log; |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.maven.plugin.AbstractMojo#execute() |
| */ |
| public void execute() throws MojoExecutionException { |
| |
| // create the PEAR packaging directory in the target directory |
| this.pearPackagingDir = new File(this.targetDir, "pearPackaging"); |
| |
| // save current UIMA log level |
| Level level = getCurrentUIMALogLevel(); |
| // change UIMA log level to only log warnings and errors |
| UIMAFramework.getLogger().setLevel(Level.WARNING); |
| |
| // create final PEAR file object |
| File finalPearFileName = new File(this.targetDir, this.componentId |
| + ".pear"); |
| |
| log = getLog(); |
| log.info("Start building PEAR package for component " + this.componentId); |
| log.debug("UIMA PEAR INFORMATION "); |
| log.debug("======================"); |
| log.debug("main component dir: " + this.mainComponentDir); |
| log.debug("main component desc: " + this.mainComponentDesc); |
| log.debug("component id: " + this.componentId); |
| log.debug("classpath: " + this.classpath); |
| log.debug("datapath: " + this.datapath); |
| log.debug("target dir: " + this.targetDir); |
| log.debug("pear packaging dir: " |
| + this.pearPackagingDir.getAbsolutePath()); |
| log.debug("final PEAR file: " + finalPearFileName.getAbsolutePath()); |
| |
| // check Maven project packaging type - only jar packaging is supported |
| if (!this.project.getPackaging().equals("jar")) { |
| throw new MojoExecutionException( |
| "Wrong packaging type, only 'jar' packaging is supported"); |
| } |
| |
| try { |
| // copies all PEAR data to the PEAR packaging directory |
| copyPearData(); |
| |
| // copy created jar package to the PEAR packaging lib directory |
| // get jar file name |
| String jarFileName = this.project.getBuild().getFinalName() + ".jar"; |
| // get jar file location |
| File finalJarFile = new File(this.project.getBuild().getDirectory(), |
| jarFileName); |
| // check if the jar file exist |
| if (finalJarFile.exists()) { |
| // specify the target directory for the jar file |
| File target = new File(this.pearPackagingDir, |
| InstallationController.PACKAGE_LIB_DIR); |
| File targetFile = new File(target, jarFileName); |
| // copy the jar file to the target directory |
| FileUtils.copyFile(finalJarFile, targetFile); |
| } else { |
| // jar file does not exist - build was not successful |
| String errorMessage = "Jar package " |
| + finalJarFile.getAbsolutePath() + " not found"; |
| log.debug(errorMessage); |
| throw new IOException(errorMessage); |
| } |
| |
| // classpath handling: |
| // 1) keep order: |
| // jar for this artifact if it exists, |
| // followed by user-specified, |
| // followed by jars in lib |
| // 2) remove duplicates |
| // 3) paths that are generated are in form $main_root/lib/jar-name |
| |
| classpathsInOrder = new ArrayList<String>(); |
| classpathsDefined = new HashSet<String>(); |
| |
| String pathToLib = String.format("$main_root/%s", InstallationController.PACKAGE_LIB_DIR); |
| log.debug("pear pathToLib = " + pathToLib); |
| String mainJar = String.format("%s/%s.jar", pathToLib, this.project.getBuild().getFinalName()); |
| |
| maybeAddClasspath(mainJar); |
| |
| if (classpath != null && !classpath.equals("")) { |
| if (classpath.indexOf(':') != -1) { |
| throw new MojoExecutionException( |
| "classpath: " + classpath + " must use semicolons as separators."); |
| } |
| String[] userClasspath = classpath.split(";"); |
| for (String ucp : userClasspath) { |
| maybeAddClasspath(ucp); |
| } |
| } |
| |
| File libDir = new File(this.pearPackagingDir, InstallationController.PACKAGE_LIB_DIR); |
| if (libDir.isDirectory()) { |
| FileFilter jarFilter = new FileFilter() { |
| public boolean accept(File pathname) { |
| return pathname.isFile() && pathname.getAbsolutePath().toLowerCase().endsWith(".jar"); |
| } |
| }; |
| File[] jars = libDir.listFiles(jarFilter); |
| if (null != jars) { |
| for (File jar : jars) { |
| maybeAddClasspath(String.format("%s/%s", pathToLib, jar.getName())); |
| } |
| } |
| } |
| |
| StringBuffer buffer = new StringBuffer(); |
| for (String cp : classpathsInOrder) { |
| buffer.append(cp).append(";"); |
| } |
| |
| // add compiled jar to the PEAR classpath |
| // not done here - done as part of next step |
| // buffer.append(";$main_root/"); |
| // buffer.append(InstallationController.PACKAGE_LIB_DIR); |
| // buffer.append("/"); |
| // buffer.append(this.project.getBuild().getFinalName()); |
| // buffer.append(".jar"); |
| |
| // add lib jars to the PEAR classpath |
| |
| classpath = buffer.substring(0, buffer.length()-1); |
| |
| // if (this.classpath != null) { |
| // this.classpath = this.classpath + ";" + classpathExtension; |
| // } else { |
| // this.classpath = classpathExtension.substring(1,classpathExtension.length()); |
| // } |
| |
| // create the PEAR package |
| createPear(); |
| |
| // log success message |
| log.info("PEAR package for component " + this.componentId |
| + " successfully created at: " |
| + finalPearFileName.getAbsolutePath()); |
| |
| // set UIMA logger back to the original log level |
| UIMAFramework.getLogger().setLevel(level); |
| |
| } catch (PackageCreatorException e) { |
| log.debug(e.getMessage()); |
| throw new MojoExecutionException(e.getMessage()); |
| } catch (IOException e) { |
| log.debug(e.getMessage()); |
| throw new MojoExecutionException(e.getMessage()); |
| } |
| |
| } |
| |
| private void maybeAddClasspath(String acp) { |
| // System.out.println("TEST maybeAddClasspath: " + acp); |
| log.debug("pear maybe add classpath: " + acp); |
| if (!classpathsDefined.contains(acp)) { |
| classpathsInOrder.add(acp); |
| classpathsDefined.add(acp); |
| } else { |
| // System.out.println("TEST duplicate found"); |
| log.debug("pear maybe add classpath: duplicate found"); |
| } |
| } |
| |
| /** |
| * Returns the current UIMA log level for the UIMA root logger |
| * |
| * @return the current UIMA log level |
| */ |
| private Level getCurrentUIMALogLevel() { |
| if (UIMAFramework.getLogger().isLoggable(Level.ALL)) { |
| return Level.ALL; |
| } else if (UIMAFramework.getLogger().isLoggable(Level.FINEST)) { |
| return Level.FINEST; |
| } else if (UIMAFramework.getLogger().isLoggable(Level.FINER)) { |
| return Level.FINER; |
| } else if (UIMAFramework.getLogger().isLoggable(Level.FINE)) { |
| return Level.FINE; |
| } else if (UIMAFramework.getLogger().isLoggable(Level.CONFIG)) { |
| return Level.CONFIG; |
| } else if (UIMAFramework.getLogger().isLoggable(Level.INFO)) { |
| return Level.INFO; |
| } else if (UIMAFramework.getLogger().isLoggable(Level.WARNING)) { |
| return Level.WARNING; |
| } else if (UIMAFramework.getLogger().isLoggable(Level.SEVERE)) { |
| return Level.SEVERE; |
| } else { |
| return Level.OFF; |
| } |
| } |
| |
| /** |
| * Copies the given directory when available to the PEAR packaging directory |
| * |
| * @param directory |
| * directory to copy |
| * |
| * @throws IOException passthru |
| */ |
| private void copyDirIfAvailable(String directory) throws IOException { |
| |
| // check if directory exist |
| File dirToCopy = new File(this.mainComponentDir, directory); |
| if (dirToCopy.exists()) { |
| File target = new File(this.pearPackagingDir, directory); |
| FileUtils.copyDirectory(dirToCopy, target); |
| // remove directories that begins with a "." -> e.g. .SVN |
| removeDotDirectories(target); |
| } |
| } |
| |
| /** |
| * Removes recursively all directories that begins with a "." e.g. ".SVN" |
| * |
| * @param dir |
| * directory to check for Dot-directories |
| * |
| * @throws IOException passthru |
| */ |
| private void removeDotDirectories(File dir) throws IOException { |
| ArrayList<File> subdirs = org.apache.uima.util.FileUtils.getSubDirs(dir); |
| |
| for (int i = 0; i < subdirs.size(); i++) { |
| File current = subdirs.get(i); |
| if (current.getName().startsWith(".")) { |
| org.apache.uima.util.FileUtils.deleteRecursive(current); |
| } else { |
| removeDotDirectories(current); |
| } |
| } |
| } |
| |
| /** |
| * Copies all the necessary PEAR directories (UIMA nature) to the PEAR |
| * packaging directory |
| * |
| * @throws IOException passthru |
| */ |
| private void copyPearData() throws IOException { |
| |
| // select all necessary PEAR package directories that have to be copied |
| String[] dirsToCopy = new String[] { |
| InstallationController.PACKAGE_CONF_DIR, |
| InstallationController.PACKAGE_DATA_DIR, |
| InstallationController.PACKAGE_DESC_DIR, |
| InstallationController.PACKAGE_DOC_DIR, |
| InstallationController.PACKAGE_LIB_DIR, |
| InstallationController.PACKAGE_METADATA_DIR, |
| InstallationController.PACKAGE_RESOURCES_DIR, |
| /* InstallationController.PACKAGE_SOURCES_DIR , */InstallationController.PACKAGE_BIN_DIR, }; |
| |
| // copies the selected directories if they exists |
| for (int i = 0; i < dirsToCopy.length; i++) { |
| copyDirIfAvailable(dirsToCopy[i]); |
| } |
| } |
| |
| /** |
| * create a PEAR package with |
| * |
| * @throws PackageCreatorException passthru |
| */ |
| private void createPear() throws PackageCreatorException { |
| //generates the PEAR packages with the given information |
| PackageCreator |
| .generatePearPackage(this.componentId, this.mainComponentDesc, |
| this.classpath, this.datapath, this.pearPackagingDir |
| .getAbsolutePath(), this.targetDir, this.props); |
| } |
| } |