| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.j2ee.clientproject.api; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.PrintWriter; |
| import java.math.BigDecimal; |
| import java.nio.charset.Charset; |
| import java.util.Map; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import org.netbeans.api.java.platform.JavaPlatform; |
| import org.netbeans.api.java.platform.JavaPlatformManager; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.api.project.ProjectManager; |
| import org.netbeans.api.java.project.JavaProjectConstants; |
| import org.netbeans.api.project.libraries.LibraryManager; |
| import org.netbeans.api.queries.FileEncodingQuery; |
| import org.netbeans.modules.j2ee.clientproject.AppClientProject; |
| import org.netbeans.modules.j2ee.clientproject.AppClientProjectType; |
| import org.netbeans.modules.j2ee.clientproject.AppClientProvider; |
| import org.netbeans.modules.j2ee.clientproject.Utils; |
| import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties; |
| import org.netbeans.modules.j2ee.common.SharabilityUtility; |
| import org.netbeans.modules.j2ee.dd.api.client.AppClient; |
| import org.netbeans.modules.j2ee.dd.api.client.DDProvider; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform; |
| import org.netbeans.api.j2ee.core.Profile; |
| import org.netbeans.modules.j2ee.common.dd.DDHelper; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.InstanceRemovedException; |
| import org.netbeans.modules.javaee.project.api.ant.AntProjectConstants; |
| import org.netbeans.modules.javaee.project.api.ant.ui.J2EEProjectProperties; |
| import org.netbeans.modules.java.api.common.ant.UpdateHelper; |
| import org.netbeans.modules.java.api.common.project.ProjectProperties; |
| import org.netbeans.modules.java.api.common.ui.PlatformUiSupport; |
| import org.netbeans.spi.java.project.support.PreferredProjectPlatform; |
| 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.netbeans.spi.project.support.ant.ReferenceHelper; |
| import org.openide.filesystems.FileObject; |
| import org.openide.filesystems.FileUtil; |
| import org.openide.loaders.DataFolder; |
| import org.openide.loaders.DataObject; |
| import org.openide.util.Mutex; |
| import org.openide.util.MutexException; |
| import org.openide.filesystems.FileLock; |
| import org.openide.filesystems.FileSystem; |
| import org.openide.filesystems.FileSystem.AtomicAction; |
| import org.openide.modules.SpecificationVersion; |
| import org.openide.util.Exceptions; |
| import org.openide.util.NbBundle; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NodeList; |
| |
| /** |
| * Creates a AppClientProject from scratch according to some initial configuration. |
| */ |
| public class AppClientProjectGenerator { |
| private static final String DEFAULT_CONF_FOLDER = "conf"; //NOI18N |
| private static final String DEFAULT_SRC_FOLDER = "src"; //NOI18N |
| private static final String DEFAULT_TEST_FOLDER = "test"; //NOI18N |
| private static final String DEFAULT_RESOURCE_FOLDER = "setup"; //NOI18N |
| private static final String DEFAULT_JAVA_FOLDER = "java"; //NOI18N |
| private static final String DEFAULT_BUILD_DIR = "build"; //NOI18N |
| |
| public static final String MINIMUM_ANT_VERSION = "1.6.5"; // NOI18N |
| |
| private static final String MANIFEST_FILE = "MANIFEST.MF"; // NOI18N |
| |
| private AppClientProjectGenerator() {} |
| |
| /** |
| * Create a new Application client project. |
| * |
| * @param dir the top-level directory (need not yet exist but if it does it must be empty) |
| * @param name the name for the project |
| * @param mainClass the name for the main class |
| * @param j2eeLevel defined in <code>org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule</code> |
| * @param serverInstanceID provided by j2eeserver module |
| * |
| * @return the helper object permitting it to be further customized |
| * @throws IOException in case something went wrong |
| */ |
| @Deprecated |
| public static AntProjectHelper createProject(File dir, final String name, |
| final String mainClass, final String j2eeLevel, |
| final String serverInstanceID) throws IOException { |
| return createProject(dir, name, mainClass, j2eeLevel, serverInstanceID, null); |
| } |
| |
| @Deprecated |
| public static AntProjectHelper createProject(File dir, final String name, |
| final String mainClass, final String j2eeLevel, |
| final String serverInstanceID, final String librariesDefinition |
| ) throws IOException { |
| |
| AppClientProjectCreateData createData = new AppClientProjectCreateData(); |
| createData.setProjectDir(dir); |
| createData.setName(name); |
| createData.setMainClass(mainClass); |
| createData.setJavaEEProfile(Profile.fromPropertiesString(j2eeLevel)); |
| createData.setServerInstanceID(serverInstanceID); |
| createData.setLibrariesDefinition(librariesDefinition); |
| return createProject(createData); |
| } |
| |
| public static AntProjectHelper createProject(final AppClientProjectCreateData createData) throws IOException { |
| File dir = createData.getProjectDir(); |
| |
| final AntProjectHelper[] h = new AntProjectHelper[1]; |
| final FileObject projectDir = FileUtil.createFolder(dir); |
| |
| // create project in one FS atomic action: |
| FileSystem fs = projectDir.getFileSystem(); |
| fs.runAtomicAction(new FileSystem.AtomicAction() { |
| @Override |
| public void run() throws IOException { |
| AntProjectHelper helper = createProjectImpl(createData, projectDir); |
| h[0] = helper; |
| }}); |
| return h[0]; |
| } |
| |
| private static AntProjectHelper createProjectImpl(final AppClientProjectCreateData createData, |
| final FileObject projectDir) throws IOException { |
| |
| String name = createData.getName(); |
| String mainClass = createData.getMainClass(); |
| String serverInstanceID = createData.getServerInstanceID(); |
| Profile j2eeProfile = createData.getJavaEEProfile(); |
| |
| FileObject srcRoot = projectDir.createFolder(DEFAULT_SRC_FOLDER); |
| FileObject javaRoot = srcRoot.createFolder(DEFAULT_JAVA_FOLDER); |
| FileObject confRoot = srcRoot.createFolder(DEFAULT_CONF_FOLDER); |
| projectDir.createFolder(DEFAULT_TEST_FOLDER); |
| |
| // create application-client.xml |
| String resource; |
| if(j2eeProfile == null) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-6.xml"; // NOI18N |
| } else if (Profile.JAKARTA_EE_10_FULL.equals(j2eeProfile) || Profile.JAKARTA_EE_10_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-10.xml"; // NOI18N |
| } else if (Profile.JAKARTA_EE_9_1_FULL.equals(j2eeProfile) || Profile.JAKARTA_EE_9_1_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-9.xml"; // NOI18N |
| } else if (Profile.JAKARTA_EE_9_FULL.equals(j2eeProfile) || Profile.JAKARTA_EE_9_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-9.xml"; // NOI18N |
| } else if (Profile.JAKARTA_EE_8_FULL.equals(j2eeProfile) || Profile.JAKARTA_EE_8_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-8.xml"; // NOI18N |
| } else if (Profile.JAVA_EE_8_FULL.equals(j2eeProfile) || Profile.JAVA_EE_8_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-8.xml"; // NOI18N |
| } else if (Profile.JAVA_EE_7_FULL.equals(j2eeProfile) || Profile.JAVA_EE_7_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-7.xml"; // NOI18N |
| } else if (Profile.JAVA_EE_5.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-5.xml"; // NOI18N |
| } else if (Profile.J2EE_14.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-1.4.xml"; // NOI18N |
| } else { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-6.xml"; // NOI18N |
| } |
| FileObject foSource = FileUtil.getConfigFile(resource); |
| FileObject ddFile = FileUtil.copyFile(foSource, confRoot, "application-client"); //NOI18N |
| AppClient appClient = DDProvider.getDefault().getDDRoot(ddFile); |
| appClient.setDisplayName(name); |
| appClient.write(ddFile); |
| if (createData.isCDIEnabled()) { |
| DDHelper.createBeansXml(j2eeProfile, confRoot); |
| } |
| |
| final AntProjectHelper h = setupProject(projectDir, name, |
| DEFAULT_SRC_FOLDER, DEFAULT_TEST_FOLDER, |
| null, null, null, mainClass, j2eeProfile, |
| serverInstanceID, createData.getLibrariesDefinition(), |
| createData.skipTests()); |
| |
| EditableProperties ep = h.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| ep.put(AppClientProjectProperties.SOURCE_ROOT, DEFAULT_SRC_FOLDER); //NOI18N |
| ep.setProperty(AppClientProjectProperties.META_INF, "${"+AppClientProjectProperties.SOURCE_ROOT+"}/"+DEFAULT_CONF_FOLDER); //NOI18N |
| ep.setProperty(AppClientProjectProperties.SRC_DIR, "${"+AppClientProjectProperties.SOURCE_ROOT+"}/"+DEFAULT_JAVA_FOLDER); //NOI18N |
| |
| h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep); |
| |
| AppClientProject p = (AppClientProject) ProjectManager.getDefault().findProject(projectDir); |
| ProjectManager.getDefault().saveProject(p); |
| |
| final ReferenceHelper refHelper = p.getReferenceHelper(); |
| try { |
| ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() { |
| @Override |
| public Void run() throws Exception { |
| copyRequiredLibraries(h, refHelper, createData); |
| return null; |
| } |
| }); |
| } catch (MutexException ex) { |
| Exceptions.printStackTrace(ex.getException()); |
| } |
| |
| if ( mainClass != null ) { |
| createMainClass( mainClass, javaRoot ); |
| } |
| |
| createManifest(confRoot, MANIFEST_FILE); |
| |
| return h; |
| } |
| |
| /** |
| * Imports an existing Application client project into NetBeans project. |
| * |
| * @param dir the top-level directory (need not yet exist but if it does it must be empty) - "nbproject" location |
| * @param name the name for the project |
| * @param sourceFolders top-level location(s) of java sources - must not be null |
| * @param testFolders top-level location(s) of test(s) - must not be null |
| * @param confFolder top-level location of configuration file(s) folder - must not be null |
| * @param libFolder top-level location of libraries |
| * @param j2eeLevel defined in <code>org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule</code> |
| * @param serverInstanceID provided by j2eeserver module |
| * |
| * @return the helper object permitting it to be further customized |
| * @throws IOException in case something went wrong |
| */ |
| @Deprecated |
| public static AntProjectHelper importProject(final File dir, final String name, |
| final File[] sourceFolders, final File[] testFolders, final File confFolder, |
| final File libFolder, final String j2eeLevel, final String serverInstanceID) throws IOException { |
| |
| return importProject(dir, name, sourceFolders, testFolders, confFolder, |
| libFolder, j2eeLevel, serverInstanceID, null); |
| } |
| |
| @Deprecated |
| public static AntProjectHelper importProject(final File dir, final String name, |
| final File[] sourceFolders, final File[] testFolders, final File confFolder, |
| final File libFolder, final String j2eeLevel, final String serverInstanceID, |
| final String librariesDefinition) throws IOException { |
| |
| AppClientProjectCreateData createData = new AppClientProjectCreateData(); |
| createData.setProjectDir(dir); |
| createData.setName(name); |
| createData.setSourceFolders(sourceFolders); |
| createData.setTestFolders(testFolders); |
| createData.setConfFolder(confFolder); |
| createData.setLibFolder(libFolder); |
| createData.setJavaEEProfile(Profile.fromPropertiesString(j2eeLevel)); |
| createData.setServerInstanceID(serverInstanceID); |
| createData.setLibrariesDefinition(librariesDefinition); |
| return importProject(createData); |
| } |
| |
| public static AntProjectHelper importProject(final AppClientProjectCreateData createData) throws IOException { |
| File dir = createData.getProjectDir(); |
| |
| final AntProjectHelper[] h = new AntProjectHelper[1]; |
| final FileObject projectDir = FileUtil.createFolder(dir); |
| |
| // create project in one FS atomic action: |
| FileSystem fs = projectDir.getFileSystem(); |
| fs.runAtomicAction(new FileSystem.AtomicAction() { |
| @Override |
| public void run() throws IOException { |
| AntProjectHelper helper = importProjectImpl(createData, projectDir); |
| h[0] = helper; |
| }}); |
| return h[0]; |
| } |
| |
| private static AntProjectHelper importProjectImpl(final AppClientProjectCreateData createData, final FileObject projectDir) throws IOException { |
| final File[] sourceFolders = createData.getSourceFolders(); |
| final File[] testFolders = createData.getTestFolders(); |
| String name = createData.getName(); |
| String serverInstanceID = createData.getServerInstanceID(); |
| File confFolder = createData.getConfFolder(); |
| Profile j2eeProfile = createData.getJavaEEProfile(); |
| |
| assert sourceFolders != null && testFolders != null: "Package roots can't be null"; //NOI18N |
| |
| final AntProjectHelper h = setupProject(projectDir, name, null, null, |
| confFolder, createData.getLibFolder(), |
| null, null, j2eeProfile, serverInstanceID, createData.getLibrariesDefinition(), |
| createData.skipTests()); |
| |
| final AppClientProject p = (AppClientProject) ProjectManager.getDefault().findProject(projectDir); |
| final ReferenceHelper refHelper = p.getReferenceHelper(); |
| |
| try { |
| ProjectManager.mutex().writeAccess( new Mutex.ExceptionAction<Void>() { |
| @Override |
| public Void run() throws Exception { |
| Element data = h.getPrimaryConfigurationData(true); |
| Document doc = data.getOwnerDocument(); |
| NodeList nl = data.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots"); // NOI18N |
| assert nl.getLength() == 1; |
| Element sourceRoots = (Element) nl.item(0); |
| nl = data.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots"); //NOI18N |
| assert nl.getLength() == 1; |
| Element testRoots = (Element) nl.item(0); |
| for (int i=0; i<sourceFolders.length; i++) { |
| String propName = "src.dir" + (i == 0 ? "" : Integer.toString(i+1)); //NOI18N |
| String srcReference = refHelper.createForeignFileReference(sourceFolders[i], JavaProjectConstants.SOURCES_TYPE_JAVA); |
| Element root = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root"); //NOI18N |
| root.setAttribute("id",propName); //NOI18N |
| sourceRoots.appendChild(root); |
| EditableProperties props = h.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| props.put(propName,srcReference); |
| h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props); // #47609 |
| } |
| |
| if (testFolders.length == 0) { |
| EditableProperties props = h.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| props.put("test.src.dir", ""); // NOI18N |
| h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props); // #47609 |
| } else { |
| for (int i=0; i<testFolders.length; i++) { |
| if (!testFolders[i].exists()) { |
| FileUtil.createFolder(testFolders[i]); |
| } |
| String propName = "test.src.dir" + (i == 0 ? "" : Integer.toString(i+1)); //NOI18N |
| String testReference = refHelper.createForeignFileReference(testFolders[i], JavaProjectConstants.SOURCES_TYPE_JAVA); |
| Element root = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root"); //NOI18N |
| root.setAttribute("id",propName); //NOI18N |
| testRoots.appendChild(root); |
| EditableProperties props = h.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); // #47609 |
| props.put(propName,testReference); |
| h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props); |
| } |
| } |
| h.putPrimaryConfigurationData(data,true); |
| copyRequiredLibraries(h, refHelper, createData); |
| ProjectManager.getDefault().saveProject(p); |
| return null; |
| } |
| }); |
| } catch (MutexException me ) { |
| IOException ex = new IOException("project creation failed"); |
| ex.initCause(me); |
| throw ex; |
| } |
| |
| // AB: fix for #53170: if j2eeLevel is 1.4 and application-client.xml is version 1.3, we upgrade it to version 1.4 |
| FileObject confFolderFO = FileUtil.toFileObject(confFolder); |
| FileObject appClientXML = confFolderFO == null ? null |
| : confFolderFO.getFileObject(AppClientProvider.FILE_DD); |
| if (appClientXML != null) { |
| try { |
| AppClient root = DDProvider.getDefault().getDDRoot(appClientXML); |
| boolean writeDD = false; |
| boolean upgradeTo14 = root.getVersion() == null ? true : |
| new BigDecimal(AppClient.VERSION_1_4).compareTo(root.getVersion()) > 0; |
| if (upgradeTo14 && Profile.J2EE_14.equals(j2eeProfile)) { |
| root.setVersion(new BigDecimal(AppClient.VERSION_1_4)); |
| writeDD = true; |
| } |
| // also set the display name if not set (#55733) |
| String dispName = root.getDefaultDisplayName(); |
| if (null == dispName || dispName.trim().length() == 0) { |
| root.setDisplayName(name); |
| writeDD = true; |
| } |
| if (writeDD) { |
| root.write(appClientXML); |
| } |
| } catch (IOException e) { |
| Exceptions.printStackTrace(e); |
| } |
| } else { |
| // XXX just temporary, since now the import would fail due to another bug |
| String resource; |
| if (j2eeProfile == null) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-6.xml"; // NOI18N |
| } else if (Profile.JAKARTA_EE_10_FULL.equals(j2eeProfile) || Profile.JAKARTA_EE_10_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-10.xml"; // NOI18N |
| } else if (Profile.JAKARTA_EE_9_1_FULL.equals(j2eeProfile) || Profile.JAKARTA_EE_9_1_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-9.xml"; // NOI18N |
| } else if (Profile.JAKARTA_EE_9_FULL.equals(j2eeProfile) || Profile.JAKARTA_EE_9_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-9.xml"; // NOI18N |
| } else if (Profile.JAKARTA_EE_8_FULL.equals(j2eeProfile) || Profile.JAKARTA_EE_8_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-8.xml"; // NOI18N |
| } else if (Profile.JAVA_EE_8_FULL.equals(j2eeProfile) || Profile.JAVA_EE_8_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-8.xml"; // NOI18N |
| } else if (Profile.JAVA_EE_7_FULL.equals(j2eeProfile) || Profile.JAVA_EE_7_WEB.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-7.xml"; // NOI18N |
| } else if (Profile.JAVA_EE_5.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-5.xml"; // NOI18N |
| } else if (Profile.J2EE_14.equals(j2eeProfile)) { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-1.4.xml"; // NOI18N |
| } else { |
| resource = "org-netbeans-modules-j2ee-clientproject/application-client-6.xml"; // NOI18N |
| } |
| FileUtil.copyFile(FileUtil.getConfigFile(resource), |
| confFolderFO, "application-client"); //NOI18N |
| } |
| createManifest(confFolderFO, MANIFEST_FILE); |
| return h; |
| } |
| |
| private static void copyRequiredLibraries(AntProjectHelper h, ReferenceHelper rh, |
| AppClientProjectCreateData createData) throws IOException { |
| |
| if (!h.isSharableProject()) { |
| return; |
| } |
| if (!createData.skipTests() && rh.getProjectLibraryManager().getLibrary("junit") == null) { // NOI18N |
| if (LibraryManager.getDefault().getLibrary("junit") != null) { |
| rh.copyLibrary(LibraryManager.getDefault().getLibrary("junit")); // NOI18N |
| } |
| } |
| if (!createData.skipTests() && rh.getProjectLibraryManager().getLibrary("junit_4") == null) { // NOI18N |
| if (LibraryManager.getDefault().getLibrary("junit_4") != null) { |
| rh.copyLibrary(LibraryManager.getDefault().getLibrary("junit_4")); // NOI18N |
| } |
| } |
| Profile j2eeProfile = createData.getJavaEEProfile(); |
| String libraryName = null; |
| if (j2eeProfile.equals(Profile.JAVA_EE_6_FULL) || j2eeProfile.equals(Profile.JAVA_EE_6_WEB)) { |
| libraryName = AntProjectConstants.ENDORSED_LIBRARY_NAME_6; |
| if (rh.getProjectLibraryManager().getLibrary(libraryName) == null) { // NOI18N |
| rh.copyLibrary(LibraryManager.getDefault().getLibrary(libraryName)); // NOI18N |
| } |
| } else if (j2eeProfile.equals(Profile.JAVA_EE_7_FULL) || j2eeProfile.equals(Profile.JAVA_EE_7_WEB)) { |
| libraryName = AntProjectConstants.ENDORSED_LIBRARY_NAME_7; |
| if (rh.getProjectLibraryManager().getLibrary(libraryName) == null) { // NOI18N |
| rh.copyLibrary(LibraryManager.getDefault().getLibrary(libraryName)); // NOI18N |
| } |
| } |
| SharabilityUtility.makeSureProjectHasCopyLibsLibrary(h, rh); |
| } |
| |
| /** |
| * Imports an existing Application client project into NetBeans project |
| * with a flag to specify whether the project contains java source files |
| * or was created from an exploded archive. |
| * @return the helper object permitting it to be further customized |
| * @param fromJavaSource indicate whether the project is "from" source or an exploded archive |
| * @param dir the top-level directory (need not yet exist but if it does it must be empty) - "nbproject" location |
| * @param name the name for the project |
| * @param sourceFolders top-level location(s) of java sources - must not be null |
| * @param testFolders top-level location(s) of test(s) - must not be null |
| * @param confFolder top-level location of configuration file(s) folder - must not be null |
| * @param libFolder top-level location of libraries |
| * @param j2eeLevel defined in <code>org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule</code> |
| * @param serverInstanceID provided by j2eeserver module |
| * @throws IOException in case something went wrong |
| */ |
| public static AntProjectHelper importProject(final File dir, final String name, |
| final File[] sourceFolders, final File[] testFolders, final File confFolder, |
| final File libFolder, String j2eeLevel, String serverInstanceID,boolean fromJavaSource) throws IOException { |
| AntProjectHelper h = importProject(dir,name,sourceFolders,testFolders, |
| confFolder,libFolder,j2eeLevel,serverInstanceID); |
| EditableProperties subEp = h.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| subEp.setProperty(AppClientProjectProperties.JAVA_SOURCE_BASED,fromJavaSource+""); // NOI18N |
| h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,subEp); |
| Project subP = ProjectManager.getDefault().findProject(h.getProjectDirectory()); |
| ProjectManager.getDefault().saveProject(subP); |
| return h; |
| } |
| |
| private static AntProjectHelper setupProject(FileObject dirFO, String name, |
| String srcRoot, String testRoot, File configFiles, File libraries, |
| String resources, String mainClass, Profile j2eeProfile, |
| String serverInstanceID, String librariesDefinition, |
| boolean skipTests) throws IOException { |
| |
| Utils.logUI(NbBundle.getBundle(AppClientProjectGenerator.class), "UI_APP_PROJECT_CREATE_SHARABILITY", // NOI18N |
| new Object[]{(librariesDefinition != null), Boolean.FALSE}); |
| |
| AntProjectHelper h = ProjectGenerator.createProject(dirFO, AppClientProjectType.TYPE, librariesDefinition); |
| final AppClientProject prj = (AppClientProject)ProjectManager.getDefault().findProject(h.getProjectDirectory()); |
| final ReferenceHelper referenceHelper = prj.getReferenceHelper(); |
| Element data = h.getPrimaryConfigurationData(true); |
| Document doc = data.getOwnerDocument(); |
| Element nameEl = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N |
| nameEl.appendChild(doc.createTextNode(name)); |
| data.appendChild(nameEl); |
| Element minant = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "minimum-ant-version"); // NOI18N |
| minant.appendChild(doc.createTextNode(MINIMUM_ANT_VERSION)); // NOI18N |
| data.appendChild(minant); |
| |
| //TODO: ma154696: not sure if needed |
| // Element addLibs = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "ejb-module-additional-libraries"); //NOI18N |
| // data.appendChild(addLibs); |
| |
| EditableProperties ep = h.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| EditableProperties epPriv = h.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH); |
| Element sourceRoots = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots"); //NOI18N |
| if (srcRoot != null) { |
| Element root = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root"); //NOI18N |
| root.setAttribute("id","src.dir"); //NOI18N |
| root.setAttribute("name",NbBundle.getMessage(AppClientProjectGenerator.class, "NAME_src.dir")); |
| sourceRoots.appendChild(root); |
| ep.setProperty("src.dir", srcRoot); // NOI18N |
| } |
| data.appendChild(sourceRoots); |
| Element testRoots = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"test-roots"); //NOI18N |
| if (testRoot != null) { |
| Element root = doc.createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE,"root"); //NOI18N |
| root.setAttribute("id","test.src.dir"); //NOI18N |
| root.setAttribute("name",NbBundle.getMessage(AppClientProjectGenerator.class, "NAME_test.src.dir")); |
| testRoots.appendChild(root); |
| ep.setProperty("test.src.dir", testRoot); // NOI18N |
| } |
| data.appendChild(testRoots); |
| h.putPrimaryConfigurationData(data, true); |
| |
| if (configFiles != null) { |
| String ref = createFileReference(referenceHelper, dirFO, FileUtil.toFileObject(configFiles)); |
| ep.setProperty(AppClientProjectProperties.META_INF, ref); |
| } |
| if (libraries != null) { |
| String ref = createFileReference(referenceHelper, dirFO, FileUtil.toFileObject(libraries)); |
| ep.setProperty(AppClientProjectProperties.LIBRARIES_DIR, ref); |
| } |
| |
| if (resources != null) { |
| ep.setProperty(AppClientProjectProperties.RESOURCE_DIR, resources); |
| } else { |
| ep.setProperty(AppClientProjectProperties.RESOURCE_DIR, DEFAULT_RESOURCE_FOLDER); |
| } |
| |
| //XXX the name of the dist.ear.jar file should be different, but now it cannot be since the name is used as a key in module provider mapping |
| ep.setProperty(AppClientProjectProperties.DIST_EAR_JAR, "${"+AppClientProjectProperties.DIST_DIR+"}/" + "${" + AppClientProjectProperties.JAR_NAME + "}"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAR_NAME, PropertyUtils.getUsablePropertyName(name) + ".jar"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.BUILD_EAR_CLASSES_DIR, "${"+AppClientProjectProperties.BUILD_DIR+"}/jar"); // NOI18N |
| |
| ep.setProperty("dist.dir", "dist"); // NOI18N |
| ep.setComment("dist.dir", new String[] {"# " + NbBundle.getMessage(AppClientProjectGenerator.class, "COMMENT_dist.dir")}, false); // NOI18N |
| // ep.setProperty("dist.jar", "${dist.dir}/" + PropertyUtils.getUsablePropertyName(name) + ".jar"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.DIST_JAR, "${"+AppClientProjectProperties.DIST_DIR+"}/" + "${" + AppClientProjectProperties.JAR_NAME + "}"); // NOI18N |
| ep.setProperty("build.sysclasspath", "ignore"); // NOI18N |
| ep.setComment("build.sysclasspath", new String[] {"# " + NbBundle.getMessage(AppClientProjectGenerator.class, "COMMENT_build.sysclasspath")}, false); // NOI18N |
| ep.setProperty("run.classpath", new String[] { // NOI18N |
| "${javac.classpath}:", // NOI18N |
| "${build.classes.dir}", // NOI18N |
| }); |
| ep.setProperty("debug.classpath", new String[] { // NOI18N |
| "${run.classpath}", // NOI18N |
| }); |
| ep.setProperty("jar.compress", "false"); // NOI18N |
| if (mainClass != null) { |
| ep.setProperty("main.class", mainClass); // NOI18N |
| } |
| |
| ep.setProperty("javac.compilerargs", ""); // NOI18N |
| ep.setComment("javac.compilerargs", new String[] { // NOI18N |
| "# " + NbBundle.getMessage(AppClientProjectGenerator.class, "COMMENT_javac.compilerargs"), // NOI18N |
| }, false); |
| |
| JavaPlatform defaultPlatform = JavaPlatformManager.getDefault().getDefaultPlatform(); |
| SpecificationVersion v = defaultPlatform.getSpecification().getVersion(); |
| String sourceLevel = v.toString(); |
| // #89131: these levels are not actually distinct from 1.5. |
| // #181215: JDK 6 should be the default source/binary format for Java EE 6 projects |
| // #181215: Not neccessary anymore because NetBeans should run on minimum JDK 8 |
| ep.setProperty(AppClientProjectProperties.JAVAC_SOURCE, sourceLevel); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVAC_TARGET, sourceLevel); // NOI18N |
| |
| ep.setProperty("javac.deprecation", "false"); // NOI18N |
| ep.setProperty("javac.test.classpath", skipTests ? new String[] { // NOI18N |
| "${javac.classpath}:", // NOI18N |
| "${build.classes.dir}", // NOI18N |
| } : new String[] { // NOI18N |
| "${javac.classpath}:", // NOI18N |
| "${build.classes.dir}:", // NOI18N |
| "${libs.junit.classpath}:", // NOI18N |
| "${libs.junit_4.classpath}", // NOI18N |
| }); |
| ep.setProperty("run.test.classpath", new String[] { // NOI18N |
| "${javac.test.classpath}:", // NOI18N |
| "${build.test.classes.dir}", // NOI18N |
| }); |
| ep.setProperty("debug.test.classpath", new String[] { // NOI18N |
| "${run.test.classpath}", // NOI18N |
| }); |
| |
| ep.setProperty("build.generated.dir", "${build.dir}/generated"); // NOI18N |
| //ep.setProperty("meta.inf.dir", "${src.dir}/META-INF"); // NOI18N |
| |
| ep.setProperty("build.dir", DEFAULT_BUILD_DIR); // NOI18N |
| ep.setComment("build.dir", new String[] {"# " + NbBundle.getMessage(AppClientProjectGenerator.class, "COMMENT_build.dir")}, false); // NOI18N |
| //ep.setProperty("build.classes.dir", "${build.dir}/classes"); // NOI18N |
| ep.setProperty("build.classes.dir", "${build.dir}/jar"); // NOI18N |
| ep.setProperty("build.generated.sources.dir", "${build.dir}/generated-sources"); // NOI18N |
| ep.setProperty("build.test.classes.dir", "${build.dir}/test/classes"); // NOI18N |
| ep.setProperty("build.test.results.dir", "${build.dir}/test/results"); // NOI18N |
| ep.setProperty("build.classes.excludes", "**/*.java,**/*.form"); // NOI18N |
| ep.setProperty("dist.javadoc.dir", "${dist.dir}/javadoc"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVA_PLATFORM, "default_platform"); // NOI18N |
| |
| ep.setProperty("run.jvmargs", ""); // NOI18N |
| ep.setComment("run.jvmargs", new String[] { // NOI18N |
| "# " + NbBundle.getMessage(AppClientProjectGenerator.class, "COMMENT_run.jvmargs"), // NOI18N |
| "# " + NbBundle.getMessage(AppClientProjectGenerator.class, "COMMENT_run.jvmargs_2"), // NOI18N |
| "# " + NbBundle.getMessage(AppClientProjectGenerator.class, "COMMENT_run.jvmargs_3"), // NOI18N |
| }, false); |
| |
| ep.setProperty(AppClientProjectProperties.JAVADOC_PRIVATE, "false"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_NO_TREE, "false"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_USE, "true"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_NO_NAVBAR, "false"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_NO_INDEX, "false"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_SPLIT_INDEX, "true"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_AUTHOR, "false"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_VERSION, "false"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_WINDOW_TITLE, ""); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_ENCODING, "${" + AppClientProjectProperties.SOURCE_ENCODING + "}"); // NOI18N |
| ep.setProperty(AppClientProjectProperties.JAVADOC_ADDITIONALPARAM, ""); // NOI18N |
| |
| //Deployment deployment = Deployment.getDefault(); |
| J2eePlatform j2eePlatform = null; |
| try { |
| j2eePlatform = Deployment.getDefault().getServerInstance(serverInstanceID).getJ2eePlatform(); |
| if (!j2eePlatform.getSupportedProfiles(J2eeModule.Type.CAR).contains(j2eeProfile)) { |
| Logger.getLogger(AppClientProjectGenerator.class.getName()) |
| .log(Level.WARNING, NbBundle.getMessage(AppClientProjectGenerator.class, |
| "MSG_Warning_SpecLevelNotSupported", |
| new Object[] {j2eeProfile, Deployment.getDefault().getServerInstance(serverInstanceID).getDisplayName()})); |
| } |
| } catch (InstanceRemovedException ie) { |
| // noop ignore |
| Logger.getLogger(AppClientProjectGenerator.class.getName()).log(Level.FINE, "{0}", ie); |
| } |
| |
| ep.setProperty(AppClientProjectProperties.J2EE_PLATFORM, j2eeProfile.toPropertiesString()); |
| ep.setProperty("manifest.file", "${" +AppClientProjectProperties.META_INF + "}/" + MANIFEST_FILE); // NOI18N |
| |
| ep.setProperty(ProjectProperties.JAVAC_CLASSPATH, ""); |
| J2EEProjectProperties.setServerProperties(ep, epPriv, null, null, serverInstanceID, j2eeProfile, J2eeModule.Type.CAR); |
| AppClientProjectProperties.generateExtraServerProperty(epPriv); |
| |
| String mainClassArgs = j2eePlatform.getToolProperty(J2eePlatform.TOOL_APP_CLIENT_RUNTIME, J2eePlatform.TOOL_PROP_MAIN_CLASS_ARGS); |
| if (mainClassArgs != null && !mainClassArgs.equals("")) { |
| ep.put(AppClientProjectProperties.APPCLIENT_MAINCLASS_ARGS, mainClassArgs); |
| } else if ((j2eePlatform.getToolProperty(J2eePlatform.TOOL_APP_CLIENT_RUNTIME, AppClientProjectProperties.CLIENT_NAME)) != null) { |
| ep.put(AppClientProjectProperties.CLIENT_NAME, mainClassArgs); |
| } |
| |
| if (j2eeProfile.equals(Profile.JAVA_EE_6_FULL) || j2eeProfile.equals(Profile.JAVA_EE_6_WEB)) { |
| ep.setProperty(ProjectProperties.ENDORSED_CLASSPATH, new String[]{AntProjectConstants.ENDORSED_LIBRARY_CLASSPATH_6}); |
| } else if (j2eeProfile.equals(Profile.JAVA_EE_7_FULL) || j2eeProfile.equals(Profile.JAVA_EE_7_WEB)) { |
| ep.setProperty(ProjectProperties.ENDORSED_CLASSPATH, new String[]{AntProjectConstants.ENDORSED_LIBRARY_CLASSPATH_7}); |
| } |
| |
| h.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep); |
| |
| // XXX this seems to be used in runtime only so, not part of sharable server |
| // set j2ee.appclient environment |
| File[] accrt = j2eePlatform.getToolClasspathEntries(J2eePlatform.TOOL_APP_CLIENT_RUNTIME); |
| Map<String, String> roots = J2EEProjectProperties.extractPlatformLibrariesRoot(j2eePlatform); |
| epPriv.setProperty(AppClientProjectProperties.APPCLIENT_TOOL_RUNTIME, J2EEProjectProperties.toClasspathString(accrt, roots)); |
| |
| String acMain = j2eePlatform.getToolProperty(J2eePlatform.TOOL_APP_CLIENT_RUNTIME, J2eePlatform.TOOL_PROP_MAIN_CLASS); |
| if (acMain != null) { |
| epPriv.setProperty(AppClientProjectProperties.APPCLIENT_TOOL_MAINCLASS, acMain); |
| } |
| String jvmOpts = j2eePlatform.getToolProperty(J2eePlatform.TOOL_APP_CLIENT_RUNTIME, J2eePlatform.TOOL_PROP_JVM_OPTS); |
| if (jvmOpts != null) { |
| epPriv.setProperty(AppClientProjectProperties.APPCLIENT_TOOL_JVMOPTS, jvmOpts); |
| } |
| String args = j2eePlatform.getToolProperty(J2eePlatform.TOOL_APP_CLIENT_RUNTIME, |
| AppClientProjectProperties.J2EE_PLATFORM_APPCLIENT_ARGS); |
| if (args != null) { |
| epPriv.setProperty(AppClientProjectProperties.APPCLIENT_TOOL_ARGS, args); |
| } |
| |
| // WORKAROUND for --retrieve option in asadmin deploy command |
| // works only for local domains |
| // see also http://www.netbeans.org/issues/show_bug.cgi?id=82929 |
| String copyProperty = j2eePlatform.getToolProperty(J2eePlatform.TOOL_APP_CLIENT_RUNTIME, J2eePlatform.TOOL_PROP_CLIENT_JAR_LOCATION); |
| if (copyProperty != null) { |
| ep.setProperty(AppClientProjectProperties.APPCLIENT_TOOL_CLIENT_JAR, copyProperty); |
| } else { |
| ep.remove(AppClientProjectProperties.APPCLIENT_TOOL_CLIENT_JAR); |
| } |
| |
| J2EEProjectProperties.createDeploymentScript(dirFO, ep, epPriv, serverInstanceID, J2eeModule.Type.CAR); |
| |
| // use the default encoding |
| Charset enc = FileEncodingQuery.getDefaultEncoding(); |
| epPriv.setProperty(AppClientProjectProperties.SOURCE_ENCODING, enc.name()); |
| |
| h.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, epPriv); |
| |
| return h; |
| } |
| |
| private static String createFileReference(ReferenceHelper refHelper, FileObject projectFO, FileObject referencedFO) { |
| String relPath = FileUtil.getRelativePath(projectFO, referencedFO); |
| if (relPath != null) { |
| return relPath; |
| } else { |
| return refHelper.createForeignFileReference(FileUtil.toFile(referencedFO), null); |
| } |
| } |
| |
| private static void createMainClass( String mainClassName, FileObject srcFolder ) throws IOException { |
| |
| int lastDotIdx = mainClassName.lastIndexOf( '.' ); |
| String mName, pName; |
| if ( lastDotIdx == -1 ) { |
| mName = mainClassName.trim(); |
| pName = null; |
| } else { |
| mName = mainClassName.substring( lastDotIdx + 1 ).trim(); |
| pName = mainClassName.substring( 0, lastDotIdx ).trim(); |
| } |
| |
| if ( mName.length() == 0 ) { |
| return; |
| } |
| |
| FileObject mainTemplate = FileUtil.getConfigFile( "Templates/Classes/Main.java" ); // NOI18N |
| |
| if ( mainTemplate == null ) { |
| return; // Don't know the template |
| } |
| |
| DataObject mt = DataObject.find( mainTemplate ); |
| |
| FileObject pkgFolder = srcFolder; |
| if ( pName != null ) { |
| String fName = pName.replace( '.', '/' ); // NOI18N |
| pkgFolder = FileUtil.createFolder( srcFolder, fName ); |
| } |
| DataFolder pDf = DataFolder.findFolder( pkgFolder ); |
| mt.createFromTemplate( pDf, mName ); |
| |
| } |
| |
| /** |
| * Set J2SE platform to be used. |
| * |
| * @param helper "reference" to project to be updated |
| * @param platformName the name of the J2SE platform |
| * @param sourceLevel the source level to be set |
| */ |
| // AB: this method is also called from the enterprise application, so we can't pass UpdateHelper here |
| // well, actually we can, but let's not expose too many classes |
| public static void setPlatform(final AntProjectHelper helper, final String platformName, final String sourceLevel) { |
| FileObject projectDir = helper.getProjectDirectory(); |
| if (projectDir == null) { |
| return; |
| } |
| // issue 89278: do not fire file change events under ProjectManager.MUTEX, |
| // it is deadlock-prone |
| try { |
| projectDir.getFileSystem().runAtomicAction(new AtomicAction() { |
| @Override |
| public void run() throws IOException { |
| ProjectManager.mutex().writeAccess(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| AppClientProject project = (AppClientProject)ProjectManager.getDefault().findProject(helper.getProjectDirectory()); |
| UpdateHelper updateHelper = project.getUpdateHelper(); |
| EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| String finalPlatformName = platformName; |
| if (finalPlatformName == null) { |
| finalPlatformName = PreferredProjectPlatform.getPreferredPlatform(JavaPlatform.getDefault().getSpecification().getName()).getDisplayName(); |
| } |
| // #89131: these levels are not actually distinct from 1.5. |
| // #181215: JDK 6 should be the default source/binary format for Java EE 6 projects |
| // #181215: Not neccessary anymore because NetBeans should run on minimum JDK 8 |
| String srcLevel = sourceLevel; |
| PlatformUiSupport.storePlatform(ep, updateHelper, AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, finalPlatformName, srcLevel != null ? new SpecificationVersion(srcLevel) : null); |
| helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep); |
| ProjectManager.getDefault().saveProject(ProjectManager.getDefault().findProject(helper.getProjectDirectory())); |
| } catch (IOException e) { |
| Exceptions.printStackTrace(e); |
| } |
| } |
| }); |
| } |
| }); |
| } catch (IOException e) { |
| Exceptions.printStackTrace(e); |
| } |
| } |
| |
| /** |
| * Create a new application manifest file with minimal initial contents. |
| * @param dir the directory to create it in |
| * @param path the relative path of the file |
| * @throws IOException in case of problems |
| */ |
| private static void createManifest(FileObject dir, String path) throws IOException { |
| if (dir.getFileObject(path) == null) { |
| FileObject manifest = FileUtil.createData(dir, path); |
| try (FileLock lock = manifest.lock(); |
| OutputStream os = manifest.getOutputStream(lock); PrintWriter pw = new PrintWriter(os, true)) { |
| pw.println("Manifest-Version: 1.0"); // NOI18N |
| pw.println("X-COMMENT: Main-Class will be added automatically by build"); // NOI18N |
| pw.println(); // safest to end in \n\n due to JRE parsing bug |
| } |
| } |
| } |
| |
| } |