/** Generates a manifest file to be included in the .hpi file */
  protected void generateManifest(MavenArchiveConfiguration archive, File manifestFile)
      throws MojoExecutionException {
    // create directory if it doesn't exist yet
    if (!manifestFile.getParentFile().exists()) manifestFile.getParentFile().mkdirs();

    getLog().info("Generating " + manifestFile);

    MavenArchiver ma = new MavenArchiver();
    ma.setOutputFile(manifestFile);

    PrintWriter printWriter = null;
    try {
      Manifest mf = ma.getManifest(project, archive.getManifest());
      Section mainSection = mf.getMainSection();
      setAttributes(mainSection);

      printWriter =
          new PrintWriter(new OutputStreamWriter(new FileOutputStream(manifestFile), "UTF-8"));
      mf.write(printWriter);
    } catch (ManifestException e) {
      throw new MojoExecutionException("Error preparing the manifest: " + e.getMessage(), e);
    } catch (DependencyResolutionRequiredException e) {
      throw new MojoExecutionException("Error preparing the manifest: " + e.getMessage(), e);
    } catch (IOException e) {
      throw new MojoExecutionException("Error preparing the manifest: " + e.getMessage(), e);
    } finally {
      IOUtil.close(printWriter);
    }
  }
 /** Create the {@link ResourceFinderImpl} for the project */
 @SuppressWarnings("unchecked")
 protected ResourceFinder getResourceFinder() throws MojoExecutionException {
   final ResourceFinder finder = new ResourceFinderImpl(this.project);
   try {
     final List<String> classpathElements = this.project.getCompileClasspathElements();
     finder.setCompileClassPath(classpathElements);
   } catch (DependencyResolutionRequiredException e) {
     throw new MojoExecutionException(e.getMessage(), e);
   }
   finder.setPluginClassPath(getClass().getClassLoader());
   return finder;
 }
  private File[] getClassPathFiles() {
    final List<File> files = new ArrayList<>();
    List<?> classpathElements;
    try {
      classpathElements = project.getTestClasspathElements();
    } catch (DependencyResolutionRequiredException e) {
      throw new RuntimeException(e.getMessage(), e);
    }

    for (final Object o : classpathElements) {
      if (o != null) {
        final File file = new File(o.toString());
        if (file.canRead()) {
          files.add(file);
        }
      }
    }
    return files.toArray(new File[files.size()]);
  }
  @SuppressWarnings({"unchecked"})
  public final void execute(final Callback callback)
      throws MojoExecutionException, MojoFailureException {
    if (!skip) {
      if (header == null) {
        warn("No header file specified to check for license");
        return;
      }
      if (!strictCheck) {
        warn(
            "Property 'strictCheck' is not enabled. Please consider adding <strictCheck>true</strictCheck> in your pom.xml file.");
        warn("See http://mycila.github.io/license-maven-plugin for more information.");
      }

      finder = new ResourceFinder(basedir);
      try {
        finder.setCompileClassPath(project.getCompileClasspathElements());
      } catch (DependencyResolutionRequiredException e) {
        throw new MojoExecutionException(e.getMessage(), e);
      }
      finder.setPluginClassPath(getClass().getClassLoader());

      final Header h = new Header(finder.findResource(this.header), encoding, headerSections);
      debug("Header %s:\n%s", h.getLocation(), h);

      if (this.validHeaders == null) {
        this.validHeaders = new String[0];
      }
      final List<Header> validHeaders = new ArrayList<Header>(this.validHeaders.length);
      for (String validHeader : this.validHeaders) {
        validHeaders.add(new Header(finder.findResource(validHeader), encoding, headerSections));
      }

      final List<PropertiesProvider> propertiesProviders = new LinkedList<PropertiesProvider>();
      for (PropertiesProvider provider :
          ServiceLoader.load(
              PropertiesProvider.class, Thread.currentThread().getContextClassLoader())) {
        propertiesProviders.add(provider);
      }
      final DocumentPropertiesLoader propertiesLoader =
          new DocumentPropertiesLoader() {
            @Override
            public Properties load(Document document) {
              Properties props = new Properties();

              for (Map.Entry<String, String> entry : mergeProperties(document).entrySet()) {
                if (entry.getValue() != null) {
                  props.setProperty(entry.getKey(), entry.getValue());
                } else {
                  props.remove(entry.getKey());
                }
              }
              for (PropertiesProvider provider : propertiesProviders) {
                try {
                  final Map<String, String> providerProperties =
                      provider.getAdditionalProperties(AbstractLicenseMojo.this, props, document);
                  if (getLog().isDebugEnabled()) {
                    getLog()
                        .debug(
                            "provider: "
                                + provider.getClass()
                                + " brought new properties\n"
                                + providerProperties);
                  }
                  for (Map.Entry<String, String> entry : providerProperties.entrySet()) {
                    if (entry.getValue() != null) {
                      props.setProperty(entry.getKey(), entry.getValue());
                    } else {
                      props.remove(entry.getKey());
                    }
                  }
                } catch (Exception e) {
                  getLog().warn("failure occured while calling " + provider.getClass(), e);
                }
              }
              return props;
            }
          };

      final DocumentFactory documentFactory =
          new DocumentFactory(
              basedir,
              buildMapping(),
              buildHeaderDefinitions(),
              encoding,
              keywords,
              propertiesLoader);

      int nThreads = (int) (Runtime.getRuntime().availableProcessors() * concurrencyFactor);
      ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
      CompletionService completionService = new ExecutorCompletionService(executorService);
      int count = 0;
      debug("Number of execution threads: %s", nThreads);

      try {
        for (final String file : listSelectedFiles()) {
          completionService.submit(
              new Runnable() {
                @Override
                public void run() {
                  Document document = documentFactory.createDocuments(file);
                  debug(
                      "Selected file: %s [header style: %s]",
                      document.getFilePath(), document.getHeaderDefinition());
                  if (document.isNotSupported()) {
                    callback.onUnknownFile(document, h);
                  } else if (document.is(h)) {
                    debug("Skipping header file: %s", document.getFilePath());
                  } else if (document.hasHeader(h, strictCheck)) {
                    callback.onExistingHeader(document, h);
                  } else {
                    boolean headerFound = false;
                    for (Header validHeader : validHeaders) {
                      if (headerFound = document.hasHeader(validHeader, strictCheck)) {
                        callback.onExistingHeader(document, h);
                        break;
                      }
                    }
                    if (!headerFound) {
                      callback.onHeaderNotFound(document, h);
                    }
                  }
                }
              },
              null);
          count++;
        }

        while (count-- > 0) {
          try {
            completionService.take().get();
          } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
          } catch (ExecutionException e) {
            Throwable cause = e.getCause();
            if (cause instanceof Error) {
              throw (Error) cause;
            }
            if (cause instanceof MojoExecutionException) {
              throw (MojoExecutionException) cause;
            }
            if (cause instanceof MojoFailureException) {
              throw (MojoFailureException) cause;
            }
            if (cause instanceof RuntimeException) {
              throw (RuntimeException) cause;
            }
            throw new RuntimeException(cause.getMessage(), cause);
          }
        }

      } finally {
        executorService.shutdownNow();
      }
    }
  }