package org.netbeans.gradle.project.newproject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.JComponent;
import javax.swing.event.ChangeListener;
import org.netbeans.api.annotations.common.StaticResource;
import org.netbeans.api.java.platform.JavaPlatform;
import org.netbeans.api.templates.TemplateRegistration;
import org.netbeans.gradle.project.NbIcons;
import org.netbeans.gradle.project.properties.standard.SourceLevelProperty;
import org.netbeans.gradle.project.script.CommonScripts;
import org.netbeans.gradle.project.script.GroovyScripts;
import org.netbeans.gradle.project.util.NbFileUtils;
import org.netbeans.gradle.project.util.StringUtils;
import org.openide.WizardDescriptor;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.NbBundle.Messages;
@TemplateRegistration(
folder="Project/Gradle",
displayName="#template.multiGradleProject",
description="MultiProject.html",
iconBase=NbIcons.PROJECT_ICON_PATH)
@Messages("template.multiGradleProject=Gradle Root Project")
public final class GradleMultiProjectWizardIterator
implements
WizardDescriptor.BackgroundInstantiatingIterator<WizardDescriptor> {
@StaticResource
private static final String MULTI_PROJECT_BUILD_GRADLE = "org/netbeans/gradle/project/resources/newproject/multi-project-root.gradle";
@StaticResource
private static final String MULTI_PROJECT_COMMON_GRADLE = "org/netbeans/gradle/project/resources/newproject/multi-project-common.gradle";
@StaticResource
private static final String MULTI_PROJECT_SETTINGS_GRADLE = "org/netbeans/gradle/project/resources/newproject/multi-project-settings.gradle";
private static final String EXTENSION = GroovyScripts.EXTENSION;
private final List<WizardDescriptor.Panel<WizardDescriptor>> descriptors;
private final AtomicReference<GradleMultiProjectConfig> configRef;
private int descriptorIndex;
public GradleMultiProjectWizardIterator() {
this.descriptors = new ArrayList<>(1);
this.descriptorIndex = 0;
this.configRef = new AtomicReference<>(null);
}
private static void createSettingsGradle(Path projectDir) throws IOException {
Map<String, String> varReplaceMap =
Collections.singletonMap("${PROJECT_NAME}", NbFileUtils.getFileNameStr(projectDir));
NewProjectUtils.copyTemplateFile(MULTI_PROJECT_SETTINGS_GRADLE,
projectDir.resolve(CommonScripts.SETTINGS_BASE_NAME + EXTENSION),
NewProjectUtils.DEFAULT_FILE_ENCODING,
varReplaceMap);
}
private static void createParentGradle(
Path projectDir,
GradleMultiProjectConfig config) throws IOException {
Map<String, String> varReplaceMap = new HashMap<>();
varReplaceMap.put("${MAVEN_GROUP}", config.getMavenGroupId());
varReplaceMap.put("${MAVEN_VERSION}", config.getMavenVersion());
varReplaceMap.put("${SOURCE_LEVEL}", SourceLevelProperty.getSourceLevelFromPlatform(JavaPlatform.getDefault()));
NewProjectUtils.copyTemplateFile(
MULTI_PROJECT_COMMON_GRADLE,
projectDir.resolve("common.gradle"),
NewProjectUtils.DEFAULT_FILE_ENCODING,
varReplaceMap);
}
private static void copyToProject(
Path projectDir,
String resourcePath,
String fileName) throws IOException {
String content = StringUtils.getResourceAsString(
resourcePath,
NewProjectUtils.DEFAULT_FILE_ENCODING);
Path file = projectDir.resolve(fileName);
content = StringUtils.replaceLFWithPreferredLineSeparator(content);
StringUtils.writeStringToFile(content, NewProjectUtils.DEFAULT_FILE_ENCODING, file);
}
@Override
public Set<FileObject> instantiate() throws IOException {
GradleMultiProjectConfig config = configRef.get();
if (config == null) {
throw new IOException("Missing configuration.");
}
Path projectDir = config.getProjectFolder().normalize();
Files.createDirectories(projectDir);
FileObject projectDirObj = FileUtil.toFileObject(projectDir.toFile());
if (projectDirObj == null) {
throw new IOException("Failed to open directory: " + projectDir);
}
NewProjectUtils.createDefaultSourceDirs(projectDir);
createParentGradle(projectDir, config);
copyToProject(projectDir, MULTI_PROJECT_BUILD_GRADLE, CommonScripts.BUILD_BASE_NAME + EXTENSION);
createSettingsGradle(projectDir);
return Collections.singleton(projectDirObj);
}
@Override
public void initialize(WizardDescriptor wizard) {
uninitialize(wizard);
descriptorIndex = 0;
descriptors.add(new GradleMultiProjectConfigPanel(configRef, wizard));
wizard.putProperty ("NewProjectWizard_Title", "Gradle Project"); // NOI18N
JComponent c = (JComponent) descriptors.get(0).getComponent();
c.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, 0);
c.putClientProperty(WizardDescriptor.PROP_CONTENT_DATA, new String[] {"Name and Location"});
c.setName("Name and Location");
}
@Override
public void uninitialize(WizardDescriptor wizard) {
descriptors.clear();
configRef.set(null);
}
@Override
public WizardDescriptor.Panel<WizardDescriptor> current() {
return descriptors.get(descriptorIndex);
}
@Override
public String name() {
return "GradleMultiProjectTemplate";
}
@Override
public boolean hasNext() {
return descriptorIndex < descriptors.size() - 1;
}
@Override
public boolean hasPrevious() {
return descriptorIndex > 0;
}
@Override
public void nextPanel() {
if (!hasNext()) {
throw new NoSuchElementException();
}
descriptorIndex++;
}
@Override
public void previousPanel() {
if (!hasPrevious()) {
throw new NoSuchElementException();
}
descriptorIndex--;
}
@Override
public void addChangeListener(ChangeListener l) {
}
@Override
public void removeChangeListener(ChangeListener l) {
}
}