| /******************************************************************************* |
| * Copyright (c) 2008, 2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 219530 [jar application] add Jar-in-Jar ClassLoader option |
| *******************************************************************************/ |
| |
| package org.eclipse.jdt.internal.ui.jarpackagerfat; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Set; |
| import java.util.zip.ZipFile; |
| |
| import org.eclipse.swt.widgets.Shell; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.MultiStatus; |
| |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| |
| import org.eclipse.jdt.ui.jarpackager.IManifestProvider; |
| import org.eclipse.jdt.ui.jarpackager.JarPackageData; |
| |
| import org.eclipse.jdt.internal.ui.jarpackager.JarPackagerUtil; |
| |
| /** |
| * A jar builder which extracts the required libraries into a folder next to the generated jar. |
| * |
| * @since 3.5 |
| */ |
| public class UnpackJarBuilder extends FatJarBuilder { |
| |
| public static final String BUILDER_ID= "org.eclipse.jdt.ui.unpack_jar_builder"; //$NON-NLS-1$ |
| private static final String SUBFOLDER_SUFFIX= "_lib"; //$NON-NLS-1$ |
| |
| private final String fSubfolder; |
| private final IPath fSubfolderPath; |
| |
| private JarPackageData fJarPackage; |
| |
| private Set<String> jarNames; |
| |
| public UnpackJarBuilder(JarPackageData jarPackage) { |
| fSubfolder= jarPackage.getAbsoluteJarLocation().removeFileExtension().lastSegment() + SUBFOLDER_SUFFIX; |
| fSubfolderPath= jarPackage.getAbsoluteJarLocation().removeLastSegments(1).append(fSubfolder); |
| fJarPackage= jarPackage; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public String getId() { |
| return BUILDER_ID; |
| } |
| |
| /** |
| * we do not need to merge any manifests here. |
| * @return false |
| */ |
| @Override |
| public boolean isMergeManifests() { |
| return false; |
| } |
| |
| /** |
| * we do not need to remove signers here. |
| * @return false |
| */ |
| @Override |
| public boolean isRemoveSigners() { |
| return false; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public IManifestProvider getManifestProvider() { |
| return new FatJarManifestProvider(this); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public String getManifestClasspath() { |
| Set<String> renamedJarNames= new HashSet<String>(); |
| Object[] elements= fJarPackage.getElements(); |
| for (int i= 0; i < elements.length; i++) { |
| Object element= elements[i]; |
| if (element instanceof IPackageFragmentRoot && ((IPackageFragmentRoot)element).isArchive()) { |
| String jarName= ((IPackageFragmentRoot)element).getPath().toFile().getName(); |
| while (renamedJarNames.contains(jarName)) { |
| jarName= FatJarPackagerUtil.nextNumberedFileName(jarName); |
| } |
| renamedJarNames.add(jarName); |
| } |
| } |
| StringBuffer result= new StringBuffer(); |
| result.append("."); //$NON-NLS-1$ |
| for (Iterator<String> iterator= renamedJarNames.iterator(); iterator.hasNext();) { |
| String jarName= iterator.next(); |
| result.append(" ").append(fSubfolder).append("/").append(jarName); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return result.toString(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void open(JarPackageData jarPackage, Shell displayShell, MultiStatus status) throws CoreException { |
| super.open(jarPackage, displayShell, status); |
| fJarPackage= jarPackage; |
| jarNames= new HashSet<String>(); |
| createBlankSubfolder(displayShell, jarPackage.allowOverwrite()); |
| } |
| |
| /** |
| * creates the subfolder or cleanup an existing subfolder. A dialog will ask the user. |
| * |
| * @param parent the parent for the dialog, or <code>null</code> if no dialog should be |
| * presented |
| * @param allowOverwrite true if the packager is allowed to overwrite existing folders |
| * @throws CoreException if creation of folder failed |
| */ |
| protected void createBlankSubfolder(Shell parent, boolean allowOverwrite) throws CoreException { |
| File folder= fSubfolderPath.toFile(); |
| // Test if directory exists |
| if (!folder.exists()) { |
| // create sub-folder |
| if (!folder.mkdirs()) |
| throw JarPackagerUtil.createCoreException("Could not create lib-folder '" + folder.getAbsolutePath() + "'", null); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else { |
| if (!folder.canWrite()) |
| throw JarPackagerUtil.createCoreException("Folder '" + folder.getAbsolutePath() + "' is not writable", null); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (!allowOverwrite) |
| if (parent == null || !JarPackagerUtil.askForOverwriteFolderPermission(parent, fSubfolderPath, true)) |
| throw JarPackagerUtil.createCoreException("Folder '" + folder.getAbsolutePath() + "' exists and should not be overwritten", null); //$NON-NLS-1$ //$NON-NLS-2$ |
| File[] jarFiles= folder.listFiles(); |
| for (int i= 0; i < jarFiles.length; i++) { |
| if (!jarFiles[i].isFile()) |
| throw JarPackagerUtil.createCoreException("Subfolder '" + jarFiles[i].getAbsolutePath() + "' exists", null); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (!jarFiles[i].delete()) |
| throw JarPackagerUtil.createCoreException("Could not delete file '" + jarFiles[i].getAbsolutePath() + "'", null); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| } |
| |
| /** |
| * |
| * {@inheritDoc} |
| */ |
| |
| public void writeArchive(ZipFile jarFile, IProgressMonitor progressMonitor) { |
| File jarPathFile= new File(jarFile.getName()); |
| String jarName= jarPathFile.getName(); |
| while (jarNames.contains(jarName)) { |
| jarName= FatJarPackagerUtil.nextNumberedFileName(jarName); |
| } |
| jarNames.add(jarName); |
| File destJarPathFile= new File(fSubfolderPath.toFile(), jarName); |
| copyFile(jarPathFile, destJarPathFile); |
| } |
| |
| private void copyFile(File src, File dest) { |
| InputStream in= null; |
| OutputStream out= null; |
| try { |
| in= new FileInputStream(src); |
| out= new FileOutputStream(dest); |
| byte[] buf= new byte[4096]; |
| int cnt= in.read(buf); |
| while (cnt > 0) { |
| out.write(buf, 0, cnt); |
| cnt= in.read(buf); |
| } |
| } catch (RuntimeException e) { |
| throw new RuntimeException(e); |
| } catch (FileNotFoundException e) { |
| throw new RuntimeException(e); |
| } catch (IOException e) { |
| throw new RuntimeException(e); |
| } finally { |
| try { |
| out.close(); |
| } catch (IOException ignore) { |
| } |
| try { |
| in.close(); |
| } catch (IOException ignore) { |
| } |
| } |
| } |
| |
| } |