AbstractPreferences.java revision 5e23b687ef8b3c696d54d1880b454942875665b7
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.prefs; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream; 22e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughesimport java.nio.charset.Charsets; 235cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilsonimport java.util.Collection; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.EventListener; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.EventObject; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashMap; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.LinkedList; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Map; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.TreeSet; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Base64; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This abstract class is a partial implementation of the abstract class 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Preferences, which can be used to simplify {@code Preferences} provider's 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation. This class defines nine abstract SPI methods, which must be 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implemented by a preference provider. 395cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 405cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * @since 1.4 415cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * @see Preferences 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class AbstractPreferences extends Preferences { 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class fields 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 495cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** the unhandled events collection */ 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final List<EventObject> events = new LinkedList<EventObject>(); 515cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** the event dispatcher thread */ 5203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes private static final EventDispatcher dispatcher = new EventDispatcher("Preference Event Dispatcher"); 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class initializer 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatcher.setDaemon(true); 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatcher.start(); 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Runtime.getRuntime().addShutdownHook(new Thread() { 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void run() { 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences uroot = Preferences.userRoot(); 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences sroot = Preferences.systemRoot(); 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project uroot.flush(); 695cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } catch (BackingStoreException e) { 705cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignore 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sroot.flush(); 745cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } catch (BackingStoreException e) { 755cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignore 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }); 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Instance fields (package-private) 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 865cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** true if this node is in user preference hierarchy */ 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean userNode; 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Instance fields (private) 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The object used to lock this node. 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final Object lock; 98f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This field is true if this node is created while it doesn't exist in the 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * backing store. This field's default value is false, and it is checked 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * when the node creation is completed, and if it is true, the node change 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * event will be fired for this node's parent. 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected boolean newNode; 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1075cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** cached child nodes */ 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Map<String, AbstractPreferences> cachedNode; 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //the collections of listeners 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<EventListener> nodeChangeListeners; 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<EventListener> preferenceChangeListeners; 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //this node's name 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String nodeName; 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //handler to this node's parent 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences parentPref; 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //true if this node has been removed 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isRemoved; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //handler to this node's root node 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences root; 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructors 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1325cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Constructs a new {@code AbstractPreferences} instance using the given 1335cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * parent node and node name. 1345cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param parent 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parent node of the new node or {@code null} to indicate 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that the new node is a root node. 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the new node or an empty string to indicate that 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this node is called "root". 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the name contains a slash character or is empty if {@code 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parent} is not {@code null}. 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AbstractPreferences(AbstractPreferences parent, String name) { 14603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if ((null == parent ^ name.length() == 0) || name.indexOf("/") >= 0) { 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project root = null == parent ? this : parent.root; 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners = new LinkedList<EventListener>(); 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners = new LinkedList<EventListener>(); 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isRemoved = false; 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cachedNode = new HashMap<String, AbstractPreferences>(); 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeName = name; 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref = parent; 1565e23b687ef8b3c696d54d1880b454942875665b7Elliott Hughes lock = new Object(); 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project userNode = root.userNode; 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of all cached child nodes. 167f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of cached child nodes. 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final AbstractPreferences[] cachedChildren() { 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return cachedNode.values().toArray(new AbstractPreferences[cachedNode.size()]); 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the child node with the specified name or {@code null} if it 1765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * doesn't exist. Implementers can assume that the name supplied to this 1775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * method will be a valid node name string (conforming to the node naming 1785cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * format) and will not correspond to a node that has been cached or 1795cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * removed. 180f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the desired child node. 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the child node with the given name or {@code null} if it doesn't 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exist. 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AbstractPreferences getChild(String name) 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws BackingStoreException { 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences result = null; 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] childrenNames = childrenNames(); 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < childrenNames.length; i++) { 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (childrenNames[i].equals(name)) { 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = childSpi(name); 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this node has been removed by invoking the method {@code 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removeNode()}. 2095cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true}, if this node has been removed, {@code false} 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected boolean isRemoved() { 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isRemoved; 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Flushes changes of this node to the backing store. This method should 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only flush this node and should not include the descendant nodes. Any 2225cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * implementation that wants to provide functionality to flush all nodes 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * at once should override the method {@link #flush() flush()}. 2245cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void flushSpi() throws BackingStoreException; 230f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2325cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Returns the names of all of the child nodes of this node or an empty 2335cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * array if this node has no children. The names of cached children are not 2345cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * required to be returned. 2355cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the names of this node's children. 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String[] childrenNamesSpi() throws BackingStoreException; 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the child preference node with the given name, creating it 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if it does not exist. The caller of this method should ensure that the 2465cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * given name is valid and that this node has not been removed or cached. 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the named node has just been removed, the implementation 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this method must create a new one instead of reactivating the removed 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one. 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The new creation is not required to be persisted immediately until the 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * flush method will be invoked. 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </p> 254f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the child preference to be returned. 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the child preference node. 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract AbstractPreferences childSpi(String name); 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Puts the given key-value pair into this node. Caller of this method 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * should ensure that both of the given values are valid and that this 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * node has not been removed. 2665cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given preference key. 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given preference value. 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void putSpi(String name, String value); 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2755cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Gets the preference value mapped to the given key. The caller of this 2765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * method should ensure that the given key is valid and that this node has 2775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * not been removed. This method should not throw any exceptions but if it 2785cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * does, the caller will ignore the exception, regarding it as a {@code 2795cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * null} return value. 2805cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given key to be searched for. 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the preference value mapped to the given key. 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String getSpi(String key); 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of all preference keys of this node or an empty array if 2905cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * no preferences have been found. The caller of this method should ensure 2915cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * that this node has not been removed. 2925cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of all preference keys. 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String[] keysSpi() throws BackingStoreException; 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes this node from the preference hierarchy tree. The caller of this 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method should ensure that this node has no child nodes, which means the 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method {@link Preferences#removeNode() Preferences.removeNode()} should 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invoke this method multiple-times in bottom-up pattern. The removal is 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not required to be persisted until after it is flushed. 3065cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void removeNodeSpi() throws BackingStoreException; 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes the preference with the specified key. The caller of this method 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * should ensure that the given key is valid and that this node has not been 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removed. 317f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key of the preference that is to be removed. 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void removeSpi(String key); 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Synchronizes this node with the backing store. This method should only 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * synchronize this node and should not include the descendant nodes. An 3265cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * implementation that wants to provide functionality to synchronize all 3275cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * nodes at once should override the method {@link #sync() sync()}. 328f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void syncSpi() throws BackingStoreException; 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods inherited from Preferences 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String absolutePath() { 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentPref == null) { 34303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return "/"; 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (parentPref == root) { 34503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return "/" + nodeName; 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 34703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return parentPref.absolutePath() + "/" + nodeName; 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] childrenNames() throws BackingStoreException { 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project TreeSet<String> result = new TreeSet<String>(cachedNode.keySet()); 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] names = childrenNamesSpi(); 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < names.length; i++) { 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(names[i]); 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3595cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return result.toArray(new String[result.size()]); 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() throws BackingStoreException { 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] keyList = keys(); 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < keyList.length; i++) { 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project remove(keyList[i]); 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 37403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes public void exportNode(OutputStream ostream) throws IOException, BackingStoreException { 37503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (ostream == null) { 37603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new NullPointerException("Stream is null"); 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project XMLParser.exportPrefs(this, ostream, false); 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 38303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes public void exportSubtree(OutputStream ostream) throws IOException, BackingStoreException { 38403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (ostream == null) { 38503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new NullPointerException("Stream is null"); 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project XMLParser.exportPrefs(this, ostream, true); 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void flush() throws BackingStoreException { 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project flushSpi(); 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences[] cc = cachedChildren(); 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i; 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (i = 0; i < cc.length; i++) { 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cc[i].flush(); 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String get(String key, String deflt) { 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key == null) { 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4085cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson String result = null; 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = getSpi(key); 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 4145cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignored 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (result == null ? deflt : result); 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getBoolean(String key, boolean deflt) { 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 4255cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 42603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if ("true".equalsIgnoreCase(result)) { 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 42803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } else if ("false".equalsIgnoreCase(result)) { 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getByteArray(String key, byte[] deflt) { 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String svalue = get(key, null); 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (svalue == null) { 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 441f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (svalue.length() == 0) { 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new byte[0]; 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 445e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes byte[] bavalue = svalue.getBytes(Charsets.US_ASCII); 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bavalue.length % 4 != 0) { 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4495cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Base64.decode(bavalue); 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 4515cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public double getDouble(String key, double deflt) { 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4625cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Double.parseDouble(result); 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4645cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public float getFloat(String key, float deflt) { 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4755cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Float.parseFloat(result); 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getInt(String key, int deflt) { 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4885cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Integer.parseInt(result); 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4905cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getLong(String key, long deflt) { 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 5015cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Long.parseLong(result); 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 5035cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isUserNode() { 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return root == Preferences.userRoot(); 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] keys() throws BackingStoreException { 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return keysSpi(); 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String name() { 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return nodeName; 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Preferences node(String name) { 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences startNode = null; 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validateName(name); 53180a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes if (name.isEmpty()) { 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 53303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } else if ("/".equals(name)) { 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return root; 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 53603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.startsWith("/")) { 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = root; 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.substring(1); 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = this; 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 5445cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return startNode.nodeImpl(name, true); 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (BackingStoreException e) { 5465cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // should not happen 5475cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return null; 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void validateName(String name) { 55203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.endsWith("/") && name.length() > 1) { 55303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name cannot end with '/'"); 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 55503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.indexOf("//") >= 0) { 55603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name cannot contain consecutive '/' characters"); 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences nodeImpl(String path, boolean createNew) 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws BackingStoreException { 562fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes String[] names = path.split("/"); 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences currentNode = this; 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences temp = null; 5655cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (null != currentNode) { 5665cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson for (int i = 0; i < names.length; i++) { 5675cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson String name = names[i]; 5685cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson synchronized (currentNode.lock) { 5695cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson temp = currentNode.cachedNode.get(name); 5705cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (temp == null) { 5715cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson temp = getNodeFromBackend(createNew, currentNode, name); 5725cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 5735cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 5745cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson currentNode = temp; 5755cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (null == currentNode) { 5765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson break; 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return currentNode; 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences getNodeFromBackend(boolean createNew, 58403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes AbstractPreferences currentNode, String name) throws BackingStoreException { 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name.length() > MAX_NAME_LENGTH) { 58603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name '" + name + "' too long"); 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 5885cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson AbstractPreferences temp; 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (createNew) { 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project temp = currentNode.childSpi(name); 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentNode.cachedNode.put(name, temp); 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (temp.newNode && currentNode.nodeChangeListeners.size() > 0) { 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentNode.notifyChildAdded(temp); 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project temp = currentNode.getChild(name); 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return temp; 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean nodeExists(String name) throws BackingStoreException { 6035cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (null == name) { 6045cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson throw new NullPointerException(); 6055cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences startNode = null; 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isRemoved()) { 60903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.isEmpty()) { 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 61203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalStateException("This node has been removed"); 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validateName(name); 61503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.isEmpty() || "/".equals(name)) { 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 61803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.startsWith("/")) { 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = root; 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.substring(1); 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = this; 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences result = startNode.nodeImpl(name, false); 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null == result ? false : true; 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch(IllegalArgumentException e) { 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Preferences parent() { 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return parentPref; 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkState() { 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isRemoved()) { 64103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalStateException("This node has been removed"); 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void put(String key, String value) { 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == key || null == value) { 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key.length() > MAX_KEY_LENGTH || value.length() > MAX_VALUE_LENGTH) { 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project putSpi(key, value); 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project notifyPreferenceChange(key, value); 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putBoolean(String key, boolean value) { 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = String.valueOf(value); 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putByteArray(String key, byte[] value) { 668b1b8fbeeae579e9f49c41166bb5d9b2e60b75438Elliott Hughes put(key, Base64.encode(value, Charsets.US_ASCII)); 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putDouble(String key, double value) { 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Double.toString(value); 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putFloat(String key, float value) { 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Float.toString(value); 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putInt(String key, int value) { 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Integer.toString(value); 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putLong(String key, long value) { 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Long.toString(value); 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void remove(String key) { 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeSpi(key); 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project notifyPreferenceChange(key, null); 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeNode() throws BackingStoreException { 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (root == this) { 70703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new UnsupportedOperationException("Cannot remove root node"); 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (parentPref.lock) { 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeNodeImpl(); 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void removeNodeImpl() throws BackingStoreException { 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] childrenNames = childrenNamesSpi(); 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < childrenNames.length; i++) { 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == cachedNode.get(childrenNames[i])) { 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences child = childSpi(childrenNames[i]); 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cachedNode.put(childrenNames[i], child); 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 724f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 7255cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson final Collection<AbstractPreferences> values = cachedNode.values(); 7265cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson final AbstractPreferences[] children = values.toArray(new AbstractPreferences[values.size()]); 7275cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson for (AbstractPreferences child : children) { 7285cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson child.removeNodeImpl(); 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeNodeSpi(); 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isRemoved = true; 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref.cachedNode.remove(nodeName); 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentPref.nodeChangeListeners.size() > 0) { 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref.notifyChildRemoved(this); 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addNodeChangeListener(NodeChangeListener ncl) { 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == ncl) { 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners.add(ncl); 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addPreferenceChangeListener(PreferenceChangeListener pcl) { 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == pcl) { 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners.add(pcl); 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeNodeChangeListener(NodeChangeListener ncl) { 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos; 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((pos = nodeChangeListeners.indexOf(ncl)) == -1) { 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners.remove(pos); 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removePreferenceChangeListener(PreferenceChangeListener pcl) { 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos; 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((pos = preferenceChangeListeners.indexOf(pcl)) == -1) { 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners.remove(pos); 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void sync() throws BackingStoreException { 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project syncSpi(); 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 79103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes for (AbstractPreferences child : cachedChildren()) { 79203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes child.sync(); 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 798328f533a177f7579a9ea916f5569053ec9c149b8Elliott Hughes return (isUserNode() ? "User" : "System") + " Preference Node: " + absolutePath(); 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyChildAdded(Preferences child) { 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeEvent nce = new NodeAddEvent(this, child); 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(nce); 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyChildRemoved(Preferences child) { 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeEvent nce = new NodeRemoveEvent(this, child); 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(nce); 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyPreferenceChange(String key, String newValue) { 81803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes PreferenceChangeEvent pce = new PreferenceChangeEvent(this, key, newValue); 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(pce); 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class EventDispatcher extends Thread { 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventDispatcher(String name){ 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(name); 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 829f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void run() { 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventObject event = null; 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project event = getEventObject(); 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InterruptedException e) { 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e.printStackTrace(); 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences pref = (AbstractPreferences) event 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getSource(); 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (event instanceof NodeAddEvent) { 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchNodeAdd((NodeChangeEvent) event, 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.nodeChangeListeners); 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (event instanceof NodeRemoveEvent) { 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchNodeRemove((NodeChangeEvent) event, 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.nodeChangeListeners); 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (event instanceof PreferenceChangeEvent) { 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchPrefChange((PreferenceChangeEvent) event, 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.preferenceChangeListeners); 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private EventObject getEventObject() throws InterruptedException { 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (events.isEmpty()) { 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.wait(); 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventObject event = events.get(0); 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.remove(0); 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return event; 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchPrefChange(PreferenceChangeEvent event, 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> preferenceChangeListeners) { 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<EventListener> i = preferenceChangeListeners.iterator(); 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (i.hasNext()) { 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project PreferenceChangeListener pcl = (PreferenceChangeListener) i 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .next(); 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pcl.preferenceChange(event); 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchNodeRemove(NodeChangeEvent event, 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> nodeChangeListeners) { 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<EventListener> i = nodeChangeListeners.iterator(); 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (i.hasNext()) { 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeListener ncl = (NodeChangeListener) i.next(); 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ncl.childRemoved(event); 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchNodeAdd(NodeChangeEvent event, 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> nodeChangeListeners) { 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<EventListener> i = nodeChangeListeners.iterator(); 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (i.hasNext()) { 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeListener ncl = (NodeChangeListener) i.next(); 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ncl.childAdded(event); 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class NodeAddEvent extends NodeChangeEvent { 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //The base class is NOT serializable, so this class isn't either. 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 1L; 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeAddEvent(Preferences p, Preferences c) { 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(p, c); 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class NodeRemoveEvent extends NodeChangeEvent { 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //The base class is NOT serializable, so this class isn't either. 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 1L; 913f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeRemoveEvent(Preferences p, Preferences c) { 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(p, c); 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 919