
org.nuiton.eugene.writer.FileGrabberFromClassPath Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eugene-core Show documentation
Show all versions of eugene-core Show documentation
Efficient Universal Generator.
package org.nuiton.eugene.writer;
/*
* #%L
* EUGene :: EUGene Core
* %%
* Copyright (C) 2004 - 2017 Code Lutin, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import io.ultreia.java4all.lang.ClassLoaders;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.plexus.util.FileUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Created on 5/24/15.
*
* @author Tony Chemit - [email protected]
* @since 3.0
*/
public class FileGrabberFromClassPath implements FileGrabber {
/** Logger. */
private static final Log log = LogFactory.getLog(FileGrabberFromClassPath.class);
private final ChainedFileWriterConfiguration configuration;
public FileGrabberFromClassPath(ChainedFileWriterConfiguration configuration) {
this.configuration = configuration;
}
@Override
public void addFilesToTreate(File extractDirectory,
String inputDirectory,
Set includePatterns,
ChainedFileWriterData result) throws IOException {
Map> filesByRoot = result.getFilesByRoot();
Map> resourcesByFile = result.getResourcesByFile();
// final input directory to use
File realInputDirectory;
// use the extracted path as input directory, otherwise there
// will have a problem : the incoming inputPath will not be
// an ancestor of his resources, so prefer to use the extracted
// path which fix this problem.
String inputPath = inputDirectory;
if (inputPath.equals("/")) {
realInputDirectory = extractDirectory;
} else {
realInputDirectory = new File(extractDirectory, inputPath.substring(1));
}
List newUrls = getFiles(inputDirectory, includePatterns);
List files = filesByRoot.get(realInputDirectory);
if (files == null) {
files = new ArrayList<>();
filesByRoot.put(realInputDirectory, files);
}
for (URL url : newUrls) {
// get the file
File file = extractFileFromClassPath(extractDirectory, url);
// add the file in reactor
files.add(file);
// get resources associated with the file
URL resourceFileUrl = getAssociatedResource(url);
if (resourceFileUrl == null) {
// no resource associated with the file
if (log.isDebugEnabled()) {
log.debug("[" + file + "] No resource associated.");
}
} else {
// get the resource file
File resourceFile = extractFileFromClassPath(extractDirectory, resourceFileUrl);
if (log.isDebugEnabled()) {
log.debug("[" + file + "] Detected resource " + resourceFile);
}
resourcesByFile.put(file, Collections.singletonList(resourceFile));
}
}
if (CollectionUtils.isNotEmpty(files)) {
// check that extracted directory exists, or creates it
boolean b = extractDirectory.exists() || extractDirectory.mkdirs();
if (!b) {
throw new IOException("Could not create directory " + extractDirectory);
}
}
}
protected List getFiles(String inputPath, Set includePattern) {
if (CollectionUtils.isEmpty(includePattern)) {
throw new IllegalArgumentException("Must have at least one include pattern");
}
List result = new ArrayList<>();
// search in class-path
ClassLoader loader = configuration.getClassLoader();
for (String pattern : includePattern) {
String path = inputPath;
//FIXME must change the file.separator to /
if (!path.endsWith("/")) {
path += "/";
}
path += pattern;
if (path.startsWith("/")) {
path = path.substring(1);
}
if (log.isDebugEnabled()) {
log.debug("Try to seek class-path file " + path);
}
if (pattern.contains("*")) {
// this is a multi-files to search
List urlList = ClassLoaders.getURLs(path, (URLClassLoader) loader);
if (CollectionUtils.isEmpty(urlList)) {
log.warn("Could not find in class-path files " + path);
} else {
for (URL url : urlList) {
if (configuration.isVerbose()) {
log.info("Detected class-path file " + url);
}
result.add(url);
}
}
} else {
// this is a simple unique search, improve performance
// by searching directly in classloader the resource
URL url = loader.getResource(path);
if (url == null) {
log.warn("Could not find in class-path the file " + path);
} else {
if (configuration.isVerbose()) {
log.info("Detected class-path file " + url);
}
result.add(url);
}
}
}
return result;
}
protected URL getAssociatedResource(URL file) throws IOException {
// obtain the properties files associated with the file
String path = file.toString();
String extension = "." + FileUtils.extension(path);
String filename = StringUtils.substring(path, 0, -extension.length()).concat(".properties");
if (log.isDebugEnabled()) {
log.info("path of file : " + path);
log.info("path of resource : " + filename);
}
URL result;
URL propertiesFile = URI.create(filename).toURL();
if (path.startsWith("file:")) {
//FIXME-tchemit-2015-05-24 Does this case happen here ?
// local file (not from class-path)
// can test directly on resource if it exists
File file1 = new File(propertiesFile.getFile());
if (file1.exists()) {
// resource exist, keep it
result = propertiesFile;
} else {
result = null;
}
} else {
InputStream in = null;
try {
in = propertiesFile.openStream();
// resource exist, keep it
result = propertiesFile;
} catch (IOException eee) {
// resource does not exists
log.warn("Could not find resource " + propertiesFile);
result = null;
} finally {
if (in != null) {
in.close();
}
}
}
return result;
}
protected File extractFileFromClassPath(File extractDirectory, URL url) throws IOException {
String path = url.getPath();
// case where file is extracted from jar, "!" found into url, ex:
// url: /home/.../agrosyst-api/target/agrosyst-api-1.0.1-SNAPSHOT.jar!/agrosyst.objectmodel
// path: /home/.../agrosyst-services/target/extracted-sources/model/agrosyst.objectmodel
// case where file is no extracted from jar, "!" not found into url, ex:
// url: /home/.../agrosyst-api/target/classes/agrosyst.objectmodel
// path: /home/.../agrosyst-services/target/extracted-sources/model/agrosyst.objectmodel
int index = path.indexOf("!");
if (index == -1) {
// case where file is no extracted from jar:
index = path.lastIndexOf("/") - 1; // -1: because we need to keep the last "/" from path
}
String relativePath = path.substring(index + 1);
File f = new File(extractDirectory, relativePath);
if (log.isDebugEnabled()) {
log.debug("extract " + url + " to " + f);
}
File parentFile = f.getParentFile();
boolean b = parentFile.exists() || parentFile.mkdirs();
if (!b) {
throw new IOException("Could not create directory " + f);
}
try (FileOutputStream out = new FileOutputStream(f)) {
IOUtils.copy(url.openStream(), out);
}
return f;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy