PageRenderTime 29ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/netbeans-7.3/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/J2SEProjectProperties.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 972 lines | 731 code | 93 blank | 148 comment | 159 complexity | 88589d32d300f186481d930767792920 MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. package org.netbeans.modules.java.j2seproject.ui.customizer;
  45. import java.awt.event.ActionListener;
  46. import java.io.File;
  47. import java.io.IOException;
  48. import java.net.MalformedURLException;
  49. import java.net.URI;
  50. import java.net.URISyntaxException;
  51. import java.net.URL;
  52. import java.nio.charset.Charset;
  53. import java.nio.charset.UnsupportedCharsetException;
  54. import java.util.ArrayList;
  55. import java.util.Arrays;
  56. import java.util.Collections;
  57. import java.util.Comparator;
  58. import java.util.Enumeration;
  59. import java.util.HashMap;
  60. import java.util.HashSet;
  61. import java.util.LinkedList;
  62. import java.util.List;
  63. import java.util.Map;
  64. import java.util.Set;
  65. import java.util.TreeMap;
  66. import java.util.Vector;
  67. import java.util.concurrent.CopyOnWriteArrayList;
  68. import java.util.logging.Logger;
  69. import javax.swing.ButtonModel;
  70. import javax.swing.ComboBoxModel;
  71. import javax.swing.DefaultListModel;
  72. import javax.swing.JToggleButton;
  73. import javax.swing.ListCellRenderer;
  74. import javax.swing.table.DefaultTableModel;
  75. import javax.swing.text.BadLocationException;
  76. import javax.swing.text.Document;
  77. import javax.swing.text.PlainDocument;
  78. import org.netbeans.api.annotations.common.NonNull;
  79. import org.netbeans.api.queries.FileEncodingQuery;
  80. import org.netbeans.api.project.ProjectManager;
  81. import org.netbeans.api.project.ProjectUtils;
  82. import org.netbeans.api.project.ant.AntBuildExtender;
  83. import org.netbeans.modules.java.api.common.SourceRoots;
  84. import org.netbeans.modules.java.api.common.ant.UpdateHelper;
  85. import org.netbeans.modules.java.api.common.classpath.ClassPathSupport;
  86. import org.netbeans.modules.java.api.common.project.ProjectProperties;
  87. import org.netbeans.modules.java.api.common.project.ui.ClassPathUiSupport;
  88. import org.netbeans.modules.java.api.common.project.ui.customizer.ClassPathListCellRenderer;
  89. import org.netbeans.modules.java.api.common.project.ui.customizer.SourceRootsUi;
  90. import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
  91. import org.netbeans.modules.java.api.common.util.CommonProjectUtils;
  92. import org.netbeans.modules.java.j2seproject.J2SEProject;
  93. import org.netbeans.modules.java.j2seproject.J2SEProjectUtil;
  94. import org.netbeans.spi.java.project.support.ui.IncludeExcludeVisualizer;
  95. import org.netbeans.spi.java.project.support.ui.SharableLibrariesUtils;
  96. import org.netbeans.spi.project.ActionProvider;
  97. import org.netbeans.spi.project.support.ant.AntProjectHelper;
  98. import org.netbeans.spi.project.support.ant.EditableProperties;
  99. import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
  100. import org.netbeans.spi.project.support.ant.PropertyEvaluator;
  101. import org.netbeans.spi.project.support.ant.ReferenceHelper;
  102. import org.netbeans.spi.project.support.ant.ui.StoreGroup;
  103. import org.openide.ErrorManager;
  104. import org.openide.filesystems.FileObject;
  105. import org.openide.filesystems.FileUtil;
  106. import org.openide.util.*;
  107. import org.openide.util.lookup.Lookups;
  108. /**
  109. * @author Petr Hrebejk
  110. */
  111. public class J2SEProjectProperties {
  112. //Hotfix of the issue #70058
  113. //Should be removed when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
  114. private static final Integer BOOLEAN_KIND_TF = new Integer( 0 );
  115. private static final Integer BOOLEAN_KIND_YN = new Integer( 1 );
  116. private static final Integer BOOLEAN_KIND_ED = new Integer( 2 );
  117. private static final String COS_MARK = ".netbeans_automatic_build"; //NOI18N
  118. private static final Logger LOG = Logger.getLogger(J2SEProjectProperties.class.getName());
  119. private Integer javacDebugBooleanKind;
  120. private Integer doJarBooleanKind;
  121. private Integer javadocPreviewBooleanKind;
  122. // Special properties of the project
  123. public static final String J2SE_PROJECT_NAME = "j2se.project.name"; // NOI18N
  124. public static final String JAVA_PLATFORM = "platform.active"; // NOI18N
  125. // folowing properties have moved to ProjectProperties in java.api.common module:
  126. //public static final String JAVAC_CLASSPATH = "javac.classpath"; // NOI18N
  127. //public static final String RUN_CLASSPATH = "run.classpath"; // NOI18N
  128. //public static final String JAVAC_TEST_CLASSPATH = "javac.test.classpath"; // NOI18N
  129. //public static final String RUN_TEST_CLASSPATH = "run.test.classpath"; // NOI18N
  130. //public static final String BUILD_CLASSES_DIR = "build.classes.dir"; // NOI18N
  131. //public static final String BUILD_TEST_CLASSES_DIR = "build.test.classes.dir"; // NOI18N
  132. //public static final String INCLUDES = "includes"; // NOI18N
  133. //public static final String EXCLUDES = "excludes"; // NOI18N
  134. //public static final String[] WELL_KNOWN_PATHS = new String[] {
  135. //public static final String ANT_ARTIFACT_PREFIX = "${reference."; // NOI18N
  136. // Properties stored in the PROJECT.PROPERTIES
  137. public static final String DIST_DIR = "dist.dir"; // NOI18N
  138. public static final String DIST_JAR = "dist.jar"; // NOI18N
  139. public static final String DEBUG_CLASSPATH = "debug.classpath"; // NOI18N
  140. public static final String JAR_COMPRESS = "jar.compress"; // NOI18N
  141. public static final String JAVAC_SOURCE = "javac.source"; // NOI18N
  142. public static final String JAVAC_TARGET = "javac.target"; // NOI18N
  143. public static final String JAVAC_DEBUG = "javac.debug"; // NOI18N
  144. public static final String JAVAC_DEPRECATION = "javac.deprecation"; // NOI18N
  145. public static final String JAVAC_COMPILER_ARG = "javac.compilerargs"; //NOI18N
  146. public static final String BUILD_TEST_RESULTS_DIR = "build.test.results.dir"; // NOI18N
  147. public static final String BUILD_CLASSES_EXCLUDES = "build.classes.excludes"; // NOI18N
  148. public static final String DIST_JAVADOC_DIR = "dist.javadoc.dir"; // NOI18N
  149. public static final String NO_DEPENDENCIES="no.dependencies"; // NOI18N
  150. public static final String DEBUG_TEST_CLASSPATH = "debug.test.classpath"; // NOI18N
  151. public static final String SOURCE_ENCODING="source.encoding"; // NOI18N
  152. public static final String JAVADOC_PRIVATE="javadoc.private"; // NOI18N
  153. public static final String JAVADOC_NO_TREE="javadoc.notree"; // NOI18N
  154. public static final String JAVADOC_USE="javadoc.use"; // NOI18N
  155. public static final String JAVADOC_NO_NAVBAR="javadoc.nonavbar"; // NOI18N
  156. public static final String JAVADOC_NO_INDEX="javadoc.noindex"; // NOI18N
  157. public static final String JAVADOC_SPLIT_INDEX="javadoc.splitindex"; // NOI18N
  158. public static final String JAVADOC_AUTHOR="javadoc.author"; // NOI18N
  159. public static final String JAVADOC_VERSION="javadoc.version"; // NOI18N
  160. public static final String JAVADOC_WINDOW_TITLE="javadoc.windowtitle"; // NOI18N
  161. public static final String JAVADOC_ENCODING="javadoc.encoding"; // NOI18N
  162. public static final String JAVADOC_ADDITIONALPARAM="javadoc.additionalparam"; // NOI18N
  163. public static final String APPLICATION_TITLE ="application.title"; // NOI18N
  164. public static final String APPLICATION_VENDOR ="application.vendor"; // NOI18N
  165. public static final String APPLICATION_DESC ="application.desc"; // NOI18N
  166. public static final String APPLICATION_HOMEPAGE ="application.homepage"; // NOI18N
  167. public static final String APPLICATION_SPLASH ="application.splash"; // NOI18N
  168. // Properties stored in the PRIVATE.PROPERTIES
  169. public static final String JAVADOC_PREVIEW="javadoc.preview"; // NOI18N
  170. // Main build.xml location
  171. public static final String BUILD_SCRIPT ="buildfile"; //NOI18N
  172. //Disables copying of dependencies to dist folder
  173. public static final String MKDIST_DISABLED = "mkdist.disabled"; //NOI18N
  174. ClassPathSupport cs;
  175. // SOURCE ROOTS
  176. // public static final String SOURCE_ROOTS = "__virtual_source_roots__"; //NOI18N
  177. // public static final String TEST_ROOTS = "__virtual_test_roots__"; // NOI18N
  178. // MODELS FOR VISUAL CONTROLS
  179. // CustomizerSources
  180. DefaultTableModel SOURCE_ROOTS_MODEL;
  181. DefaultTableModel TEST_ROOTS_MODEL;
  182. ComboBoxModel JAVAC_SOURCE_MODEL;
  183. // CustomizerLibraries
  184. DefaultListModel JAVAC_CLASSPATH_MODEL;
  185. DefaultListModel JAVAC_PROCESSORPATH_MODEL;
  186. DefaultListModel JAVAC_TEST_CLASSPATH_MODEL;
  187. DefaultListModel RUN_CLASSPATH_MODEL;
  188. DefaultListModel RUN_TEST_CLASSPATH_MODEL;
  189. DefaultListModel ENDORSED_CLASSPATH_MODEL;
  190. ComboBoxModel PLATFORM_MODEL;
  191. ListCellRenderer CLASS_PATH_LIST_RENDERER;
  192. ListCellRenderer PLATFORM_LIST_RENDERER;
  193. ListCellRenderer JAVAC_SOURCE_RENDERER;
  194. Document SHARED_LIBRARIES_MODEL;
  195. // CustomizerCompile
  196. ButtonModel JAVAC_DEPRECATION_MODEL;
  197. ButtonModel JAVAC_DEBUG_MODEL;
  198. ButtonModel DO_DEPEND_MODEL;
  199. ButtonModel COMPILE_ON_SAVE_MODEL;
  200. ButtonModel NO_DEPENDENCIES_MODEL;
  201. ButtonModel ENABLE_ANNOTATION_PROCESSING_MODEL;
  202. ButtonModel ENABLE_ANNOTATION_PROCESSING_IN_EDITOR_MODEL;
  203. DefaultListModel ANNOTATION_PROCESSORS_MODEL;
  204. DefaultTableModel PROCESSOR_OPTIONS_MODEL;
  205. Document JAVAC_COMPILER_ARG_MODEL;
  206. // CustomizerCompileTest
  207. // CustomizerJar
  208. Document DIST_JAR_MODEL;
  209. Document BUILD_CLASSES_EXCLUDES_MODEL;
  210. ButtonModel JAR_COMPRESS_MODEL;
  211. ButtonModel DO_JAR_MODEL;
  212. ButtonModel COPY_LIBS_MODEL;
  213. // CustomizerJavadoc
  214. ButtonModel JAVADOC_PRIVATE_MODEL;
  215. ButtonModel JAVADOC_NO_TREE_MODEL;
  216. ButtonModel JAVADOC_USE_MODEL;
  217. ButtonModel JAVADOC_NO_NAVBAR_MODEL;
  218. ButtonModel JAVADOC_NO_INDEX_MODEL;
  219. ButtonModel JAVADOC_SPLIT_INDEX_MODEL;
  220. ButtonModel JAVADOC_AUTHOR_MODEL;
  221. ButtonModel JAVADOC_VERSION_MODEL;
  222. Document JAVADOC_WINDOW_TITLE_MODEL;
  223. ButtonModel JAVADOC_PREVIEW_MODEL;
  224. Document JAVADOC_ADDITIONALPARAM_MODEL;
  225. // CustomizerRun
  226. Map<String/*|null*/,Map<String,String/*|null*/>/*|null*/> RUN_CONFIGS;
  227. String activeConfig;
  228. // CustomizerApplication
  229. Document APPLICATION_TITLE_DOC;
  230. Document APPLICATION_VENDOR_DOC;
  231. Document APPLICATION_DESC_DOC;
  232. Document APPLICATION_HOMEPAGE_DOC;
  233. Document APPLICATION_SPLASH_DOC;
  234. // CustomizerRunTest
  235. // Private fields ----------------------------------------------------------
  236. private J2SEProject project;
  237. private UpdateHelper updateHelper;
  238. private PropertyEvaluator evaluator;
  239. private ReferenceHelper refHelper;
  240. private GeneratedFilesHelper genFileHelper;
  241. private StoreGroup privateGroup;
  242. private StoreGroup projectGroup;
  243. private Map<String,String> additionalProperties;
  244. private String includes, excludes;
  245. private final List<ActionListener> optionListeners = new CopyOnWriteArrayList<ActionListener>();
  246. J2SEProject getProject() {
  247. return project;
  248. }
  249. /** Creates a new instance of J2SEUIProperties and initializes them */
  250. public J2SEProjectProperties( J2SEProject project, UpdateHelper updateHelper, PropertyEvaluator evaluator, ReferenceHelper refHelper, GeneratedFilesHelper genFileHelper ) {
  251. this.project = project;
  252. this.updateHelper = updateHelper;
  253. this.evaluator = evaluator;
  254. this.refHelper = refHelper;
  255. this.genFileHelper = genFileHelper;
  256. this.cs = new ClassPathSupport(evaluator, refHelper, updateHelper.getAntProjectHelper(), updateHelper, null);
  257. privateGroup = new StoreGroup();
  258. projectGroup = new StoreGroup();
  259. additionalProperties = new HashMap<String,String>();
  260. init(); // Load known properties
  261. }
  262. /** Initializes the visual models
  263. */
  264. private void init() {
  265. CLASS_PATH_LIST_RENDERER = ClassPathListCellRenderer.createClassPathListRenderer(evaluator, project.getProjectDirectory());
  266. // CustomizerSources
  267. SOURCE_ROOTS_MODEL = SourceRootsUi.createModel( project.getSourceRoots() );
  268. TEST_ROOTS_MODEL = SourceRootsUi.createModel( project.getTestSourceRoots() );
  269. includes = evaluator.getProperty(ProjectProperties.INCLUDES);
  270. if (includes == null) {
  271. includes = "**"; // NOI18N
  272. }
  273. excludes = evaluator.getProperty(ProjectProperties.EXCLUDES);
  274. if (excludes == null) {
  275. excludes = ""; // NOI18N
  276. }
  277. // CustomizerLibraries
  278. EditableProperties projectProperties = updateHelper.getProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH );
  279. JAVAC_CLASSPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(projectProperties.get(ProjectProperties.JAVAC_CLASSPATH)));
  280. String processorPath = projectProperties.get(ProjectProperties.JAVAC_PROCESSORPATH);
  281. processorPath = processorPath == null ? "${javac.classpath}" : processorPath;
  282. JAVAC_PROCESSORPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(processorPath));
  283. JAVAC_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(projectProperties.get(ProjectProperties.JAVAC_TEST_CLASSPATH)));
  284. RUN_CLASSPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(projectProperties.get(ProjectProperties.RUN_CLASSPATH)));
  285. RUN_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(projectProperties.get(ProjectProperties.RUN_TEST_CLASSPATH)));
  286. ENDORSED_CLASSPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(projectProperties.get(ProjectProperties.ENDORSED_CLASSPATH)));
  287. PLATFORM_MODEL = PlatformUiSupport.createPlatformComboBoxModel (evaluator.getProperty(JAVA_PLATFORM));
  288. PLATFORM_LIST_RENDERER = PlatformUiSupport.createPlatformListCellRenderer();
  289. JAVAC_SOURCE_MODEL = PlatformUiSupport.createSourceLevelComboBoxModel (PLATFORM_MODEL, evaluator.getProperty(JAVAC_SOURCE), evaluator.getProperty(JAVAC_TARGET));
  290. JAVAC_SOURCE_RENDERER = PlatformUiSupport.createSourceLevelListCellRenderer ();
  291. SHARED_LIBRARIES_MODEL = new PlainDocument();
  292. try {
  293. SHARED_LIBRARIES_MODEL.insertString(0, project.getAntProjectHelper().getLibrariesLocation(), null);
  294. } catch (BadLocationException ex) {
  295. Exceptions.printStackTrace(ex);
  296. }
  297. // CustomizerCompile
  298. JAVAC_DEPRECATION_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVAC_DEPRECATION );
  299. //Hotfix of the issue #70058
  300. //Should use the StoreGroup when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
  301. Integer[] kind = new Integer[1];
  302. JAVAC_DEBUG_MODEL = createToggleButtonModel( evaluator, JAVAC_DEBUG, kind);
  303. javacDebugBooleanKind = kind[0];
  304. DO_DEPEND_MODEL = privateGroup.createToggleButtonModel(evaluator, ProjectProperties.DO_DEPEND);
  305. COMPILE_ON_SAVE_MODEL = privateGroup.createToggleButtonModel(evaluator, ProjectProperties.COMPILE_ON_SAVE);
  306. NO_DEPENDENCIES_MODEL = projectGroup.createInverseToggleButtonModel( evaluator, NO_DEPENDENCIES );
  307. ENABLE_ANNOTATION_PROCESSING_MODEL =projectGroup.createToggleButtonModel(evaluator, ProjectProperties.ANNOTATION_PROCESSING_ENABLED);
  308. ENABLE_ANNOTATION_PROCESSING_IN_EDITOR_MODEL = projectGroup.createToggleButtonModel(evaluator, ProjectProperties.ANNOTATION_PROCESSING_ENABLED_IN_EDITOR);
  309. String annotationProcessors = projectProperties.get(ProjectProperties.ANNOTATION_PROCESSING_PROCESSORS_LIST);
  310. if (annotationProcessors == null)
  311. annotationProcessors = ""; //NOI18N
  312. ANNOTATION_PROCESSORS_MODEL = ClassPathUiSupport.createListModel(
  313. (annotationProcessors.length() > 0 ? Arrays.asList(annotationProcessors.split(",")) : Collections.emptyList()).iterator()); //NOI18N
  314. String processorOptions = projectProperties.get(ProjectProperties.ANNOTATION_PROCESSING_PROCESSOR_OPTIONS);
  315. if (processorOptions == null)
  316. processorOptions = ""; //NOI18N
  317. PROCESSOR_OPTIONS_MODEL = new DefaultTableModel(new String[][]{}, new String[] {
  318. NbBundle.getMessage(CustomizerCompile.class, "LBL_CustomizeCompile_Processor_Options_Key"), //NOI18N
  319. NbBundle.getMessage(CustomizerCompile.class, "LBL_CustomizeCompile_Processor_Options_Value") //NOI18N
  320. }) {
  321. public boolean isCellEditable(int row, int column) {
  322. return false;
  323. }
  324. };
  325. for (String option : processorOptions.split("\\s")) { //NOI18N
  326. if (option.startsWith("-A") && option.length() > 2) { //NOI18N
  327. int sepIndex = option.indexOf('='); //NOI18N
  328. String key = null;
  329. String value = null;
  330. if (sepIndex == -1)
  331. key = option.substring(2);
  332. else if (sepIndex >= 3) {
  333. key = option.substring(2, sepIndex);
  334. value = (sepIndex < option.length() - 1) ? option.substring(sepIndex + 1) : null;
  335. }
  336. PROCESSOR_OPTIONS_MODEL.addRow(new String[] {key, value});
  337. }
  338. }
  339. JAVAC_COMPILER_ARG_MODEL = projectGroup.createStringDocument( evaluator, JAVAC_COMPILER_ARG );
  340. // CustomizerJar
  341. DIST_JAR_MODEL = projectGroup.createStringDocument( evaluator, DIST_JAR );
  342. BUILD_CLASSES_EXCLUDES_MODEL = projectGroup.createStringDocument( evaluator, BUILD_CLASSES_EXCLUDES );
  343. JAR_COMPRESS_MODEL = projectGroup.createToggleButtonModel( evaluator, JAR_COMPRESS );
  344. DO_JAR_MODEL = createToggleButtonModel(evaluator, ProjectProperties.DO_JAR, kind);
  345. doJarBooleanKind = kind[0];
  346. COPY_LIBS_MODEL = projectGroup.createInverseToggleButtonModel(evaluator, MKDIST_DISABLED);
  347. // CustomizerJavadoc
  348. JAVADOC_PRIVATE_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_PRIVATE );
  349. JAVADOC_NO_TREE_MODEL = projectGroup.createInverseToggleButtonModel( evaluator, JAVADOC_NO_TREE );
  350. JAVADOC_USE_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_USE );
  351. JAVADOC_NO_NAVBAR_MODEL = projectGroup.createInverseToggleButtonModel( evaluator, JAVADOC_NO_NAVBAR );
  352. JAVADOC_NO_INDEX_MODEL = projectGroup.createInverseToggleButtonModel( evaluator, JAVADOC_NO_INDEX );
  353. JAVADOC_SPLIT_INDEX_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_SPLIT_INDEX );
  354. JAVADOC_AUTHOR_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_AUTHOR );
  355. JAVADOC_VERSION_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_VERSION );
  356. JAVADOC_WINDOW_TITLE_MODEL = projectGroup.createStringDocument( evaluator, JAVADOC_WINDOW_TITLE );
  357. //Hotfix of the issue #70058
  358. //Should use the StoreGroup when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
  359. JAVADOC_PREVIEW_MODEL = createToggleButtonModel ( evaluator, JAVADOC_PREVIEW, kind);
  360. javadocPreviewBooleanKind = kind[0];
  361. JAVADOC_ADDITIONALPARAM_MODEL = projectGroup.createStringDocument( evaluator, JAVADOC_ADDITIONALPARAM );
  362. // CustomizerApplication
  363. APPLICATION_TITLE_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_TITLE);
  364. String title = evaluator.getProperty("application.title");
  365. if (title == null) {
  366. try {
  367. APPLICATION_TITLE_DOC.insertString(0, ProjectUtils.getInformation(project).getDisplayName(), null);
  368. } catch (BadLocationException ex) {
  369. // just do not set anything
  370. }
  371. }
  372. APPLICATION_VENDOR_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_VENDOR);
  373. String vendor = evaluator.getProperty("application.vendor");
  374. if (vendor == null) {
  375. try {
  376. APPLICATION_VENDOR_DOC.insertString(0, System.getProperty("user.name", "User Name"), null);
  377. } catch (BadLocationException ex) {
  378. // just do not set anything
  379. }
  380. }
  381. APPLICATION_DESC_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_DESC);
  382. APPLICATION_HOMEPAGE_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_HOMEPAGE);
  383. APPLICATION_SPLASH_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_SPLASH);
  384. if(!isFXProject()) {
  385. // CustomizerRun
  386. RUN_CONFIGS = readRunConfigs();
  387. activeConfig = evaluator.getProperty("config");
  388. }
  389. }
  390. public void save() {
  391. try {
  392. saveLibrariesLocation();
  393. // Store properties
  394. ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
  395. public Void run() throws IOException {
  396. storeProperties();
  397. //Delete COS mark
  398. if (!COMPILE_ON_SAVE_MODEL.isSelected()) {
  399. String buildClassesDir = evaluator.getProperty(ProjectProperties.BUILD_CLASSES_DIR);
  400. if (buildClassesDir == null) {
  401. //BUILD_CLASSES_DIR is mandatory property => broken project?
  402. //Log
  403. StringBuilder logRecord = new StringBuilder();
  404. logRecord.append("EVALUATOR: "+evaluator.getProperties().toString()+";"); //NOI18N
  405. logRecord.append("PROJECT_PROPS: "+updateHelper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH).entrySet()+";"); //NOI18N
  406. logRecord.append("PRIVATE_PROPS: "+updateHelper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH).entrySet()+";"); //NOI18N
  407. assert buildClassesDir != null : logRecord.toString(); //In dev build throw an ae to get issue to find why BUILD_CLASSES_DIR is null
  408. LOG.warning("No build.classes.dir property: " + logRecord.toString()); //In release at least log
  409. }
  410. else {
  411. FileObject buildClasses = updateHelper.getAntProjectHelper().resolveFileObject(buildClassesDir);
  412. if (buildClasses != null) {
  413. FileObject mark = buildClasses.getFileObject(COS_MARK);
  414. if (mark != null) {
  415. final ActionProvider ap = project.getLookup().lookup(ActionProvider.class);
  416. assert ap != null;
  417. Mutex.EVENT.writeAccess(new Runnable() {
  418. @Override public void run() {
  419. ap.invokeAction(ActionProvider.COMMAND_CLEAN, Lookups.fixed(project));
  420. }
  421. });
  422. }
  423. }
  424. }
  425. }
  426. return null;
  427. }
  428. });
  429. // and save the project
  430. project.setProjectPropertiesSave(true);
  431. try {
  432. ProjectManager.getDefault().saveProject(project);
  433. } finally {
  434. project.setProjectPropertiesSave(false);
  435. }
  436. }
  437. catch (MutexException e) {
  438. ErrorManager.getDefault().notify((IOException)e.getException());
  439. }
  440. catch ( IOException ex ) {
  441. ErrorManager.getDefault().notify( ex );
  442. }
  443. }
  444. private void saveLibrariesLocation() throws IOException, IllegalArgumentException {
  445. try {
  446. String str = SHARED_LIBRARIES_MODEL.getText(0, SHARED_LIBRARIES_MODEL.getLength()).trim();
  447. if (str.length() == 0) {
  448. str = null;
  449. }
  450. String old = project.getAntProjectHelper().getLibrariesLocation();
  451. if ((old == null && str == null) || (old != null && old.equals(str))) {
  452. //ignore, nothing changed..
  453. } else {
  454. project.getAntProjectHelper().setLibrariesLocation(str);
  455. ProjectManager.getDefault().saveProject(project);
  456. }
  457. } catch (BadLocationException x) {
  458. ErrorManager.getDefault().notify(x);
  459. }
  460. }
  461. private void storeProperties() throws IOException {
  462. // Store special properties
  463. // Modify the project dependencies properly
  464. resolveProjectDependencies();
  465. // Encode all paths (this may change the project properties)
  466. String[] javac_cp = cs.encodeToStrings( ClassPathUiSupport.getList( JAVAC_CLASSPATH_MODEL ) );
  467. String[] javac_pp = cs.encodeToStrings( ClassPathUiSupport.getList( JAVAC_PROCESSORPATH_MODEL ) );
  468. String[] javac_test_cp = cs.encodeToStrings( ClassPathUiSupport.getList( JAVAC_TEST_CLASSPATH_MODEL ) );
  469. String[] run_cp = cs.encodeToStrings( ClassPathUiSupport.getList( RUN_CLASSPATH_MODEL ) );
  470. String[] run_test_cp = cs.encodeToStrings( ClassPathUiSupport.getList( RUN_TEST_CLASSPATH_MODEL ) );
  471. String[] endorsed_cp = cs.encodeToStrings( ClassPathUiSupport.getList( ENDORSED_CLASSPATH_MODEL ) );
  472. // Store source roots
  473. storeRoots( project.getSourceRoots(), SOURCE_ROOTS_MODEL );
  474. storeRoots( project.getTestSourceRoots(), TEST_ROOTS_MODEL );
  475. // Store standard properties
  476. EditableProperties projectProperties = updateHelper.getProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH );
  477. EditableProperties privateProperties = updateHelper.getProperties( AntProjectHelper.PRIVATE_PROPERTIES_PATH );
  478. // Assure inegrity which can't shound not be assured in UI
  479. if ( !JAVADOC_NO_INDEX_MODEL.isSelected() ) {
  480. JAVADOC_SPLIT_INDEX_MODEL.setSelected( false ); // Can't split non existing index
  481. }
  482. // Standard store of the properties
  483. projectGroup.store( projectProperties );
  484. privateGroup.store( privateProperties );
  485. final boolean isFXProject = isFXProject();
  486. if(!isFXProject) {
  487. storeRunConfigs(RUN_CONFIGS, projectProperties, privateProperties);
  488. EditableProperties ep = updateHelper.getProperties("nbproject/private/config.properties");
  489. if (activeConfig == null) {
  490. ep.remove("config");
  491. } else {
  492. ep.setProperty("config", activeConfig);
  493. }
  494. updateHelper.putProperties("nbproject/private/config.properties", ep);
  495. }
  496. //Hotfix of the issue #70058
  497. //Should use the StoreGroup when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
  498. //Save javac.debug
  499. privateProperties.setProperty(JAVAC_DEBUG, encodeBoolean (JAVAC_DEBUG_MODEL.isSelected(), javacDebugBooleanKind));
  500. privateProperties.setProperty(ProjectProperties.DO_JAR, encodeBoolean(DO_JAR_MODEL.isSelected(), doJarBooleanKind));
  501. //Hotfix of the issue #70058
  502. //Should use the StoreGroup when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
  503. //Save javadoc.preview
  504. privateProperties.setProperty(JAVADOC_PREVIEW, encodeBoolean (JAVADOC_PREVIEW_MODEL.isSelected(), javadocPreviewBooleanKind));
  505. // Save all paths
  506. projectProperties.setProperty( ProjectProperties.JAVAC_CLASSPATH, javac_cp );
  507. projectProperties.setProperty( ProjectProperties.JAVAC_PROCESSORPATH, javac_pp );
  508. projectProperties.setProperty( ProjectProperties.JAVAC_TEST_CLASSPATH, javac_test_cp );
  509. projectProperties.setProperty( ProjectProperties.RUN_CLASSPATH, run_cp );
  510. projectProperties.setProperty( ProjectProperties.RUN_TEST_CLASSPATH, run_test_cp );
  511. projectProperties.setProperty( ProjectProperties.ENDORSED_CLASSPATH, endorsed_cp );
  512. //Handle platform selection and javac.source javac.target properties
  513. PlatformUiSupport.storePlatform (
  514. projectProperties,
  515. updateHelper,
  516. J2SEProject.PROJECT_CONFIGURATION_NAMESPACE,
  517. PLATFORM_MODEL.getSelectedItem(),
  518. JAVAC_SOURCE_MODEL.getSelectedItem(),
  519. !isFXProject);
  520. // Handle other special cases
  521. if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
  522. projectProperties.remove( NO_DEPENDENCIES ); // Remove the property completely if not set
  523. }
  524. projectProperties.putAll(additionalProperties);
  525. projectProperties.put(ProjectProperties.INCLUDES, includes);
  526. projectProperties.put(ProjectProperties.EXCLUDES, excludes);
  527. StringBuilder sb = new StringBuilder();
  528. for (Enumeration elements = ANNOTATION_PROCESSORS_MODEL.elements(); elements.hasMoreElements();) {
  529. sb.append(elements.nextElement());
  530. if (elements.hasMoreElements())
  531. sb.append(',');
  532. }
  533. if (sb.length() > 0) {
  534. projectProperties.put(ProjectProperties.ANNOTATION_PROCESSING_RUN_ALL_PROCESSORS, encodeBoolean(false, BOOLEAN_KIND_TF));
  535. projectProperties.put(ProjectProperties.ANNOTATION_PROCESSING_PROCESSORS_LIST, sb.toString());
  536. } else {
  537. projectProperties.put(ProjectProperties.ANNOTATION_PROCESSING_RUN_ALL_PROCESSORS, encodeBoolean(true, BOOLEAN_KIND_TF));
  538. projectProperties.put(ProjectProperties.ANNOTATION_PROCESSING_PROCESSORS_LIST, ""); // NOI18N
  539. }
  540. sb = new StringBuilder();
  541. for (int i = 0; i < PROCESSOR_OPTIONS_MODEL.getRowCount(); i++) {
  542. String key = (String) PROCESSOR_OPTIONS_MODEL.getValueAt(i, 0);
  543. String value = (String) PROCESSOR_OPTIONS_MODEL.getValueAt(i, 1);
  544. sb.append("-A").append(key); //NOI18N
  545. if (value != null && value.length() > 0) {
  546. sb.append('=').append(value); //NOI18N
  547. }
  548. if (i < PROCESSOR_OPTIONS_MODEL.getRowCount() - 1) {
  549. sb.append(' '); //NOI18N
  550. }
  551. }
  552. if (sb.length() > 0) {
  553. projectProperties.put(ProjectProperties.ANNOTATION_PROCESSING_PROCESSOR_OPTIONS, sb.toString());
  554. } else {
  555. projectProperties.remove(ProjectProperties.ANNOTATION_PROCESSING_PROCESSOR_OPTIONS);
  556. }
  557. // Store the property changes into the project
  558. updateHelper.putProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH, projectProperties );
  559. updateHelper.putProperties( AntProjectHelper.PRIVATE_PROPERTIES_PATH, privateProperties );
  560. String value = additionalProperties.get(SOURCE_ENCODING);
  561. if (value != null) {
  562. try {
  563. FileEncodingQuery.setDefaultEncoding(Charset.forName(value));
  564. } catch (UnsupportedCharsetException e) {
  565. //When the encoding is not supported by JVM do not set it as default
  566. }
  567. }
  568. }
  569. /** Finds out what are new and removed project dependencies and
  570. * applyes the info to the project
  571. */
  572. private void resolveProjectDependencies() {
  573. // Create a set of old and new artifacts.
  574. Set<ClassPathSupport.Item> oldArtifacts = new HashSet<ClassPathSupport.Item>();
  575. EditableProperties projectProperties = updateHelper.getProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH );
  576. oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.JAVAC_CLASSPATH ) ) );
  577. oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.JAVAC_PROCESSORPATH ) ) );
  578. oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.JAVAC_TEST_CLASSPATH ) ) );
  579. oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.RUN_CLASSPATH ) ) );
  580. oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.RUN_TEST_CLASSPATH ) ) );
  581. oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.ENDORSED_CLASSPATH ) ) );
  582. Set<ClassPathSupport.Item> newArtifacts = new HashSet<ClassPathSupport.Item>();
  583. newArtifacts.addAll( ClassPathUiSupport.getList( JAVAC_CLASSPATH_MODEL ) );
  584. newArtifacts.addAll( ClassPathUiSupport.getList( JAVAC_PROCESSORPATH_MODEL ) );
  585. newArtifacts.addAll( ClassPathUiSupport.getList( JAVAC_TEST_CLASSPATH_MODEL ) );
  586. newArtifacts.addAll( ClassPathUiSupport.getList( RUN_CLASSPATH_MODEL ) );
  587. newArtifacts.addAll( ClassPathUiSupport.getList( RUN_TEST_CLASSPATH_MODEL ) );
  588. newArtifacts.addAll( ClassPathUiSupport.getList( ENDORSED_CLASSPATH_MODEL ) );
  589. // Create set of removed artifacts and remove them
  590. Set<ClassPathSupport.Item> removed = new HashSet<ClassPathSupport.Item>(oldArtifacts);
  591. removed.removeAll( newArtifacts );
  592. Set<ClassPathSupport.Item> added = new HashSet<ClassPathSupport.Item>(newArtifacts);
  593. added.removeAll(oldArtifacts);
  594. // 1. first remove all project references. The method will modify
  595. // project property files, so it must be done separately
  596. for (ClassPathSupport.Item item : removed) {
  597. if ( item.getType() == ClassPathSupport.Item.TYPE_ARTIFACT ||
  598. item.getType() == ClassPathSupport.Item.TYPE_JAR ) {
  599. refHelper.destroyReference(item.getReference());
  600. if (item.getType() == ClassPathSupport.Item.TYPE_JAR) {
  601. item.removeSourceAndJavadoc(updateHelper);
  602. }
  603. }
  604. }
  605. boolean changed = false;
  606. // 2. now read project.properties and modify rest
  607. EditableProperties ep = updateHelper.getProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH );
  608. for (ClassPathSupport.Item item : removed) {
  609. if (item.getType() == ClassPathSupport.Item.TYPE_LIBRARY) {
  610. // remove helper property pointing to library jar if there is any
  611. String prop = item.getReference();
  612. prop = CommonProjectUtils.getAntPropertyName(prop);
  613. ep.remove(prop);
  614. changed = true;
  615. }
  616. }
  617. if (changed) {
  618. updateHelper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
  619. }
  620. }
  621. private void storeRoots( SourceRoots roots, DefaultTableModel tableModel ) throws MalformedURLException {
  622. Vector data = tableModel.getDataVector();
  623. URL[] rootURLs = new URL[data.size()];
  624. String []rootLabels = new String[data.size()];
  625. final LinkedList<URL> oldRootURLs = new LinkedList<URL>(Arrays.asList (roots.getRootURLs ()));
  626. final LinkedList<String> oldRootLabels = new LinkedList<String>(Arrays.asList(roots.getRootNames()));
  627. final LinkedList<String> oldRootProps = new LinkedList<String>(Arrays.asList (roots.getRootProperties()));
  628. boolean rootsAreSame = true;
  629. for (int i=0; i<data.size();i++) {
  630. File f = (File) ((Vector)data.elementAt(i)).elementAt(0);
  631. rootURLs[i] = J2SEProjectUtil.getRootURL(f,null);
  632. validateURL(rootURLs[i],f);
  633. rootLabels[i] = (String) ((Vector)data.elementAt(i)).elementAt(1);
  634. rootsAreSame &= !oldRootURLs.isEmpty() &&
  635. oldRootURLs.removeFirst().equals(rootURLs[i]) &&
  636. roots.getRootDisplayName(oldRootLabels.removeFirst(), oldRootProps.removeFirst()).equals(rootLabels[i]);
  637. }
  638. if (!rootsAreSame || !oldRootURLs.isEmpty ()) {
  639. roots.putRoots(rootURLs,rootLabels);
  640. }
  641. }
  642. private void validateURL(final URL url, final File file) {
  643. try {
  644. final URI uri = url.toURI();
  645. if (!uri.isAbsolute()) {
  646. throw new IllegalArgumentException("URI is not absolute: " + uri.toString() + " File: " + file.getAbsolutePath()); //NOI18N
  647. }
  648. if (uri.isOpaque()) {
  649. throw new IllegalArgumentException("URI is not hierarchical: " + uri.toString() + " File: " + file.getAbsolutePath()); //NOI18N
  650. }
  651. if (!"file".equals(uri.getScheme())) {
  652. throw new IllegalArgumentException("URI scheme is not \"file\": " + uri.toString() + " File: " + file.getAbsolutePath()); //NOI18N
  653. }
  654. } catch (URISyntaxException use) {
  655. throw new IllegalArgumentException(use);
  656. }
  657. }
  658. /* This is used by CustomizerWSServiceHost */
  659. public void putAdditionalProperty(String propertyName, String propertyValue) {
  660. additionalProperties.put(propertyName, propertyValue);
  661. }
  662. //Hotfix of the issue #70058
  663. //Should be removed when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
  664. private static String encodeBoolean (boolean value, Integer kind) {
  665. if ( kind == BOOLEAN_KIND_ED ) {
  666. return value ? "on" : "off"; // NOI18N
  667. }
  668. else if ( kind == BOOLEAN_KIND_YN ) { // NOI18N
  669. return value ? "yes" : "no";
  670. }
  671. else {
  672. return value ? "true" : "false"; // NOI18N
  673. }
  674. }
  675. //Hotfix of the issue #70058
  676. //Should be removed when the StoreGroup SPI will be extended to allow true default value in ToggleButtonModel
  677. private static JToggleButton.ToggleButtonModel createToggleButtonModel (final PropertyEvaluator evaluator, final String propName, Integer[] kind) {
  678. assert evaluator != null && propName != null && kind != null && kind.length == 1;
  679. String value = evaluator.getProperty( propName );
  680. boolean isSelected = false;
  681. if (value == null) {
  682. isSelected = true;
  683. }
  684. else {
  685. String lowercaseValue = value.toLowerCase();
  686. if ( lowercaseValue.equals( "yes" ) || lowercaseValue.equals( "no" ) ) { // NOI18N
  687. kind[0] = BOOLEAN_KIND_YN;
  688. }
  689. else if ( lowercaseValue.equals( "on" ) || lowercaseValue.equals( "off" ) ) { // NOI18N
  690. kind[0] = BOOLEAN_KIND_ED;
  691. }
  692. else {
  693. kind[0] = BOOLEAN_KIND_TF;
  694. }
  695. if ( lowercaseValue.equals( "true") || // NOI18N
  696. lowercaseValue.equals( "yes") || // NOI18N
  697. lowercaseValue.equals( "on") ) { // NOI18N
  698. isSelected = true;
  699. }
  700. }
  701. JToggleButton.ToggleButtonModel bm = new JToggleButton.ToggleButtonModel();
  702. bm.setSelected(isSelected );
  703. return bm;
  704. }
  705. /**
  706. * A mess.
  707. */
  708. Map<String/*|null*/,Map<String,String>> readRunConfigs() {
  709. Map<String,Map<String,String>> m = new TreeMap<String,Map<String,String>>(new Comparator<String>() {
  710. public int compare(String s1, String s2) {
  711. return s1 != null ? (s2 != null ? s1.compareTo(s2) : 1) : (s2 != null ? -1 : 0);
  712. }
  713. });
  714. Map<String,String> def = new TreeMap<String,String>();
  715. for (String prop : new String[] {ProjectProperties.MAIN_CLASS, ProjectProperties.APPLICATION_ARGS, ProjectProperties.RUN_JVM_ARGS, ProjectProperties.RUN_WORK_DIR}) {
  716. String v = updateHelper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH).getProperty(prop);
  717. if (v == null) {
  718. v = updateHelper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH).getProperty(prop);
  719. }
  720. if (v != null) {
  721. def.put(prop, v);
  722. }
  723. }
  724. m.put(null, def);
  725. FileObject configs = project.getProjectDirectory().getFileObject("nbproject/configs");
  726. if (configs != null) {
  727. for (FileObject kid : configs.getChildren()) {
  728. if (!kid.hasExt("properties")) {
  729. continue;
  730. }
  731. m.put(kid.getName(), new TreeMap<String,String>(updateHelper.getProperties(FileUtil.getRelativePath(project.getProjectDirectory(), kid))));
  732. }
  733. }
  734. configs = project.getProjectDirectory().getFileObject("nbproject/private/configs");
  735. if (configs != null) {
  736. for (FileObject kid : configs.getChildren()) {
  737. if (!kid.hasExt("properties")) {
  738. continue;
  739. }
  740. Map<String,String> c = m.get(kid.getName());
  741. if (c == null) {
  742. continue;
  743. }
  744. c.putAll(new HashMap<String,String>(updateHelper.getProperties(FileUtil.getRelativePath(project.getProjectDirectory(), kid))));
  745. }
  746. }
  747. //System.err.println("readRunConfigs: " + m);
  748. return m;
  749. }
  750. /**
  751. * A royal mess.
  752. */
  753. void storeRunConfigs(Map<String/*|null*/,Map<String,String/*|null*/>/*|null*/> configs,
  754. EditableProperties projectProperties, EditableProperties privateProperties) throws IOException {
  755. //System.err.println("storeRunConfigs: " + configs);
  756. Map<String,String> def = configs.get(null);
  757. for (String prop : new String[] {ProjectProperties.MAIN_CLASS, ProjectProperties.APPLICATION_ARGS, ProjectProperties.RUN_JVM_ARGS, ProjectProperties.RUN_WORK_DIR}) {
  758. String v = def.get(prop);
  759. EditableProperties ep =
  760. (prop.equals(ProjectProperties.APPLICATION_ARGS) ||
  761. prop.equals(ProjectProperties.RUN_WORK_DIR) ||
  762. privateProperties.containsKey(prop)) ?
  763. privateProperties : projectProperties;
  764. if (!Utilities.compareObjects(v, ep.getProperty(prop))) {
  765. if (v != null && v.length() > 0) {
  766. ep.setProperty(prop, v);
  767. } else {
  768. ep.remove(prop);
  769. }
  770. }
  771. }
  772. for (Map.Entry<String,Map<String,String>> entry : configs.entrySet()) {
  773. String config = entry.getKey();
  774. if (config == null) {
  775. continue;
  776. }
  777. String sharedPath = "nbproject/configs/" + config + ".properties"; // NOI18N
  778. String privatePath = "nbproject/private/configs/" + config + ".properties"; // NOI18N
  779. Map<String,String> c = entry.getValue();
  780. if (c == null) {
  781. updateHelper.putProperties(sharedPath, null);
  782. updateHelper.putProperties(privatePath, null);
  783. continue;
  784. }
  785. final EditableProperties sharedCfgProps = updateHelper.getProperties(sharedPath);
  786. final EditableProperties privateCfgProps = updateHelper.getProperties(privatePath);
  787. boolean privatePropsChanged = false;
  788. for (Map.Entry<String,String> entry2 : c.entrySet()) {
  789. String prop = entry2.getKey();
  790. String v = entry2.getValue();
  791. EditableProperties ep =
  792. (prop.equals(ProjectProperties.APPLICATION_ARGS) ||
  793. prop.equals(ProjectProperties.RUN_WORK_DIR) ||
  794. privateCfgProps.containsKey(prop)) ?
  795. privateCfgProps : sharedCfgProps;
  796. if (!Utilities.compareObjects(v, ep.getProperty(prop))) {
  797. if (v != null && (v.length() > 0 || (def.get(prop) != null && def.get(prop).length() > 0))) {
  798. ep.setProperty(prop, v);
  799. } else {
  800. ep.remove(prop);
  801. }
  802. privatePropsChanged |= ep == privateCfgProps;
  803. }
  804. }
  805. updateHelper.putProperties(sharedPath, sharedCfgProps); //Make sure the definition file is always created, even if it is empty.
  806. if (privatePropsChanged) { //Definition file is written, only when changed
  807. updateHelper.putProperties(privatePath, privateCfgProps);
  808. }
  809. }
  810. }
  811. /**
  812. * Checks presence of JavaFX 2.0 project extension.
  813. * Used to disable JSE Run config read/save mechanism
  814. * to enable its replacement in JFX2 Project implementation.
  815. */
  816. boolean isFXProject() {
  817. return J2SEProjectUtil.isTrue(evaluator.getProperty("javafx.enabled")); // NOI18N
  818. }
  819. void loadIncludesExcludes(IncludeExcludeVisualizer v) {
  820. Set<File> roots = new HashSet<File>();
  821. for (DefaultTableModel model : new DefaultTableModel[] {SOURCE_ROOTS_MODEL, TEST_ROOTS_MODEL}) {
  822. for (Object row : model.getDataVector()) {
  823. File d = (File) ((Vector) row).elementAt(0);
  824. if (/* #104996 */d.isDirectory()) {
  825. roots.add(d);
  826. }
  827. }
  828. }
  829. v.setRoots(roots.toArray(new File[roots.size()]));
  830. v.setIncludePattern(includes);
  831. v.setExcludePattern(excludes);
  832. }
  833. void storeIncludesExcludes(IncludeExcludeVisualizer v) {
  834. includes = v.getIncludePattern();
  835. excludes = v.getExcludePattern();
  836. }
  837. boolean makeSharable() {
  838. List<String> libs = new ArrayList<String>();
  839. List<String> jars = new ArrayList<String>();
  840. collectLibs(JAVAC_CLASSPATH_MODEL, libs, jars);
  841. collectLibs(JAVAC_PROCESSORPATH_MODEL, libs, jars);
  842. collectLibs(JAVAC_TEST_CLASSPATH_MODEL, libs, jars);
  843. collectLibs(RUN_CLASSPATH_MODEL, libs, jars);
  844. collectLibs(RUN_TEST_CLASSPATH_MODEL, libs, jars);
  845. collectLibs(ENDORSED_CLASSPATH_MODEL, libs, jars);
  846. libs.add("CopyLibs"); // #132201 - copylibs is integral part of j2seproject
  847. String customTasksLibs = getProject().evaluator().getProperty(AntBuildExtender.ANT_CUSTOMTASKS_LIBS_PROPNAME);
  848. if (customTasksLibs != null) {
  849. String libIDs[] = customTasksLibs.split(",");
  850. for (String libID : libIDs) {
  851. libs.add(libID.trim());
  852. }
  853. }
  854. return SharableLibrariesUtils.showMakeSharableWizard(getProject().getAntProjectHelper(),
  855. getProject().getReferenceHelper(), libs, jars);
  856. }
  857. private void collectLibs(DefaultListModel model, List<String> libs, List<String> jarReferences) {
  858. for (int i = 0; i < model.size(); i++) {
  859. ClassPathSupport.Item item = (ClassPathSupport.Item) model.get(i);
  860. if (item.getType() == ClassPathSupport.Item.TYPE_LIBRARY) {
  861. if (!item.isBroken() && !libs.contains(item.getLibrary().getName())) {
  862. libs.add(item.getLibrary().getName());
  863. }
  864. }
  865. if (item.getType() == ClassPathSupport.Item.TYPE_JAR) {
  866. if (item.getReference() != null && item.getVariableBasedProperty() == null && !jarReferences.contains(item.getReference())) {
  867. //TODO reference is null for not yet persisted items.
  868. // there seems to be no way to generate a reference string without actually
  869. // creating and writing the property..
  870. jarReferences.add(item.getReference());
  871. }
  872. }
  873. }
  874. }
  875. @NonNull
  876. Iterable<? extends ActionListener> getOptionListeners() {
  877. return optionListeners;
  878. }
  879. void addOptionListener(@NonNull final ActionListener al) {