blob: f7bb6d76ee76a4cc8ad77bb84b48b5252702719b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.web.clientproject.createprojectapi;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.netbeans.api.annotations.common.CheckForNull;
import org.netbeans.api.project.Project;
import org.netbeans.modules.web.clientproject.ui.wizard.ClientSideProjectWizardIterator;
import org.netbeans.modules.web.clientproject.ui.wizard.NewClientSideProjectPanel;
import org.netbeans.modules.web.clientproject.ui.wizard.ToolsPanel;
import org.netbeans.modules.web.common.spi.ProjectWebRootQuery;
import org.openide.WizardDescriptor;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.util.NbBundle;
import org.openide.util.Pair;
/**
* Support class for creating new HTML5 projects.
* @since 1.65
*/
public final class CreateProjectUtils {
/**
* Constant for project directory, stored as {@link java.io.File} (the file does not need to exist).
* @see #createBaseWizardPanel(String)
*/
public static final String PROJECT_DIRECTORY = ClientSideProjectWizardIterator.Wizard.PROJECT_DIRECTORY;
/**
* Constant for project name, stored as {@link String}.
* @see #createBaseWizardPanel(String)
*/
public static final String PROJECT_NAME = ClientSideProjectWizardIterator.Wizard.NAME;
private CreateProjectUtils() {
}
/**
* Create base wizard panel for new HTML5 projects. This panel contains the base information
* about project, e.g. name, location etc. These properties are stored in the given {@link WizardDescriptor}.
* @param projectNameTemplate default project name, e.g. "JsLibrary"
* @return base wizard panel for new HTML5 projects together with its default display name
* @see #PROJECT_DIRECTORY
* @see #PROJECT_NAME
*/
@NbBundle.Messages("CreateProjectUtils.nameLocation.displayName=Name and Location")
public static Pair<WizardDescriptor.FinishablePanel<WizardDescriptor>, String> createBaseWizardPanel(String projectNameTemplate) {
return Pair.<WizardDescriptor.FinishablePanel<WizardDescriptor>, String>of(new NewClientSideProjectPanel(projectNameTemplate),
Bundle.CreateProjectUtils_nameLocation_displayName());
}
/**
* Create wizard panel for "Tools" (Bower, NPM, Grunt). All
* these tools are enabled by default.
* <p>
* Currently, this panel is always finishable.
* @param tools information about tools
* @return panel for "Tools" (Bower, NPM, Grunt) together with its default display name
*/
@NbBundle.Messages("CreateProjectUtils.tools.displayName=Tools")
public static Pair<WizardDescriptor.FinishablePanel<WizardDescriptor>, String> createToolsWizardPanel(Tools tools) {
return Pair.<WizardDescriptor.FinishablePanel<WizardDescriptor>, String>of(new ToolsPanel(new Tools(tools)),
Bundle.CreateProjectUtils_tools_displayName());
}
/**
* Instantiate "Tools" support. In other words, generate proper files.
* <p>
* This method is typically used in <code>WizardIterator</code>.
* @param project project to be used
* @param toolsPanel panel, created by {@link #createToolsWizardPanel()}
* @return set of generated files; can be empty but never {@code null}
* @throws IOException if any error occurs
* @see #createToolsWizardPanel()
* @since 1.68
*/
public static Set<FileObject> instantiateTools(Project project, WizardDescriptor.FinishablePanel<WizardDescriptor> toolsPanel) throws IOException {
if (!(toolsPanel instanceof ToolsPanel)) {
throw new IllegalArgumentException("toolsPanel must be created by #createToolsWizardPanel() method");
}
Set<FileObject> files = new HashSet<>();
FileObject folder = project.getProjectDirectory();
assert folder != null;
Tools tools = ((ToolsPanel) toolsPanel).getTools();
if (tools.isBower()) {
files.add(createFile(folder, "bower.json", "Templates/ClientSide/bower.json")); // NOI18N
// #251608
String webRootPath = getWebRootPath(project);
if (webRootPath != null) {
files.add(createFile(folder, ".bowerrc", "Templates/ClientSide/.bowerrc", // NOI18N
Collections.<String, Object>singletonMap("project", Collections.singletonMap("webRootPath", webRootPath)))); // NOI18N
}
}
if (tools.isNpm()) {
files.add(createFile(folder, "package.json", "Templates/ClientSide/package.json")); // NOI18N
}
if (tools.isGrunt()) {
files.add(createFile(folder, "Gruntfile.js", "Templates/ClientSide/Gruntfile.js")); // NOI18N
}
if (tools.isGulp()) {
files.add(createFile(folder, "gulpfile.js", "Templates/ClientSide/gulpfile.js")); // NOI18N
}
return files;
}
@CheckForNull
private static String getWebRootPath(Project project) {
for (FileObject webRoot : ProjectWebRootQuery.getWebRoots(project)) {
return FileUtil.getRelativePath(project.getProjectDirectory(), webRoot);
}
return null;
}
private static FileObject createFile(FileObject root, String file, String template) throws IOException {
return createFile(root, file, template, Collections.<String, Object>emptyMap());
}
private static FileObject createFile(FileObject root, String file, String template, Map<String, Object> parameters) throws IOException {
assert root != null;
assert root.isFolder() : root;
FileObject target = root.getFileObject(file);
if (target != null
&& target.isValid()) {
return target;
}
FileObject templateFile = FileUtil.getConfigFile(template);
DataFolder dataFolder = DataFolder.findFolder(root);
DataObject dataIndex = DataObject.find(templateFile);
return dataIndex.createFromTemplate(dataFolder, null, parameters).getPrimaryFile();
}
//~ Inner classes
/**
* Information about external tools.
* @since 1.68
*/
public static final class Tools {
private volatile boolean npm;
private volatile boolean bower;
private volatile boolean grunt;
private volatile boolean gulp;
/**
* Creates new tools with all tools disabled.
*/
public Tools() {
}
Tools(Tools tools) {
npm = tools.npm;
bower = tools.bower;
grunt = tools.grunt;
gulp = tools.gulp;
}
/**
* Creates external tools with all tools enabled.
* @return external tools with all tools enabled
*/
public static Tools all() {
return new Tools()
.setNpm(true)
.setBower(true)
.setGrunt(true)
.setGulp(true);
}
/**
* Is NPM tool enabled?
* @return {@code true} if NPM tool is enabled
*/
public boolean isNpm() {
return npm;
}
/**
* Set NPM tool.
* @param npm {@code true} if NPM tool is enabled
* @return self
*/
public Tools setNpm(boolean npm) {
this.npm = npm;
return this;
}
/**
* Is Bower tool enabled?
* @return {@code true} if Bower tool is enabled
*/
public boolean isBower() {
return bower;
}
/**
* Set Bower tool.
* @param bower {@code true} if Bower tool is enabled
* @return self
*/
public Tools setBower(boolean bower) {
this.bower = bower;
return this;
}
/**
* Is Grunt tool enabled?
* @return {@code true} if Grunt tool is enabled
*/
public boolean isGrunt() {
return grunt;
}
/**
* Set Grunt tool.
* @param grunt {@code true} if Grunt tool is enabled
* @return self
*/
public Tools setGrunt(boolean grunt) {
this.grunt = grunt;
return this;
}
/**
* Is Gulp tool enabled?
* @return {@code true} if Gulp tool is enabled
* @since 1.77
*/
public boolean isGulp() {
return gulp;
}
/**
* Set Gulp tool.
* @param gulp {@code true} if Gulp tool is enabled
* @return self
* @since 1.77
*/
public Tools setGulp(boolean gulp) {
this.gulp = gulp;
return this;
}
@Override
public String toString() {
return "Tools{" + "npm=" + npm + ", bower=" + bower + ", grunt=" + grunt + ", gulp=" + gulp + '}'; // NOI18N
}
}
}