nbproject/project.xml
(inside <configuration>
).
+ */
+ public static final String PROJECT_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/clientside-project/1"; // NOI18N
+
+ /**
+ * The namespace of the XML element that should be used to store the project's specific configuration
+ * data in nbproject/private/private.xml
(inside <project-private>
).
+ */
+ public static final String PRIVATE_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/clientside-project-private/1"; // NOI18N
+
+ public static final Charset DEFAULT_PROJECT_CHARSET = getDefaultProjectCharset();
+
+ // #217970
+ private static Charset getDefaultProjectCharset() {
+ try {
+ return Charset.forName("UTF-8"); // NOI18N
+ } catch (IllegalCharsetNameException exception) {
+ // fallback
+ LOGGER.log(Level.INFO, "UTF-8 charset not supported, falling back to the default charset.", exception);
+ } catch (UnsupportedCharsetException exception) {
+ // fallback
+ LOGGER.log(Level.INFO, "UTF-8 charset not supported, falling back to the default charset.", exception);
+ }
+ return Charset.defaultCharset();
+ }
+
+ // misc persistent project properties:
+ public static final String PROJECT_ENCODING = "files.encoding"; //NOI18N
+ public static final String PROJECT_SITE_ROOT_FOLDER = "site.root.folder"; //NOI18N
+ public static final String PROJECT_TEST_FOLDER = "test.folder"; //NOI18N
+ public static final String PROJECT_CONFIG_FOLDER = "config.folder"; //NOI18N
+ public static final String PROJECT_SERVER = "server"; //NOI18N
+ public static final String PROJECT_START_FILE = "start.file"; //NOI18N
+ public static final String PROJECT_WEB_ROOT = "web.context.root"; //NOI18N
+ public static final String PROJECT_PROJECT_URL = "external.project.url"; //NOI18N
+ public static final String PROJECT_AUTO_REFRESH = "browser.autorefresh"; //NOI18N
+ public static final String PROJECT_HIGHLIGHT_SELECTION = "browser.highlightselection"; //NOI18N
+ public static final String PROJECT_SELECTED_BROWSER = "browser"; //NOI18N
+
+ // default paths:
+ public static final String DEFAULT_SITE_ROOT_FOLDER = "public_html"; //NOI18N
+ public static final String DEFAULT_TEST_FOLDER = "test"; //NOI18N
+ public static final String DEFAULT_CONFIG_FOLDER = "config"; //NOI18N
+
+ // template's descriptor file
+ public static final String TEMPLATE_DESCRIPTOR = "netbeans-project.properties"; //NOI18N
}
diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/ClientSideProjectGenerator.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/ClientSideProjectGenerator.java
new file mode 100644
--- /dev/null
+++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/ClientSideProjectGenerator.java
@@ -0,0 +1,370 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.web.clientproject.api.project;
+
+import java.awt.EventQueue;
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.netbeans.api.annotations.common.CheckForNull;
+import org.netbeans.api.annotations.common.NonNull;
+import org.netbeans.api.project.FileOwnerQuery;
+import org.netbeans.api.project.Project;
+import org.netbeans.api.project.ProjectManager;
+import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants;
+import org.netbeans.spi.project.support.ant.AntProjectHelper;
+import org.netbeans.spi.project.support.ant.EditableProperties;
+import org.netbeans.spi.project.support.ant.ProjectGenerator;
+import org.netbeans.spi.project.support.ant.PropertyUtils;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.Mutex;
+import org.openide.util.MutexException;
+import org.openide.util.Parameters;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * Creates a Web Client Side project from scratch according to some initial configuration.
+ *
+ * @since 1.34
+ * @author Martin Janicek
+ */
+public final class ClientSideProjectGenerator {
+
+ private static final Logger LOGGER = Logger.getLogger(ClientSideProjectGenerator.class.getName());
+
+
+ private ClientSideProjectGenerator() {
+ }
+
+ /**
+ * Creates a new empty client side project defined by the given {@link ProjectProperties}.
+ *
+ * @param properties used for project setup
+ * @return the helper object permitting it to be further customized
+ * @throws IOException in case something went wrong
+ */
+ public static AntProjectHelper createProject(@NonNull ProjectProperties properties) throws IOException {
+ FileObject projectDir = properties.getProjectDir();
+
+ AntProjectHelper helper = ProjectGenerator.createProject(projectDir, WebClientProjectConstants.WEB_CLIENT_PROJECT_TYPE);
+ Project project = FileOwnerQuery.getOwner(projectDir);
+
+ ensureDirectoriesExists(FileUtil.toFile(projectDir), properties);
+
+ setProjectName(helper, properties.getProjectName());
+ save(helper, project, properties);
+
+ return helper;
+ }
+
+ private static void ensureDirectoriesExists(@NonNull File projectDir, @NonNull ProjectProperties properties) throws IOException {
+ ensureDirectoryExists(PropertyUtils.resolveFile(projectDir, properties.getSiteRootFolder()));
+
+ String test = properties.getTestFolder();
+ if (test != null) {
+ ensureDirectoryExists(PropertyUtils.resolveFile(projectDir, test));
+ }
+
+ String config = properties.getConfigFolder();
+ if (config != null) {
+ ensureDirectoryExists(PropertyUtils.resolveFile(projectDir, config));
+ }
+ }
+
+ private static void ensureDirectoryExists(File folder) throws IOException {
+ if (!folder.isDirectory()) {
+ if (!folder.mkdirs()) {
+ throw new IOException("Cannot create folder " + folder);
+ }
+ }
+ }
+
+ private static void setProjectName(final AntProjectHelper projectHelper, final String name) {
+ ProjectManager.mutex().writeAccess(new Runnable() {
+ @Override
+ public void run() {
+ Element data = projectHelper.getPrimaryConfigurationData(true);
+ Document document = data.getOwnerDocument();
+ NodeList nameList = data.getElementsByTagNameNS(WebClientProjectConstants.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N
+ Element nameElement;
+ if (nameList.getLength() == 1) {
+ nameElement = (Element) nameList.item(0);
+ NodeList deadKids = nameElement.getChildNodes();
+ while (deadKids.getLength() > 0) {
+ nameElement.removeChild(deadKids.item(0));
+ }
+ } else {
+ nameElement = document.createElementNS(WebClientProjectConstants.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N
+ data.insertBefore(nameElement, data.getChildNodes().item(0));
+ }
+ nameElement.appendChild(document.createTextNode(name));
+ projectHelper.putPrimaryConfigurationData(data, true);
+ }
+ });
+ }
+
+ private static void save(
+ final AntProjectHelper helper,
+ final Project project,
+ final ProjectProperties properties) {
+
+ assert !EventQueue.isDispatchThread();
+ try {
+ // store properties
+ ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction
+ * This class is not thread-safe.
+ */
+ public static final class ProjectProperties {
+
+ private FileObject projectDir;
+ private String projectName;
+ private String startFile;
+ private String siteRootFolder;
+ private String testFolder;
+ private String configFolder;
+ private String encoding;
+
+
+ /**
+ * Get project directory, usually relative path.
+ *
+ * @return project directory, usually relative path; never returns {@code null} or empty string
+ */
+ @NonNull
+ public FileObject getProjectDir() {
+ return projectDir;
+ }
+
+ /**
+ * Set project directory, never {@code null} or empty string.
+ *
+ * @param projectDir project directory, never {@code null} or empty string
+ * @return itself
+ */
+ public ProjectProperties setProjectDir(FileObject projectDir) {
+ this.projectDir = projectDir;
+ return this;
+ }
+
+ /**
+ * Get project name.
+ *
+ * @return project name; never returns {@code null} or empty string
+ */
+ @NonNull
+ public String getProjectName() {
+ return projectName;
+ }
+
+ /**
+ * Set project name, never {@code null} or empty string.
+ *
+ * @param projectName project name, never {@code null} or empty string
+ * @return itself
+ */
+ public ProjectProperties setProjectName(String projectName) {
+ this.projectName = projectName;
+ return this;
+ }
+
+ /**
+ * Get start file.
+ *
+ * @return start file; never returns {@code null} or empty string
+ */
+ @NonNull
+ public String getStartFile() {
+ return startFile;
+ }
+
+ /**
+ * Set start file, never {@code null} or empty string.
+ *
+ * @param startFile start file, never {@code null} or empty string
+ * @return itself
+ */
+ public ProjectProperties setStartFile(String startFile) {
+ this.startFile = startFile;
+ return this;
+ }
+
+ /**
+ * Get Site Root folder, usually relative path.
+ *
+ * @return Site Root folder, usually relative path; never returns
+ * {@code null} or empty string
+ */
+ @NonNull
+ public String getSiteRootFolder() {
+ return siteRootFolder;
+ }
+
+ /**
+ * Set Site Root folder, never {@code null} or empty string.
+ *
+ * @param siteRootFolder Site Root folder, never {@code null} or empty
+ * string
+ * @return itself
+ */
+ public ProjectProperties setSiteRootFolder(@NonNull String siteRootFolder) {
+ Parameters.notEmpty("siteRootFolder", siteRootFolder);
+ this.siteRootFolder = siteRootFolder;
+ return this;
+ }
+
+ /**
+ * Get Test folder, usually relative path.
+ *
+ * @return Test folder, usually relative path; can be {@code null} if no
+ * Test folder is present
+ */
+ @CheckForNull
+ public String getTestFolder() {
+ return testFolder;
+ }
+
+ /**
+ * Set Test folder, can be {@code null} if there are no tests available.
+ *
+ * @param testFolder Test folder, can be {@code null} if there are no
+ * tests available
+ * @return itself
+ */
+ public ProjectProperties setTestFolder(String testFolder) {
+ this.testFolder = testFolder;
+ return this;
+ }
+
+ /**
+ * Get Config folder, usually relative path.
+ *
+ * @return Config folder, usually relative path; can be {@code null} if
+ * no Config folder is present
+ */
+ @CheckForNull
+ public String getConfigFolder() {
+ return configFolder;
+ }
+
+ /**
+ * Set Config folder, can be {@code null} if there is no config
+ * available.
+ *
+ * @param configFolder Config folder, can be {@code null} if there is no
+ * config available
+ * @return itself
+ */
+ public ProjectProperties setConfigFolder(String configFolder) {
+ this.configFolder = configFolder;
+ return this;
+ }
+
+ /**
+ * Get encoding.
+ *
+ * @return Encoding; can be {@code null} if no encoding is present
+ */
+ @NonNull
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Set encoding, can be {@code null} if there is no encoding available.
+ *
+ * @param encoding encoding, can be {@code null} if there is no encoding available
+ * @return itself
+ */
+ public ProjectProperties setEncoding(String encoding) {
+ this.encoding = encoding;
+ return this;
+ }
+ }
+}
diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/OnlineSites.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/sites/OnlineSites.java
rename from web.clientproject/src/org/netbeans/modules/web/clientproject/sites/OnlineSites.java
rename to web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/sites/OnlineSites.java
--- a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/OnlineSites.java
+++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/sites/OnlineSites.java
@@ -39,7 +39,7 @@
*
* Portions Copyrighted 2012 Sun Microsystems, Inc.
*/
-package org.netbeans.modules.web.clientproject.sites;
+package org.netbeans.modules.web.clientproject.api.project.sites;
import java.awt.EventQueue;
import java.io.File;
@@ -48,10 +48,8 @@
import java.util.logging.Logger;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation;
-import org.netbeans.modules.web.clientproject.util.FileUtilities;
+import org.netbeans.modules.web.clientproject.api.util.FileUtilities;
import org.openide.filesystems.FileObject;
-import org.openide.util.NbBundle;
-import org.openide.util.lookup.ServiceProvider;
public abstract class OnlineSites implements SiteTemplateImplementation {
@@ -126,116 +124,4 @@
public Collection