/***************************************************************************** * Copyright (c) 2006-2013, Cloudsmith Inc. * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the copyright holder * listed above, as the Initial Contributor under such license. The text of * such license is available at www.eclipse.org. *****************************************************************************/ package org.eclipse.buckminster.core.commands; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.List; import org.eclipse.buckminster.cmdline.Option; import org.eclipse.buckminster.cmdline.OptionDescriptor; import org.eclipse.buckminster.cmdline.OptionValueType; import org.eclipse.buckminster.cmdline.SimpleErrorExitException; import org.eclipse.buckminster.core.Messages; import org.eclipse.buckminster.core.helpers.FileUtils; import org.eclipse.buckminster.core.mspec.ConflictResolution; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.runtime.IOUtils; import org.eclipse.buckminster.runtime.URLUtils; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.osgi.util.NLS; /** * @author Thomas Hallgren */ public abstract class WorkspaceInitCommand extends WorkspaceCommand { static final OptionDescriptor CONTINUE_ON_ERROR = new OptionDescriptor('C', "continueonerror", OptionValueType.NONE); //$NON-NLS-1$ static final OptionDescriptor MATERIALIZER = new OptionDescriptor('M', "materializer", OptionValueType.REQUIRED); //$NON-NLS-1$ static final OptionDescriptor TEMPLATE = new OptionDescriptor('T', "template", OptionValueType.REQUIRED); //$NON-NLS-1$ private static boolean isFolderEmpty(File folder) { String[] names = folder.list(); if (names != null) { int idx = names.length; while (--idx >= 0) if (!isFolderEmpty(new File(folder, names[idx]))) return false; } return !folder.isFile(); } private boolean continueOnError; private String materializer; private URL template; public void setContinueOnError(boolean flag) { continueOnError = flag; } public void setMaterializer(String materializer) { this.materializer = materializer; } public void setTemplate(URL template) { this.template = template; } protected String getMaterializer() { return materializer; } @Override protected void getOptionDescriptors(List<OptionDescriptor> appendHere) throws Exception { super.getOptionDescriptors(appendHere); appendHere.add(CONTINUE_ON_ERROR); appendHere.add(MATERIALIZER); appendHere.add(TEMPLATE); } @Override protected void handleOption(Option option) throws Exception { if (option.is(CONTINUE_ON_ERROR)) setContinueOnError(true); else if (option.is(TEMPLATE)) setTemplate(URLUtils.normalizeToURL(option.getValue())); else if (option.is(MATERIALIZER)) setMaterializer(option.getValue()); else super.handleOption(option); } @Override protected void initWorkspace(IProgressMonitor monitor) throws Exception { if (template != null) initWorkspaceFromTemplate(); super.initWorkspace(monitor); } /** * Initialize the current workspace from a template workspace. This method * must be called very early in the execution process. The current workspace * must be empty. It may well exist but it cannot contain any files, just * empty folders. * * @param template */ protected void initWorkspaceFromTemplate() throws Exception { try { File wsRoot = FileUtils.getFile(FileLocator.toFileURL(Platform.getInstanceLocation().getURL())); if (!isFolderEmpty(wsRoot)) throw new SimpleErrorExitException(NLS.bind(Messages.Workspace_at_0_is_not_empty, wsRoot)); IProgressMonitor nullMon = new NullProgressMonitor(); URL templateURL = FileLocator.toFileURL(template); String path = templateURL.getPath(); File fileTemplate; if (path.endsWith(".zip") || path.endsWith(".jar")) //$NON-NLS-1$ //$NON-NLS-2$ { File dest = FileUtils.createTempFolder("bmtpl", ".tmp"); //$NON-NLS-1$ //$NON-NLS-2$ InputStream input = null; try { input = new BufferedInputStream(templateURL.openStream()); FileUtils.unzip(input, null, dest, ConflictResolution.UPDATE, nullMon); } finally { IOUtils.close(input); } fileTemplate = dest; } else { fileTemplate = FileUtils.getFile(templateURL); if (fileTemplate == null) throw new SimpleErrorExitException(Messages.Only_zip_and_jar_files_allowed_for_remote_workspace_templates); if (!fileTemplate.isAbsolute()) fileTemplate = fileTemplate.getAbsoluteFile(); if (!fileTemplate.isDirectory()) throw new SimpleErrorExitException(Messages.Only_folders_zip_and_jar_files_can_be_uses_as_workspace_template); } FileUtils.deepCopyUnchecked(fileTemplate, wsRoot, nullMon); ResourcesPlugin.getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, nullMon); } catch (IOException e) { throw BuckminsterException.wrap(e); } } protected abstract int internalRun(boolean contOnError, IProgressMonitor monitor) throws Exception; @Override protected final int internalRun(IProgressMonitor monitor) throws Exception { return internalRun(continueOnError, monitor); } protected boolean isContinueOnError() { return continueOnError; } }