blob: 077dc5fd827a4c49a3baaad0748837bef3e10c5a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.wizards;
import java.util.Arrays;
import java.util.HashSet;
import org.eclipse.swt.widgets.Display;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.util.InfoFilesUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.ui.wizards.NewModuleInfoWizardPage;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
public class NewModuleInfoWizard extends Wizard implements INewWizard {
private static final String TRUE= "true"; //$NON-NLS-1$
private NewModuleInfoWizardPage fPage;
private static final String MODULE_INFO_JAVA_FILENAME= JavaModelUtil.MODULE_INFO_JAVA;
private IPackageFragmentRoot fTargetPkgFragmentRoot;
private IPackageFragmentRoot[] fPackageFragmentRoots;
private IJavaProject fProject;
public NewModuleInfoWizard(IJavaProject project, IPackageFragmentRoot[] packageFragmentRoots, IPackageFragmentRoot targetPkgFragmentRoot) {
setDefaultPageImageDescriptor(JavaPluginImages.DESC_WIZBAN_NEWMODULE);
setDialogSettings(JavaPlugin.getDefault().getDialogSettings());
setWindowTitle(NewWizardMessages.NewModuleInfoWizard_title);
fProject= project;
fPackageFragmentRoots= packageFragmentRoots;
if (targetPkgFragmentRoot != null) {
fTargetPkgFragmentRoot= targetPkgFragmentRoot;
} else if (fPackageFragmentRoots != null && fPackageFragmentRoots.length > 0) {
fTargetPkgFragmentRoot= fPackageFragmentRoots[0];
}
}
@Override
public void addPages() {
super.addPages();
if (fPage == null) {
fPage= new NewModuleInfoWizardPage();
fPage.setWizard(this);
fPage.init(fProject);
}
addPage(fPage);
}
@Override
public boolean performFinish() {
IStatus status= fPage.getModuleNameStatus();
int severity= status.getSeverity();
if (severity == IStatus.OK || severity == IStatus.WARNING || severity == IStatus.INFO) {
if (fProject != null && fTargetPkgFragmentRoot != null && fPackageFragmentRoots != null && fPackageFragmentRoots.length > 0) {
try {
createAndOpenFile(fTargetPkgFragmentRoot, fPackageFragmentRoots);
new Job(Messages.format(NewWizardMessages.NewModuleInfoWizard_updateProject_job, this.fProject.getElementName())) {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
convertClasspathToModulePath(monitor);
} catch (CoreException e) {
return e.getStatus();
}
return Status.OK_STATUS;
}
}.schedule();
} catch (CoreException e) {
JavaPlugin.log(e);
}
}
}
return true;
}
private void createAndOpenFile(IPackageFragmentRoot targetPkgFragmentRoot, IPackageFragmentRoot[] packageFragmentRoots) throws CoreException {
createModuleInfoJava(targetPkgFragmentRoot, packageFragmentRoots);
IFile file= ((IFolder) targetPkgFragmentRoot.getCorrespondingResource()).getFile(MODULE_INFO_JAVA_FILENAME);
if (file.exists()) {
BasicNewResourceWizard.selectAndReveal(file, JavaPlugin.getActiveWorkbenchWindow());
openFile(file);
}
}
private void openFile(final IFile file) {
final IWorkbenchPage activePage= JavaPlugin.getActivePage();
if (activePage != null) {
final Display display= getDisplay();
if (display != null) {
display.asyncExec(new Runnable() {
@Override
public void run() {
try {
IDE.openEditor(activePage, file, true);
} catch (PartInitException e) {
JavaPlugin.log(e);
}
}
});
}
}
}
private Display getDisplay() {
Display display= Display.getCurrent();
if (display == null)
display= Display.getDefault();
return display;
}
private void createModuleInfoJava(IPackageFragmentRoot targetPkgFragmentRoot, IPackageFragmentRoot[] packageFragmentRoots) throws CoreException {
String fileContent= getModuleInfoFileContent(packageFragmentRoots);
IPackageFragment defaultPkg= targetPkgFragmentRoot.getPackageFragment(""); //$NON-NLS-1$
InfoFilesUtil.createInfoJavaFile(MODULE_INFO_JAVA_FILENAME, fileContent.toString(), defaultPkg, new NullProgressMonitor());
}
private String getModuleInfoFileContent(IPackageFragmentRoot[] packageFragmentRoots) throws CoreException {
HashSet<String> exportedPackages= new HashSet<>();
for (IPackageFragmentRoot packageFragmentRoot : packageFragmentRoots) {
for (IJavaElement child : packageFragmentRoot.getChildren()) {
if (child instanceof IPackageFragment) {
IPackageFragment pkgFragment= (IPackageFragment) child;
if (!pkgFragment.isDefaultPackage() && pkgFragment.getCompilationUnits().length != 0) {
exportedPackages.add(pkgFragment.getElementName());
}
}
}
}
String[] requiredModules= JavaCore.getReferencedModules(fProject);
String moduleName= fPage.getModuleNameText();
StringBuilder fileContent= new StringBuilder();
fileContent.append("module "); //$NON-NLS-1$
fileContent.append(moduleName);
fileContent.append(" {"); //$NON-NLS-1$
for (String exportedPkg : exportedPackages) {
fileContent.append("exports "); //$NON-NLS-1$
fileContent.append(exportedPkg);
fileContent.append(";"); //$NON-NLS-1$
}
for (String requiredModule : requiredModules) {
fileContent.append("requires "); //$NON-NLS-1$
fileContent.append(requiredModule);
fileContent.append(';');
}
fileContent.append('}');
return fileContent.toString();
}
private void convertClasspathToModulePath(IProgressMonitor monitor) throws JavaModelException {
boolean changed= false;
IClasspathEntry[] rawClasspath= this.fProject.getRawClasspath();
for (int i= 0; i < rawClasspath.length; i++) {
IClasspathEntry entry= rawClasspath[i];
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_LIBRARY:
case IClasspathEntry.CPE_PROJECT:
IClasspathAttribute[] newAttributes= addModuleAttributeIfNeeded(entry.getExtraAttributes());
if (newAttributes != null) {
rawClasspath[i]= addAttributes(entry, newAttributes);
changed= true;
}
break;
default:
// other kinds are not handled
}
}
if (changed) {
this.fProject.setRawClasspath(rawClasspath, monitor);
}
}
private IClasspathAttribute[] addModuleAttributeIfNeeded(IClasspathAttribute[] extraAttributes) {
for (int j= 0; j < extraAttributes.length; j++) {
IClasspathAttribute classpathAttribute= extraAttributes[j];
if (IClasspathAttribute.MODULE.equals(classpathAttribute.getName())) {
if (TRUE.equals(classpathAttribute.getValue())) {
return null; // no change required
}
extraAttributes[j]= JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, TRUE);
return extraAttributes;
}
}
extraAttributes= Arrays.copyOf(extraAttributes, extraAttributes.length+1);
extraAttributes[extraAttributes.length-1]= JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, TRUE);
return extraAttributes;
}
private IClasspathEntry addAttributes(IClasspathEntry entry, IClasspathAttribute[] extraAttributes) {
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_LIBRARY:
return JavaCore.newLibraryEntry(entry.getPath(), entry.getSourceAttachmentPath(),
entry.getSourceAttachmentRootPath(), entry.getAccessRules(), extraAttributes, entry.isExported());
case IClasspathEntry.CPE_PROJECT:
return JavaCore.newProjectEntry(entry.getPath(), entry.getAccessRules(), entry.combineAccessRules(),
extraAttributes, entry.isExported());
default:
return entry; // other kinds are not handled
}
}
@Override
public void init(IWorkbench workbench, IStructuredSelection selection) {
//do nothing
}
}