AbstractPreferences.java revision e810d3b49631329b11440aa5b7a54db181d42ed1
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; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.UnsupportedEncodingException; 23e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughesimport java.nio.charset.Charsets; 245cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilsonimport java.util.Collection; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.EventListener; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.EventObject; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashMap; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.LinkedList; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Map; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.TreeSet; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Base64; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This abstract class is a partial implementation of the abstract class 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Preferences, which can be used to simplify {@code Preferences} provider's 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation. This class defines nine abstract SPI methods, which must be 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implemented by a preference provider. 415cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 425cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * @since 1.4 435cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * @see Preferences 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class AbstractPreferences extends Preferences { 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class fields 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 515cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** the unhandled events collection */ 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final List<EventObject> events = new LinkedList<EventObject>(); 535cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** the event dispatcher thread */ 5403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes private static final EventDispatcher dispatcher = new EventDispatcher("Preference Event Dispatcher"); 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class initializer 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatcher.setDaemon(true); 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatcher.start(); 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Runtime.getRuntime().addShutdownHook(new Thread() { 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void run() { 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences uroot = Preferences.userRoot(); 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences sroot = Preferences.systemRoot(); 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project uroot.flush(); 715cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } catch (BackingStoreException e) { 725cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignore 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sroot.flush(); 765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } catch (BackingStoreException e) { 775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignore 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }); 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 82f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Instance fields (package-private) 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 885cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** true if this node is in user preference hierarchy */ 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean userNode; 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Instance fields (private) 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 965cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** Marker class for 'lock' field. */ 975cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson private static class Lock {} 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The object used to lock this node. 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final Object lock; 103f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This field is true if this node is created while it doesn't exist in the 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * backing store. This field's default value is false, and it is checked 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * when the node creation is completed, and if it is true, the node change 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * event will be fired for this node's parent. 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected boolean newNode; 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1125cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** cached child nodes */ 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Map<String, AbstractPreferences> cachedNode; 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //the collections of listeners 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<EventListener> nodeChangeListeners; 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<EventListener> preferenceChangeListeners; 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //this node's name 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String nodeName; 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //handler to this node's parent 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences parentPref; 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //true if this node has been removed 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isRemoved; 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //handler to this node's root node 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences root; 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructors 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1375cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Constructs a new {@code AbstractPreferences} instance using the given 1385cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * parent node and node name. 1395cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param parent 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parent node of the new node or {@code null} to indicate 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that the new node is a root node. 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the new node or an empty string to indicate that 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this node is called "root". 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the name contains a slash character or is empty if {@code 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parent} is not {@code null}. 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AbstractPreferences(AbstractPreferences parent, String name) { 15103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if ((null == parent ^ name.length() == 0) || name.indexOf("/") >= 0) { 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project root = null == parent ? this : parent.root; 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners = new LinkedList<EventListener>(); 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners = new LinkedList<EventListener>(); 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isRemoved = false; 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cachedNode = new HashMap<String, AbstractPreferences>(); 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeName = name; 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref = parent; 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock = new Lock(); 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project userNode = root.userNode; 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of all cached child nodes. 172f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of cached child nodes. 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final AbstractPreferences[] cachedChildren() { 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return cachedNode.values().toArray(new AbstractPreferences[cachedNode.size()]); 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the child node with the specified name or {@code null} if it 1815cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * doesn't exist. Implementers can assume that the name supplied to this 1825cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * method will be a valid node name string (conforming to the node naming 1835cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * format) and will not correspond to a node that has been cached or 1845cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * removed. 185f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the desired child node. 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the child node with the given name or {@code null} if it doesn't 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exist. 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AbstractPreferences getChild(String name) 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws BackingStoreException { 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences result = null; 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] childrenNames = childrenNames(); 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < childrenNames.length; i++) { 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (childrenNames[i].equals(name)) { 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = childSpi(name); 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this node has been removed by invoking the method {@code 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removeNode()}. 2145cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true}, if this node has been removed, {@code false} 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected boolean isRemoved() { 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isRemoved; 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Flushes changes of this node to the backing store. This method should 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only flush this node and should not include the descendant nodes. Any 2275cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * implementation that wants to provide functionality to flush all nodes 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * at once should override the method {@link #flush() flush()}. 2295cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void flushSpi() throws BackingStoreException; 235f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2375cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Returns the names of all of the child nodes of this node or an empty 2385cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * array if this node has no children. The names of cached children are not 2395cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * required to be returned. 2405cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the names of this node's children. 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String[] childrenNamesSpi() throws BackingStoreException; 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the child preference node with the given name, creating it 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if it does not exist. The caller of this method should ensure that the 2515cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * given name is valid and that this node has not been removed or cached. 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the named node has just been removed, the implementation 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this method must create a new one instead of reactivating the removed 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one. 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The new creation is not required to be persisted immediately until the 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * flush method will be invoked. 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </p> 259f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the child preference to be returned. 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the child preference node. 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract AbstractPreferences childSpi(String name); 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Puts the given key-value pair into this node. Caller of this method 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * should ensure that both of the given values are valid and that this 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * node has not been removed. 2715cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given preference key. 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given preference value. 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void putSpi(String name, String value); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2805cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Gets the preference value mapped to the given key. The caller of this 2815cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * method should ensure that the given key is valid and that this node has 2825cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * not been removed. This method should not throw any exceptions but if it 2835cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * does, the caller will ignore the exception, regarding it as a {@code 2845cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * null} return value. 2855cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given key to be searched for. 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the preference value mapped to the given key. 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String getSpi(String key); 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of all preference keys of this node or an empty array if 2955cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * no preferences have been found. The caller of this method should ensure 2965cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * that this node has not been removed. 2975cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of all preference keys. 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String[] keysSpi() throws BackingStoreException; 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes this node from the preference hierarchy tree. The caller of this 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method should ensure that this node has no child nodes, which means the 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method {@link Preferences#removeNode() Preferences.removeNode()} should 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invoke this method multiple-times in bottom-up pattern. The removal is 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not required to be persisted until after it is flushed. 3115cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void removeNodeSpi() throws BackingStoreException; 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes the preference with the specified key. The caller of this method 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * should ensure that the given key is valid and that this node has not been 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removed. 322f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key of the preference that is to be removed. 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void removeSpi(String key); 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Synchronizes this node with the backing store. This method should only 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * synchronize this node and should not include the descendant nodes. An 3315cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * implementation that wants to provide functionality to synchronize all 3325cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * nodes at once should override the method {@link #sync() sync()}. 333f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void syncSpi() throws BackingStoreException; 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods inherited from Preferences 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String absolutePath() { 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentPref == null) { 34803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return "/"; 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (parentPref == root) { 35003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return "/" + nodeName; 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 35203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return parentPref.absolutePath() + "/" + nodeName; 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] childrenNames() throws BackingStoreException { 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project TreeSet<String> result = new TreeSet<String>(cachedNode.keySet()); 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] names = childrenNamesSpi(); 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < names.length; i++) { 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(names[i]); 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3645cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return result.toArray(new String[result.size()]); 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() throws BackingStoreException { 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] keyList = keys(); 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < keyList.length; i++) { 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project remove(keyList[i]); 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 37903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes public void exportNode(OutputStream ostream) throws IOException, BackingStoreException { 38003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (ostream == null) { 38103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new NullPointerException("Stream is null"); 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project XMLParser.exportPrefs(this, ostream, false); 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 38803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes public void exportSubtree(OutputStream ostream) throws IOException, BackingStoreException { 38903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (ostream == null) { 39003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new NullPointerException("Stream is null"); 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project XMLParser.exportPrefs(this, ostream, true); 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void flush() throws BackingStoreException { 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project flushSpi(); 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences[] cc = cachedChildren(); 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i; 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (i = 0; i < cc.length; i++) { 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cc[i].flush(); 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String get(String key, String deflt) { 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key == null) { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4135cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson String result = null; 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = getSpi(key); 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 4195cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignored 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (result == null ? deflt : result); 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getBoolean(String key, boolean deflt) { 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 4305cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 43103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if ("true".equalsIgnoreCase(result)) { 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 43303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } else if ("false".equalsIgnoreCase(result)) { 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getByteArray(String key, byte[] deflt) { 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String svalue = get(key, null); 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (svalue == null) { 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 446f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (svalue.length() == 0) { 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new byte[0]; 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 450e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes byte[] bavalue = svalue.getBytes(Charsets.US_ASCII); 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bavalue.length % 4 != 0) { 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4545cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Base64.decode(bavalue); 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 4565cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public double getDouble(String key, double deflt) { 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4675cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Double.parseDouble(result); 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4695cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public float getFloat(String key, float deflt) { 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4805cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Float.parseFloat(result); 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4825cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getInt(String key, int deflt) { 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4935cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Integer.parseInt(result); 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4955cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getLong(String key, long deflt) { 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 5065cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Long.parseLong(result); 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 5085cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isUserNode() { 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return root == Preferences.userRoot(); 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] keys() throws BackingStoreException { 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return keysSpi(); 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String name() { 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return nodeName; 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Preferences node(String name) { 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences startNode = null; 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validateName(name); 53680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes if (name.isEmpty()) { 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 53803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } else if ("/".equals(name)) { 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return root; 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 54103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.startsWith("/")) { 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = root; 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.substring(1); 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = this; 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 5495cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return startNode.nodeImpl(name, true); 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (BackingStoreException e) { 5515cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // should not happen 5525cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return null; 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void validateName(String name) { 55703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.endsWith("/") && name.length() > 1) { 55803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name cannot end with '/'"); 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 56003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.indexOf("//") >= 0) { 56103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name cannot contain consecutive '/' characters"); 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences nodeImpl(String path, boolean createNew) 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws BackingStoreException { 567fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes String[] names = path.split("/"); 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences currentNode = this; 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences temp = null; 5705cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (null != currentNode) { 5715cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson for (int i = 0; i < names.length; i++) { 5725cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson String name = names[i]; 5735cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson synchronized (currentNode.lock) { 5745cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson temp = currentNode.cachedNode.get(name); 5755cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (temp == null) { 5765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson temp = getNodeFromBackend(createNew, currentNode, name); 5775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 5785cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 5795cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson currentNode = temp; 5805cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (null == currentNode) { 5815cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson break; 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return currentNode; 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences getNodeFromBackend(boolean createNew, 58903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes AbstractPreferences currentNode, String name) throws BackingStoreException { 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name.length() > MAX_NAME_LENGTH) { 59103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name '" + name + "' too long"); 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 5935cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson AbstractPreferences temp; 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (createNew) { 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project temp = currentNode.childSpi(name); 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentNode.cachedNode.put(name, temp); 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (temp.newNode && currentNode.nodeChangeListeners.size() > 0) { 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentNode.notifyChildAdded(temp); 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project temp = currentNode.getChild(name); 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return temp; 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean nodeExists(String name) throws BackingStoreException { 6085cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (null == name) { 6095cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson throw new NullPointerException(); 6105cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences startNode = null; 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isRemoved()) { 61403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.isEmpty()) { 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 61703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalStateException("This node has been removed"); 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validateName(name); 62003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.isEmpty() || "/".equals(name)) { 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 62303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.startsWith("/")) { 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = root; 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.substring(1); 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = this; 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences result = startNode.nodeImpl(name, false); 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null == result ? false : true; 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch(IllegalArgumentException e) { 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Preferences parent() { 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return parentPref; 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkState() { 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isRemoved()) { 64603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalStateException("This node has been removed"); 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void put(String key, String value) { 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == key || null == value) { 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key.length() > MAX_KEY_LENGTH || value.length() > MAX_VALUE_LENGTH) { 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project putSpi(key, value); 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project notifyPreferenceChange(key, value); 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putBoolean(String key, boolean value) { 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = String.valueOf(value); 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putByteArray(String key, byte[] value) { 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 67403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes put(key, Base64.encode(value, "US-ASCII")); 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (UnsupportedEncodingException e) { 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new AssertionError(e); 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putDouble(String key, double value) { 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Double.toString(value); 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putFloat(String key, float value) { 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Float.toString(value); 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putInt(String key, int value) { 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Integer.toString(value); 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putLong(String key, long value) { 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Long.toString(value); 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void remove(String key) { 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeSpi(key); 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project notifyPreferenceChange(key, null); 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeNode() throws BackingStoreException { 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (root == this) { 71603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new UnsupportedOperationException("Cannot remove root node"); 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (parentPref.lock) { 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeNodeImpl(); 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void removeNodeImpl() throws BackingStoreException { 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] childrenNames = childrenNamesSpi(); 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < childrenNames.length; i++) { 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == cachedNode.get(childrenNames[i])) { 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences child = childSpi(childrenNames[i]); 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cachedNode.put(childrenNames[i], child); 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 733f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 7345cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson final Collection<AbstractPreferences> values = cachedNode.values(); 7355cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson final AbstractPreferences[] children = values.toArray(new AbstractPreferences[values.size()]); 7365cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson for (AbstractPreferences child : children) { 7375cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson child.removeNodeImpl(); 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeNodeSpi(); 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isRemoved = true; 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref.cachedNode.remove(nodeName); 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentPref.nodeChangeListeners.size() > 0) { 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref.notifyChildRemoved(this); 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addNodeChangeListener(NodeChangeListener ncl) { 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == ncl) { 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners.add(ncl); 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addPreferenceChangeListener(PreferenceChangeListener pcl) { 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == pcl) { 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners.add(pcl); 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeNodeChangeListener(NodeChangeListener ncl) { 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos; 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((pos = nodeChangeListeners.indexOf(ncl)) == -1) { 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners.remove(pos); 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removePreferenceChangeListener(PreferenceChangeListener pcl) { 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos; 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((pos = preferenceChangeListeners.indexOf(pcl)) == -1) { 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners.remove(pos); 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void sync() throws BackingStoreException { 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project syncSpi(); 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes for (AbstractPreferences child : cachedChildren()) { 80103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes child.sync(); 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project StringBuffer sb = new StringBuffer(); 80803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes sb.append(isUserNode() ? "User" : "System"); 80903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes sb.append(" Preference Node: "); 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sb.append(absolutePath()); 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sb.toString(); 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyChildAdded(Preferences child) { 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeEvent nce = new NodeAddEvent(this, child); 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(nce); 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyChildRemoved(Preferences child) { 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeEvent nce = new NodeRemoveEvent(this, child); 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(nce); 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyPreferenceChange(String key, String newValue) { 83103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes PreferenceChangeEvent pce = new PreferenceChangeEvent(this, key, newValue); 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(pce); 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class EventDispatcher extends Thread { 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventDispatcher(String name){ 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(name); 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 842f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void run() { 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventObject event = null; 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project event = getEventObject(); 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InterruptedException e) { 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e.printStackTrace(); 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences pref = (AbstractPreferences) event 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getSource(); 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (event instanceof NodeAddEvent) { 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchNodeAdd((NodeChangeEvent) event, 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.nodeChangeListeners); 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (event instanceof NodeRemoveEvent) { 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchNodeRemove((NodeChangeEvent) event, 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.nodeChangeListeners); 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (event instanceof PreferenceChangeEvent) { 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchPrefChange((PreferenceChangeEvent) event, 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.preferenceChangeListeners); 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private EventObject getEventObject() throws InterruptedException { 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (events.isEmpty()) { 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.wait(); 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventObject event = events.get(0); 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.remove(0); 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return event; 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchPrefChange(PreferenceChangeEvent event, 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> preferenceChangeListeners) { 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<EventListener> i = preferenceChangeListeners.iterator(); 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (i.hasNext()) { 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project PreferenceChangeListener pcl = (PreferenceChangeListener) i 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .next(); 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pcl.preferenceChange(event); 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchNodeRemove(NodeChangeEvent event, 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> nodeChangeListeners) { 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<EventListener> i = nodeChangeListeners.iterator(); 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (i.hasNext()) { 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeListener ncl = (NodeChangeListener) i.next(); 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ncl.childRemoved(event); 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchNodeAdd(NodeChangeEvent event, 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> nodeChangeListeners) { 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<EventListener> i = nodeChangeListeners.iterator(); 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (i.hasNext()) { 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeListener ncl = (NodeChangeListener) i.next(); 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ncl.childAdded(event); 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class NodeAddEvent extends NodeChangeEvent { 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //The base class is NOT serializable, so this class isn't either. 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 1L; 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeAddEvent(Preferences p, Preferences c) { 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(p, c); 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class NodeRemoveEvent extends NodeChangeEvent { 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //The base class is NOT serializable, so this class isn't either. 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 1L; 926f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeRemoveEvent(Preferences p, Preferences c) { 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(p, c); 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 932