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