/* * Copyright (c) 2006, 2007 Borland Software Corporation * * 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: * Artem Tikhomirov (Borland) - initial API and implementation */ package org.eclipse.gmf.internal.graphdef.codegen.ui; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.emf.common.CommonPlugin; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.gmf.graphdef.codegen.StandaloneGenerator; import org.eclipse.jdt.core.JavaConventions; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.forms.widgets.ExpandableComposite; public class GeneratePluginAction implements IObjectActionDelegate, IInputValidator { private List<IFile> mySelectedFiles = Collections.emptyList(); private IWorkbenchPart myTargetPart; private ConverterOptions myOptions; public GeneratePluginAction() { } public void setActivePart(IAction action, IWorkbenchPart targetPart) { myTargetPart = targetPart; } public void run(IAction action) { final ResourceSet rs = new ResourceSetImpl(); final Resource[] input = loadFromSelection(rs); StandaloneGeneratorOptionsDialog dialog = new StandaloneGeneratorOptionsDialog(getShell(), null, true, this); if (dialog.open() != IDialogConstants.OK_ID) { return; } String pluginId = dialog.getPluginId(); final StandaloneGenerator.Config config = new StandaloneGenerator.ConfigImpl(pluginId, pluginId, dialog.getMapModeCodeGenStrategy(), dialog.getRuntimeToken()); final ConverterOutcome converterOutcome = new ConverterOutcome(getOptions(), input); final IStatus inputCheck = converterOutcome.checkInputAgainstOptions(); if (!inputCheck.isOK()) { MessageDialog.openInformation(getShell(), "Nothing to do", inputCheck.getMessage()); return; } URL[] dynamicTemplates = null; if (dialog.getTemplatesPath() != null) { try { dynamicTemplates = new URL[1]; dynamicTemplates[0] = new URL(dialog.getTemplatesPath()); } catch (MalformedURLException ex) { MessageDialog.openWarning(getShell(), "Invalid dynamic template path", "Path for dynamic templates is invalid, proceeding without dynamic templates"); // fallthrough } } final StandaloneGenerator generator = new StandaloneGenerator(converterOutcome.getProcessor(), config, dynamicTemplates); generator.setSkipPluginStructure(false); new Job(action.getText()) { private IContainer myResourcesContainer; { setUser(true); } protected IStatus run(IProgressMonitor monitor) { try { generator.run(monitor); if (!generator.getRunStatus().isOK()) { return generator.getRunStatus(); } URI galleryURI = URI.createPlatformResourceURI(decideOnDestinationFile("bundled").getFullPath().toString(), true); URI canvasURI = URI.createPlatformResourceURI(decideOnDestinationFile("mirrored").getFullPath().toString(), true); return converterOutcome.createResources(rs, galleryURI, canvasURI); } catch (InterruptedException e) { return Status.CANCEL_STATUS; } finally { for (Resource next : rs.getResources()) { next.unload(); } } } private IFile decideOnDestinationFile(String baseName) { final IPath basePath = new Path(baseName); final String ext = "gmfgraph"; IFile resultFile = getResourcesContainer().getFile(basePath.addFileExtension(ext)); for (int i = 1; resultFile.exists(); i++) { resultFile = getResourcesContainer().getFile(new Path(basePath.lastSegment() + String.valueOf(i)).addFileExtension(ext)); } return resultFile; } private IContainer getResourcesContainer(){ if (myResourcesContainer == null){ IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(config.getPluginID()); assert p.exists(); // generator.runStatus.ok makes us believe myResourcesContainer = p; IFolder modelsFolder = p.getFolder("models"); if (!modelsFolder.exists()) { try { modelsFolder.create(true, true, new NullProgressMonitor()); myResourcesContainer = modelsFolder; } catch (CoreException ex) { // ignore or log? } } } return myResourcesContainer; } }.schedule(); } private Resource[] loadFromSelection(ResourceSet rs) { Resource[] rv = new Resource[mySelectedFiles.size()]; int i = 0; for (IFile next : mySelectedFiles) { rv[i++] = rs.getResource(URI.createPlatformResourceURI(next.getFullPath().toString(), true), true); } return rv; } public String isValid(String newText) { IStatus s = JavaConventions.validatePackageName(newText, JavaCore.VERSION_1_4, JavaCore.VERSION_1_4); if (s.isOK()) { return null; } return s.getMessage(); } private Shell getShell() { return myTargetPart.getSite().getShell(); } public void selectionChanged(IAction action, ISelection selection) { mySelectedFiles = new ArrayList<IFile>(5); if (selection instanceof IStructuredSelection) { @SuppressWarnings("unchecked") List<IFile> sel = ((IStructuredSelection) selection).toList(); mySelectedFiles.addAll(sel); } } private ConverterOptions getOptions() { if (myOptions == null) { myOptions = loadOptions(); } return myOptions; } private ConverterOptions loadOptions() { ConverterOptions options = new ConverterOptions(); options.needMirroredCanvas = true; options.needMirroredGalleries = true; return options; } private static class StandaloneGeneratorOptionsDialog extends FigureGeneratorOptionsDialog { private IInputValidator pluginIdValidator; private Text pluginIdText; private String pluginId; private String templatesPath; private final boolean shouldWarnLiteVerstionDoesNotSupportMapMode; private Text templatesPathControl; public StandaloneGeneratorOptionsDialog(Shell parentShell, String initialPluginId, boolean initialUseRuntimeFigures, IInputValidator pluginIdValidator) { this(parentShell, initialPluginId, initialUseRuntimeFigures, false, pluginIdValidator); } public StandaloneGeneratorOptionsDialog(Shell parentShell, String initialPluginId, boolean initialUseRuntimeFigures, boolean initialUseMapMode, IInputValidator pluginIdValidator) { super(parentShell, "Figure Gallery Generator", initialUseRuntimeFigures, initialUseMapMode); pluginId = initialPluginId; if (pluginId == null) { pluginId = ""; //$NON-NLS-1$ } this.pluginIdValidator = pluginIdValidator; shouldWarnLiteVerstionDoesNotSupportMapMode = Platform.getBundle("org.eclipse.gmf.codegen.lite") != null; } protected void createControls(Composite result) { Label label = new Label(result, SWT.WRAP); label.setText("Please specify the name of plug-in/main package"); GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER); data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); label.setLayoutData(data); pluginIdText = new Text(result, SWT.SINGLE | SWT.BORDER); pluginIdText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); final ModifyListener modifyListener = new ModifyListener() { public void modifyText(ModifyEvent e) { validateInput(); } }; pluginIdText.addModifyListener(modifyListener); ExpandableComposite c = new ExpandableComposite(result, SWT.NONE, ExpandableComposite.TWISTIE); final GridData d = new GridData(SWT.FILL, SWT.TOP, true, true); d.minimumHeight = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_BAR_HEIGHT); d.verticalIndent = 10; c.setLayoutData(d); c.setText("Dynamic templates"); templatesPathControl = new Text(c, SWT.SINGLE | SWT.BORDER); templatesPathControl.addModifyListener(modifyListener); c.setClient(templatesPathControl); super.createControls(result); } protected void validateInput() { String errorMessage = null; if (pluginIdValidator != null) { errorMessage = pluginIdValidator.isValid(pluginIdText.getText()); } if (errorMessage == null && templatesPathControl.getText().trim().length() > 0) { // do dynamic templates check only when pluginID is ok try { new URL(guessAndResolvePathURL(templatesPathControl.getText().trim())); } catch (Exception ex) { errorMessage = "Illegal dynamic templates path"; } } // Bug 16256: important not to treat "" (blank error) the same as null // (no error) setErrorMessage(errorMessage); } protected void warnLiteVerstionDoesNotSupportMapMode() { if (shouldWarnLiteVerstionDoesNotSupportMapMode) { super.warnLiteVerstionDoesNotSupportMapMode(); } } protected void okPressed() { pluginId = pluginIdText.getText(); templatesPath = templatesPathControl.getText().trim(); if (templatesPath.length() == 0) { templatesPath = null; } else { templatesPath = guessAndResolvePathURL(templatesPath); } super.okPressed(); } private static String guessAndResolvePathURL(String path) { assert path != null; URI templatesURI = path.indexOf(':') == -1 ? URI.createPlatformResourceURI(path, true) : URI.createURI(path); return CommonPlugin.resolve(templatesURI).toString(); } public String getPluginId() { return pluginId; } public String getTemplatesPath() { return templatesPath; } } }