diff --git a/web.client.samples/nbproject/project.xml b/web.client.samples/nbproject/project.xml --- a/web.client.samples/nbproject/project.xml +++ b/web.client.samples/nbproject/project.xml @@ -51,19 +51,11 @@ - org.netbeans.modules.web.clientproject - - - - 1.7 - - - org.netbeans.modules.web.clientproject.api - 1.29 + 1.37 diff --git a/web.client.samples/src/org/netbeans/modules/web/client/samples/wizard/iterator/OnlineSampleWizardIterator.java b/web.client.samples/src/org/netbeans/modules/web/client/samples/wizard/iterator/OnlineSampleWizardIterator.java --- a/web.client.samples/src/org/netbeans/modules/web/client/samples/wizard/iterator/OnlineSampleWizardIterator.java +++ b/web.client.samples/src/org/netbeans/modules/web/client/samples/wizard/iterator/OnlineSampleWizardIterator.java @@ -48,22 +48,16 @@ import java.util.LinkedHashSet; import java.util.Set; import org.netbeans.api.progress.ProgressHandle; -import org.netbeans.api.project.FileOwnerQuery; -import org.netbeans.api.project.ProjectManager; import org.netbeans.modules.web.client.samples.wizard.WizardConstants; import org.netbeans.modules.web.client.samples.wizard.ui.OnlineSamplePanel; -import org.netbeans.modules.web.clientproject.ClientSideProject; -import org.netbeans.modules.web.clientproject.ClientSideProjectConstants; -import org.netbeans.modules.web.clientproject.ClientSideProjectType; -import org.netbeans.modules.web.clientproject.sites.OnlineSites; -import org.netbeans.modules.web.clientproject.sites.SiteHelper; -import org.netbeans.modules.web.clientproject.spi.ClientProjectExtender; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; +import org.netbeans.modules.web.clientproject.api.project.ClientSideProjectGenerator; +import org.netbeans.modules.web.clientproject.api.project.sites.OnlineSites; +import org.netbeans.modules.web.clientproject.api.project.sites.SiteHelper; import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation; -import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation.ProjectProperties; -import org.netbeans.modules.web.clientproject.util.ClientSideProjectUtilities; 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.PropertyEvaluator; +import org.netbeans.spi.project.support.ant.PropertyUtils; import org.netbeans.spi.project.ui.support.ProjectChooser; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; @@ -71,11 +65,7 @@ import org.openide.WizardDescriptor.Panel; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; -import org.openide.util.Lookup; import org.openide.util.NbBundle; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; /** * @@ -83,7 +73,7 @@ */ public abstract class OnlineSampleWizardIterator extends AbstractWizardIterator { - private static final String LIBRARIES_PATH = "LIBRARIES_PATH"; // NOI18N + private PropertyEvaluator eval; protected OnlineSampleWizardIterator() { @@ -117,54 +107,43 @@ }; } - /* - * The whole code bellow this comment is more or less a copy of the code from - * the HTML5 Project, class ClientSideProjectWizardIterator. It wasn't possible - * to reuse easily the code from the original module and we are to close to the - * final release of NetBeans 7.3, so I don't want to change the original HTML5 - * Project at the moment. - * - * BUT the current design is quite shitty (HTML5 Sample module depends on the - * HTML5 Project which was never designed as an API). We should move some classes - * from HTML5 Project module to the HTML5 Project API/SPI and use those. Plus we - * need to get rid of the public packages in HTML5 Project (it is only temporary - * solution) - */ - @NbBundle.Messages({ - "OnlineSampleWizardIterator.creatingProject=Creating project..." + "OnlineSampleWizardIterator.creatingProject=Creating project...", + "OnlineSampleWizardIterator.applyingTemplate=Applying template..." }) @Override public Set instantiate(ProgressHandle handle) throws IOException { handle.start(); handle.progress(Bundle.OnlineSampleWizardIterator_creatingProject()); //NOI18N - final Set files = new LinkedHashSet(); - final File projectDir = FileUtil.normalizeFile((File) descriptor.getProperty(WizardConstants.SAMPLE_PROJECT_DIR)); - final String name = (String) descriptor.getProperty(WizardConstants.SAMPLE_PROJECT_NAME); + File projectDir = FileUtil.normalizeFile((File) descriptor.getProperty(WizardConstants.SAMPLE_PROJECT_DIR)); + String projectName = (String) descriptor.getProperty(WizardConstants.SAMPLE_PROJECT_NAME); if (!projectDir.isDirectory() && !projectDir.mkdirs()) { throw new IOException("Cannot create project directory"); //NOI18N } - final FileObject projectDirFO = FileUtil.toFileObject(projectDir); - - AntProjectHelper projectHelper = ProjectGenerator.createProject(projectDirFO, ClientSideProjectType.TYPE); - setProjectName(projectHelper, name); + FileObject projectDirFO = FileUtil.toFileObject(projectDir); // Always open top dir as a project: + Set files = new LinkedHashSet(); files.add(projectDirFO); - ClientSideProject project = (ClientSideProject) FileOwnerQuery.getOwner(projectHelper.getProjectDirectory()); + SiteTemplateImplementation siteTemplate = getSiteTemplate(); + SiteTemplateImplementation.ProjectProperties siteTemplateProperties = createSiteTemplateProps(siteTemplate); - // Setting start file - EditableProperties properties = projectHelper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); - properties.put(ClientSideProjectConstants.PROJECT_START_FILE, getStartFile()); - projectHelper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, properties); + ClientSideProjectGenerator.CreateProjectProperties properties = createProjectProps(siteTemplateProperties, projectDirFO, projectName); + AntProjectHelper helper = ClientSideProjectGenerator.createProject(properties); - FileObject siteRoot = instantiate(handle, descriptor, project); + if (siteTemplate != null) { + handle.progress(Bundle.OnlineSampleWizardIterator_applyingTemplate()); + applySiteTemplate(helper.getProjectDirectory(), siteTemplateProperties, siteTemplate, handle); + } - // start file - FileObject startFile = siteRoot.getFileObject(getStartFile()); // NOI18N + // get application dir: + FileObject siteRoot = getSiteRootFolder(helper); + + // Open also start file if exists + FileObject startFile = siteRoot.getFileObject(getStartFile()); if (startFile != null) { files.add(startFile); } @@ -178,75 +157,40 @@ return files; } - protected String getStartFile() { - return "index.html"; + private SiteTemplateImplementation.ProjectProperties createSiteTemplateProps(SiteTemplateImplementation siteTemplate) { + SiteTemplateImplementation.ProjectProperties properties = new SiteTemplateImplementation.ProjectProperties(); + + properties.setSiteRootFolder(WebClientProjectConstants.DEFAULT_SITE_ROOT_FOLDER); + properties.setTestFolder(WebClientProjectConstants.DEFAULT_TEST_FOLDER); + properties.setConfigFolder(WebClientProjectConstants.DEFAULT_CONFIG_FOLDER); + + if (siteTemplate != null) { + siteTemplate.configure(properties); + } + + return properties; } - private 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(ClientSideProjectType.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(ClientSideProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N - data.insertBefore(nameElement, data.getChildNodes().item(0)); - } - nameElement.appendChild(document.createTextNode(name)); - projectHelper.putPrimaryConfigurationData(data, true); - } - }); + private ClientSideProjectGenerator.CreateProjectProperties createProjectProps( + final SiteTemplateImplementation.ProjectProperties siteTemplateProperties, + final FileObject projectDirFO, + final String projectName) { + + ClientSideProjectGenerator.CreateProjectProperties properties = new ClientSideProjectGenerator.CreateProjectProperties(); + properties.setProjectDir(projectDirFO); + properties.setProjectName(projectName); + properties.setStartFile(getStartFile()); + properties.setEncoding(WebClientProjectConstants.DEFAULT_PROJECT_CHARSET.name()); + + properties.setSiteRootFolder(siteTemplateProperties.getSiteRootFolder()); + properties.setConfigFolder(siteTemplateProperties.getConfigFolder()); + properties.setTestFolder(siteTemplateProperties.getTestFolder()); + + return properties; } - @NbBundle.Messages({ - "OnlineSampleWizardIterator.applyingTemplate=Applying template..." - }) - private FileObject instantiate(ProgressHandle handle, WizardDescriptor wizardDescriptor, ClientSideProject project) throws IOException { - AntProjectHelper projectHelper = project.getProjectHelper(); - SiteTemplateImplementation siteTemplate = getSiteTemplate(); - - ProjectProperties projectProperties = new ProjectProperties(); - projectProperties.setSiteRootFolder(ClientSideProjectConstants.DEFAULT_SITE_ROOT_FOLDER); - projectProperties.setTestFolder(ClientSideProjectConstants.DEFAULT_TEST_FOLDER); - projectProperties.setConfigFolder(ClientSideProjectConstants.DEFAULT_CONFIG_FOLDER); - - if (siteTemplate != null) { - siteTemplate.configure(projectProperties); - initProject(project, projectProperties); - - handle.progress(Bundle.OnlineSampleWizardIterator_applyingTemplate()); - applySiteTemplate(projectHelper.getProjectDirectory(), projectProperties, siteTemplate, handle); - } else { - // init standard project - initProject(project, projectProperties); - } - - // get application dir: - FileObject siteRootDir = project.getSiteRootFolder(); - assert siteRootDir != null; - - // apply extenders - //no extenders for online samples -// for (ClientProjectExtender extender : Lookup.getDefault().lookupAll(ClientProjectExtender.class)) { -// extender.apply(project.getProjectDirectory(), siteRootDir, (String) wizardDescriptor.getProperty(LIBRARIES_PATH)); -// } - - return siteRootDir; - } - - private void initProject(ClientSideProject project, SiteTemplateImplementation.ProjectProperties properties) throws IOException { - ClientSideProjectUtilities.initializeProject(project, - properties.getSiteRootFolder(), - properties.getTestFolder(), - properties.getConfigFolder()); + protected String getStartFile() { + return "index.html"; // NOI18N } @NbBundle.Messages({ @@ -271,4 +215,34 @@ private void errorOccured(String message) { DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(message, NotifyDescriptor.ERROR_MESSAGE)); } + + private FileObject getSiteRootFolder(AntProjectHelper helper) { + String s = getEvaluator(helper).getProperty(WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER); + if (s == null) { + s = ""; //NOI18N + } + if (s.length() == 0) { + return helper.getProjectDirectory(); + } + return helper.resolveFileObject(s); + } + + private PropertyEvaluator getEvaluator(AntProjectHelper helper) { + if (eval == null) { + eval = createEvaluator(helper); + } + return eval; + } + + private PropertyEvaluator createEvaluator(AntProjectHelper helper) { + PropertyEvaluator baseEval2 = PropertyUtils.sequentialPropertyEvaluator( + helper.getStockPropertyPreprovider(), + helper.getPropertyProvider(AntProjectHelper.PRIVATE_PROPERTIES_PATH)); + return PropertyUtils.sequentialPropertyEvaluator( + helper.getStockPropertyPreprovider(), + helper.getPropertyProvider(AntProjectHelper.PRIVATE_PROPERTIES_PATH), + PropertyUtils.userPropertiesProvider(baseEval2, + "user.properties.file", FileUtil.toFile(helper.getProjectDirectory())), // NOI18N + helper.getPropertyProvider(AntProjectHelper.PROJECT_PROPERTIES_PATH)); + } } diff --git a/web.client.samples/src/org/netbeans/modules/web/client/samples/wizard/ui/OnlineSampleVisualPanel.java b/web.client.samples/src/org/netbeans/modules/web/client/samples/wizard/ui/OnlineSampleVisualPanel.java --- a/web.client.samples/src/org/netbeans/modules/web/client/samples/wizard/ui/OnlineSampleVisualPanel.java +++ b/web.client.samples/src/org/netbeans/modules/web/client/samples/wizard/ui/OnlineSampleVisualPanel.java @@ -55,8 +55,8 @@ import org.netbeans.modules.web.client.samples.wizard.WizardConstants; import org.netbeans.modules.web.clientproject.api.network.NetworkException; import org.netbeans.modules.web.clientproject.api.network.NetworkSupport; +import org.netbeans.modules.web.clientproject.api.util.ValidationUtilities; import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation; -import org.netbeans.modules.web.clientproject.util.ValidationUtilities; import org.netbeans.spi.project.ui.support.ProjectChooser; import org.openide.WizardDescriptor; import org.openide.filesystems.FileChooserBuilder; diff --git a/web.clientproject.api/manifest.mf b/web.clientproject.api/manifest.mf --- a/web.clientproject.api/manifest.mf +++ b/web.clientproject.api/manifest.mf @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.web.clientproject.api OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/web/clientproject/api/Bundle.properties -OpenIDE-Module-Specification-Version: 1.36 +OpenIDE-Module-Specification-Version: 1.37 diff --git a/web.clientproject.api/nbproject/project.xml b/web.clientproject.api/nbproject/project.xml --- a/web.clientproject.api/nbproject/project.xml +++ b/web.clientproject.api/nbproject/project.xml @@ -206,6 +206,8 @@ org.netbeans.modules.web.clientproject.api org.netbeans.modules.web.clientproject.api.jslibs org.netbeans.modules.web.clientproject.api.network + org.netbeans.modules.web.clientproject.api.project + org.netbeans.modules.web.clientproject.api.project.sites org.netbeans.modules.web.clientproject.api.util org.netbeans.modules.web.clientproject.api.validation org.netbeans.modules.web.clientproject.spi diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/WebClientProjectConstants.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/WebClientProjectConstants.java --- a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/WebClientProjectConstants.java +++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/WebClientProjectConstants.java @@ -42,13 +42,34 @@ package org.netbeans.modules.web.clientproject.api; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.util.logging.Level; +import java.util.logging.Logger; + /** * */ public final class WebClientProjectConstants { + private static final Logger LOGGER = Logger.getLogger(WebClientProjectConstants.class.getName()); + + private WebClientProjectConstants() { } + + // 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_START_FILE = "start.file"; //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 /** * Constant for Configuration Files sources group. @@ -65,4 +86,30 @@ */ public static final String SOURCES_TYPE_HTML5_TEST = "HTML5-Tests"; // NOI18N + /** + * Unique type identifier for web client project. + */ + public static final String WEB_CLIENT_PROJECT_TYPE = "org.netbeans.modules.web.clientproject"; // NOI18N + + /** + * The namespace of the XML element that should be used to store the project's specific configuration + * data in nbproject/project.xml (inside <configuration>). + */ + public static final String PROJECT_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/clientside-project/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(); + } } 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 Web Client Side project according to 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 CreateProjectProperties 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 CreateProjectProperties 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 CreateProjectProperties properties) { + + assert !EventQueue.isDispatchThread(); + try { + // store properties + ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction() { + @Override + public Void run() throws IOException { + saveProperties(helper, properties); + ProjectManager.getDefault().saveProject(project); + return null; + } + }); + } catch (MutexException e) { + LOGGER.log(Level.WARNING, null, e.getException()); + } + } + + private static void saveProperties(AntProjectHelper helper, CreateProjectProperties properties) { + EditableProperties projectProperties = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER, properties.getSiteRootFolder()); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_TEST_FOLDER, properties.getTestFolder()); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_CONFIG_FOLDER, properties.getConfigFolder()); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_ENCODING, properties.getEncoding()); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_START_FILE, properties.getStartFile()); + helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, projectProperties); + } + + private static void putProperty(EditableProperties properties, String property, String value) { + if (value != null) { + properties.put(property, value); + } + } + + + /** + * Project properties. It contains usually relative paths of: + *
    + *
  • Project directory
  • + *
  • Site Root folder
  • + *
  • Unit Tests folder
  • + *
  • Config folder
  • + *
+ * And few other properties are stored: + *
    + *
  • Project name
  • + *
  • Start file
  • + *
  • Encoding
  • + *
+ *

+ * This class is not thread-safe. + */ + public static final class CreateProjectProperties { + + 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 CreateProjectProperties 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 CreateProjectProperties 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 CreateProjectProperties 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 CreateProjectProperties 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 CreateProjectProperties 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 CreateProjectProperties 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 CreateProjectProperties setEncoding(String encoding) { + this.encoding = encoding; + return this; + } + } +} diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/sites/OnlineSites.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/sites/OnlineSites.java new file mode 100644 --- /dev/null +++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/sites/OnlineSites.java @@ -0,0 +1,127 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 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 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.web.clientproject.api.project.sites; + +import java.awt.EventQueue; +import java.io.File; +import java.io.IOException; +import java.util.Collection; +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.api.util.FileUtilities; +import org.openide.filesystems.FileObject; + + +public abstract class OnlineSites implements SiteTemplateImplementation { + + private static final Logger LOGGER = Logger.getLogger(OnlineSites.class.getName()); + + private final String name; + private final String url; + private final File libFile; + private final String description; + private final String id; + + + + protected OnlineSites(String id, String name, String description, String url, File libFile) { + this.id = id; + this.name = name; + this.description = description; + this.url = url; + this.libFile = libFile; + } + + @Override + public String getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public boolean isPrepared() { + return libFile.isFile(); + } + + @Override + public void prepare() throws IOException { + assert !EventQueue.isDispatchThread(); + assert !isPrepared(); + SiteHelper.download(url, libFile, null); + } + + @Override + public void configure(ProjectProperties projectProperties) { + // noop by default + } + + @Override + public final void apply(FileObject projectDir, ProjectProperties projectProperties, ProgressHandle handle) throws IOException { + assert !EventQueue.isDispatchThread(); + if (!isPrepared()) { + // not correctly prepared, user has to know about it already + LOGGER.info("Template not correctly prepared, nothing to be applied"); //NOI18N + return; + } + SiteHelper.unzipProjectTemplate(getTargetDir(projectDir, projectProperties), libFile, handle); + } + + protected FileObject getTargetDir(FileObject projectDir, ProjectProperties projectProperties) { + // by default, extract template to site root + return projectDir.getFileObject(projectProperties.getSiteRootFolder()); + } + + @Override + public Collection supportedLibraries() { + return SiteHelper.stripRootFolder(FileUtilities.listJsFilesFromZipFile(libFile)); + } +} diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/sites/SiteHelper.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/sites/SiteHelper.java new file mode 100644 --- /dev/null +++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/project/sites/SiteHelper.java @@ -0,0 +1,270 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 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 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.web.clientproject.api.project.sites; + +import java.awt.EventQueue; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; +import org.netbeans.api.progress.ProgressHandle; +import org.netbeans.modules.web.clientproject.api.network.NetworkException; +import org.netbeans.modules.web.clientproject.api.network.NetworkSupport; +import org.netbeans.modules.web.clientproject.api.util.StringUtilities; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.modules.Places; +import org.openide.util.NbBundle; + +public final class SiteHelper { + + private static final Logger LOGGER = Logger.getLogger(SiteHelper.class.getName()); + private static final String JS_LIBS_DIR = "jslibs"; // NOI18N + + + private SiteHelper() { + } + + /** + * Return <var/cache>/jslibs directory. + * @return <var/cache>/jslibs directory + */ + public static File getJsLibsDirectory() { + return Places.getCacheSubdirectory(JS_LIBS_DIR); + } + + /** + * Download the given URL to the target file. + * @param url URL to be downloaded + * @param target target file + * @param progressHandle progress handle, can be {@code null} + * @throws NetworkException if any network error occurs + * @throws IOException if any error occurs + * @deprecated Use any download method from {@link NetworkSupport}. + */ + @Deprecated + public static void download(String url, File target, @NullAllowed ProgressHandle progressHandle) throws NetworkException, IOException { + assert !EventQueue.isDispatchThread(); + try { + if (progressHandle != null) { + NetworkSupport.downloadWithProgress(url, target, progressHandle); + } else { + NetworkSupport.download(url, target); + } + } catch (InterruptedException ex) { + // cancelled - what to do? + LOGGER.log(Level.WARNING, null, ex); + } + } + + /** + * Unzip the given ZIP file to the given target directory. The target directory must exist. + * @param zipFile ZIP file to be extracted + * @param targetDirectory existing target directory + * @param progressHandle progress handle, can be {@code null} + * @throws IOException if any error occurs + */ + @NbBundle.Messages({ + "# {0} - file name", + "SiteHelper.progress.unzip=Unziping file {0}" + }) + public static void unzipProjectTemplate(@NonNull FileObject targetDir, @NonNull File zipFile, @NullAllowed ProgressHandle progressHandle, String... ignoredFiles) throws IOException { + assert targetDir != null; + if (progressHandle != null) { + progressHandle.progress(Bundle.SiteHelper_progress_unzip(zipFile.getName())); + } + String rootFolder = getZipRootFolder(new FileInputStream(zipFile)); + unzipProjectTemplateFile(targetDir, new FileInputStream(zipFile), rootFolder, ignoredFiles); + } + + /** + * Strip possible root folder of the given paths. + *

+ * Warning: only "/" as path separator expected. + *

+ * The typical usage is for file paths from a ZIP file. + * @param paths relative paths (with "/" as path separator) to be processed, never empty paths or {@code null} + * @return list of paths without possible root folder + */ + public static List stripRootFolder(List paths) { + List stripped = new ArrayList(paths.size()); + String rootFolder = null; + for (String path : paths) { + assert StringUtilities.hasText(path) : "Empty path not allowed"; + String top; + int slashIndex = path.indexOf('/'); // NOI18N + if (slashIndex == -1) { + top = path; + } else { + top = path.substring(0, slashIndex); + } + if (rootFolder == null) { + rootFolder = top; + } + if (!rootFolder.equals(top)) { + return paths; + } + if (slashIndex != -1 && path.length() > slashIndex) { + stripped.add(path.substring(slashIndex + 1)); + } + } + return stripped; + } + + @NbBundle.Messages("SiteHelper.error.emptyZip=ZIP file with site template is either empty or its download failed.") + private static void unzipProjectTemplateFile(FileObject targetDir, InputStream source, String rootFolder, String... ignoredFiles) throws IOException { + boolean firstItem = true; + try { + int stripLen = rootFolder != null ? rootFolder.length() : 0; + ZipInputStream str = new ZipInputStream(source); + ZipEntry entry; + Set ignored = Collections.emptySet(); + if (ignoredFiles != null && ignoredFiles.length > 0) { + ignored = new HashSet(Arrays.asList(ignoredFiles)); + } + while ((entry = str.getNextEntry()) != null) { + String entryName = entry.getName(); + if (stripLen > 0) { + entryName = entryName.substring(stripLen); + } + if (entryName.length() == 0) { + continue; + } + if (ignored.contains(entryName)) { + continue; + } + firstItem = false; + if (entry.isDirectory()) { + // ignore build folder from mobile boilerplate; unrelated junk IMO. + if (entryName.startsWith("build") || entryName.startsWith("nbproject")) { //NOI18N + continue; + } + if (targetDir.getFileObject(entryName) == null) { + FileUtil.createFolder(targetDir, entryName); + } + } else { + // ignore internal GIT files: + if (entryName.startsWith(".git") || entryName.contains("/.git")) { //NOI18N + continue; + } + // ignore build folder from mobile boilerplate; unrelated junk IMO. + if (entryName.startsWith("build/") || entryName.startsWith("nbproject/")) { //NOI18N + continue; + } + // NetBeans LOCK files + if (entryName.contains("/.LCK") && entryName.endsWith("~")) { //NOI18N + continue; + } + FileObject fo = FileUtil.createData(targetDir, entryName); + writeFile(str, fo); + } + } + } finally { + source.close(); + if (firstItem) { + DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(Bundle.SiteHelper_error_emptyZip())); + } + } + } + + private static void writeFile(ZipInputStream str, FileObject fo) throws IOException { + OutputStream out = fo.getOutputStream(); + try { + FileUtil.copy(str, out); + } finally { + out.close(); + } + } + + private static String getZipRootFolder(InputStream source) throws IOException { + String folder = null; + try { + ZipInputStream str = new ZipInputStream(source); + ZipEntry entry; + boolean first = true; + while ((entry = str.getNextEntry()) != null) { + if (first) { + first = false; + if (entry.isDirectory()) { + folder = entry.getName(); + } else { + String fileName = entry.getName(); + int slashIndex = fileName.indexOf('/'); + if (slashIndex != -1) { + String name = fileName.substring(slashIndex+1); + folder = fileName.substring(0, slashIndex); + if (name.length() == 0 || folder.length() == 0) { + return null; + } + folder += "/"; //NOI18N + } else { + return null; + } + } + } else { + if (!entry.getName().startsWith(folder)) { + return null; + } + } + } + } finally { + source.close(); + } + return folder; + } + +} diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/util/FileUtilities.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/util/FileUtilities.java new file mode 100644 --- /dev/null +++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/util/FileUtilities.java @@ -0,0 +1,255 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 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 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.web.clientproject.api.util; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * Miscellaneous utility methods for files. + */ +public final class FileUtilities { + + private static final Logger LOGGER = Logger.getLogger(FileUtilities.class.getName()); + + private static final String HTML_MIME_TYPE = "text/html"; // NOI18N + private static final String XHTML_MIME_TYPE = "text/xhtml"; // NOI18N + private static final String CSS_MIME_TYPE = "text/css"; // NOI18N + + + private FileUtilities() { + } + + /** + * Check whether the given file is an (X)HTML file. + * @param file file to be checked + * @return {@code true} if the given file is an (X)HTML file, {@code false} otherwise + */ + public static boolean isHtmlFile(FileObject file) { + String mimeType = FileUtil.getMIMEType(file, HTML_MIME_TYPE, XHTML_MIME_TYPE); + return HTML_MIME_TYPE.equals(mimeType) || XHTML_MIME_TYPE.equals(mimeType); + } + + /** + * Check whether the given file is a CSS file. + * @param file file to be checked + * @return {@code true} if the given file is a CSS file, {@code false} otherwise + */ + public static boolean isCssFile(FileObject file) { + return CSS_MIME_TYPE.equals(FileUtil.getMIMEType(file, CSS_MIME_TYPE)); + } + + /** + * Cleanup the given folder. The folder itself is not removed. + * @param fileObject folder to be cleaned up + * @throws IOException if any error occurs + */ + public static void cleanupFolder(FileObject fileObject) throws IOException { + for (FileObject child : fileObject.getChildren()) { + child.delete(); + } + } + + /** + * Move content of the source to the target. If the target file already exists and is a file + * (not folder), the source file is moved and renamed (suffix _0, _1 etc.). + * @param source source file object + * @param target target file object + * @throws IOException if any error occurs + */ + public static void moveContent(FileObject source, FileObject target) throws IOException { + for (FileObject child : source.getChildren()) { + FileObject newChild = target.getFileObject(child.getNameExt()); + if (newChild == null) { + // does not exists + FileUtil.moveFile(child, target, child.getName()); + } else if (newChild.isFolder()) { + // copy directory content + moveContent(child, newChild); + child.delete(); + } else { + // file already exists => rename + int i = 0; + for (;;) { + String newName = child.getName() + "_" + i++; // NOI18N + if (target.getFileObject(newName) == null) { + FileUtil.moveFile(child, target, newName); + break; + } + } + } + } + } + + /** + * Run task on the given ZIP file. + * @param zipFile ZIP file to be processed + * @param entryTask task to be applied on the ZIP file entries + * @param entryFilter filter to be applied on the ZIP file entries, can be {@code null} + * @throws IOException if any error occurs + */ + public static void runOnZipEntries(@NonNull File zipFile, @NonNull ZipEntryTask entryTask, @NullAllowed ZipEntryFilter entryFilter) throws IOException { + ZipFile zip = new ZipFile(zipFile); + try { + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry zipEntry = entries.nextElement(); + boolean accept = true; + if (entryFilter != null) { + accept = entryFilter.accept(zipEntry); + } + if (accept) { + entryTask.run(zipEntry); + InputStream inputStream = zip.getInputStream(zipEntry); + try { + entryTask.run(inputStream); + } finally { + inputStream.close(); + } + } + } + } finally { + zip.close(); + } + } + + /** + * Get list of files from the given ZIP file according to the given {@link ZipEntryFilter filter}. + * @param zipFile ZIP file to be listed + * @param entryFilter filter to be applied on the ZIP file entries + * @return list of files from the given ZIP file according to the given {@link ZipEntryFilter filter} + * @throws IOException if any error occurs + */ + public static List listZipFiles(@NonNull File zipFile, @NonNull ZipEntryFilter entryFilter) throws IOException { + assert zipFile != null; + assert entryFilter != null; + final List files = new ArrayList(); + runOnZipEntries(zipFile, new ZipEntryTask() { + @Override + public void run(ZipEntry zipEntry) { + files.add(zipEntry.getName()); + } + @Override + public void run(InputStream zipEntryInputStream) { + // noop + } + }, entryFilter); + return files; + } + + /** + * Get list of JS files (filenames with relative path) from the given ZIP file. + *

+ * If any error occurs, this error is logged with INFO level and an empty list is returned. + * @param zipFile ZIP file to be listed + * @return list of JS files (filenames with relative path) from the given ZIP file. + * @see #listZipFiles(File, ZipEntryFilter) + * @see #listJsFilenamesFromZipFile(File) + */ + public static List listJsFilesFromZipFile(File zipFile) { + try { + return listZipFiles(zipFile, new ZipEntryFilter() { + @Override + public boolean accept(ZipEntry zipEntry) { + return !zipEntry.isDirectory() + && zipEntry.getName().toLowerCase().endsWith(".js"); // NOI18N + } + }); + } catch (IOException ex) { + LOGGER.log(Level.INFO, null, ex); + } + return Collections.emptyList(); + } + + //~ Inner classes + + /** + * Filter for {@link ZipEntry}s. + *

+ * Instances of this interface may be passed to the {@link #listZipFiles(File, ZipEntryFilter)} method. + * @see #listZipFiles(File, ZipEntryFilter) + */ + public interface ZipEntryFilter { + + /** + * Test whether or not the specified {@link ZipEntry} should be + * accepted. + * + * @param zipEntry the {@link ZipEntry} to be tested + * @return {@ code true} if {@link ZipEntry} should be accepted, {@code false} otherwise + */ + boolean accept(ZipEntry zipEntry); + } + + /** + * Task for {@link ZipEntry}s, their content. + * @see #runOnZipEntries(File, ZipEntryTask, ZipEntryFilter) + */ + public interface ZipEntryTask { + + /** + * Run task on the given ZIP entry. + * @param zipEntry {@link ZipEntry} to be processed + */ + void run(ZipEntry zipEntry); + + /** + * Run task on the given content, typically read it. + * @param zipEntryInputStream content of the given {@link ZipEntry} + */ + void run(InputStream zipEntryInputStream); + } + +} diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/util/ValidationUtilities.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/util/ValidationUtilities.java new file mode 100644 --- /dev/null +++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/api/util/ValidationUtilities.java @@ -0,0 +1,99 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 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 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.web.clientproject.api.util; + +import java.io.File; + +/** + * Miscellaneous utility methods for validation. + */ +public final class ValidationUtilities { + + private static final char[] INVALID_FILENAME_CHARS = new char[] {'/', '\\', '|', ':', '*', '?', '"', '<', '>'}; // NOI18N + + + private ValidationUtilities() { + } + + /** + * Check whether the provided filename is valid. An empty string is considered to be invalid. + * @param filename file name to be validated + * @return {@code true} if the provided filename is valid + */ + public static boolean isValidFilename(String filename) { + assert filename != null; + if (filename.trim().length() == 0) { + return false; + } + for (char ch : INVALID_FILENAME_CHARS) { + if (filename.indexOf(ch) != -1) { + return false; + } + } + return true; + } + + /** + * Check whether the provided file has a valid filename. Only the non-existing filenames in the file path are checked. + * It means that if you pass existing directory, no check is done. + *

+ * For example for C:\Documents And Settings\ExistingDir\NonExistingDir\NonExistingDir2\Newdir the last free filenames + * are checked. + * @param file file to be checked + * @return {@code true} if the provided file has valid filename + * @see #isValidFilename(String) + */ + public static boolean isValidFilename(File file) { + assert file != null; + File tmp = file; + while (tmp != null && !tmp.exists()) { + if (tmp.isAbsolute() && tmp.getParentFile() == null) { + return true; + } else if (!isValidFilename(tmp.getName())) { + return false; + } + tmp = tmp.getParentFile(); + } + return true; + } + +} diff --git a/web.clientproject/nbproject/project.xml b/web.clientproject/nbproject/project.xml --- a/web.clientproject/nbproject/project.xml +++ b/web.clientproject/nbproject/project.xml @@ -142,7 +142,7 @@ - 1.36 + 1.37 @@ -298,14 +298,7 @@ - - org.netbeans.modules.web.client.samples - org.netbeans.modules.web.clientproject - org.netbeans.modules.web.clientproject.sites - org.netbeans.modules.web.clientproject.util - - + diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClassPathProviderImpl.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClassPathProviderImpl.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClassPathProviderImpl.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClassPathProviderImpl.java @@ -50,6 +50,7 @@ import java.util.Collections; import java.util.List; import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.spi.java.classpath.ClassPathImplementation; import org.netbeans.spi.java.classpath.ClassPathProvider; import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation; @@ -102,8 +103,8 @@ this.project.getEvaluator().addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { - if (ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER.equals(evt.getPropertyName()) || - ClientSideProjectConstants.PROJECT_TEST_FOLDER.equals(evt.getPropertyName()) || + if (WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER.equals(evt.getPropertyName()) || + WebClientProjectConstants.PROJECT_TEST_FOLDER.equals(evt.getPropertyName()) || evt.getPropertyName().startsWith("file.reference.")) { support.firePropertyChange(PathResourceImplementation.PROP_ROOTS, null, null); } diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProject.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProject.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProject.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProject.java @@ -72,6 +72,7 @@ import org.netbeans.modules.web.browser.api.WebBrowser; import org.netbeans.modules.web.browser.api.BrowserUISupport; import org.netbeans.modules.web.clientproject.api.ClientSideModule; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.problems.ProjectPropertiesProblemProvider; import org.netbeans.modules.web.clientproject.remote.RemoteFiles; import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserImplementation; @@ -118,10 +119,10 @@ import org.w3c.dom.Text; @AntBasedProjectRegistration( - type=ClientSideProjectType.TYPE, - iconResource=ClientSideProject.PROJECT_ICON, - sharedNamespace=ClientSideProjectType.PROJECT_CONFIGURATION_NAMESPACE, - privateNamespace=ClientSideProjectType.PRIVATE_CONFIGURATION_NAMESPACE + type = WebClientProjectConstants.WEB_CLIENT_PROJECT_TYPE, + iconResource = ClientSideProject.PROJECT_ICON, + sharedNamespace = WebClientProjectConstants.PROJECT_CONFIGURATION_NAMESPACE, + privateNamespace = ClientSideProjectConstants.PRIVATE_CONFIGURATION_NAMESPACE ) public class ClientSideProject implements Project { @@ -250,7 +251,7 @@ @CheckForNull public FileObject getSiteRootFolder() { - String s = getEvaluator().getProperty(ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER); + String s = getEvaluator().getProperty(WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER); if (s == null) { s = ""; //NOI18N } @@ -261,7 +262,7 @@ } public FileObject getTestsFolder() { - String tests = getEvaluator().getProperty(ClientSideProjectConstants.PROJECT_TEST_FOLDER); + String tests = getEvaluator().getProperty(WebClientProjectConstants.PROJECT_TEST_FOLDER); if (tests == null || tests.trim().length() == 0) { return null; } @@ -269,7 +270,7 @@ } public FileObject getConfigFolder() { - String config = getEvaluator().getProperty(ClientSideProjectConstants.PROJECT_CONFIG_FOLDER); + String config = getEvaluator().getProperty(WebClientProjectConstants.PROJECT_CONFIG_FOLDER); if (config == null || config.trim().length() == 0) { return null; } @@ -277,7 +278,7 @@ } public String getStartFile() { - String s = getEvaluator().getProperty(ClientSideProjectConstants.PROJECT_START_FILE); + String s = getEvaluator().getProperty(WebClientProjectConstants.PROJECT_START_FILE); if (s == null) { s = "index.html"; //NOI18N } @@ -332,7 +333,7 @@ @Override public Void run() { Element data = projectHelper.getPrimaryConfigurationData(true); - NodeList nameList = data.getElementsByTagNameNS(ClientSideProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N + NodeList nameList = data.getElementsByTagNameNS(WebClientProjectConstants.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N if (nameList.getLength() == 1) { nameList = nameList.item(0).getChildNodes(); if (nameList.getLength() == 1 @@ -370,7 +371,7 @@ private DynamicProjectLookup createLookup(AuxiliaryConfiguration configuration) { FileEncodingQueryImplementation fileEncodingQuery = - new FileEncodingQueryImpl(getEvaluator(), ClientSideProjectConstants.PROJECT_ENCODING); + new FileEncodingQueryImpl(getEvaluator(), WebClientProjectConstants.PROJECT_ENCODING); Lookup base = Lookups.fixed(new Object[] { this, new Info(), @@ -398,8 +399,8 @@ CssPreprocessors.getDefault().createProjectProblemsProvider(this), UILookupMergerSupport.createProjectProblemsProviderMerger(), new TemplateAttributesProviderImpl(projectHelper, fileEncodingQuery), - SharabilityQueryImpl.create(projectHelper, eval, ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER, - ClientSideProjectConstants.PROJECT_TEST_FOLDER, ClientSideProjectConstants.PROJECT_CONFIG_FOLDER), + SharabilityQueryImpl.create(projectHelper, eval, WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER, + WebClientProjectConstants.PROJECT_TEST_FOLDER, WebClientProjectConstants.PROJECT_CONFIG_FOLDER), projectBrowserProvider, }); return new DynamicProjectLookup(this, @@ -592,7 +593,7 @@ @Override public void propertyChange(PropertyChangeEvent evt) { // change in project properties - if (ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER.equals(evt.getPropertyName())) { + if (WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER.equals(evt.getPropertyName())) { synchronized (this) { removeSiteRootListener(); addSiteRootListener(); @@ -677,9 +678,9 @@ private static final class ProjectSearchInfo extends SearchInfoDefinition { private static final Set WATCHED_PROPERTIES = new HashSet(Arrays.asList( - ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER, - ClientSideProjectConstants.PROJECT_TEST_FOLDER, - ClientSideProjectConstants.PROJECT_CONFIG_FOLDER)); + WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER, + WebClientProjectConstants.PROJECT_TEST_FOLDER, + WebClientProjectConstants.PROJECT_CONFIG_FOLDER)); private final ClientSideProject project; // @GuardedBy("this") diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectBrowserProvider.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectBrowserProvider.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectBrowserProvider.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectBrowserProvider.java @@ -52,6 +52,7 @@ import org.netbeans.modules.web.browser.api.WebBrowsers; import org.netbeans.modules.web.browser.spi.ProjectBrowserProvider; import static org.netbeans.modules.web.browser.spi.ProjectBrowserProvider.PROP_BROWSER_ACTIVE; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.ui.customizer.CompositePanelProviderImpl; import org.netbeans.modules.web.clientproject.ui.customizer.CustomizerProviderImpl; import org.netbeans.spi.project.support.ant.AntProjectHelper; diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectConstants.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectConstants.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectConstants.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectConstants.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * 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. @@ -37,7 +37,7 @@ * * Contributor(s): * - * Portions Copyrighted 2012 Sun Microsystems, Inc. + * Portions Copyrighted 2013 Sun Microsystems, Inc. */ package org.netbeans.modules.web.clientproject; @@ -45,26 +45,25 @@ /** * */ -public class ClientSideProjectConstants { +public final class ClientSideProjectConstants { + + private ClientSideProjectConstants() { + } // 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_AUTO_REFRESH = "browser.autorefresh"; //NOI18N + public static final String PROJECT_SELECTED_BROWSER = "browser"; //NOI18N public static final String PROJECT_SERVER = "server"; //NOI18N - public static final String PROJECT_START_FILE = "start.file"; //NOI18N + public static final String PROJECT_PROJECT_URL = "external.project.url"; //NOI18N + public static final String PROJECT_HIGHLIGHT_SELECTION = "browser.highlightselection"; //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 + + /** + * 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 } diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectSources.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectSources.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectSources.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectSources.java @@ -94,15 +94,15 @@ private Sources initSources() { SourcesHelper sourcesHelper = new SourcesHelper(project, helper, evaluator); - sourcesHelper.sourceRoot("${" + ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER + "}") //NOI18N + sourcesHelper.sourceRoot("${" + WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER + "}") //NOI18N .displayName(org.openide.util.NbBundle.getMessage(ClientSideProjectSources.class, "SITE_ROOT")) .add() // adding as principal root, continuing configuration .type(WebClientProjectConstants.SOURCES_TYPE_HTML5).add(); // adding as typed root - sourcesHelper.sourceRoot("${" + ClientSideProjectConstants.PROJECT_TEST_FOLDER + "}") //NOI18N + sourcesHelper.sourceRoot("${" + WebClientProjectConstants.PROJECT_TEST_FOLDER + "}") //NOI18N .displayName(org.openide.util.NbBundle.getMessage(ClientSideProjectSources.class, "UNIT_TESTS")) .add() // adding as principal root, continuing configuration .type(WebClientProjectConstants.SOURCES_TYPE_HTML5_TEST).add(); // adding as typed root - sourcesHelper.sourceRoot("${" + ClientSideProjectConstants.PROJECT_CONFIG_FOLDER + "}") //NOI18N + sourcesHelper.sourceRoot("${" + WebClientProjectConstants.PROJECT_CONFIG_FOLDER + "}") //NOI18N .displayName(org.openide.util.NbBundle.getMessage(ClientSideProjectSources.class, "CONFIGURATION_FILES")) .type(WebClientProjectConstants.SOURCES_TYPE_HTML5_CONFIG).add(); // adding as principal root sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectType.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectType.java deleted file mode 100644 --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectType.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2012 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 2012 Sun Microsystems, Inc. - */ -package org.netbeans.modules.web.clientproject; - -public class ClientSideProjectType { - - public static final String TYPE = "org.netbeans.modules.web.clientproject"; // NOI18N - public static final String PROJECT_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/clientside-project/1"; // NOI18N - static final String PRIVATE_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/clientside-project-private/1"; // NOI18N - -} diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ServerURLMappingImpl.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ServerURLMappingImpl.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ServerURLMappingImpl.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ServerURLMappingImpl.java @@ -49,6 +49,7 @@ import java.net.URLDecoder; import org.netbeans.modules.javascript.jstestdriver.api.JsTestDriver; import org.netbeans.modules.web.browser.api.WebBrowser; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.common.api.ServerURLMapping; import org.netbeans.modules.web.common.spi.ServerURLMappingImplementation; import org.netbeans.modules.web.common.api.WebServer; diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/browser/ClientProjectEnhancedBrowserImpl.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/browser/ClientProjectEnhancedBrowserImpl.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/browser/ClientProjectEnhancedBrowserImpl.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/browser/ClientProjectEnhancedBrowserImpl.java @@ -47,6 +47,7 @@ import org.netbeans.modules.web.browser.api.WebBrowser; import org.netbeans.modules.web.clientproject.ClientSideProject; import org.netbeans.modules.web.clientproject.ClientSideProjectConstants; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserImplementation; import org.netbeans.modules.web.clientproject.spi.platform.ProjectConfigurationCustomizer; import org.netbeans.modules.web.clientproject.spi.platform.RefreshOnSaveListener; diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/problems/ProjectPropertiesProblemProvider.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/problems/ProjectPropertiesProblemProvider.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/problems/ProjectPropertiesProblemProvider.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/problems/ProjectPropertiesProblemProvider.java @@ -50,7 +50,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.netbeans.modules.web.clientproject.ClientSideProject; -import org.netbeans.modules.web.clientproject.ClientSideProjectConstants; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.ui.customizer.CompositePanelProviderImpl; import org.netbeans.spi.project.support.ant.PropertyEvaluator; import org.netbeans.spi.project.ui.ProjectProblemsProvider; @@ -71,9 +71,9 @@ // set would be better but it is fine to use a list for small number of items static final List WATCHED_PROPERTIES = new CopyOnWriteArrayList(Arrays.asList( - ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER, - ClientSideProjectConstants.PROJECT_TEST_FOLDER, - ClientSideProjectConstants.PROJECT_CONFIG_FOLDER)); + WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER, + WebClientProjectConstants.PROJECT_TEST_FOLDER, + WebClientProjectConstants.PROJECT_CONFIG_FOLDER)); final ProjectProblemsProviderSupport problemsProviderSupport = new ProjectProblemsProviderSupport(this); private final ClientSideProject project; @@ -123,12 +123,12 @@ "ProjectPropertiesProblemProvider.invalidSiteRootDir.description=The directory \"{0}\" does not exist and cannot be used for Site Root." }) private void checkSiteRootDir(Collection currentProblems) { - File invalidDirectory = getInvalidDirectory(project.getSiteRootFolder(), ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER); + File invalidDirectory = getInvalidDirectory(project.getSiteRootFolder(), WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER); if (invalidDirectory != null) { ProjectProblem problem = ProjectProblem.createError( Bundle.ProjectPropertiesProblemProvider_invalidSiteRootDir_title(), Bundle.ProjectPropertiesProblemProvider_invalidSiteRootDir_description(invalidDirectory.getAbsolutePath()), - new CustomizerProblemResolver(project, CompositePanelProviderImpl.SOURCES, ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER)); + new CustomizerProblemResolver(project, CompositePanelProviderImpl.SOURCES, WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER)); currentProblems.add(problem); } } @@ -139,12 +139,12 @@ "ProjectPropertiesProblemProvider.invalidTestDir.description=The directory \"{0}\" does not exist and cannot be used for Unit Tests." }) private void checkTestDir(Collection currentProblems) { - File invalidDirectory = getInvalidDirectory(project.getTestsFolder(), ClientSideProjectConstants.PROJECT_TEST_FOLDER); + File invalidDirectory = getInvalidDirectory(project.getTestsFolder(), WebClientProjectConstants.PROJECT_TEST_FOLDER); if (invalidDirectory != null) { ProjectProblem problem = ProjectProblem.createError( Bundle.ProjectPropertiesProblemProvider_invalidTestDir_title(), Bundle.ProjectPropertiesProblemProvider_invalidTestDir_description(invalidDirectory.getAbsolutePath()), - new CustomizerProblemResolver(project, CompositePanelProviderImpl.SOURCES, ClientSideProjectConstants.PROJECT_TEST_FOLDER)); + new CustomizerProblemResolver(project, CompositePanelProviderImpl.SOURCES, WebClientProjectConstants.PROJECT_TEST_FOLDER)); currentProblems.add(problem); } } @@ -157,12 +157,12 @@ "ProjectPropertiesProblemProvider.invalidConfigDir.dialog.title=Select Configuration Files for {0}" }) private void checkConfigDir(Collection currentProblems) { - File invalidDirectory = getInvalidDirectory(project.getConfigFolder(), ClientSideProjectConstants.PROJECT_CONFIG_FOLDER); + File invalidDirectory = getInvalidDirectory(project.getConfigFolder(), WebClientProjectConstants.PROJECT_CONFIG_FOLDER); if (invalidDirectory != null) { ProjectProblem problem = ProjectProblem.createError( Bundle.ProjectPropertiesProblemProvider_invalidConfigDir_title(), Bundle.ProjectPropertiesProblemProvider_invalidConfigDir_description(invalidDirectory.getAbsolutePath()), - new CustomizerProblemResolver(project, CompositePanelProviderImpl.SOURCES, ClientSideProjectConstants.PROJECT_CONFIG_FOLDER)); + new CustomizerProblemResolver(project, CompositePanelProviderImpl.SOURCES, WebClientProjectConstants.PROJECT_CONFIG_FOLDER)); currentProblems.add(problem); } } @@ -199,9 +199,9 @@ } private void addFileChangesListeners() { - addFileChangeListener(resolveFile(ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER)); - addFileChangeListener(resolveFile(ClientSideProjectConstants.PROJECT_TEST_FOLDER)); - addFileChangeListener(resolveFile(ClientSideProjectConstants.PROJECT_CONFIG_FOLDER)); + addFileChangeListener(resolveFile(WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER)); + addFileChangeListener(resolveFile(WebClientProjectConstants.PROJECT_TEST_FOLDER)); + addFileChangeListener(resolveFile(WebClientProjectConstants.PROJECT_CONFIG_FOLDER)); } private void addFileChangeListener(File file) { diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/OnlineSites.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/OnlineSites.java deleted file mode 100644 --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/OnlineSites.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2012 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 2012 Sun Microsystems, Inc. - */ -package org.netbeans.modules.web.clientproject.sites; - -import java.awt.EventQueue; -import java.io.File; -import java.io.IOException; -import java.util.Collection; -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.openide.filesystems.FileObject; -import org.openide.util.NbBundle; -import org.openide.util.lookup.ServiceProvider; - - -public abstract class OnlineSites implements SiteTemplateImplementation { - - private static final Logger LOGGER = Logger.getLogger(OnlineSites.class.getName()); - - private final String name; - private final String url; - private final File libFile; - private final String description; - private final String id; - - - - protected OnlineSites(String id, String name, String description, String url, File libFile) { - this.id = id; - this.name = name; - this.description = description; - this.url = url; - this.libFile = libFile; - } - - @Override - public String getId() { - return id; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getDescription() { - return description; - } - - @Override - public boolean isPrepared() { - return libFile.isFile(); - } - - @Override - public void prepare() throws IOException { - assert !EventQueue.isDispatchThread(); - assert !isPrepared(); - SiteHelper.download(url, libFile, null); - } - - @Override - public void configure(ProjectProperties projectProperties) { - // noop by default - } - - @Override - public final void apply(FileObject projectDir, ProjectProperties projectProperties, ProgressHandle handle) throws IOException { - assert !EventQueue.isDispatchThread(); - if (!isPrepared()) { - // not correctly prepared, user has to know about it already - LOGGER.info("Template not correctly prepared, nothing to be applied"); //NOI18N - return; - } - SiteHelper.unzipProjectTemplate(getTargetDir(projectDir, projectProperties), libFile, handle); - } - - protected FileObject getTargetDir(FileObject projectDir, ProjectProperties projectProperties) { - // by default, extract template to site root - return projectDir.getFileObject(projectProperties.getSiteRootFolder()); - } - - @Override - public Collection supportedLibraries() { - return SiteHelper.stripRootFolder(FileUtilities.listJsFilesFromZipFile(libFile)); - } - - //~ Inner classes - - @ServiceProvider(service=SiteTemplateImplementation.class, position=150) - public static class SiteAngularJsSeed extends OnlineSites { - - private static final String SITE_ROOT_FOLDER = "app"; // NOI18N - private static final String TEST_FOLDER = "test"; // NOI18N - private static final String CONFIG_FOLDER = "config"; // NOI18N - - - @NbBundle.Messages({"SiteAngularJsSeed.name=AngularJS Seed", - "SiteAngularJsSeed.description=Site template for AngularJS projects."}) - public SiteAngularJsSeed() { - super("ANGULAR", Bundle.SiteAngularJsSeed_name(), Bundle.SiteAngularJsSeed_description(), // NOI18N - "https://github.com/angular/angular-seed/zipball/master", // NOI18N - new File(SiteHelper.getJsLibsDirectory(), "angularjs-seed.zip")); // NOI18N - } - - @Override - public void configure(ProjectProperties projectProperties) { - projectProperties.setSiteRootFolder(SITE_ROOT_FOLDER) - .setTestFolder(TEST_FOLDER) - .setConfigFolder(CONFIG_FOLDER); - } - - @Override - protected FileObject getTargetDir(FileObject projectDir, ProjectProperties projectProperties) { - return projectDir; - } - - } - - @NbBundle.Messages("SiteInitializr.description=Site template from initializr.com.") - @ServiceProvider(service=SiteTemplateImplementation.class, position=200) - public static class BootstrapSiteInitializr extends OnlineSites { - - @NbBundle.Messages("BootstrapSiteInitializr.name=Initializr: Bootstrap") - public BootstrapSiteInitializr() { - super("BOOTSTRAP", Bundle.BootstrapSiteInitializr_name(), // NOI18N - Bundle.SiteInitializr_description(), - "http://www.initializr.com/builder?boot-hero&jquerydev&h5bp-iecond&h5bp-chromeframe&h5bp-analytics&h5bp-favicon&h5bp-appletouchicons&modernizrrespond&izr-emptyscript&boot-css&boot-scripts", // NOI18N - new File(SiteHelper.getJsLibsDirectory(), "initializr-bootstrap-latest.zip")); // NOI18N - } - - } - - @ServiceProvider(service=SiteTemplateImplementation.class, position=210) - public static class ClassicSiteInitializr extends OnlineSites { - - @NbBundle.Messages("ClassicSiteInitializr.name=Initializr: Classic") - public ClassicSiteInitializr() { - super("INIT.CLASSIC", Bundle.ClassicSiteInitializr_name(), // NOI18N - Bundle.SiteInitializr_description(), - "http://www.initializr.com/builder?h5bp-content&modernizr&jquerydev&h5bp-iecond&h5bp-chromeframe&h5bp-analytics&h5bp-htaccess&h5bp-favicon&h5bp-appletouchicons&h5bp-scripts&h5bp-robots&h5bp-humans&h5bp-404&h5bp-adobecrossdomain&h5bp-css&h5bp-csshelpers&h5bp-mediaqueryprint&h5bp-mediaqueries", // NOI18N - new File(SiteHelper.getJsLibsDirectory(), "initializr-classic-latest.zip")); // NOI18N - } - - } - - @ServiceProvider(service=SiteTemplateImplementation.class, position=220) - public static class ResponsiveSiteInitializr extends OnlineSites { - - @NbBundle.Messages("ResponsiveSiteInitializr.name=Initializr: Responsive") - public ResponsiveSiteInitializr() { - super("INIT.RESP", Bundle.ResponsiveSiteInitializr_name(), // NOI18N - Bundle.SiteInitializr_description(), - "http://www.initializr.com/builder?izr-responsive&jquerydev&h5bp-iecond&h5bp-chromeframe&h5bp-analytics&h5bp-favicon&h5bp-appletouchicons&modernizrrespond&h5bp-css&h5bp-csshelpers&h5bp-mediaqueryprint&izr-emptyscript", // NOI18N - new File(SiteHelper.getJsLibsDirectory(), "initializr-responsive-latest.zip")); // NOI18N - } - - } - - @ServiceProvider(service=SiteTemplateImplementation.class, position=300) - public static class SiteHtml5BoilerplateV4 extends OnlineSites { - - @NbBundle.Messages({"SiteHtml5BoilerplateV4.name=HTML5 Boilerplate v4.0.0", - "SiteHtml5BoilerplateV4.description=Site template from html5boilerplate.com. Version: 4.0.0"}) - public SiteHtml5BoilerplateV4() { - super("INIT.BOILER4", Bundle.SiteHtml5BoilerplateV4_name(), Bundle.SiteHtml5BoilerplateV4_description(), // NOI18N - "https://github.com/h5bp/html5-boilerplate/zipball/v4.0.0", // NOI18N - new File(SiteHelper.getJsLibsDirectory(), "html5-boilerplate-400.zip")); // NOI18N - } - - } - - @ServiceProvider(service=SiteTemplateImplementation.class, position=320) - public static class SiteHtml5BoilerplateV3 extends OnlineSites { - - @NbBundle.Messages({"SiteHtml5Boilerplate.name=HTML5 Boilerplate v3.0.2", - "SiteHtml5Boilerplate.description=Site template from html5boilerplate.com. Version: 3.0.2"}) - public SiteHtml5BoilerplateV3() { - super("INIT.BOILER3", Bundle.SiteHtml5Boilerplate_name(), Bundle.SiteHtml5Boilerplate_description(), // NOI18N - "https://github.com/h5bp/html5-boilerplate/zipball/v3.0.2", // NOI18N - new File(SiteHelper.getJsLibsDirectory(), "html5-boilerplate-302.zip")); // NOI18N - } - - } - - @ServiceProvider(service=SiteTemplateImplementation.class, position=400) - public static class SiteTwitterBootstrap extends OnlineSites { - - @NbBundle.Messages({"SiteTwitterBootstrap.name=Twitter Bootstrap", - "SiteTwitterBootstrap.description=Site template from twitter.github.com/bootstrap"}) - public SiteTwitterBootstrap() { - super("TWITTER", Bundle.SiteTwitterBootstrap_name(), Bundle.SiteTwitterBootstrap_description(), // NOI18N - "http://twitter.github.com/bootstrap/assets/bootstrap.zip", // NOI18N - new File(SiteHelper.getJsLibsDirectory(), "twitter-bootstrap.zip")); // NOI18N - } - - } - -} diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteHelper.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteHelper.java deleted file mode 100644 --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteHelper.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2012 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 2012 Sun Microsystems, Inc. - */ -package org.netbeans.modules.web.clientproject.sites; - -import java.awt.EventQueue; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import org.netbeans.api.annotations.common.NonNull; -import org.netbeans.api.annotations.common.NullAllowed; -import org.netbeans.api.progress.ProgressHandle; -import org.netbeans.modules.web.clientproject.api.network.NetworkException; -import org.netbeans.modules.web.clientproject.api.network.NetworkSupport; -import org.netbeans.modules.web.clientproject.api.util.StringUtilities; -import org.openide.DialogDisplayer; -import org.openide.NotifyDescriptor; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; -import org.openide.modules.Places; -import org.openide.util.NbBundle; - -public final class SiteHelper { - - private static final Logger LOGGER = Logger.getLogger(SiteHelper.class.getName()); - private static final String JS_LIBS_DIR = "jslibs"; // NOI18N - - - private SiteHelper() { - } - - /** - * Return <var/cache>/jslibs directory. - * @return <var/cache>/jslibs directory - */ - public static File getJsLibsDirectory() { - return Places.getCacheSubdirectory(JS_LIBS_DIR); - } - - /** - * Download the given URL to the target file. - * @param url URL to be downloaded - * @param target target file - * @param progressHandle progress handle, can be {@code null} - * @throws NetworkException if any network error occurs - * @throws IOException if any error occurs - * @deprecated Use any download method from {@link NetworkSupport}. - */ - @Deprecated - public static void download(String url, File target, @NullAllowed ProgressHandle progressHandle) throws NetworkException, IOException { - assert !EventQueue.isDispatchThread(); - try { - if (progressHandle != null) { - NetworkSupport.downloadWithProgress(url, target, progressHandle); - } else { - NetworkSupport.download(url, target); - } - } catch (InterruptedException ex) { - // cancelled - what to do? - LOGGER.log(Level.WARNING, null, ex); - } - } - - /** - * Unzip the given ZIP file to the given target directory. The target directory must exist. - * @param zipFile ZIP file to be extracted - * @param targetDirectory existing target directory - * @param progressHandle progress handle, can be {@code null} - * @throws IOException if any error occurs - */ - @NbBundle.Messages({ - "# {0} - file name", - "SiteHelper.progress.unzip=Unziping file {0}" - }) - public static void unzipProjectTemplate(@NonNull FileObject targetDir, @NonNull File zipFile, @NullAllowed ProgressHandle progressHandle, String... ignoredFiles) throws IOException { - assert targetDir != null; - if (progressHandle != null) { - progressHandle.progress(Bundle.SiteHelper_progress_unzip(zipFile.getName())); - } - String rootFolder = getZipRootFolder(new FileInputStream(zipFile)); - unzipProjectTemplateFile(targetDir, new FileInputStream(zipFile), rootFolder, ignoredFiles); - } - - /** - * Strip possible root folder of the given paths. - *

- * Warning: only "/" as path separator expected. - *

- * The typical usage is for file paths from a ZIP file. - * @param paths relative paths (with "/" as path separator) to be processed, never empty paths or {@code null} - * @return list of paths without possible root folder - */ - public static List stripRootFolder(List paths) { - List stripped = new ArrayList(paths.size()); - String rootFolder = null; - for (String path : paths) { - assert StringUtilities.hasText(path) : "Empty path not allowed"; - String top; - int slashIndex = path.indexOf('/'); // NOI18N - if (slashIndex == -1) { - top = path; - } else { - top = path.substring(0, slashIndex); - } - if (rootFolder == null) { - rootFolder = top; - } - if (!rootFolder.equals(top)) { - return paths; - } - if (slashIndex != -1 && path.length() > slashIndex) { - stripped.add(path.substring(slashIndex + 1)); - } - } - return stripped; - } - - @NbBundle.Messages("SiteHelper.error.emptyZip=ZIP file with site template is either empty or its download failed.") - private static void unzipProjectTemplateFile(FileObject targetDir, InputStream source, String rootFolder, String... ignoredFiles) throws IOException { - boolean firstItem = true; - try { - int stripLen = rootFolder != null ? rootFolder.length() : 0; - ZipInputStream str = new ZipInputStream(source); - ZipEntry entry; - Set ignored = Collections.emptySet(); - if (ignoredFiles != null && ignoredFiles.length > 0) { - ignored = new HashSet(Arrays.asList(ignoredFiles)); - } - while ((entry = str.getNextEntry()) != null) { - String entryName = entry.getName(); - if (stripLen > 0) { - entryName = entryName.substring(stripLen); - } - if (entryName.length() == 0) { - continue; - } - if (ignored.contains(entryName)) { - continue; - } - firstItem = false; - if (entry.isDirectory()) { - // ignore build folder from mobile boilerplate; unrelated junk IMO. - if (entryName.startsWith("build") || entryName.startsWith("nbproject")) { //NOI18N - continue; - } - if (targetDir.getFileObject(entryName) == null) { - FileUtil.createFolder(targetDir, entryName); - } - } else { - // ignore internal GIT files: - if (entryName.startsWith(".git") || entryName.contains("/.git")) { //NOI18N - continue; - } - // ignore build folder from mobile boilerplate; unrelated junk IMO. - if (entryName.startsWith("build/") || entryName.startsWith("nbproject/")) { //NOI18N - continue; - } - // NetBeans LOCK files - if (entryName.contains("/.LCK") && entryName.endsWith("~")) { //NOI18N - continue; - } - FileObject fo = FileUtil.createData(targetDir, entryName); - writeFile(str, fo); - } - } - } finally { - source.close(); - if (firstItem) { - DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(Bundle.SiteHelper_error_emptyZip())); - } - } - } - - private static void writeFile(ZipInputStream str, FileObject fo) throws IOException { - OutputStream out = fo.getOutputStream(); - try { - FileUtil.copy(str, out); - } finally { - out.close(); - } - } - - private static String getZipRootFolder(InputStream source) throws IOException { - String folder = null; - try { - ZipInputStream str = new ZipInputStream(source); - ZipEntry entry; - boolean first = true; - while ((entry = str.getNextEntry()) != null) { - if (first) { - first = false; - if (entry.isDirectory()) { - folder = entry.getName(); - } else { - String fileName = entry.getName(); - int slashIndex = fileName.indexOf('/'); - if (slashIndex != -1) { - String name = fileName.substring(slashIndex+1); - folder = fileName.substring(0, slashIndex); - if (name.length() == 0 || folder.length() == 0) { - return null; - } - folder += "/"; //NOI18N - } else { - return null; - } - } - } else { - if (!entry.getName().startsWith(folder)) { - return null; - } - } - } - } finally { - source.close(); - } - return folder; - } - -} diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteMobileBoilerplate.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteMobileBoilerplate.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteMobileBoilerplate.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteMobileBoilerplate.java @@ -47,8 +47,9 @@ import java.util.Collection; import java.util.logging.Logger; import org.netbeans.api.progress.ProgressHandle; +import org.netbeans.modules.web.clientproject.api.project.sites.SiteHelper; 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; diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteTemplateRegistration.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteTemplateRegistration.java new file mode 100644 --- /dev/null +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteTemplateRegistration.java @@ -0,0 +1,167 @@ +/* + * 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.sites; + +import java.io.File; +import org.netbeans.modules.web.clientproject.api.project.sites.OnlineSites; +import org.netbeans.modules.web.clientproject.api.project.sites.SiteHelper; +import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation; +import org.openide.filesystems.FileObject; +import org.openide.util.NbBundle; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author Martin Janicek + */ +public class SiteTemplateRegistration { + + @ServiceProvider(service=SiteTemplateImplementation.class, position=150) + public static class SiteAngularJsSeed extends OnlineSites { + + private static final String SITE_ROOT_FOLDER = "app"; // NOI18N + private static final String TEST_FOLDER = "test"; // NOI18N + private static final String CONFIG_FOLDER = "config"; // NOI18N + + + @NbBundle.Messages({"SiteAngularJsSeed.name=AngularJS Seed", + "SiteAngularJsSeed.description=Site template for AngularJS projects."}) + public SiteAngularJsSeed() { + super("ANGULAR", Bundle.SiteAngularJsSeed_name(), Bundle.SiteAngularJsSeed_description(), // NOI18N + "https://github.com/angular/angular-seed/zipball/master", // NOI18N + new File(SiteHelper.getJsLibsDirectory(), "angularjs-seed.zip")); // NOI18N + } + + @Override + public void configure(SiteTemplateImplementation.ProjectProperties projectProperties) { + projectProperties.setSiteRootFolder(SITE_ROOT_FOLDER) + .setTestFolder(TEST_FOLDER) + .setConfigFolder(CONFIG_FOLDER); + } + + @Override + protected FileObject getTargetDir(FileObject projectDir, SiteTemplateImplementation.ProjectProperties projectProperties) { + return projectDir; + } + + } + + @NbBundle.Messages("SiteInitializr.description=Site template from initializr.com.") + @ServiceProvider(service=SiteTemplateImplementation.class, position=200) + public static class BootstrapSiteInitializr extends OnlineSites { + + @NbBundle.Messages("BootstrapSiteInitializr.name=Initializr: Bootstrap") + public BootstrapSiteInitializr() { + super("BOOTSTRAP", Bundle.BootstrapSiteInitializr_name(), // NOI18N + Bundle.SiteInitializr_description(), + "http://www.initializr.com/builder?boot-hero&jquerydev&h5bp-iecond&h5bp-chromeframe&h5bp-analytics&h5bp-favicon&h5bp-appletouchicons&modernizrrespond&izr-emptyscript&boot-css&boot-scripts", // NOI18N + new File(SiteHelper.getJsLibsDirectory(), "initializr-bootstrap-latest.zip")); // NOI18N + } + + } + + @ServiceProvider(service=SiteTemplateImplementation.class, position=210) + public static class ClassicSiteInitializr extends OnlineSites { + + @NbBundle.Messages("ClassicSiteInitializr.name=Initializr: Classic") + public ClassicSiteInitializr() { + super("INIT.CLASSIC", Bundle.ClassicSiteInitializr_name(), // NOI18N + Bundle.SiteInitializr_description(), + "http://www.initializr.com/builder?h5bp-content&modernizr&jquerydev&h5bp-iecond&h5bp-chromeframe&h5bp-analytics&h5bp-htaccess&h5bp-favicon&h5bp-appletouchicons&h5bp-scripts&h5bp-robots&h5bp-humans&h5bp-404&h5bp-adobecrossdomain&h5bp-css&h5bp-csshelpers&h5bp-mediaqueryprint&h5bp-mediaqueries", // NOI18N + new File(SiteHelper.getJsLibsDirectory(), "initializr-classic-latest.zip")); // NOI18N + } + + } + + @ServiceProvider(service=SiteTemplateImplementation.class, position=220) + public static class ResponsiveSiteInitializr extends OnlineSites { + + @NbBundle.Messages("ResponsiveSiteInitializr.name=Initializr: Responsive") + public ResponsiveSiteInitializr() { + super("INIT.RESP", Bundle.ResponsiveSiteInitializr_name(), // NOI18N + Bundle.SiteInitializr_description(), + "http://www.initializr.com/builder?izr-responsive&jquerydev&h5bp-iecond&h5bp-chromeframe&h5bp-analytics&h5bp-favicon&h5bp-appletouchicons&modernizrrespond&h5bp-css&h5bp-csshelpers&h5bp-mediaqueryprint&izr-emptyscript", // NOI18N + new File(SiteHelper.getJsLibsDirectory(), "initializr-responsive-latest.zip")); // NOI18N + } + + } + + @ServiceProvider(service=SiteTemplateImplementation.class, position=300) + public static class SiteHtml5BoilerplateV4 extends OnlineSites { + + @NbBundle.Messages({"SiteHtml5BoilerplateV4.name=HTML5 Boilerplate v4.0.0", + "SiteHtml5BoilerplateV4.description=Site template from html5boilerplate.com. Version: 4.0.0"}) + public SiteHtml5BoilerplateV4() { + super("INIT.BOILER4", Bundle.SiteHtml5BoilerplateV4_name(), Bundle.SiteHtml5BoilerplateV4_description(), // NOI18N + "https://github.com/h5bp/html5-boilerplate/zipball/v4.0.0", // NOI18N + new File(SiteHelper.getJsLibsDirectory(), "html5-boilerplate-400.zip")); // NOI18N + } + + } + + @ServiceProvider(service=SiteTemplateImplementation.class, position=320) + public static class SiteHtml5BoilerplateV3 extends OnlineSites { + + @NbBundle.Messages({"SiteHtml5Boilerplate.name=HTML5 Boilerplate v3.0.2", + "SiteHtml5Boilerplate.description=Site template from html5boilerplate.com. Version: 3.0.2"}) + public SiteHtml5BoilerplateV3() { + super("INIT.BOILER3", Bundle.SiteHtml5Boilerplate_name(), Bundle.SiteHtml5Boilerplate_description(), // NOI18N + "https://github.com/h5bp/html5-boilerplate/zipball/v3.0.2", // NOI18N + new File(SiteHelper.getJsLibsDirectory(), "html5-boilerplate-302.zip")); // NOI18N + } + + } + + @ServiceProvider(service=SiteTemplateImplementation.class, position=400) + public static class SiteTwitterBootstrap extends OnlineSites { + + @NbBundle.Messages({"SiteTwitterBootstrap.name=Twitter Bootstrap", + "SiteTwitterBootstrap.description=Site template from twitter.github.com/bootstrap"}) + public SiteTwitterBootstrap() { + super("TWITTER", Bundle.SiteTwitterBootstrap_name(), Bundle.SiteTwitterBootstrap_description(), // NOI18N + "http://twitter.github.com/bootstrap/assets/bootstrap.zip", // NOI18N + new File(SiteHelper.getJsLibsDirectory(), "twitter-bootstrap.zip")); // NOI18N + } + + } +} diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteZip.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteZip.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteZip.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/sites/SiteZip.java @@ -57,10 +57,12 @@ import javax.swing.event.ChangeListener; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.modules.web.clientproject.ClientSideProjectConstants; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; +import org.netbeans.modules.web.clientproject.api.project.sites.SiteHelper; import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation; -import org.netbeans.modules.web.clientproject.util.FileUtilities; -import org.netbeans.modules.web.clientproject.util.FileUtilities.ZipEntryFilter; -import org.netbeans.modules.web.clientproject.util.FileUtilities.ZipEntryTask; +import org.netbeans.modules.web.clientproject.api.util.FileUtilities; +import org.netbeans.modules.web.clientproject.api.util.FileUtilities.ZipEntryFilter; +import org.netbeans.modules.web.clientproject.api.util.FileUtilities.ZipEntryTask; import org.netbeans.spi.project.support.ant.EditableProperties; import org.openide.filesystems.FileObject; import org.openide.util.ChangeSupport; @@ -136,9 +138,9 @@ EditableProperties templateProperties = new EditableProperties(false); try { templateProperties.load(zipEntryInputStream); - projectProperties.setSiteRootFolder(templateProperties.getProperty(ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER)) - .setTestFolder(templateProperties.getProperty(ClientSideProjectConstants.PROJECT_TEST_FOLDER)) - .setConfigFolder(templateProperties.getProperty(ClientSideProjectConstants.PROJECT_CONFIG_FOLDER)); + projectProperties.setSiteRootFolder(templateProperties.getProperty(WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER)) + .setTestFolder(templateProperties.getProperty(WebClientProjectConstants.PROJECT_TEST_FOLDER)) + .setConfigFolder(templateProperties.getProperty(WebClientProjectConstants.PROJECT_CONFIG_FOLDER)); } catch (IOException ex) { LOGGER.log(Level.WARNING, "Error while reading file", ex); } diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/ClientSideProjectLogicalView.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/ClientSideProjectLogicalView.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/ClientSideProjectLogicalView.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/ClientSideProjectLogicalView.java @@ -67,7 +67,7 @@ import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.queries.VisibilityQuery; import org.netbeans.modules.web.clientproject.ClientSideProject; -import org.netbeans.modules.web.clientproject.ClientSideProjectConstants; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserImplementation; import org.netbeans.modules.web.clientproject.util.ClientSideProjectUtilities; import org.netbeans.modules.web.common.api.RemoteFileCache; @@ -524,13 +524,13 @@ @Override public void propertyChange(PropertyChangeEvent evt) { - if (ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER.equals(evt.getPropertyName())) { + if (WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER.equals(evt.getPropertyName())) { sourcesNodeHidden = isNodeHidden(BasicNodes.Sources); refreshKey(BasicNodes.Sources); - } else if (ClientSideProjectConstants.PROJECT_TEST_FOLDER.equals(evt.getPropertyName())) { + } else if (WebClientProjectConstants.PROJECT_TEST_FOLDER.equals(evt.getPropertyName())) { testsNodeHidden = isNodeHidden(BasicNodes.Tests); refreshKey(BasicNodes.Tests); - } else if (ClientSideProjectConstants.PROJECT_CONFIG_FOLDER.equals(evt.getPropertyName())) { + } else if (WebClientProjectConstants.PROJECT_CONFIG_FOLDER.equals(evt.getPropertyName())) { configNodeHidden = isNodeHidden(BasicNodes.Configuration); refreshKey(BasicNodes.Configuration); } diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/customizer/ClientSideProjectProperties.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/customizer/ClientSideProjectProperties.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/customizer/ClientSideProjectProperties.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/customizer/ClientSideProjectProperties.java @@ -54,6 +54,7 @@ import org.netbeans.modules.web.browser.api.WebBrowser; import org.netbeans.modules.web.clientproject.ClientSideProject; import org.netbeans.modules.web.clientproject.ClientSideProjectConstants; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.api.jslibs.JavaScriptLibrarySelectionPanel; import org.netbeans.modules.web.clientproject.api.jslibs.JavaScriptLibrarySelectionPanel.SelectedLibrary; import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserImplementation; @@ -163,11 +164,11 @@ String configFolderReference = createForeignFileReference(configFolder); // save properties EditableProperties projectProperties = project.getProjectHelper().getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); - putProperty(projectProperties, ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER, siteRootFolderReference); - putProperty(projectProperties, ClientSideProjectConstants.PROJECT_TEST_FOLDER, testFolderReference); - putProperty(projectProperties, ClientSideProjectConstants.PROJECT_CONFIG_FOLDER, configFolderReference); - putProperty(projectProperties, ClientSideProjectConstants.PROJECT_ENCODING, encoding); - putProperty(projectProperties, ClientSideProjectConstants.PROJECT_START_FILE, startFile); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER, siteRootFolderReference); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_TEST_FOLDER, testFolderReference); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_CONFIG_FOLDER, configFolderReference); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_ENCODING, encoding); + putProperty(projectProperties, WebClientProjectConstants.PROJECT_START_FILE, startFile); putProperty(projectProperties, ClientSideProjectConstants.PROJECT_SELECTED_BROWSER, selectedBrowser); if (projectServer != null) { putProperty(projectProperties, ClientSideProjectConstants.PROJECT_SERVER, projectServer.name()); @@ -197,7 +198,7 @@ public String getSiteRootFolder() { if (siteRootFolder == null) { - siteRootFolder = getProjectProperty(ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER, ""); // NOI18N + siteRootFolder = getProjectProperty(WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER, ""); // NOI18N } return siteRootFolder; } @@ -208,7 +209,7 @@ public String getTestFolder() { if (testFolder == null) { - testFolder = getProjectProperty(ClientSideProjectConstants.PROJECT_TEST_FOLDER, ""); // NOI18N + testFolder = getProjectProperty(WebClientProjectConstants.PROJECT_TEST_FOLDER, ""); // NOI18N } return testFolder; } @@ -223,7 +224,7 @@ public String getConfigFolder() { if (configFolder == null) { - configFolder = getProjectProperty(ClientSideProjectConstants.PROJECT_CONFIG_FOLDER, ""); // NOI18N + configFolder = getProjectProperty(WebClientProjectConstants.PROJECT_CONFIG_FOLDER, ""); // NOI18N } return configFolder; } @@ -238,7 +239,7 @@ public String getEncoding() { if (encoding == null) { - encoding = getProjectProperty(ClientSideProjectConstants.PROJECT_ENCODING, ClientSideProjectUtilities.DEFAULT_PROJECT_CHARSET.name()); + encoding = getProjectProperty(WebClientProjectConstants.PROJECT_ENCODING, WebClientProjectConstants.DEFAULT_PROJECT_CHARSET.name()); } return encoding; } diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/customizer/CompositePanelProviderImpl.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/customizer/CompositePanelProviderImpl.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/customizer/CompositePanelProviderImpl.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/customizer/CompositePanelProviderImpl.java @@ -47,7 +47,7 @@ import javax.swing.JComponent; import javax.swing.JPanel; import org.netbeans.modules.editor.indent.project.api.Customizers; -import org.netbeans.modules.web.clientproject.ClientSideProjectType; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.api.jslibs.JavaScriptLibraries; import org.netbeans.modules.web.clientproject.api.jslibs.JavaScriptLibrarySelectionPanel; import org.netbeans.modules.web.common.api.CssPreprocessors; @@ -117,28 +117,28 @@ } @ProjectCustomizer.CompositeCategoryProvider.Registration( - projectType = ClientSideProjectType.TYPE, + projectType = WebClientProjectConstants.WEB_CLIENT_PROJECT_TYPE, position = 100) public static CompositePanelProviderImpl createSources() { return new CompositePanelProviderImpl(SOURCES); } @ProjectCustomizer.CompositeCategoryProvider.Registration( - projectType = ClientSideProjectType.TYPE, + projectType = WebClientProjectConstants.WEB_CLIENT_PROJECT_TYPE, position = 150) public static ProjectCustomizer.CompositeCategoryProvider createCssPreprocessors() { return CssPreprocessors.getDefault().createCustomizer(); } @ProjectCustomizer.CompositeCategoryProvider.Registration( - projectType = ClientSideProjectType.TYPE, + projectType = WebClientProjectConstants.WEB_CLIENT_PROJECT_TYPE, position = 300) public static CompositePanelProviderImpl createRunConfigs() { return new CompositePanelProviderImpl(RUN); } @ProjectCustomizer.CompositeCategoryProvider.Registration( - projectType = ClientSideProjectType.TYPE, + projectType = WebClientProjectConstants.WEB_CLIENT_PROJECT_TYPE, position = 200) public static ProjectCustomizer.CompositeCategoryProvider createJavaScriptFiles() { return JavaScriptLibraries.createCustomizer(new JavaScriptLibraries.CustomizerSupport() { @@ -166,7 +166,7 @@ } @ProjectCustomizer.CompositeCategoryProvider.Registration( - projectType = ClientSideProjectType.TYPE, + projectType = WebClientProjectConstants.WEB_CLIENT_PROJECT_TYPE, position=605 ) public static ProjectCustomizer.CompositeCategoryProvider createLicense() { @@ -174,7 +174,7 @@ } @ProjectCustomizer.CompositeCategoryProvider.Registration( - projectType = ClientSideProjectType.TYPE, + projectType = WebClientProjectConstants.WEB_CLIENT_PROJECT_TYPE, position = 1000 ) public static ProjectCustomizer.CompositeCategoryProvider createFormatting() { diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/ClientSideProjectWizardIterator.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/ClientSideProjectWizardIterator.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/ClientSideProjectWizardIterator.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/ClientSideProjectWizardIterator.java @@ -62,13 +62,13 @@ import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.templates.TemplateRegistration; import org.netbeans.modules.web.clientproject.ClientSideProject; -import org.netbeans.modules.web.clientproject.ClientSideProjectConstants; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.api.jslibs.JavaScriptLibraries; import org.netbeans.modules.web.clientproject.spi.ClientProjectExtender; import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation; import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation.ProjectProperties; import org.netbeans.modules.web.clientproject.util.ClientSideProjectUtilities; -import org.netbeans.modules.web.clientproject.util.FileUtilities; +import org.netbeans.modules.web.clientproject.api.util.FileUtilities; import org.netbeans.spi.project.support.ant.AntProjectHelper; import org.netbeans.spi.project.ui.support.ProjectChooser; import org.openide.DialogDisplayer; @@ -428,9 +428,9 @@ // site template SiteTemplateImplementation siteTemplate = (SiteTemplateImplementation) wizardDescriptor.getProperty(SITE_TEMPLATE); ProjectProperties projectProperties = new ProjectProperties() - .setSiteRootFolder(ClientSideProjectConstants.DEFAULT_SITE_ROOT_FOLDER) - .setTestFolder(ClientSideProjectConstants.DEFAULT_TEST_FOLDER) - .setConfigFolder(ClientSideProjectConstants.DEFAULT_CONFIG_FOLDER); + .setSiteRootFolder(WebClientProjectConstants.DEFAULT_SITE_ROOT_FOLDER) + .setTestFolder(WebClientProjectConstants.DEFAULT_TEST_FOLDER) + .setConfigFolder(WebClientProjectConstants.DEFAULT_CONFIG_FOLDER); if (siteTemplate != null) { // configure siteTemplate.configure(projectProperties); @@ -564,8 +564,8 @@ testFolder = null; configFolder = null; } else { - testFolder = getExistingDir(wizardDescriptor, TEST_ROOT, ClientSideProjectConstants.DEFAULT_TEST_FOLDER); - configFolder = getExistingDir(wizardDescriptor, CONFIG_ROOT, ClientSideProjectConstants.DEFAULT_CONFIG_FOLDER); + testFolder = getExistingDir(wizardDescriptor, TEST_ROOT, WebClientProjectConstants.DEFAULT_TEST_FOLDER); + configFolder = getExistingDir(wizardDescriptor, CONFIG_ROOT, WebClientProjectConstants.DEFAULT_CONFIG_FOLDER); } ClientSideProjectUtilities.initializeProject(project, siteRoot.getAbsolutePath(), testFolder, configFolder); return FileUtil.toFileObject(siteRoot); diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/CreateSiteTemplate.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/CreateSiteTemplate.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/CreateSiteTemplate.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/CreateSiteTemplate.java @@ -64,6 +64,7 @@ import org.netbeans.api.queries.VisibilityQuery; import org.netbeans.modules.web.clientproject.ClientSideProject; import org.netbeans.modules.web.clientproject.ClientSideProjectConstants; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.sites.SiteZip; import org.netbeans.modules.web.clientproject.ui.customizer.ClientSideProjectProperties; import org.netbeans.modules.web.clientproject.util.ClientSideProjectUtilities; @@ -573,7 +574,7 @@ /** * This node wraps 'external site root folder node' and gives it - * display name of {@value ClientSideProjectConstants#DEFAULT_SITE_ROOT_FOLDER}. + * display name of {@value WebClientProjectConstants#DEFAULT_SITE_ROOT_FOLDER}. */ private class ExternalSiteRootNode extends OurFilteredNode { @@ -583,7 +584,7 @@ @Override public String getDisplayName() { - return ClientSideProjectConstants.DEFAULT_SITE_ROOT_FOLDER; + return WebClientProjectConstants.DEFAULT_SITE_ROOT_FOLDER; } @Override @@ -690,13 +691,13 @@ ClientSideProjectProperties projectProperties = new ClientSideProjectProperties(project); String siteRoot; if (isSiteRootExternal(project.getProjectDirectory(), project.getSiteRootFolder())) { - siteRoot = ClientSideProjectConstants.DEFAULT_SITE_ROOT_FOLDER; + siteRoot = WebClientProjectConstants.DEFAULT_SITE_ROOT_FOLDER; } else { siteRoot = projectProperties.getSiteRootFolder(); } - ep.setProperty(ClientSideProjectConstants.PROJECT_SITE_ROOT_FOLDER, siteRoot); - ep.setProperty(ClientSideProjectConstants.PROJECT_TEST_FOLDER, projectProperties.getTestFolder()); - ep.setProperty(ClientSideProjectConstants.PROJECT_CONFIG_FOLDER, projectProperties.getConfigFolder()); + ep.setProperty(WebClientProjectConstants.PROJECT_SITE_ROOT_FOLDER, siteRoot); + ep.setProperty(WebClientProjectConstants.PROJECT_TEST_FOLDER, projectProperties.getTestFolder()); + ep.setProperty(WebClientProjectConstants.PROJECT_CONFIG_FOLDER, projectProperties.getConfigFolder()); ep.store(str); } @@ -747,12 +748,12 @@ } if (fo.equals(siteRoot)) { // site root itself - return ClientSideProjectConstants.DEFAULT_SITE_ROOT_FOLDER; + return WebClientProjectConstants.DEFAULT_SITE_ROOT_FOLDER; } relativePath = FileUtil.getRelativePath(siteRoot, fo); assert relativePath != null : "File '" + fo + "' not underneath site root '" + siteRoot + "'"; assert !relativePath.isEmpty() : "Some relative path expected for '" + fo + "' and site root '" + siteRoot + "'"; - return ClientSideProjectConstants.DEFAULT_SITE_ROOT_FOLDER + "/" + relativePath; // NOI18N + return WebClientProjectConstants.DEFAULT_SITE_ROOT_FOLDER + "/" + relativePath; // NOI18N } } diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/ExistingClientSideProject.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/ExistingClientSideProject.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/ExistingClientSideProject.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/ExistingClientSideProject.java @@ -57,8 +57,8 @@ import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import org.netbeans.modules.web.clientproject.api.util.ValidationUtilities; import org.netbeans.modules.web.clientproject.util.ClientSideProjectUtilities; -import org.netbeans.modules.web.clientproject.util.ValidationUtilities; import org.openide.awt.Mnemonics; import org.openide.filesystems.FileChooserBuilder; import org.openide.filesystems.FileUtil; diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/JavaScriptLibrarySelectionPanel.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/JavaScriptLibrarySelectionPanel.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/JavaScriptLibrarySelectionPanel.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/JavaScriptLibrarySelectionPanel.java @@ -60,7 +60,7 @@ import org.netbeans.modules.web.clientproject.api.util.JsLibUtilities; import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation; import org.netbeans.modules.web.clientproject.ui.customizer.ClientSideProjectProperties; -import org.netbeans.modules.web.clientproject.util.FileUtilities; +import org.netbeans.modules.web.clientproject.api.util.FileUtilities; import org.openide.WizardDescriptor; import org.openide.WizardValidationException; import org.openide.filesystems.FileObject; diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/NewClientSideProject.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/NewClientSideProject.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/NewClientSideProject.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/NewClientSideProject.java @@ -46,8 +46,8 @@ import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; +import org.netbeans.modules.web.clientproject.api.util.ValidationUtilities; import org.netbeans.modules.web.clientproject.util.ClientSideProjectUtilities; -import org.netbeans.modules.web.clientproject.util.ValidationUtilities; import org.netbeans.spi.project.ui.support.ProjectChooser; import org.openide.filesystems.FileChooserBuilder; import org.openide.filesystems.FileUtil; diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/NewFileWizardIterator.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/NewFileWizardIterator.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/NewFileWizardIterator.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/ui/wizard/NewFileWizardIterator.java @@ -57,7 +57,7 @@ import org.netbeans.modules.web.clientproject.ClientSideProject; import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.util.ClientSideProjectUtilities; -import org.netbeans.modules.web.clientproject.util.FileUtilities; +import org.netbeans.modules.web.clientproject.api.util.FileUtilities; import org.netbeans.spi.project.ui.templates.support.Templates; import org.openide.WizardDescriptor; import org.openide.WizardDescriptor.Panel; diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/util/ClientSideProjectUtilities.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/util/ClientSideProjectUtilities.java --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/util/ClientSideProjectUtilities.java +++ b/web.clientproject/src/org/netbeans/modules/web/clientproject/util/ClientSideProjectUtilities.java @@ -44,9 +44,6 @@ import java.awt.Color; import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -63,7 +60,6 @@ import org.netbeans.api.project.SourceGroup; import org.netbeans.api.project.Sources; import org.netbeans.modules.web.clientproject.ClientSideProject; -import org.netbeans.modules.web.clientproject.ClientSideProjectType; import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.ui.customizer.ClientSideProjectProperties; import org.netbeans.spi.project.support.ant.AntProjectHelper; @@ -84,11 +80,8 @@ */ public final class ClientSideProjectUtilities { - private static final Logger LOGGER = Logger.getLogger(ClientSideProjectUtilities.class.getName()); private static final Logger USG_LOGGER = Logger.getLogger("org.netbeans.ui.metrics.web.clientproject"); // NOI18N - public static final Charset DEFAULT_PROJECT_CHARSET = getDefaultProjectCharset(); - private ClientSideProjectUtilities() { } @@ -123,7 +116,7 @@ */ public static AntProjectHelper setupProject(FileObject dirFO, String name) throws IOException { // create project - AntProjectHelper projectHelper = ProjectGenerator.createProject(dirFO, ClientSideProjectType.TYPE); + AntProjectHelper projectHelper = ProjectGenerator.createProject(dirFO, WebClientProjectConstants.WEB_CLIENT_PROJECT_TYPE); setProjectName(projectHelper, name); // #231319 ProjectManager.getDefault().clearNonProjectCache(); @@ -135,7 +128,7 @@ } // set encoding ClientSideProjectProperties projectProperties = new ClientSideProjectProperties(clientSideProject); - projectProperties.setEncoding(DEFAULT_PROJECT_CHARSET.name()); + projectProperties.setEncoding(WebClientProjectConstants.DEFAULT_PROJECT_CHARSET.name()); projectProperties.save(); return projectHelper; } @@ -175,7 +168,7 @@ public void run() { Element data = projectHelper.getPrimaryConfigurationData(true); Document document = data.getOwnerDocument(); - NodeList nameList = data.getElementsByTagNameNS(ClientSideProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N + NodeList nameList = data.getElementsByTagNameNS(WebClientProjectConstants.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N Element nameElement; if (nameList.getLength() == 1) { nameElement = (Element) nameList.item(0); @@ -185,7 +178,7 @@ } } else { nameElement = document.createElementNS( - ClientSideProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N + WebClientProjectConstants.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N data.insertBefore(nameElement, data.getChildNodes().item(0)); } nameElement.appendChild(document.createTextNode(name)); @@ -219,20 +212,6 @@ return fileObjects; } - // #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(); - } - /** * Splits paths like 'index.html#/path' into 'index.html' and '#/path' */ diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/util/FileUtilities.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/util/FileUtilities.java deleted file mode 100644 --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/util/FileUtilities.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2012 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 2012 Sun Microsystems, Inc. - */ -package org.netbeans.modules.web.clientproject.util; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import org.netbeans.api.annotations.common.NonNull; -import org.netbeans.api.annotations.common.NullAllowed; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; - -/** - * Miscellaneous utility methods for files. - */ -public final class FileUtilities { - - private static final Logger LOGGER = Logger.getLogger(FileUtilities.class.getName()); - - private static final String HTML_MIME_TYPE = "text/html"; // NOI18N - private static final String XHTML_MIME_TYPE = "text/xhtml"; // NOI18N - private static final String CSS_MIME_TYPE = "text/css"; // NOI18N - - - private FileUtilities() { - } - - /** - * Check whether the given file is an (X)HTML file. - * @param file file to be checked - * @return {@code true} if the given file is an (X)HTML file, {@code false} otherwise - */ - public static boolean isHtmlFile(FileObject file) { - String mimeType = FileUtil.getMIMEType(file, HTML_MIME_TYPE, XHTML_MIME_TYPE); - return HTML_MIME_TYPE.equals(mimeType) || XHTML_MIME_TYPE.equals(mimeType); - } - - /** - * Check whether the given file is a CSS file. - * @param file file to be checked - * @return {@code true} if the given file is a CSS file, {@code false} otherwise - */ - public static boolean isCssFile(FileObject file) { - return CSS_MIME_TYPE.equals(FileUtil.getMIMEType(file, CSS_MIME_TYPE)); - } - - /** - * Cleanup the given folder. The folder itself is not removed. - * @param fileObject folder to be cleaned up - * @throws IOException if any error occurs - */ - public static void cleanupFolder(FileObject fileObject) throws IOException { - for (FileObject child : fileObject.getChildren()) { - child.delete(); - } - } - - /** - * Move content of the source to the target. If the target file already exists and is a file - * (not folder), the source file is moved and renamed (suffix _0, _1 etc.). - * @param source source file object - * @param target target file object - * @throws IOException if any error occurs - */ - public static void moveContent(FileObject source, FileObject target) throws IOException { - for (FileObject child : source.getChildren()) { - FileObject newChild = target.getFileObject(child.getNameExt()); - if (newChild == null) { - // does not exists - FileUtil.moveFile(child, target, child.getName()); - } else if (newChild.isFolder()) { - // copy directory content - moveContent(child, newChild); - child.delete(); - } else { - // file already exists => rename - int i = 0; - for (;;) { - String newName = child.getName() + "_" + i++; // NOI18N - if (target.getFileObject(newName) == null) { - FileUtil.moveFile(child, target, newName); - break; - } - } - } - } - } - - /** - * Run task on the given ZIP file. - * @param zipFile ZIP file to be processed - * @param entryTask task to be applied on the ZIP file entries - * @param entryFilter filter to be applied on the ZIP file entries, can be {@code null} - * @throws IOException if any error occurs - */ - public static void runOnZipEntries(@NonNull File zipFile, @NonNull ZipEntryTask entryTask, @NullAllowed ZipEntryFilter entryFilter) throws IOException { - ZipFile zip = new ZipFile(zipFile); - try { - Enumeration entries = zip.entries(); - while (entries.hasMoreElements()) { - ZipEntry zipEntry = entries.nextElement(); - boolean accept = true; - if (entryFilter != null) { - accept = entryFilter.accept(zipEntry); - } - if (accept) { - entryTask.run(zipEntry); - InputStream inputStream = zip.getInputStream(zipEntry); - try { - entryTask.run(inputStream); - } finally { - inputStream.close(); - } - } - } - } finally { - zip.close(); - } - } - - /** - * Get list of files from the given ZIP file according to the given {@link ZipEntryFilter filter}. - * @param zipFile ZIP file to be listed - * @param entryFilter filter to be applied on the ZIP file entries - * @return list of files from the given ZIP file according to the given {@link ZipEntryFilter filter} - * @throws IOException if any error occurs - */ - public static List listZipFiles(@NonNull File zipFile, @NonNull ZipEntryFilter entryFilter) throws IOException { - assert zipFile != null; - assert entryFilter != null; - final List files = new ArrayList(); - runOnZipEntries(zipFile, new ZipEntryTask() { - @Override - public void run(ZipEntry zipEntry) { - files.add(zipEntry.getName()); - } - @Override - public void run(InputStream zipEntryInputStream) { - // noop - } - }, entryFilter); - return files; - } - - /** - * Get list of JS files (filenames with relative path) from the given ZIP file. - *

- * If any error occurs, this error is logged with INFO level and an empty list is returned. - * @param zipFile ZIP file to be listed - * @return list of JS files (filenames with relative path) from the given ZIP file. - * @see #listZipFiles(File, ZipEntryFilter) - * @see #listJsFilenamesFromZipFile(File) - */ - public static List listJsFilesFromZipFile(File zipFile) { - try { - return listZipFiles(zipFile, new ZipEntryFilter() { - @Override - public boolean accept(ZipEntry zipEntry) { - return !zipEntry.isDirectory() - && zipEntry.getName().toLowerCase().endsWith(".js"); // NOI18N - } - }); - } catch (IOException ex) { - LOGGER.log(Level.INFO, null, ex); - } - return Collections.emptyList(); - } - - //~ Inner classes - - /** - * Filter for {@link ZipEntry}s. - *

- * Instances of this interface may be passed to the {@link #listZipFiles(File, ZipEntryFilter)} method. - * @see #listZipFiles(File, ZipEntryFilter) - */ - public interface ZipEntryFilter { - - /** - * Test whether or not the specified {@link ZipEntry} should be - * accepted. - * - * @param zipEntry the {@link ZipEntry} to be tested - * @return {@ code true} if {@link ZipEntry} should be accepted, {@code false} otherwise - */ - boolean accept(ZipEntry zipEntry); - } - - /** - * Task for {@link ZipEntry}s, their content. - * @see #runOnZipEntries(File, ZipEntryTask, ZipEntryFilter) - */ - public interface ZipEntryTask { - - /** - * Run task on the given ZIP entry. - * @param zipEntry {@link ZipEntry} to be processed - */ - void run(ZipEntry zipEntry); - - /** - * Run task on the given content, typically read it. - * @param zipEntryInputStream content of the given {@link ZipEntry} - */ - void run(InputStream zipEntryInputStream); - } - -} diff --git a/web.clientproject/src/org/netbeans/modules/web/clientproject/util/ValidationUtilities.java b/web.clientproject/src/org/netbeans/modules/web/clientproject/util/ValidationUtilities.java deleted file mode 100644 --- a/web.clientproject/src/org/netbeans/modules/web/clientproject/util/ValidationUtilities.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2012 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 2012 Sun Microsystems, Inc. - */ -package org.netbeans.modules.web.clientproject.util; - -import java.io.File; - -/** - * Miscellaneous utility methods for validation. - */ -public final class ValidationUtilities { - - private static final char[] INVALID_FILENAME_CHARS = new char[] {'/', '\\', '|', ':', '*', '?', '"', '<', '>'}; // NOI18N - - - private ValidationUtilities() { - } - - /** - * Check whether the provided filename is valid. An empty string is considered to be invalid. - * @param filename file name to be validated - * @return {@code true} if the provided filename is valid - */ - public static boolean isValidFilename(String filename) { - assert filename != null; - if (filename.trim().length() == 0) { - return false; - } - for (char ch : INVALID_FILENAME_CHARS) { - if (filename.indexOf(ch) != -1) { - return false; - } - } - return true; - } - - /** - * Check whether the provided file has a valid filename. Only the non-existing filenames in the file path are checked. - * It means that if you pass existing directory, no check is done. - *

- * For example for C:\Documents And Settings\ExistingDir\NonExistingDir\NonExistingDir2\Newdir the last free filenames - * are checked. - * @param file file to be checked - * @return {@code true} if the provided file has valid filename - * @see #isValidFilename(String) - */ - public static boolean isValidFilename(File file) { - assert file != null; - File tmp = file; - while (tmp != null && !tmp.exists()) { - if (tmp.isAbsolute() && tmp.getParentFile() == null) { - return true; - } else if (!isValidFilename(tmp.getName())) { - return false; - } - tmp = tmp.getParentFile(); - } - return true; - } - -} diff --git a/web.clientproject/test/unit/src/org/netbeans/modules/web/clientproject/ClientSideProjectTest.java b/web.clientproject/test/unit/src/org/netbeans/modules/web/clientproject/ClientSideProjectTest.java --- a/web.clientproject/test/unit/src/org/netbeans/modules/web/clientproject/ClientSideProjectTest.java +++ b/web.clientproject/test/unit/src/org/netbeans/modules/web/clientproject/ClientSideProjectTest.java @@ -51,6 +51,7 @@ import org.netbeans.junit.NbTestCase; import org.netbeans.modules.web.browser.api.BrowserFamilyId; import org.netbeans.modules.web.browser.spi.EnhancedBrowserFactory; +import org.netbeans.modules.web.clientproject.api.WebClientProjectConstants; import org.netbeans.modules.web.clientproject.sites.SiteZip; import org.netbeans.modules.web.clientproject.sites.SiteZipPanel; import org.netbeans.modules.web.clientproject.spi.SiteTemplateImplementation; @@ -106,9 +107,9 @@ AntProjectHelper projectHelper = ClientSideProjectUtilities.setupProject(wd, "Project2"); ClientSideProject project = (ClientSideProject) FileOwnerQuery.getOwner(projectHelper.getProjectDirectory()); ClientSideProjectProperties projectProperties = new ClientSideProjectProperties(project); - projectProperties.setSiteRootFolder(ClientSideProjectConstants.DEFAULT_SITE_ROOT_FOLDER); - projectProperties.setTestFolder(ClientSideProjectConstants.DEFAULT_TEST_FOLDER); - projectProperties.setConfigFolder(ClientSideProjectConstants.DEFAULT_CONFIG_FOLDER); + projectProperties.setSiteRootFolder(WebClientProjectConstants.DEFAULT_SITE_ROOT_FOLDER); + projectProperties.setTestFolder(WebClientProjectConstants.DEFAULT_TEST_FOLDER); + projectProperties.setConfigFolder(WebClientProjectConstants.DEFAULT_CONFIG_FOLDER); projectProperties.save(); ProjectProblemsProvider ppp = project.getLookup().lookup(ProjectProblemsProvider.class); assertNotNull("project does have ProjectProblemsProvider", ppp);