\
NetBeans IDE and NetBeans Platform are based on software from netbeans.org, \
which has been dual licensed under the Common Development and Distribution License (CDDL) \
--- a/o.n.core/src/org/netbeans/core/ui/ProductInformationPanel.java
+++ a/o.n.core/src/org/netbeans/core/ui/ProductInformationPanel.java
@@ -68,19 +68,36 @@
import org.openide.awt.HtmlBrowser;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
+import org.openide.modules.Places;
import org.openide.util.NbBundle;
+import static org.netbeans.core.ui.Bundle.*;
+import org.openide.util.NbBundle.Messages;
public class ProductInformationPanel extends JPanel implements HyperlinkListener {
URL url = null;
Icon about;
+ @Messages({
+ "# {0} - product version",
+ "# {1} - Java version",
+ "# {2} - VM version",
+ "# {3} - OS",
+ "# {4} - encoding",
+ "# {5} - locale",
+ "# {6} - user dir",
+ "# {7} - cache dir",
+ "LBL_description=
"
+ + "
Product Version: {0}
\n "
+ + "
Java: {1}; {2}
\n "
+ + "
System: {3}; {4}; {5}
\n "
+ + "
User directory: {6}
\n "
+ + "
Cache directory: {7}
"
+ })
public ProductInformationPanel() {
initComponents();
imageLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
- description.setText(org.openide.util.NbBundle.getMessage(ProductInformationPanel.class,
- "LBL_Description", new Object[] {getProductVersionValue(), getJavaValue(), getVMValue(),
- getOperatingSystemValue(), getEncodingValue(), getSystemLocaleValue(), getUserDirValue()}));
+ description.setText(LBL_description(getProductVersionValue(), getJavaValue(), getVMValue(), getOperatingSystemValue(), getEncodingValue(), getSystemLocaleValue(), getUserDirValue(), Places.getCacheDirectory().getAbsolutePath()));
description.setCaretPosition(0); // so that text is not scrolled down
description.addHyperlinkListener(this);
copyright.addHyperlinkListener(this);
--- a/openide.modules/apichanges.xml
+++ a/openide.modules/apichanges.xml
@@ -50,6 +50,26 @@
Modules API
+
+
+ Added Places
+
+
+
+
+
+ Modules using system properties such as netbeans.user
+ should use this new API instead.
+
+
+
+
+ Introduced a structured API for accessing well-known file locations.
+
+
+
+
+
Module names can contain Java keywords
--- a/openide.modules/manifest.mf
+++ a/openide.modules/manifest.mf
@@ -1,5 +1,5 @@
Manifest-Version: 1.0
OpenIDE-Module: org.openide.modules
OpenIDE-Module-Localizing-Bundle: org/openide/modules/Bundle.properties
-OpenIDE-Module-Specification-Version: 7.24
+OpenIDE-Module-Specification-Version: 7.25
--- a/openide.modules/src/org/openide/modules/Places.java
+++ a/openide.modules/src/org/openide/modules/Places.java
@@ -0,0 +1,158 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development and
+ * Distribution License("CDDL") (collectively, the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy of
+ * the License at http://www.netbeans.org/cddl-gplv2.html or
+ * nbbuild/licenses/CDDL-GPL-2-CP. See the License for the specific language
+ * governing permissions and limitations under the License. When distributing
+ * the software, include this License Header Notice in each file and include
+ * the License file at nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided by
+ * Oracle in the GPL Version 2 section of the License file that accompanied
+ * this code. If applicable, add the following below the License Header, with
+ * the fields enclosed by brackets [] replaced by your own identifying
+ * information: "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you do not indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to its
+ * licensees as provided above. However, if you add GPL Version 2 code and
+ * therefore, elected the GPL Version 2 license, then the option applies only
+ * if the new code is made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+
+package org.openide.modules;
+
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Provides access to standard file locations.
+ *
+ * This class should be used for limited purposes only. You might instead want to use:
+ * FileUtil.getConfigFile
+ * to find a file declared in an XML layer or created or overridden in the {@code config} subdirectory of the user directory.
+ * - {@link InstalledFileLocator} to find modules installed as part of an NBM.
+ *
- {@code someClass.getProtectionDomain().getCodeSource().getLocation()} to find resources inside a module class loader.
+ *
+ *
+ * @since 7.25
+ */
+public class Places {
+
+ /**
+ * System property key for {@link #getUserDirectory}.
+ * Should not be used by most code directly.
+ */
+ public static final String USER_DIR_PROP = "netbeans.user";
+
+ private static final String MEMORY = "memory";
+
+ private static final Logger LOG = Logger.getLogger(Places.class.getName());
+
+ private static File cacheDir;
+
+ /**
+ * Locates the NetBeans user directory.
+ * This may be used to persist valuable files for which the system filesystem
+ * ({@code FileUtil.getConfigFile}) is inappropriate due its being virtual.
+ * Each module is responsible for using sufficiently unique filenames within this directory.
+ * The system property {@link #USER_DIR_PROP} is used for compatibility.
+ * @return a directory location (need not yet exist), or null if unconfigured
+ */
+ public static synchronized /*@CheckForNull*/ File getUserDirectory() {
+ String p = System.getProperty(USER_DIR_PROP);
+ return p != null && !p.equals(MEMORY) ? new File(p) : null;
+ }
+
+ /**
+ * Configures the NetBeans user directory.
+ * This would be called by startup code in the NetBeans Platform,
+ * but might also be useful to call from a unit test if tested code calls {@link #getUserDirectory} or {@link #getCacheDirectory}.
+ * @param dir a directory location (need not yet exist); null be passed but means the same as {@code memory} for the system property, interpreted by the module system
+ */
+ public static synchronized void setUserDirectory(/*@NullAllowed*/ File dir) {
+ System.setProperty(USER_DIR_PROP, dir != null ? dir.getAbsolutePath() : MEMORY);
+ }
+
+ /**
+ * Locates the NetBeans cache directory.
+ * This may be used to store pure performance caches - files which could be safely deleted,
+ * since they would be automatically recreated on demand.
+ * Each module is responsible for using sufficiently unique filenames within this directory.
+ * {@code $userdir/var/cache/} is used as a default when {@link #getUserDirectory} is configured.
+ * As a final fallback, a location in the system temporary directory will be returned.
+ * @return a directory location (never null but need not yet exist)
+ * @see #getCacheSubdirectory
+ * @see #getCacheSubfile
+ */
+ public static synchronized /*@NonNull*/ File getCacheDirectory() {
+ if (cacheDir != null) {
+ return cacheDir;
+ }
+ File userdir = getUserDirectory();
+ if (userdir != null) {
+ return new File(new File(userdir, "var"), "cache");
+ }
+ return new File(System.getProperty("java.io.tmpdir"), "nbcache");
+ }
+
+ /**
+ * Convenience method to get a particular subdirectory within {@link #getCacheDirectory}.
+ * The directory will be created if it does not yet exist (but a warning logged if permissions do not allow this).
+ * @param path a subdirectory path such as {@code stuff} or {@code mymodule/stuff} ({@code /} permitted even on Windows)
+ * @return a directory of that name within the general cache directory
+ */
+ public static /*@NonNull*/ File getCacheSubdirectory(String path) {
+ File d = new File(getCacheDirectory(), path);
+ if (!d.isDirectory() && !d.mkdirs()) {
+ LOG.log(Level.WARNING, "could not create {0}", d);
+ }
+ return d;
+ }
+
+ /**
+ * Convenience method to get a particular file within {@link #getCacheDirectory}.
+ * The parent directory will be created if it does not yet exist (but a warning logged if permissions do not allow this);
+ * the file itself will not be automatically created.
+ * @param path a file path such as {@code stuff.ser} or {@code mymodule/stuff.ser} ({@code /} permitted even on Windows)
+ * @return a file of that name within the general cache directory
+ */
+ public static /*@NonNull*/ File getCacheSubfile(String path) {
+ File f = new File(getCacheDirectory(), path);
+ File d = f.getParentFile();
+ if (!d.isDirectory() && !d.mkdirs()) {
+ LOG.log(Level.WARNING, "could not create {0}", d);
+ }
+ return f;
+ }
+
+ /**
+ * Configures the NetBeans cache directory.
+ * This would be called by startup code in the NetBeans Platform,
+ * but might also be useful to call from a unit test if tested code calls {@link #getCacheDirectory}.
+ * @param dir a directory location (need not yet exist)
+ */
+ public static synchronized void setCacheDirectory(/*@NonNull*/ File dir) {
+ cacheDir = dir;
+ }
+
+ private Places() {}
+
+}
--- a/parsing.api/nbproject/project.xml
+++ a/parsing.api/nbproject/project.xml
@@ -178,7 +178,7 @@
- 7.6
+ 7.25
--- a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/CacheFolder.java
+++ a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/CacheFolder.java
@@ -59,6 +59,7 @@
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.URLMapper;
+import org.openide.modules.Places;
/**
*
@@ -68,8 +69,6 @@
private static final Logger LOG = Logger.getLogger(CacheFolder.class.getName());
- private static final String NB_USER_DIR = "netbeans.user"; //NOI18N
- private static final String INDEX_DIR = "var"+File.separatorChar+"cache"+File.separatorChar+"index"; //NOI18N
private static final String SEGMENTS_FILE = "segments"; //NOI18N
private static final String SLICE_PREFIX = "s"; //NOI18N
@@ -198,20 +197,7 @@
public static synchronized FileObject getCacheFolder () {
if (cacheFolder == null) {
- final String nbUserDirProp = System.getProperty(NB_USER_DIR);
- if (nbUserDirProp == null) {
- throw new IllegalStateException("No " + NB_USER_DIR + " system property"); //NOI18N
- }
-
- final File nbUserDir = new File (nbUserDirProp);
- File cache = FileUtil.normalizeFile(new File (nbUserDir, INDEX_DIR));
- if (!cache.exists()) {
- cache.mkdirs();
- if (!cache.exists()) {
- throw new IllegalStateException("Can't create indices cache folder " + cache.getAbsolutePath()); //NOI18N
- }
- }
-
+ File cache = Places.getCacheSubdirectory("index"); // NOI18N
if (!cache.isDirectory()) {
throw new IllegalStateException("Indices cache folder " + cache.getAbsolutePath() + " is not a folder"); //NOI18N
}
--- a/spellchecker/nbproject/project.xml
+++ a/spellchecker/nbproject/project.xml
@@ -149,7 +149,7 @@
- 7.15
+ 7.25
--- a/spellchecker/src/org/netbeans/modules/spellchecker/TrieDictionary.java
+++ a/spellchecker/src/org/netbeans/modules/spellchecker/TrieDictionary.java
@@ -69,6 +69,7 @@
import java.util.logging.Logger;
import org.netbeans.modules.spellchecker.spi.dictionary.Dictionary;
import org.netbeans.modules.spellchecker.spi.dictionary.ValidityType;
+import org.openide.modules.Places;
import org.openide.util.CharSequences;
import org.openide.util.Exceptions;
import org.openide.util.RequestProcessor;
@@ -225,10 +226,8 @@
private static final int CURRENT_TRIE_DICTIONARY_VERSION = 1;
- private static final File CACHE_DIR = new File(new File(new File(System.getProperty("netbeans.user"), "var"), "cache"), "dict");
-
public static Dictionary getDictionary(String suffix, List sources) throws IOException {
- File trie = new File(CACHE_DIR, "dictionary" + suffix + ".trie" + CURRENT_TRIE_DICTIONARY_VERSION);
+ File trie = Places.getCacheSubfile("dict/dictionary" + suffix + ".trie" + CURRENT_TRIE_DICTIONARY_VERSION);
return getDictionary(trie, sources);
}
--- a/subversion/nbproject/project.xml
+++ a/subversion/nbproject/project.xml
@@ -229,7 +229,7 @@
- 6.6
+ 7.25
--- a/subversion/src/org/netbeans/modules/subversion/DiskMapTurboProvider.java
+++ a/subversion/src/org/netbeans/modules/subversion/DiskMapTurboProvider.java
@@ -48,11 +48,11 @@
import org.netbeans.modules.turbo.CacheIndex;
import org.netbeans.modules.subversion.util.*;
import org.netbeans.modules.turbo.TurboProvider;
-import org.openide.filesystems.FileUtil;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import org.netbeans.modules.proxy.Base64Encoder;
+import org.openide.modules.Places;
/**
* Storage of file attributes with shortcut to retrieve all stored values.
@@ -481,14 +481,7 @@
}
private void initCacheStore() {
- String userDir = System.getProperty("netbeans.user"); // NOI18N
- if (userDir != null) {
- cacheStore = new File(new File(new File (userDir, "var"), "cache"), CACHE_DIRECTORY); // NOI18N
- } else {
- File cachedir = FileUtil.toFile(FileUtil.getConfigRoot());
- cacheStore = new File(cachedir, CACHE_DIRECTORY); // NOI18N
- }
- cacheStore.mkdirs();
+ cacheStore = Places.getCacheSubdirectory(CACHE_DIRECTORY);
}
private static void copyStreams(OutputStream out, InputStream in, int len) throws IOException {
--- a/versioning.system.cvss/nbproject/project.xml
+++ a/versioning.system.cvss/nbproject/project.xml
@@ -253,7 +253,7 @@
- 6.0
+ 7.25
--- a/versioning.system.cvss/src/org/netbeans/modules/versioning/system/cvss/DiskMapTurboProvider.java
+++ a/versioning.system.cvss/src/org/netbeans/modules/versioning/system/cvss/DiskMapTurboProvider.java
@@ -45,12 +45,12 @@
package org.netbeans.modules.versioning.system.cvss;
import org.netbeans.modules.turbo.TurboProvider;
-import org.openide.filesystems.FileUtil;
import org.openide.ErrorManager;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
+import org.openide.modules.Places;
/**
* Storage of file attributes with shortcut to retrieve all stored values.
@@ -306,13 +306,7 @@
}
private void initCacheStore() {
- String userDir = System.getProperty("netbeans.user"); // NOI18N
- if (userDir != null) {
- cacheStore = new File(new File(new File (userDir, "var"), "cache"), "cvscache"); // NOI18N
- } else {
- File cachedir = FileUtil.toFile(FileUtil.getConfigRoot());
- cacheStore = new File(cachedir, "cvscache"); // NOI18N
- }
+ cacheStore = Places.getCacheSubdirectory("cvscache"); // NOI18N
}
private void makeSureCacheStoreExists() {
--- a/versioning.util/nbproject/project.xml
+++ a/versioning.util/nbproject/project.xml
@@ -210,6 +210,14 @@
+ org.openide.modules
+
+
+
+ 7.25
+
+
+
org.openide.nodes
--- a/versioning.util/src/org/netbeans/modules/versioning/historystore/StorageManager.java
+++ a/versioning.util/src/org/netbeans/modules/versioning/historystore/StorageManager.java
@@ -48,6 +48,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.modules.versioning.util.Utils;
+import org.openide.modules.Places;
import org.openide.util.NbPreferences;
/**
@@ -99,8 +100,7 @@
}
private File getBaseFolder() {
- String userDir = System.getProperty("netbeans.user"); // NOI18N
- return new File(new File(new File(userDir, "var"), "cache"), "vcshistory"); // NOI18N
+ return Places.getCacheSubdirectory("vcshistory"); // NOI18N
}
private void cleanUp() {
--- a/welcome/nbproject/project.xml
+++ a/welcome/nbproject/project.xml
@@ -68,6 +68,14 @@
+ org.netbeans.modules.projectui
+
+
+
+ 1.12
+
+
+
org.netbeans.modules.projectuiapi
@@ -77,14 +85,6 @@
- org.netbeans.modules.projectui
-
-
-
- 1.12
-
-
-
org.openide.awt
@@ -119,7 +119,7 @@
- 7.0
+ 7.25
--- a/welcome/src/org/netbeans/modules/welcome/content/RSSFeed.java
+++ a/welcome/src/org/netbeans/modules/welcome/content/RSSFeed.java
@@ -92,7 +92,7 @@
import javax.xml.parsers.ParserConfigurationException;
import org.openide.ErrorManager;
import org.openide.awt.Mnemonics;
-import org.openide.filesystems.FileUtil;
+import org.openide.modules.Places;
import org.openide.util.NbPreferences;
import org.openide.util.RequestProcessor;
import org.openide.util.WeakListeners;
@@ -135,16 +135,7 @@
* Enclosing folder is created if it does not exist yet.
*/
private static File initCacheStore(String path) throws IOException {
- File cacheStore;
- String userDir = System.getProperty("netbeans.user"); // NOI18N
- if (userDir != null) {
- cacheStore = new File(new File(new File (userDir, "var"), "cache"), "welcome"); // NOI18N
- } else {
- File cachedir = FileUtil.toFile(FileUtil.getConfigRoot());
- cacheStore = new File(cachedir, "welcome"); // NOI18N
- }
- cacheStore = new File(cacheStore, path);
- cacheStore.getParentFile().mkdirs();
+ File cacheStore = Places.getCacheSubfile("welcome/" + path); // NOI18N
cacheStore.createNewFile();
return cacheStore;
}
--- a/welcome/src/org/netbeans/modules/welcome/content/Utils.java
+++ a/welcome/src/org/netbeans/modules/welcome/content/Utils.java
@@ -64,7 +64,7 @@
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataObject;
-import org.openide.util.Lookup;
+import org.openide.modules.Places;
import org.openide.util.NbBundle;
/**
@@ -144,15 +144,7 @@
}
public static File getCacheStore() throws IOException {
- File cacheStore;
- String userDir = System.getProperty("netbeans.user"); // NOI18N
- if (userDir != null) {
- cacheStore = new File(new File(new File (userDir, "var"), "cache"), "welcome"); // NOI18N
- } else {
- File cachedir = FileUtil.toFile(FileUtil.getConfigRoot());
- cacheStore = new File(cachedir, "welcome"); // NOI18N
- }
- return cacheStore;
+ return Places.getCacheSubdirectory("welcome"); // NOI18N
}
/**