/******************************************************************************* * Copyright (c) 2015, 2016 Red Hat Inc. 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: * Red Hat - Initial Contribution *******************************************************************************/ package org.eclipse.linuxtools.internal.docker.ui.wizards; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashSet; import java.util.Set; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.runtime.Path; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.linuxtools.docker.ui.Activator; import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; public class ImageBuildPage extends WizardPage { private final static String NAME = "ImageBuild.name"; //$NON-NLS-1$ private final static String TITLE = "ImageBuild.title"; //$NON-NLS-1$ private final static String DESC = "ImageBuild.desc"; //$NON-NLS-1$ private final static String NAME_LABEL = "ImageBuildName.label"; //$NON-NLS-1$ private final static String NAME_TOOLTIP = "ImageBuildName.toolTip"; //$NON-NLS-1$ private final static String DIRECTORY_LABEL = "ImageBuildDirectory.label"; //$NON-NLS-1$ private final static String DIRECTORY_TOOLTIP = "ImageBuildDirectory.toolTip"; //$NON-NLS-1$ private final static String BROWSE_LABEL = "BrowseButton.label"; //$NON-NLS-1$ private final static String EDIT_LABEL = "EditButton.label"; //$NON-NLS-1$ private final static String NONEXISTENT_DIRECTORY = "ErrorNonexistentDirectory.msg"; //$NON-NLS-1$ private final static String INVALID_DIRECTORY = "ErrorInvalidDirectory.msg"; //$NON-NLS-1$ private final static String UNREADABLE_DIRECTORY = "ErrorUnreadableDirectory.msg"; //$NON-NLS-1$ private final static String INVALID_ID = "ErrorInvalidImageId.msg"; //$NON-NLS-1$ private final static String NO_DOCKER_FILE = "ErrorNoDockerFile.msg"; //$NON-NLS-1$ private Text nameText; private Text directoryText; private Button editButton; private Set<IEditorPart> editors = new HashSet<>(); /* * For now just hold the last directory path used here. If this page gets * more complicated (and ends up requiring a model) we should consider using * a launch configuration to store all other previous values. */ private static String lastDirectoryPath; public ImageBuildPage() { super(WizardMessages.getString(NAME)); setDescription(WizardMessages.getString(DESC)); setTitle(WizardMessages.getString(TITLE)); setImageDescriptor(SWTImagesFactory.DESC_WIZARD); } public String getImageName() { return nameText.getText(); } public String getDirectory() { return directoryText.getText(); } @Override public void dispose() { super.dispose(); for (IEditorPart p : editors) { p.getEditorSite().getPage().closeEditor(p, true); } editors.clear(); } private ModifyListener Listener = e -> validate(); private void validate() { boolean complete = true; boolean error = false; String name = nameText.getText(); if (name.length() > 0 && name.charAt(name.length() - 1) == ':') { //$NON-NLS-1$ // && (tag.length() > 0) || tag.contains(":")) { //$NON-NLS-1$ setErrorMessage(WizardMessages.getString(INVALID_ID)); error = true; } else { if (name.contains(":")) { //$NON-NLS-$ if (name.substring(name.indexOf(':') + 1).contains(":")) { //$NON-NLS-1$ setErrorMessage(WizardMessages.getString(INVALID_ID)); error = true; } } } if (!error) { String dir = directoryText.getText(); if (dir.length() == 0) { editButton.setEnabled(false); complete = false; } else { IFileStore fileStore = EFS.getLocalFileSystem().getStore( new Path(dir)); IFileInfo info = fileStore.fetchInfo(); if (!info.exists()) { error = true; setErrorMessage(WizardMessages .getString(NONEXISTENT_DIRECTORY)); } else if (!info.isDirectory()) { error = true; setErrorMessage(WizardMessages.getString(INVALID_DIRECTORY)); } else if (!Files.isReadable(Paths.get(dir))) { error = true; setErrorMessage( WizardMessages.getString(UNREADABLE_DIRECTORY)); } else { editButton.setEnabled(true); IFileStore dockerStore = fileStore.getChild("Dockerfile"); //$NON-NLS-1$ if (!dockerStore.fetchInfo().exists()) { complete = false; setMessage(WizardMessages.getString(NO_DOCKER_FILE), IMessageProvider.INFORMATION); } else { setMessage(null, IMessageProvider.INFORMATION); lastDirectoryPath = dir; } } } } if (!error) { setErrorMessage(null); } else { editButton.setEnabled(false); } setPageComplete(complete && !error); } @Override public void createControl(Composite parent) { final Composite container = new Composite(parent, SWT.NULL); FormLayout layout = new FormLayout(); layout.marginHeight = 5; layout.marginWidth = 5; container.setLayout(layout); Label label = new Label(container, SWT.NULL); Label nameLabel = new Label(container, SWT.NULL); nameLabel.setText(WizardMessages.getString(NAME_LABEL)); nameText = new Text(container, SWT.BORDER | SWT.SINGLE); nameText.addModifyListener(Listener); nameText.setToolTipText(WizardMessages.getString(NAME_TOOLTIP)); Label dirLabel = new Label(container, SWT.NULL); dirLabel.setText(WizardMessages.getString(DIRECTORY_LABEL)); directoryText = new Text(container, SWT.BORDER | SWT.SINGLE); directoryText.addModifyListener(Listener); directoryText.setToolTipText(WizardMessages .getString(DIRECTORY_TOOLTIP)); Button browse = new Button(container, SWT.NULL); browse.setText(WizardMessages.getString(BROWSE_LABEL)); browse.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { DirectoryDialog d = new DirectoryDialog(container.getShell()); String k = d.open(); if (k != null) directoryText.setText(k); } }); editButton = new Button(container, SWT.NULL); editButton.setText(WizardMessages.getString(EDIT_LABEL)); editButton.setEnabled(false); editButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String dir = directoryText.getText(); IFileStore fileStore = EFS.getLocalFileSystem().getStore( new Path(dir).append("Dockerfile")); //$NON-NLS-1$ java.nio.file.Path filePath = Paths.get(dir, "Dockerfile"); //$NON-NLS-1$ if (!Files.exists(filePath)) { try { Files.createFile(filePath); } catch (IOException e1) { // File won't exist, and directory should be writable } } IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); try { IEditorPart dockerFileEditor = IDE.openEditorOnFileStore(page, fileStore); IWorkbenchPartSite site = page.getActivePart().getSite(); EModelService s = site.getService(EModelService.class); MPartSashContainerElement p = site.getService(MPart.class); s.detach(p, 100, 100, 500, 375); editors.add(dockerFileEditor); } catch (PartInitException e1) { Activator.log(e1); } validate(); } }); Point p1 = label.computeSize(SWT.DEFAULT, SWT.DEFAULT); Point p2 = directoryText.computeSize(SWT.DEFAULT, SWT.DEFAULT); Point p3 = browse.computeSize(SWT.DEFAULT, SWT.DEFAULT); int centering = (p2.y - p1.y + 1) / 2; int centering2 = (p3.y - p2.y + 1) / 2; FormData f = new FormData(); f.top = new FormAttachment(0); label.setLayoutData(f); f = new FormData(); f.top = new FormAttachment(label, 11 + centering + centering2); f.left = new FormAttachment(0, 0); nameLabel.setLayoutData(f); f = new FormData(); f.top = new FormAttachment(label, 11 + centering2); f.left = new FormAttachment(nameLabel, 5); f.right = new FormAttachment(browse, -10); nameText.setLayoutData(f); f = new FormData(); f.top = new FormAttachment(nameLabel, 11 + centering + centering2); f.left = new FormAttachment(0, 0); dirLabel.setLayoutData(f); f = new FormData(); f.top = new FormAttachment(nameLabel, 11); f.right = new FormAttachment(100); editButton.setLayoutData(f); f = new FormData(); f.top = new FormAttachment(nameLabel, 11); f.right = new FormAttachment(editButton, -10); browse.setLayoutData(f); f = new FormData(); f.top = new FormAttachment(nameLabel, 11 + centering2); f.left = new FormAttachment(nameLabel, 5); f.right = new FormAttachment(browse, -10); directoryText.setLayoutData(f); if (lastDirectoryPath != null) { directoryText.setText(lastDirectoryPath); } setControl(container); setPageComplete(false); } }