src/macosx/classes/java/util/prefs/MacOSXPreferences.java

Print this page




  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util.prefs;
  27 
  28 import java.util.Objects;
  29 
  30 class MacOSXPreferences extends AbstractPreferences {
  31     // fixme need security checks?
  32 
  33     // CF preferences file name for Java nodes with short names
  34     // This value is also in MacOSXPreferencesFile.c
  35     private static final String defaultAppName = "com.apple.java.util.prefs";
  36 
  37     // true if this node is a child of userRoot or is userRoot
  38     private boolean isUser;
  39 
  40     // true if this node is userRoot or systemRoot
  41     private boolean isRoot;
  42 
  43     // CF's storage location for this node and its keys
  44     private MacOSXPreferencesFile file;
  45 
  46     // absolutePath() + "/"
  47     private String path;
  48 
  49     // User root and system root nodes
  50     private static MacOSXPreferences userRoot = null;
  51     private static MacOSXPreferences systemRoot = null;
  52 
  53 
  54     // Returns user root node, creating it if necessary.
  55     // Called by MacOSXPreferencesFactory
  56     static synchronized Preferences getUserRoot() {
  57         if (userRoot == null) {
  58             userRoot = new MacOSXPreferences(true);
  59         }
  60         return userRoot;
  61     }
  62 
  63 
  64     // Returns system root node, creating it if necessary.
  65     // Called by MacOSXPreferencesFactory
  66     static synchronized Preferences getSystemRoot() {
  67         if (systemRoot == null) {
  68             systemRoot = new MacOSXPreferences(false);
  69         }
  70         return systemRoot;
  71     }
  72 
  73 
  74     // Create a new root node. Called by getUserRoot() and getSystemRoot()
  75     // Synchronization is provided by the caller.
  76     private MacOSXPreferences(boolean newIsUser)
  77     {
  78         super(null, "");
  79         isUser = newIsUser;
  80         isRoot = true;
  81 
  82         initFields();
  83     }
  84 
  85 
  86     // Create a new non-root node with the given parent.
  87     // Called by childSpi().
  88     private MacOSXPreferences(MacOSXPreferences parent, String name)
  89     {
  90         super(parent, name);
  91         isUser = isUserNode();
  92         isRoot = false;
  93 
  94         initFields();
  95     }
  96 





  97 
  98     private void initFields()

  99     {






 100         path = isRoot ? absolutePath() : absolutePath() + "/";
 101         file = cfFileForNode(isUser);



 102         newNode = file.addNode(path);
 103     }
 104 
 105 
 106     // Create and return the MacOSXPreferencesFile for this node.
 107     // Does not write anything to the file.
 108     private MacOSXPreferencesFile cfFileForNode(boolean isUser)
 109     {
 110         String name = path;
 111         // /one/two/three/four/five/
 112         // The fourth slash is the end of the first three components.
 113         // If there is no fourth slash, the name has fewer than 3 components
 114         int componentCount = 0;
 115         int pos = -1;
 116         for (int i = 0; i < 4; i++) {
 117             pos = name.indexOf('/', pos+1);
 118             if (pos == -1) break;
 119         }
 120 
 121         if (pos == -1) {
 122             // fewer than three components - use default name
 123             name = defaultAppName;
 124         } else {
 125             // truncate to three components, no leading or trailing '/'


 187         return result;
 188     }
 189 
 190     // AbstractPreferences implementation
 191     @Override
 192     protected String[] keysSpi()
 193         throws BackingStoreException
 194     {
 195         String[] result = file.getKeysForNode(path);
 196         if (result == null) throw new BackingStoreException("Couldn't get list of keys for node '" + path + "'");
 197         return result;
 198     }
 199 
 200     // AbstractPreferences implementation
 201     @Override
 202     protected AbstractPreferences childSpi(String name)
 203     {
 204         // Add to parent's child list here and disallow sync
 205         // because parent and child might be in different files.
 206         synchronized(MacOSXPreferencesFile.class) {
 207             file.addChildToNode(path, name);
 208             return new MacOSXPreferences(this, name);
 209         }
 210     }
 211 
 212     // AbstractPreferences override
 213     @Override
 214     public void flush()
 215         throws BackingStoreException
 216     {
 217         // Flush should *not* check for removal, unlike sync, but should
 218         // prevent simultaneous removal.
 219         synchronized(lock) {
 220             // fixme! overkill
 221             if (!MacOSXPreferencesFile.flushWorld()) {
 222                 throw new BackingStoreException("Synchronization failed for node '" + path + "'");
 223             }
 224         }
 225     }
 226 
 227     // AbstractPreferences implementation
 228     @Override




  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util.prefs;
  27 
  28 import java.util.Objects;
  29 
  30 class MacOSXPreferences extends AbstractPreferences {
  31     // fixme need security checks?
  32     
  33     // CF preferences file name for Java nodes with short names
  34     // This value is also in MacOSXPreferencesFile.c
  35     private static final String defaultAppName = "com.apple.java.util.prefs";
  36     
  37     // true if this node is a child of userRoot or is userRoot
  38     private final boolean isUser;
  39     
  40     // true if this node is userRoot or systemRoot
  41     private final boolean isRoot;
  42     
  43     // CF's storage location for this node and its keys
  44     private final MacOSXPreferencesFile file;
  45     
  46     // absolutePath() + "/"
  47     private final String path;
  48     
  49     // User root and system root nodes
  50     private static MacOSXPreferences userRoot = null;
  51     private static MacOSXPreferences systemRoot = null;
  52     
  53     
  54     // Returns user root node, creating it if necessary.
  55     // Called by MacOSXPreferencesFactory
  56     static synchronized Preferences getUserRoot() {
  57         if (userRoot == null) {
  58             userRoot = new MacOSXPreferences(true);
  59         }
  60         return userRoot;
  61     }
  62     
  63     
  64     // Returns system root node, creating it if necessary.
  65     // Called by MacOSXPreferencesFactory
  66     static synchronized Preferences getSystemRoot() {
  67         if (systemRoot == null) {
  68             systemRoot = new MacOSXPreferences(false);
  69         }
  70         return systemRoot;
  71     }
  72     
  73     
  74     // Create a new root node. Called by getUserRoot() and getSystemRoot()
  75     // Synchronization is provided by the caller.
  76     private MacOSXPreferences(boolean newIsUser) {
  77         this(null, "", false, true, newIsUser);





  78     }
  79     
  80     
  81     // Create a new non-root node with the given parent.
  82     // Called by childSpi().
  83     private MacOSXPreferences(MacOSXPreferences parent, String name) {
  84         this(parent, name, false, false, false);





  85     }
  86     
  87     private MacOSXPreferences(MacOSXPreferences parent, String name,
  88                               boolean isNew)
  89     {
  90         this(parent, name, isNew, false, false);
  91     }
  92     
  93     private MacOSXPreferences(MacOSXPreferences parent, String name,
  94                               boolean isNew, boolean isRoot, boolean isUser)
  95     {
  96         super(parent, name);
  97         this.isRoot = isRoot;
  98         if (isRoot)
  99             this.isUser = isUser;
 100         else
 101             this.isUser = isUserNode();
 102         path = isRoot ? absolutePath() : absolutePath() + "/";
 103         file = cfFileForNode(isUser);
 104         if (isNew)
 105             newNode = isNew;
 106         else 
 107             newNode = file.addNode(path);
 108     }
 109 

 110     // Create and return the MacOSXPreferencesFile for this node.
 111     // Does not write anything to the file.
 112     private MacOSXPreferencesFile cfFileForNode(boolean isUser)
 113     {
 114         String name = path;
 115         // /one/two/three/four/five/
 116         // The fourth slash is the end of the first three components.
 117         // If there is no fourth slash, the name has fewer than 3 components
 118         int componentCount = 0;
 119         int pos = -1;
 120         for (int i = 0; i < 4; i++) {
 121             pos = name.indexOf('/', pos+1);
 122             if (pos == -1) break;
 123         }
 124         
 125         if (pos == -1) {
 126             // fewer than three components - use default name
 127             name = defaultAppName;
 128         } else {
 129             // truncate to three components, no leading or trailing '/'


 191         return result;
 192     }
 193     
 194     // AbstractPreferences implementation
 195     @Override
 196     protected String[] keysSpi()
 197     throws BackingStoreException
 198     {
 199         String[] result = file.getKeysForNode(path);
 200         if (result == null) throw new BackingStoreException("Couldn't get list of keys for node '" + path + "'");
 201         return result;
 202     }
 203     
 204     // AbstractPreferences implementation
 205     @Override
 206     protected AbstractPreferences childSpi(String name)
 207     {
 208         // Add to parent's child list here and disallow sync
 209         // because parent and child might be in different files.
 210         synchronized(MacOSXPreferencesFile.class) {
 211             boolean isNew = file.addChildToNode(path, name);
 212             return new MacOSXPreferences(this, name, isNew);
 213         }
 214     }
 215     
 216     // AbstractPreferences override
 217     @Override
 218     public void flush()
 219     throws BackingStoreException
 220     {
 221         // Flush should *not* check for removal, unlike sync, but should
 222         // prevent simultaneous removal.
 223         synchronized(lock) {
 224             // fixme! overkill
 225             if (!MacOSXPreferencesFile.flushWorld()) {
 226                 throw new BackingStoreException("Synchronization failed for node '" + path + "'");
 227             }
 228         }
 229     }
 230     
 231     // AbstractPreferences implementation
 232     @Override