PageRenderTime 28ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/projects/netbeans-7.3/php.project/src/org/netbeans/modules/php/project/ui/customizer/PhpProjectProperties.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 891 lines | 694 code | 102 blank | 95 comment | 143 complexity | 1f7b99efcda617c24700b6076f174d1f 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.php.project.ui.customizer;
  45. import java.io.File;
  46. import java.io.IOException;
  47. import java.nio.charset.Charset;
  48. import java.nio.charset.UnsupportedCharsetException;
  49. import java.util.Arrays;
  50. import java.util.EnumSet;
  51. import java.util.HashMap;
  52. import java.util.HashSet;
  53. import java.util.Map;
  54. import java.util.Set;
  55. import java.util.TreeMap;
  56. import javax.swing.DefaultListModel;
  57. import javax.swing.ListCellRenderer;
  58. import org.netbeans.api.project.ProjectManager;
  59. import org.netbeans.api.queries.FileEncodingQuery;
  60. import org.netbeans.modules.php.api.phpmodule.PhpModule;
  61. import org.netbeans.modules.php.api.util.StringUtils;
  62. import org.netbeans.modules.php.project.PhpProject;
  63. import org.netbeans.modules.php.project.ProjectPropertiesSupport;
  64. import org.netbeans.modules.php.project.ProjectSettings;
  65. import org.netbeans.modules.php.project.classpath.IncludePathSupport;
  66. import org.netbeans.modules.php.project.connections.ConfigManager;
  67. import org.netbeans.modules.php.project.connections.ConfigManager.Configuration;
  68. import org.netbeans.modules.php.project.ui.PathUiSupport;
  69. import org.netbeans.modules.php.project.util.PhpProjectUtils;
  70. import org.netbeans.modules.php.spi.framework.PhpModuleCustomizerExtender;
  71. import org.netbeans.spi.project.support.ant.AntProjectHelper;
  72. import org.netbeans.spi.project.support.ant.EditableProperties;
  73. import org.netbeans.spi.project.support.ant.PropertyUtils;
  74. import org.openide.filesystems.FileObject;
  75. import org.openide.filesystems.FileUtil;
  76. import org.openide.util.Exceptions;
  77. import org.openide.util.Mutex;
  78. import org.openide.util.MutexException;
  79. import org.openide.util.NbBundle;
  80. import org.openide.util.RequestProcessor;
  81. import org.openide.util.Utilities;
  82. /**
  83. * @author Tomas Mysik, Radek Matous
  84. */
  85. public final class PhpProjectProperties implements ConfigManager.ConfigProvider {
  86. public static final int DEFAULT_DEBUG_PROXY_PORT = 9001;
  87. public static final String SRC_DIR = "src.dir"; // NOI18N
  88. public static final String TEST_SRC_DIR = "test.src.dir"; // NOI18N
  89. public static final String SELENIUM_SRC_DIR = "selenium.src.dir"; // NOI18N
  90. public static final String SOURCE_ENCODING = "source.encoding"; // NOI18N
  91. public static final String COPY_SRC_FILES = "copy.src.files"; // NOI18N
  92. public static final String COPY_SRC_TARGET = "copy.src.target"; // NOI18N
  93. public static final String WEB_ROOT = "web.root"; // NOI18N
  94. public static final String URL = "url"; // NOI18N
  95. public static final String INDEX_FILE = "index.file"; // NOI18N
  96. public static final String INCLUDE_PATH = "include.path"; // NOI18N
  97. public static final String GLOBAL_INCLUDE_PATH = "php.global.include.path"; // NOI18N
  98. public static final String ARGS = "script.arguments"; // NOI18N
  99. public static final String PHP_ARGS = "php.arguments"; // NOI18N
  100. public static final String WORK_DIR = "work.dir"; // NOI18N
  101. public static final String INTERPRETER = "interpreter"; // NOI18N
  102. public static final String HOSTNAME = "hostname"; // NOI18N
  103. public static final String PORT = "port"; // NOI18N
  104. public static final String ROUTER = "router"; // NOI18N
  105. public static final String RUN_AS = "run.as"; // NOI18N
  106. public static final String REMOTE_CONNECTION = "remote.connection"; // NOI18N
  107. public static final String REMOTE_DIRECTORY = "remote.directory"; // NOI18N
  108. public static final String REMOTE_UPLOAD = "remote.upload"; // NOI18N
  109. public static final String REMOTE_PERMISSIONS = "remote.permissions"; // NOI18N
  110. public static final String REMOTE_UPLOAD_DIRECTLY = "remote.upload.directly"; // NOI18N
  111. public static final String DEBUG_URL = "debug.url"; // NOI18N
  112. public static final String DEBUG_PATH_MAPPING_REMOTE = "debug.path.mapping.remote"; // NOI18N
  113. public static final String DEBUG_PATH_MAPPING_LOCAL = "debug.path.mapping.local"; // NOI18N
  114. public static final String DEBUG_PROXY_HOST = "debug.proxy.host"; // NOI18N
  115. public static final String DEBUG_PROXY_PORT = "debug.proxy.port"; // NOI18N
  116. public static final String SHORT_TAGS = "tags.short"; // NOI18N
  117. public static final String ASP_TAGS = "tags.asp"; // NOI18N
  118. public static final String PHP_VERSION = "php.version"; // NOI18N
  119. public static final String IGNORE_PATH = "ignore.path"; // NOI18N
  120. public static final String PHP_UNIT_BOOTSTRAP = "phpunit.bootstrap"; // NOI18N
  121. public static final String PHP_UNIT_BOOTSTRAP_FOR_CREATE_TESTS = "phpunit.bootstrap.create.tests"; // NOI18N
  122. public static final String PHP_UNIT_CONFIGURATION = "phpunit.configuration"; // NOI18N
  123. public static final String PHP_UNIT_SUITE = "phpunit.suite"; // NOI18N
  124. public static final String PHP_UNIT_SCRIPT = "phpunit.script"; // NOI18N
  125. public static final String PHP_UNIT_RUN_TEST_FILES = "phpunit.run.test.files"; // NOI18N
  126. public static final String PHP_UNIT_ASK_FOR_TEST_GROUPS = "phpunit.test.groups.ask"; // NOI18N
  127. public static final String PHP_UNIT_LAST_USED_TEST_GROUPS = "phpunit.test.groups.last.used"; // NOI18N
  128. public static final String DEBUG_PATH_MAPPING_SEPARATOR = "||NB||"; // NOI18N
  129. private static final String[] CFG_PROPS = new String[] {
  130. URL,
  131. INDEX_FILE,
  132. ARGS,
  133. PHP_ARGS,
  134. WORK_DIR,
  135. INTERPRETER,
  136. HOSTNAME,
  137. PORT,
  138. ROUTER,
  139. RUN_AS,
  140. REMOTE_CONNECTION,
  141. REMOTE_DIRECTORY,
  142. REMOTE_UPLOAD,
  143. REMOTE_PERMISSIONS,
  144. REMOTE_UPLOAD_DIRECTLY,
  145. DEBUG_URL,
  146. DEBUG_PATH_MAPPING_REMOTE,
  147. DEBUG_PATH_MAPPING_LOCAL,
  148. DEBUG_PROXY_HOST,
  149. DEBUG_PROXY_PORT,
  150. };
  151. @NbBundle.Messages({
  152. "RunAsType.local.label=Local Web Site (running on local web server)",
  153. "RunAsType.script.label=Script (run in command line)",
  154. "RunAsType.remote.label=Remote Web Site (FTP, SFTP)",
  155. "RunAsType.internal.label=PHP Built-in Web Server (running on built-in web server)"
  156. })
  157. public static enum RunAsType {
  158. LOCAL(Bundle.RunAsType_local_label()),
  159. SCRIPT(Bundle.RunAsType_script_label()),
  160. REMOTE(Bundle.RunAsType_remote_label()),
  161. INTERNAL(Bundle.RunAsType_internal_label());
  162. private final String label;
  163. private RunAsType(String label) {
  164. this.label = label;
  165. }
  166. public String getLabel() {
  167. return label;
  168. }
  169. }
  170. public static enum UploadFiles {
  171. MANUALLY ("LBL_UploadFilesManually", "TXT_UploadFilesManually"), // NOI18N
  172. ON_RUN ("LBL_UploadFilesOnRun", "TXT_UploadFilesOnRun"), // NOI18N
  173. ON_SAVE ("LBL_UploadFilesOnSave", "TXT_UploadFilesOnSave"); // NOI18N
  174. private final String label;
  175. private final String description;
  176. UploadFiles(String labelKey, String descriptionKey) {
  177. label = NbBundle.getMessage(PhpProjectProperties.class, labelKey);
  178. description = NbBundle.getMessage(PhpProjectProperties.class, descriptionKey);
  179. }
  180. public String getLabel() {
  181. return label;
  182. }
  183. public String getDescription() {
  184. return description;
  185. }
  186. }
  187. public static enum DebugUrl {
  188. DEFAULT_URL,
  189. ASK_FOR_URL,
  190. DO_NOT_OPEN_BROWSER
  191. }
  192. public static enum XDebugUrlArguments {
  193. XDEBUG_SESSION_START,
  194. XDEBUG_SESSION_STOP,
  195. XDEBUG_SESSION_STOP_NO_EXEC
  196. }
  197. static final String CONFIG_PRIVATE_PROPERTIES_PATH = "nbproject/private/config.properties"; // NOI18N
  198. private static final RequestProcessor RP = new RequestProcessor(PhpProjectProperties.class.getName(), 2);
  199. private final PhpProject project;
  200. private final IncludePathSupport includePathSupport;
  201. private final IgnorePathSupport ignorePathSupport;
  202. // all these fields don't have to be volatile - this ensures request processor
  203. // CustomizerSources
  204. private String srcDir;
  205. private String testDir;
  206. private boolean testDirRemoved = false;
  207. private String copySrcFiles;
  208. private String copySrcTarget;
  209. private String webRoot;
  210. private String url;
  211. private String indexFile;
  212. private String encoding;
  213. private String shortTags;
  214. private String aspTags;
  215. private String phpVersion;
  216. private String phpUnitBootstrap;
  217. private Boolean phpUnitBootstrapForCreateTests;
  218. private String phpUnitConfiguration;
  219. private String phpUnitSuite;
  220. private String phpUnitScript;
  221. private Boolean phpUnitRunTestFiles;
  222. private Boolean phpUnitAskForTestGroups;
  223. private String phpUnitLastUsedTestGroups;
  224. private Set<PhpModuleCustomizerExtender> customizerExtenders;
  225. // CustomizerRun
  226. final Map<String/*|null*/, Map<String, String/*|null*/>/*|null*/> runConfigs;
  227. private final ConfigManager configManager;
  228. // CustomizerPhpIncludePath
  229. private DefaultListModel includePathListModel = null;
  230. private ListCellRenderer includePathListRenderer = null;
  231. // CustomizerIgnorePath
  232. private DefaultListModel ignorePathListModel = null;
  233. private ListCellRenderer ignorePathListRenderer = null;
  234. public PhpProjectProperties(PhpProject project) {
  235. this(project, null, null);
  236. }
  237. public PhpProjectProperties(PhpProject project, IncludePathSupport includePathSupport, IgnorePathSupport ignorePathSupport) {
  238. assert project != null;
  239. this.project = project;
  240. this.includePathSupport = includePathSupport;
  241. this.ignorePathSupport = ignorePathSupport;
  242. runConfigs = readRunConfigs();
  243. String currentConfig = ProjectPropertiesSupport.getPropertyEvaluator(project).getProperty("config"); // NOI18N
  244. configManager = new ConfigManager(this, currentConfig);
  245. }
  246. @Override
  247. public String[] getConfigProperties() {
  248. return CFG_PROPS.clone();
  249. }
  250. @Override
  251. public Map<String, Map<String, String>> getConfigs() {
  252. return runConfigs;
  253. }
  254. public ConfigManager getConfigManager() {
  255. return configManager;
  256. }
  257. public String getCopySrcFiles() {
  258. if (copySrcFiles == null) {
  259. copySrcFiles = ProjectPropertiesSupport.getPropertyEvaluator(project).getProperty(COPY_SRC_FILES);
  260. }
  261. return copySrcFiles;
  262. }
  263. public void setCopySrcFiles(String copySrcFiles) {
  264. this.copySrcFiles = copySrcFiles;
  265. }
  266. public String getCopySrcTarget() {
  267. if (copySrcTarget == null) {
  268. copySrcTarget = ProjectPropertiesSupport.getPropertyEvaluator(project).getProperty(COPY_SRC_TARGET);
  269. }
  270. return copySrcTarget;
  271. }
  272. public void setCopySrcTarget(String copySrcTarget) {
  273. this.copySrcTarget = copySrcTarget;
  274. }
  275. public void setShortTags(String shortTags) {
  276. this.shortTags = shortTags;
  277. }
  278. public void setAspTags(String aspTags) {
  279. this.aspTags = aspTags;
  280. }
  281. public void setPhpVersion(String phpVersion) {
  282. this.phpVersion = phpVersion;
  283. }
  284. /**
  285. * @return the webRoot, which is relative path to srcDir.
  286. */
  287. public String getWebRoot() {
  288. if (webRoot == null) {
  289. webRoot = ProjectPropertiesSupport.getPropertyEvaluator(project).getProperty(WEB_ROOT);
  290. }
  291. return webRoot != null ? webRoot : ""; // NOI18N
  292. }
  293. /**
  294. * @param webRoot the webRoot to set
  295. */
  296. public void setWebRoot(String webRoot) {
  297. this.webRoot = webRoot;
  298. }
  299. public String getEncoding() {
  300. if (encoding == null) {
  301. encoding = ProjectPropertiesSupport.getPropertyEvaluator(project).getProperty(SOURCE_ENCODING);
  302. }
  303. return encoding;
  304. }
  305. public void setEncoding(String encoding) {
  306. this.encoding = encoding;
  307. }
  308. public String getSrcDir() {
  309. if (srcDir == null) {
  310. srcDir = ProjectPropertiesSupport.getPropertyEvaluator(project).getProperty(SRC_DIR);
  311. }
  312. return srcDir;
  313. }
  314. // getter not needed
  315. public void setTestDir(String testDir) {
  316. testDirRemoved = false;
  317. this.testDir = testDir;
  318. }
  319. public void testDirRemoved() {
  320. testDirRemoved = true;
  321. }
  322. public String getUrl() {
  323. if (url == null) {
  324. url = ProjectPropertiesSupport.getPropertyEvaluator(project).getProperty(URL);
  325. }
  326. return url;
  327. }
  328. public void setUrl(String url) {
  329. this.url = url;
  330. }
  331. public String getIndexFile() {
  332. if (indexFile == null) {
  333. indexFile = ProjectPropertiesSupport.getPropertyEvaluator(project).getProperty(INDEX_FILE);
  334. }
  335. return indexFile;
  336. }
  337. public void setIndexFile(String indexFile) {
  338. this.indexFile = indexFile;
  339. }
  340. public DefaultListModel getIncludePathListModel() {
  341. if (includePathListModel == null) {
  342. EditableProperties properties = project.getHelper().getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
  343. includePathListModel = PathUiSupport.createListModel(includePathSupport.itemsIterator(
  344. properties.getProperty(INCLUDE_PATH)));
  345. }
  346. return includePathListModel;
  347. }
  348. public ListCellRenderer getIncludePathListRenderer() {
  349. if (includePathListRenderer == null) {
  350. includePathListRenderer = new PathUiSupport.ClassPathListCellRenderer(ProjectPropertiesSupport.getPropertyEvaluator(project),
  351. project.getProjectDirectory());
  352. }
  353. return includePathListRenderer;
  354. }
  355. public DefaultListModel getIgnorePathListModel() {
  356. if (ignorePathListModel == null) {
  357. EditableProperties properties = project.getHelper().getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
  358. ignorePathListModel = PathUiSupport.createListModel(ignorePathSupport.itemsIterator(
  359. properties.getProperty(IGNORE_PATH)));
  360. }
  361. return ignorePathListModel;
  362. }
  363. public ListCellRenderer getIgnorePathListRenderer() {
  364. if (ignorePathListRenderer == null) {
  365. ignorePathListRenderer = new PathUiSupport.ClassPathListCellRenderer(ProjectPropertiesSupport.getPropertyEvaluator(project),
  366. project.getProjectDirectory());
  367. }
  368. return ignorePathListRenderer;
  369. }
  370. public String getPhpUnitBootstrap() {
  371. if (phpUnitBootstrap == null) {
  372. File bootstrap = ProjectPropertiesSupport.getPhpUnitBootstrap(project);
  373. if (bootstrap != null) {
  374. phpUnitBootstrap = bootstrap.getAbsolutePath();
  375. }
  376. }
  377. return phpUnitBootstrap;
  378. }
  379. public void setPhpUnitBootstrap(String phpUnitBootstrap) {
  380. this.phpUnitBootstrap = phpUnitBootstrap;
  381. }
  382. public boolean getPhpUnitBootstrapForCreateTests() {
  383. if (phpUnitBootstrapForCreateTests == null) {
  384. phpUnitBootstrapForCreateTests = ProjectPropertiesSupport.usePhpUnitBootstrapForCreateTests(project);
  385. }
  386. return phpUnitBootstrapForCreateTests;
  387. }
  388. public void setPhpUnitBootstrapForCreateTests(Boolean phpUnitBootstrapForCreateTests) {
  389. this.phpUnitBootstrapForCreateTests = phpUnitBootstrapForCreateTests;
  390. }
  391. public String getPhpUnitConfiguration() {
  392. if (phpUnitConfiguration == null) {
  393. File configuration = ProjectPropertiesSupport.getPhpUnitConfiguration(project);
  394. if (configuration != null) {
  395. phpUnitConfiguration = configuration.getAbsolutePath();
  396. }
  397. }
  398. return phpUnitConfiguration;
  399. }
  400. public void setPhpUnitConfiguration(String phpUnitConfiguration) {
  401. this.phpUnitConfiguration = phpUnitConfiguration;
  402. }
  403. public String getPhpUnitSuite() {
  404. if (phpUnitSuite == null) {
  405. File suite = ProjectPropertiesSupport.getPhpUnitSuite(project);
  406. if (suite != null) {
  407. phpUnitSuite = suite.getAbsolutePath();
  408. }
  409. }
  410. return phpUnitSuite;
  411. }
  412. public void setPhpUnitSuite(String phpUnitSuite) {
  413. this.phpUnitSuite = phpUnitSuite;
  414. }
  415. public String getPhpUnitScript() {
  416. if (phpUnitScript == null) {
  417. File script = ProjectPropertiesSupport.getPhpUnitScript(project);
  418. if (script != null) {
  419. phpUnitScript = script.getAbsolutePath();
  420. }
  421. }
  422. return phpUnitScript;
  423. }
  424. public void setPhpUnitScript(String phpUnitScript) {
  425. this.phpUnitScript = phpUnitScript;
  426. }
  427. public Boolean getPhpUnitRunTestFiles() {
  428. if (phpUnitRunTestFiles == null) {
  429. phpUnitRunTestFiles = ProjectPropertiesSupport.runAllTestFilesUsingPhpUnit(project);
  430. }
  431. return phpUnitRunTestFiles;
  432. }
  433. public void setPhpUnitRunTestFiles(Boolean phpUnitRunTestFiles) {
  434. this.phpUnitRunTestFiles = phpUnitRunTestFiles;
  435. }
  436. public Boolean getPhpUnitAskForTestGroups() {
  437. if (phpUnitAskForTestGroups == null) {
  438. phpUnitAskForTestGroups = ProjectPropertiesSupport.askForTestGroups(project);
  439. }
  440. return phpUnitAskForTestGroups;
  441. }
  442. public void setPhpUnitAskForTestGroups(Boolean phpUnitAskForTestGroups) {
  443. this.phpUnitAskForTestGroups = phpUnitAskForTestGroups;
  444. }
  445. public String getPhpUnitLastUsedTestGroups() {
  446. if (phpUnitLastUsedTestGroups == null) {
  447. phpUnitLastUsedTestGroups = ProjectPropertiesSupport.getPhpUnitLastUsedTestGroups(project);
  448. }
  449. return phpUnitLastUsedTestGroups;
  450. }
  451. public void setPhpUnitLastUsedTestGroups(String phpUnitLastUsedTestGroups) {
  452. this.phpUnitLastUsedTestGroups = phpUnitLastUsedTestGroups;
  453. }
  454. public void addCustomizerExtender(PhpModuleCustomizerExtender customizerExtender) {
  455. if (customizerExtenders == null) {
  456. customizerExtenders = new HashSet<PhpModuleCustomizerExtender>();
  457. }
  458. customizerExtenders.add(customizerExtender);
  459. }
  460. public void save() {
  461. try {
  462. // store properties
  463. ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
  464. @Override
  465. public Void run() throws IOException {
  466. saveProperties();
  467. saveCustomizerExtenders();
  468. ProjectManager.getDefault().saveProject(project);
  469. return null;
  470. }
  471. });
  472. } catch (MutexException e) {
  473. Exceptions.printStackTrace((IOException) e.getException());
  474. }
  475. }
  476. /**
  477. * Add or replace project and/or private properties of the given project.
  478. * @param project project to be saved
  479. * @param projectProperties project properties to be added (replaced) to the current project properties
  480. * @param privateProperties private properties to be added (replaced) to the current private properties
  481. */
  482. public static void save(final PhpProject project, final Map<String, String> projectProperties, final Map<String, String> privateProperties) {
  483. assert !projectProperties.isEmpty() || !privateProperties.isEmpty() : "Neither project nor private properties to be saved";
  484. try {
  485. // store properties
  486. ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
  487. @Override
  488. public Void run() throws IOException {
  489. AntProjectHelper helper = project.getHelper();
  490. mergeProperties(helper, AntProjectHelper.PROJECT_PROPERTIES_PATH, projectProperties);
  491. mergeProperties(helper, AntProjectHelper.PRIVATE_PROPERTIES_PATH, privateProperties);
  492. ProjectManager.getDefault().saveProject(project);
  493. return null;
  494. }
  495. private void mergeProperties(AntProjectHelper helper, String path, Map<String, String> properties) {
  496. if (properties.isEmpty()) {
  497. return;
  498. }
  499. EditableProperties currentProperties = helper.getProperties(path);
  500. for (Map.Entry<String, String> entry : properties.entrySet()) {
  501. currentProperties.put(entry.getKey(), entry.getValue());
  502. }
  503. helper.putProperties(path, currentProperties);
  504. }
  505. });
  506. } catch (MutexException e) {
  507. Exceptions.printStackTrace((IOException) e.getException());
  508. }
  509. }
  510. void saveProperties() throws IOException {
  511. AntProjectHelper helper = project.getHelper();
  512. // encode include path
  513. String[] includePath = null;
  514. if (includePathListModel != null) {
  515. includePath = includePathSupport.encodeToStrings(PathUiSupport.getIterator(includePathListModel));
  516. }
  517. // encode ignore path
  518. String[] ignorePath = null;
  519. if (ignorePathListModel != null) {
  520. ignorePath = ignorePathSupport.encodeToStrings(PathUiSupport.getIterator(ignorePathListModel));
  521. }
  522. // get properties
  523. EditableProperties projectProperties = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
  524. EditableProperties privateProperties = helper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
  525. // sources
  526. if (testDirRemoved) {
  527. projectProperties.remove(TEST_SRC_DIR);
  528. } else if (testDir != null) {
  529. projectProperties.setProperty(TEST_SRC_DIR, testDir);
  530. }
  531. if (copySrcFiles != null) {
  532. privateProperties.setProperty(COPY_SRC_FILES, copySrcFiles);
  533. }
  534. if (copySrcTarget != null) {
  535. privateProperties.setProperty(COPY_SRC_TARGET, copySrcTarget);
  536. }
  537. if (encoding != null) {
  538. projectProperties.setProperty(SOURCE_ENCODING, encoding);
  539. }
  540. if (webRoot != null) {
  541. projectProperties.setProperty(WEB_ROOT, webRoot);
  542. }
  543. if (phpVersion != null) {
  544. projectProperties.setProperty(PHP_VERSION, phpVersion);
  545. }
  546. if (shortTags != null) {
  547. projectProperties.setProperty(SHORT_TAGS, shortTags);
  548. }
  549. if (aspTags != null) {
  550. projectProperties.setProperty(ASP_TAGS, aspTags);
  551. }
  552. // php include path
  553. if (includePath != null) {
  554. projectProperties.setProperty(INCLUDE_PATH, includePath);
  555. }
  556. // ignore path
  557. if (ignorePath != null) {
  558. projectProperties.setProperty(IGNORE_PATH, ignorePath);
  559. }
  560. // phpunit
  561. if (phpUnitBootstrap != null) {
  562. projectProperties.setProperty(PHP_UNIT_BOOTSTRAP, relativizeFile(phpUnitBootstrap));
  563. }
  564. if (phpUnitBootstrapForCreateTests != null) {
  565. projectProperties.setProperty(PHP_UNIT_BOOTSTRAP_FOR_CREATE_TESTS, phpUnitBootstrapForCreateTests.toString());
  566. }
  567. if (phpUnitConfiguration != null) {
  568. projectProperties.setProperty(PHP_UNIT_CONFIGURATION, relativizeFile(phpUnitConfiguration));
  569. }
  570. if (phpUnitSuite != null) {
  571. projectProperties.setProperty(PHP_UNIT_SUITE, relativizeFile(phpUnitSuite));
  572. }
  573. if (phpUnitScript != null) {
  574. projectProperties.setProperty(PHP_UNIT_SCRIPT, relativizeFile(phpUnitScript));
  575. }
  576. if (phpUnitRunTestFiles != null) {
  577. projectProperties.setProperty(PHP_UNIT_RUN_TEST_FILES, phpUnitRunTestFiles.toString());
  578. }
  579. if (phpUnitAskForTestGroups != null) {
  580. projectProperties.setProperty(PHP_UNIT_ASK_FOR_TEST_GROUPS, phpUnitAskForTestGroups.toString());
  581. }
  582. if (phpUnitLastUsedTestGroups != null) {
  583. projectProperties.setProperty(PHP_UNIT_LAST_USED_TEST_GROUPS, phpUnitLastUsedTestGroups);
  584. }
  585. // configs
  586. storeRunConfigs(projectProperties, privateProperties);
  587. EditableProperties ep = helper.getProperties(CONFIG_PRIVATE_PROPERTIES_PATH);
  588. String currentConfig = configManager.currentConfiguration().getName();
  589. if (currentConfig == null) {
  590. ep.remove("config"); // NOI18N
  591. } else {
  592. ep.setProperty("config", currentConfig); // NOI18N
  593. }
  594. // store all the properties
  595. helper.putProperties(CONFIG_PRIVATE_PROPERTIES_PATH, ep);
  596. helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, projectProperties);
  597. helper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, privateProperties);
  598. // additional changes
  599. // encoding
  600. if (encoding != null) {
  601. try {
  602. FileEncodingQuery.setDefaultEncoding(Charset.forName(encoding));
  603. } catch (UnsupportedCharsetException e) {
  604. //When the encoding is not supported by JVM do not set it as default
  605. }
  606. }
  607. // reset timestamp of the last upload & download
  608. ProjectSettings.resetLastUpload(project);
  609. ProjectSettings.resetLastDownload(project);
  610. // UI log
  611. logUsage(helper.getProjectDirectory(), ProjectPropertiesSupport.getSourcesDirectory(project),
  612. getActiveRunAsType(), getNumOfRunConfigs(), Boolean.valueOf(getCopySrcFiles()));
  613. }
  614. void saveCustomizerExtenders() {
  615. if (customizerExtenders != null) {
  616. final EnumSet<PhpModuleCustomizerExtender.Change> changes = EnumSet.noneOf(PhpModuleCustomizerExtender.Change.class);
  617. final PhpModule phpModule = project.getPhpModule();
  618. for (PhpModuleCustomizerExtender customizerExtender : customizerExtenders) {
  619. EnumSet<PhpModuleCustomizerExtender.Change> change = customizerExtender.save(phpModule);
  620. if (change != null) {
  621. changes.addAll(change);
  622. }
  623. }
  624. // fire events (background thread, no locks)
  625. if (!changes.isEmpty()) {
  626. RP.execute(new Runnable() {
  627. @Override
  628. public void run() {
  629. for (PhpModuleCustomizerExtender.Change change : changes) {
  630. switch (change) {
  631. case SOURCES_CHANGE:
  632. project.getSourceRoots().fireChange();
  633. break;
  634. case TESTS_CHANGE:
  635. project.getTestRoots().fireChange();
  636. break;
  637. case SELENIUM_CHANGE:
  638. project.getSeleniumRoots().fireChange();
  639. break;
  640. case IGNORED_FILES_CHANGE:
  641. project.fireIgnoredFilesChange();
  642. break;
  643. case FRAMEWORK_CHANGE:
  644. project.resetFrameworks();
  645. break;
  646. default:
  647. throw new IllegalStateException("Unknown change: " + change);
  648. }
  649. }
  650. }
  651. });
  652. }
  653. }
  654. }
  655. private String relativizeFile(String filePath) {
  656. if (StringUtils.hasText(filePath)) {
  657. File file = new File(filePath);
  658. String path = PropertyUtils.relativizeFile(FileUtil.toFile(project.getProjectDirectory()), file);
  659. if (path == null) {
  660. // sorry, cannot be relativized
  661. path = file.getAbsolutePath();
  662. }
  663. return path;
  664. }
  665. return ""; // NOI18N
  666. }
  667. private String getActiveRunAsType() {
  668. return configManager.currentConfiguration().getValue(RUN_AS);
  669. }
  670. private int getNumOfRunConfigs() {
  671. int n = 0;
  672. // removed configs may be null, do not count them
  673. for (String name : configManager.configurationNames()) {
  674. if (configManager.exists(name)) {
  675. ++n;
  676. }
  677. }
  678. return n;
  679. }
  680. // http://wiki.netbeans.org/UsageLoggingSpecification
  681. private void logUsage(FileObject projectDir, FileObject sourceDir, String activeRunAsType, int numOfConfigs, boolean copyFiles) {
  682. PhpProjectUtils.logUsage(PhpProjectProperties.class, "USG_PROJECT_CONFIG_PHP", Arrays.asList(
  683. FileUtil.isParentOf(projectDir, sourceDir) ? "EXTRA_SRC_DIR_NO" : "EXTRA_SRC_DIR_YES", // NOI18N
  684. activeRunAsType,
  685. Integer.toString(numOfConfigs),
  686. copyFiles ? "COPY_FILES_YES" : "COPY_FILES_NO")); // NOI18N
  687. }
  688. public PhpProject getProject() {
  689. return project;
  690. }
  691. /**
  692. * A mess.
  693. */
  694. Map<String/*|null*/, Map<String, String>> readRunConfigs() {
  695. Map<String, Map<String, String>> m = ConfigManager.createEmptyConfigs();
  696. Map<String, String> def = new TreeMap<String, String>();
  697. EditableProperties privateProperties = getProject().getHelper().getProperties(
  698. AntProjectHelper.PRIVATE_PROPERTIES_PATH);
  699. EditableProperties projectProperties = getProject().getHelper().getProperties(
  700. AntProjectHelper.PROJECT_PROPERTIES_PATH);
  701. for (String prop : CFG_PROPS) {
  702. String v = privateProperties.getProperty(prop);
  703. if (v == null) {
  704. v = projectProperties.getProperty(prop);
  705. }
  706. if (v != null) {
  707. def.put(prop, v);
  708. }
  709. }
  710. m.put(null, def);
  711. FileObject configs = project.getProjectDirectory().getFileObject("nbproject/configs"); // NOI18N
  712. if (configs != null) {
  713. for (FileObject kid : configs.getChildren()) {
  714. if (!kid.hasExt("properties")) { // NOI18N
  715. continue;
  716. }
  717. String path = FileUtil.getRelativePath(project.getProjectDirectory(), kid);
  718. m.put(kid.getName(), new TreeMap<String, String>(getProject().getHelper().getProperties(path)));
  719. }
  720. }
  721. configs = project.getProjectDirectory().getFileObject("nbproject/private/configs"); // NOI18N
  722. if (configs != null) {
  723. for (FileObject kid : configs.getChildren()) {
  724. if (!kid.hasExt("properties")) { // NOI18N
  725. continue;
  726. }
  727. Map<String, String> c = m.get(kid.getName());
  728. if (c == null) {
  729. continue;
  730. }
  731. String path = FileUtil.getRelativePath(project.getProjectDirectory(), kid);
  732. c.putAll(new HashMap<String, String>(getProject().getHelper().getProperties(path)));
  733. }
  734. }
  735. //System.err.println("readRunConfigs: " + m);
  736. return m;
  737. }
  738. /**
  739. * A royal mess.
  740. */
  741. void storeRunConfigs(EditableProperties projectProperties, EditableProperties privateProperties) throws IOException {
  742. Configuration defaultConfiguration = configManager.defaultConfiguration();
  743. for (String prop : CFG_PROPS) {
  744. String value = defaultConfiguration.getValue(prop);
  745. EditableProperties ep = isPrivateProperty(prop) ? privateProperties : projectProperties;
  746. if (!Utilities.compareObjects(value, ep.getProperty(prop))) {
  747. if (StringUtils.hasText(value)) {
  748. ep.setProperty(prop, value);
  749. } else {
  750. ep.remove(prop);
  751. }
  752. }
  753. }
  754. for (String name : configManager.configurationNames()) {
  755. if (name == null) {
  756. // default config
  757. continue;
  758. }
  759. String sharedPath = "nbproject/configs/" + name + ".properties"; // NOI18N
  760. String privatePath = "nbproject/private/configs/" + name + ".properties"; // NOI18N
  761. if (!configManager.exists(name)) {
  762. // deleted config
  763. getProject().getHelper().putProperties(sharedPath, null);
  764. getProject().getHelper().putProperties(privatePath, null);
  765. continue;
  766. }
  767. Configuration configuration = configManager.configurationFor(name);
  768. for (String prop : CFG_PROPS) {
  769. String value = configuration.getValue(prop);
  770. String path = isPrivateProperty(prop) ? privatePath : sharedPath;
  771. EditableProperties ep = getProject().getHelper().getProperties(path);
  772. if (!Utilities.compareObjects(value, ep.getProperty(prop))) {
  773. if (value != null && (value.length() > 0 || (StringUtils.hasText(defaultConfiguration.getValue(prop))))) {
  774. ep.setProperty(prop, value);
  775. } else {
  776. ep.remove(prop);
  777. }
  778. getProject().getHelper().putProperties(path, ep);
  779. }
  780. }
  781. // make sure the definition file is always created, even if it is empty.
  782. getProject().getHelper().putProperties(sharedPath, getProject().getHelper().getProperties(sharedPath));
  783. }
  784. }
  785. private boolean isPrivateProperty(String property) {
  786. // #145477 - all the config properties are stored in private properties because we don't want them to be versioned
  787. return true;
  788. }
  789. }