blob: f30cd381fbf8c9cf701fb5a98ca2538009a8ec27 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2005, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.ui.wizards;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.resources.IFile;
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.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.dialogs.WizardNewProjectReferencePage;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.statet.ecommons.templates.TemplateMessages;
import org.eclipse.statet.ecommons.text.TextUtil;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.ui.templates.CodeGenerationTemplateContext;
import org.eclipse.statet.ltk.ui.templates.TemplateUtils.EvaluatedTemplate;
import org.eclipse.statet.ltk.ui.wizards.LTKWizardsMessages;
import org.eclipse.statet.ltk.ui.wizards.NewElementWizard;
import org.eclipse.statet.r.core.RBuildpaths;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.RProjects;
import org.eclipse.statet.r.core.RResourceUnit;
import org.eclipse.statet.r.ui.RUI;
public class NewRPkgProjectWizard extends NewElementWizard {
private static class NewDescriptionFile extends NewFile {
private final String pkgName;
private final String pkgAuthor;
private final String pkgMaintainer;
public NewDescriptionFile(final IPath containerPath, final String pkgName,
final String pkgAuthor, final String pkgMaintainer) {
super(containerPath, RBuildpaths.PKG_DESCRIPTION_FILE_NAME,
RCore.RPKG_DESCRIPTION_CONTENT_TYPE );
this.pkgName= pkgName;
this.pkgAuthor= pkgAuthor;
this.pkgMaintainer= pkgMaintainer;
}
@Override
protected String getInitialFileContent(final IFile newFileHandle, final SubMonitor m) {
final String lineDelimiter= TextUtil.getLineDelimiter(newFileHandle.getProject());
final ISourceUnit su= RResourceUnit.createTempUnit(newFileHandle, "RPkgDescription"); //$NON-NLS-1$
try {
final EvaluatedTemplate data= evaluateTemplate(su, lineDelimiter);
if (data != null) {
this.initialSelection= data.getRegionToSelect();
return data.getContent();
}
}
catch (final CoreException e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, 0,
"An error occured when applying template to new package description file.",
e ));
}
finally {
if (su != null) {
su.disconnect(m);
}
}
return null;
}
private EvaluatedTemplate evaluateTemplate(final ISourceUnit su,
final String lineDelimiter)
throws CoreException {
final Template template= RUIPlugin.getInstance().getRPkgCodeGenerationTemplateStore()
.findTemplate(RPkgTemplateContextType.NEW_DESCRIPTION_FILE_ID);
if (template == null) {
return null;
}
final CodeGenerationTemplateContext context= new CodeGenerationTemplateContext(
new RPkgTemplateContextType(RPkgTemplateContextType.NEW_DESCRIPTION_CONTEXTTYPE),
su, lineDelimiter );
context.setVariable(RPkgTemplateContextType.R_PKG_NAME_VAR_NAME, this.pkgName);
context.setVariable(RPkgTemplateContextType.R_PKG_AUTHOR_VAR_NAME, this.pkgAuthor);
context.setVariable(RPkgTemplateContextType.R_PKG_MAINTAINER_VAR_NAME, this.pkgMaintainer);
try {
final TemplateBuffer buffer= context.evaluate(template);
if (buffer == null) {
return null;
}
return new EvaluatedTemplate(buffer, lineDelimiter);
}
catch (final Exception e) {
throw new CoreException(new Status(IStatus.ERROR, RUI.BUNDLE_ID, NLS.bind(
TemplateMessages.TemplateEvaluation_error_description, template.getDescription()), e));
}
}
}
private static class NewNamespaceFile extends NewFile {
private final String pkgName;
public NewNamespaceFile(final IPath containerPath, final String pkgName) {
super(containerPath, RBuildpaths.PKG_NAMESPACE_FILE_NAME,
RCore.RPKG_NAMESPACE_CONTENT_TYPE );
this.pkgName= pkgName;
}
@Override
protected String getInitialFileContent(final IFile newFileHandle, final SubMonitor m) {
final String lineDelimiter= TextUtil.getLineDelimiter(newFileHandle.getProject());
final ISourceUnit su= RResourceUnit.createTempUnit(newFileHandle, "RPkgDescription"); //$NON-NLS-1$
try {
final EvaluatedTemplate data= evaluateTemplate(su, lineDelimiter);
if (data != null) {
this.initialSelection= data.getRegionToSelect();
return data.getContent();
}
}
catch (final CoreException e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, 0,
"An error occured when applying template to new package description file.",
e ));
}
finally {
if (su != null) {
su.disconnect(m);
}
}
return null;
}
private EvaluatedTemplate evaluateTemplate(final ISourceUnit su,
final String lineDelimiter)
throws CoreException {
final Template template= RUIPlugin.getInstance().getRPkgCodeGenerationTemplateStore()
.findTemplate(RPkgTemplateContextType.NEW_NAMESPACE_FILE_ID);
if (template == null) {
return null;
}
final CodeGenerationTemplateContext context= new CodeGenerationTemplateContext(
new RPkgTemplateContextType(RPkgTemplateContextType.NEW_NAMESPACE_CONTEXTTYPE),
su, lineDelimiter );
context.setVariable(RPkgTemplateContextType.R_PKG_NAME_VAR_NAME, this.pkgName);
try {
final TemplateBuffer buffer= context.evaluate(template);
if (buffer == null) {
return null;
}
return new EvaluatedTemplate(buffer, lineDelimiter);
}
catch (final Exception e) {
throw new CoreException(new Status(IStatus.ERROR, RUI.BUNDLE_ID, NLS.bind(
TemplateMessages.TemplateEvaluation_error_description, template.getDescription()), e));
}
}
}
private NewRProjectWizardPage firstPage;
private RPkgProjectWizardPage rPkgPage;
private WizardNewProjectReferencePage referencePage;
private NewProject newRProject;
private NewContainer newRPkgRoot;
private NewDescriptionFile newDescriptionFile;
private NewNamespaceFile newNamespaceFile;
public NewRPkgProjectWizard() {
setDialogSettings(DialogUtils.getDialogSettings(RUIPlugin.getInstance(), "NewElementWizard")); //$NON-NLS-1$
setDefaultPageImageDescriptor(RUI.getImageDescriptor(RUIPlugin.IMG_WIZBAN_NEW_RPKGPROJECT));
setWindowTitle(Messages.NewRPkgProjectWizard_title);
}
@Override
public void addPages() {
super.addPages();
this.firstPage= new NewRProjectWizardPage(getSelection(), Messages.NewRPkgProjectWizardPage_title);
addPage(this.firstPage);
this.rPkgPage= new RPkgProjectWizardPage(this.firstPage);
addPage(this.rPkgPage);
// only add page if there are already projects in the workspace
if (ResourcesPlugin.getWorkspace().getRoot().getProjects().length > 0) {
this.referencePage= new WizardNewProjectReferencePage("BasicProjectReferencePage"); //$NON-NLS-1$
this.referencePage.setTitle(LTKWizardsMessages.NewProjectReferencePage_title);
this.referencePage.setDescription(LTKWizardsMessages.NewProjectReferencePage_description);
addPage(this.referencePage);
}
}
// protected ISchedulingRule getSchedulingRule() { // root-rule required to change project description
@Override
public boolean performFinish() {
final IProject project= this.firstPage.getProjectHandle();
final String pkgName= this.rPkgPage.getPkgName();
final IPath pkgRoot= this.rPkgPage.getPkgFolderPath();
final IPath pkgRootFullPath= project.getFullPath().append(pkgRoot);
this.newRProject= new NewProject(project,
(this.firstPage.useDefaults()) ? null : this.firstPage.getLocationPath(),
(this.referencePage != null) ? this.referencePage.getReferencedProjects() : null,
this.firstPage.getSelectedWorkingSets()
) {
@Override
protected void doConfigProject(final IProject project, final IProgressMonitor monitor) throws CoreException {
RProjects.setupRPkgProject(getResource(), pkgRoot, monitor);
}
};
this.newRPkgRoot= new NewContainer(pkgRootFullPath);
this.newDescriptionFile= new NewDescriptionFile(pkgRootFullPath, pkgName,
this.rPkgPage.getPkgAuthor(), this.rPkgPage.getPkgMaintainer() );
this.newNamespaceFile= new NewNamespaceFile(pkgRootFullPath, pkgName);
final boolean result= super.performFinish();
if (result) {
this.rPkgPage.saveSettings();
updatePerspective();
selectAndReveal(this.newDescriptionFile.getResource());
openResource(this.newDescriptionFile);
}
return result;
}
@Override
protected void performOperations(
final IProgressMonitor monitor) throws InterruptedException, CoreException, InvocationTargetException {
final SubMonitor m= SubMonitor.convert(monitor, "Create new R package project...",
10 + 2 + 2 + 1 + 2 * 1);
this.newRProject.createProject(m.newChild(10));
this.newRPkgRoot.createContainer(m.newChild(2));
if (!this.newDescriptionFile.getResource().exists()) {
this.newDescriptionFile.createFile(m.newChild(2));
}
if (!this.newNamespaceFile.getResource().exists()) {
this.newNamespaceFile.createFile(m.newChild(1));
}
this.newRPkgRoot.createSubFolder(RBuildpaths.PKG_R_FOLDER_PATH, m.newChild(1));
this.newRPkgRoot.createSubFolder(RBuildpaths.PKG_MAN_FOLDER_PATH, m.newChild(1));
}
}