/******************************************************************************* * Copyright (c) 2008 Pierre-Antoine Grégoire. * 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: * Pierre-Antoine Grégoire - initial API and implementation *******************************************************************************/ package org.org.eclipse.cheatsheet.commands.internal.jobs; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Proxy; import java.net.URISyntaxException; import java.net.URL; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.org.eclipse.cheatsheet.commands.handlers.ModeParameterValues; import org.org.eclipse.core.utils.platform.tools.ArchivesToolBox; import org.org.eclipse.core.utils.platform.tools.IOToolBox; import org.org.eclipse.core.utils.platform.tools.ArchivesToolBox.WriteMode; import org.org.eclipse.core.utils.platform.wizards.StatusInfo; public class ExtractContentsInProjectJob extends Job { private static String JOB_ID = "CheatSheet helper: extract contents in project"; private URL fileUrl; private String pathInArchive; private String pathInProject; private String targetProjectName; private String mode; private String customSuffix; public ExtractContentsInProjectJob(String targetProjectName, URL fileUrl, String pathInArchive, String pathInProject, String mode, String customSuffix) { super(JOB_ID); this.targetProjectName = targetProjectName; this.fileUrl = fileUrl; this.pathInArchive = pathInArchive; this.pathInProject = pathInProject; this.mode = mode; this.customSuffix = customSuffix; } public IStatus run(IProgressMonitor monitor) { IStatus result = new StatusInfo(IStatus.OK, "Content extracted successfully."); try { if (!projectExistsInWorkspace(targetProjectName)) { decompressRemoteProjectArchiveIntoWorkspace(fileUrl, pathInArchive, targetProjectName, pathInProject, mode, monitor); } else { if (mode.equals(ModeParameterValues.REPLACE)) { decompressRemoteProjectArchiveIntoWorkspace(fileUrl, pathInArchive, targetProjectName, pathInProject, mode, monitor); } else if (mode.equals(ModeParameterValues.SUFFIX)) { decompressRemoteProjectArchiveIntoWorkspace(fileUrl, pathInArchive, targetProjectName, pathInProject, mode, monitor); } else if (mode.equals(ModeParameterValues.SKIP)) { // Skip ;) } } } catch (Throwable e) { monitor.setCanceled(true); result = new StatusInfo(IStatus.ERROR, "A problem occured while extracting data:\n" + e.getMessage()); } monitor.done(); return result; } private void decompressRemoteProjectArchiveIntoWorkspace(URL fileUrl, String pathInArchive, String targetProjectName, String pathInProject, final String mode, IProgressMonitor createProgressGroup) throws IOException, CoreException, URISyntaxException { File tmpFile = File.createTempFile("cheatsheets", ".zipfile"); downloadToLocalFile(tmpFile, fileUrl, IOToolBox.determineProxy(fileUrl)); IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceRoot root = workspace.getRoot(); IProject project = root.getProject(targetProjectName); File targetFolder = project.getLocation().makeAbsolute().toFile(); targetFolder = new File(targetFolder, pathInProject); targetFolder.mkdirs(); ArchivesToolBox.decompressArchiveSubPartTo(tmpFile, targetFolder, pathInArchive, new ArchivesToolBox.IWriteHinter() { public WriteMode getFileWriteMode(File file) { WriteMode result = WriteMode.REPLACE; if (file.exists()) { if (mode.equals(ModeParameterValues.SKIP)) { result = WriteMode.SKIP; } } return result; } public String alterFolderName(File targetFolder, String folderName) { return folderName; } public String alterFileName(File targetFolder, String fileName) { String result = fileName; File file = new File(targetFolder, fileName); if (file.exists()) { if (mode.equals(ModeParameterValues.SUFFIX)) { if (customSuffix != null) { result = suffixFileNameWithCustomSuffix(targetFolder, fileName); } else { result = suffixFileNameWithNumber(targetFolder, fileName); } } } return result; } private String suffixFileNameWithNumber(File targetFolder, String fileName) { int i = 1; int lastDotIndex = fileName.lastIndexOf("."); String result = fileName; if (lastDotIndex == 0) { result = fileName + "." + (i++); } else { result = fileName.substring(0, lastDotIndex) + "." + (i++) + fileName.substring(lastDotIndex, fileName.length()); } File file = new File(targetFolder, result); while (file.exists()) { lastDotIndex = fileName.lastIndexOf("."); if (lastDotIndex == 0) { result = fileName + "." + (i++); } else { result = fileName.substring(0, lastDotIndex) + "." + (i++) + fileName.substring(lastDotIndex, fileName.length()); } file = new File(targetFolder, result); } return result; } private String suffixFileNameWithCustomSuffix(File targetFolder, String fileName) { String result = fileName; int lastDotIndex = fileName.lastIndexOf("."); if (lastDotIndex == 0) { result = fileName + customSuffix; } else { result = fileName.substring(0, lastDotIndex) + customSuffix + fileName.substring(lastDotIndex, fileName.length()); } if (new File(targetFolder, result).exists()) { result = suffixFileNameWithNumber(targetFolder, result); } return result; } }); if (!project.isOpen()) { project.open(new SubProgressMonitor(createProgressGroup, 1)); } project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(createProgressGroup, 1)); } private boolean projectExistsInWorkspace(String targetProjectName) { IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); IResource member = workspaceRoot.findMember(targetProjectName); return (member != null && member.getAdapter(IProject.class) != null); } private static void downloadToLocalFile(File targetFile, URL requestedURL, Proxy proxy) { InputStream is = null; FileOutputStream out = null; try { is = open(requestedURL, proxy); targetFile.createNewFile(); out = new FileOutputStream(targetFile); byte[] buf = new byte[1024]; // 1K buffer int bytesRead; while ((bytesRead = is.read(buf)) != -1) { out.write(buf, 0, bytesRead); } } catch (IOException e) { e.printStackTrace(); } finally { close(is); close(out); } } private static void close(InputStream in) { if (in != null) { try { in.close(); } catch (IOException e1) { // ignore. } } } private static void close(OutputStream out) { if (out != null) { try { out.close(); } catch (IOException e1) { // ignore. } } } private static InputStream open(URL url, Proxy proxy) throws IOException { InputStream inputStream = null; if (proxy != null) { inputStream = url.openConnection(proxy).getInputStream(); } else { inputStream = url.openConnection().getInputStream(); } return inputStream; } }