use of hudson.util.IOException2 in project hudson-2.x by hudson.
the class ClassicPluginStrategy method createPluginWrapper.
public PluginWrapper createPluginWrapper(File archive) throws IOException {
final Manifest manifest;
URL baseResourceURL;
File expandDir = null;
// if .hpi, this is the directory where war is expanded
boolean isLinked = archive.getName().endsWith(".hpl");
if (isLinked) {
// resolve the .hpl file to the location of the manifest file
String firstLine = new BufferedReader(new FileReader(archive)).readLine();
if (firstLine.startsWith("Manifest-Version:")) {
// this is the manifest already
} else {
// indirection
archive = resolve(archive, firstLine);
}
// then parse manifest
FileInputStream in = new FileInputStream(archive);
try {
manifest = new Manifest(in);
} catch (IOException e) {
throw new IOException2("Failed to load " + archive, e);
} finally {
in.close();
}
} else {
if (archive.isDirectory()) {
// already expanded
expandDir = archive;
} else {
expandDir = new File(archive.getParentFile(), PluginWrapper.getBaseName(archive));
explode(archive, expandDir);
}
File manifestFile = new File(expandDir, "META-INF/MANIFEST.MF");
if (!manifestFile.exists()) {
throw new IOException("Plugin installation failed. No manifest at " + manifestFile);
}
FileInputStream fin = new FileInputStream(manifestFile);
try {
manifest = new Manifest(fin);
} finally {
fin.close();
}
}
final Attributes atts = manifest.getMainAttributes();
// TODO: define a mechanism to hide classes
// String export = manifest.getMainAttributes().getValue("Export");
List<File> paths = new ArrayList<File>();
if (isLinked) {
parseClassPath(manifest, archive, paths, "Libraries", ",");
// backward compatibility
parseClassPath(manifest, archive, paths, "Class-Path", " +");
baseResourceURL = resolve(archive, atts.getValue("Resource-Path")).toURI().toURL();
} else {
File classes = new File(expandDir, "WEB-INF/classes");
if (classes.exists())
paths.add(classes);
File lib = new File(expandDir, "WEB-INF/lib");
File[] libs = lib.listFiles(JAR_FILTER);
if (libs != null)
paths.addAll(Arrays.asList(libs));
baseResourceURL = expandDir.toURI().toURL();
}
File disableFile = new File(archive.getPath() + ".disabled");
if (disableFile.exists()) {
LOGGER.info("Plugin " + archive.getName() + " is disabled");
}
// compute dependencies
List<PluginWrapper.Dependency> dependencies = new ArrayList<PluginWrapper.Dependency>();
List<PluginWrapper.Dependency> optionalDependencies = new ArrayList<PluginWrapper.Dependency>();
String v = atts.getValue("Plugin-Dependencies");
if (v != null) {
for (String s : v.split(",")) {
PluginWrapper.Dependency d = new PluginWrapper.Dependency(s);
if (d.optional) {
optionalDependencies.add(d);
} else {
dependencies.add(d);
}
}
}
for (DetachedPlugin detached : DETACHED_LIST) detached.fix(atts, optionalDependencies);
ClassLoader dependencyLoader = new DependencyClassLoader(getBaseClassLoader(atts), archive, Util.join(dependencies, optionalDependencies));
return new PluginWrapper(pluginManager, archive, manifest, baseResourceURL, createClassLoader(paths, dependencyLoader, atts), disableFile, dependencies, optionalDependencies);
}
use of hudson.util.IOException2 in project hudson-2.x by hudson.
the class FilePath method copyFrom.
/**
* Place the data from {@link FileItem} into the file location specified by this {@link FilePath} object.
*/
public void copyFrom(FileItem file) throws IOException, InterruptedException {
if (channel == null) {
try {
file.write(new File(remote));
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException2(e);
}
} else {
InputStream i = file.getInputStream();
OutputStream o = write();
try {
IOUtils.copy(i, o);
} finally {
o.close();
i.close();
}
}
}
use of hudson.util.IOException2 in project hudson-2.x by hudson.
the class FilePath method installIfNecessaryFrom.
/**
* Given a tgz/zip file, extracts it to the given target directory, if necessary.
*
* <p>
* This method is a convenience method designed for installing a binary package to a location
* that supports upgrade and downgrade. Specifically,
*
* <ul>
* <li>If the target directory doesn't exist {@linkplain #mkdirs() it'll be created}.
* <li>The timestamp of the .tgz file is left in the installation directory upon extraction.
* <li>If the timestamp left in the directory doesn't match with the timestamp of the current archive file,
* the directory contents will be discarded and the archive file will be re-extracted.
* <li>If the connection is refused but the target directory already exists, it is left alone.
* </ul>
*
* @param archive
* The resource that represents the tgz/zip file. This URL must support the "Last-Modified" header.
* (Most common usage is to get this from {@link ClassLoader#getResource(String)})
* @param listener
* If non-null, a message will be printed to this listener once this method decides to
* extract an archive.
* @return
* true if the archive was extracted. false if the extraction was skipped because the target directory
* was considered up to date.
* @since 1.299
*/
public boolean installIfNecessaryFrom(URL archive, TaskListener listener, String message) throws IOException, InterruptedException {
try {
URLConnection con;
try {
con = ProxyConfiguration.open(archive);
con.connect();
} catch (IOException x) {
if (this.exists()) {
// Cannot connect now, so assume whatever was last unpacked is still OK.
if (listener != null) {
listener.getLogger().println("Skipping installation of " + archive + " to " + remote + ": " + x);
}
return false;
} else {
throw x;
}
}
long sourceTimestamp = con.getLastModified();
FilePath timestamp = this.child(".timestamp");
if (this.exists()) {
if (timestamp.exists() && sourceTimestamp == timestamp.lastModified())
// already up to date
return false;
this.deleteContents();
} else {
this.mkdirs();
}
if (listener != null)
listener.getLogger().println(message);
InputStream in = con.getInputStream();
CountingInputStream cis = new CountingInputStream(in);
try {
if (archive.toExternalForm().endsWith(".zip"))
unzipFrom(cis);
else
untarFrom(cis, GZIP);
} catch (IOException e) {
throw new IOException2(String.format("Failed to unpack %s (%d bytes read of total %d)", archive, cis.getByteCount(), con.getContentLength()), e);
}
timestamp.touch(sourceTimestamp);
return true;
} catch (IOException e) {
throw new IOException2("Failed to install " + archive + " to " + remote, e);
}
}
use of hudson.util.IOException2 in project hudson-2.x by hudson.
the class FilePath method readFromTar.
/**
* Reads from a tar stream and stores obtained files to the base dir.
*/
private static void readFromTar(String name, File baseDir, InputStream in) throws IOException {
TarInputStream t = new TarInputStream(in);
try {
TarEntry te;
while ((te = t.getNextEntry()) != null) {
File f = new File(baseDir, te.getName());
if (te.isDirectory()) {
f.mkdirs();
} else {
File parent = f.getParentFile();
if (parent != null)
parent.mkdirs();
IOUtils.copy(t, f);
f.setLastModified(te.getModTime().getTime());
int mode = te.getMode() & 0777;
if (// be defensive
mode != 0 && !Functions.isWindows())
_chmod(f, mode);
}
}
} catch (IOException e) {
throw new IOException2("Failed to extract " + name, e);
} finally {
t.close();
}
}
use of hudson.util.IOException2 in project hudson-2.x by hudson.
the class Util method getDigestOf.
/**
* Computes MD5 digest of the given input stream.
*
* @param source
* The stream will be closed by this method at the end of this method.
* @return
* 32-char wide string
*/
public static String getDigestOf(InputStream source) throws IOException {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
DigestInputStream in = new DigestInputStream(source, md5);
try {
while (in.read(garbage) > 0) // simply discard the input
;
} finally {
in.close();
}
return toHexString(md5.digest());
} catch (NoSuchAlgorithmException e) {
// impossible
throw new IOException2("MD5 not installed", e);
}
}
Aggregations