AbstractPreferences.java revision 693eacca9fa67ad79d1b35dbaad61c5ac1ac457c
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.prefs; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream; 22e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughesimport java.nio.charset.Charsets; 235cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilsonimport java.util.Collection; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.EventListener; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.EventObject; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashMap; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.LinkedList; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Map; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.TreeSet; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Base64; 33693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughesimport libcore.base.EmptyArray; 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 */ 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The object used to lock this node. 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final Object lock; 99f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This field is true if this node is created while it doesn't exist in the 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * backing store. This field's default value is false, and it is checked 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * when the node creation is completed, and if it is true, the node change 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * event will be fired for this node's parent. 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected boolean newNode; 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1085cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** cached child nodes */ 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Map<String, AbstractPreferences> cachedNode; 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //the collections of listeners 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<EventListener> nodeChangeListeners; 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<EventListener> preferenceChangeListeners; 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //this node's name 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String nodeName; 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //handler to this node's parent 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences parentPref; 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //true if this node has been removed 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isRemoved; 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //handler to this node's root node 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences root; 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructors 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1335cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Constructs a new {@code AbstractPreferences} instance using the given 1345cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * parent node and node name. 1355cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param parent 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parent node of the new node or {@code null} to indicate 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that the new node is a root node. 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the new node or an empty string to indicate that 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this node is called "root". 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the name contains a slash character or is empty if {@code 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parent} is not {@code null}. 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AbstractPreferences(AbstractPreferences parent, String name) { 14703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if ((null == parent ^ name.length() == 0) || name.indexOf("/") >= 0) { 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project root = null == parent ? this : parent.root; 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners = new LinkedList<EventListener>(); 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners = new LinkedList<EventListener>(); 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isRemoved = false; 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cachedNode = new HashMap<String, AbstractPreferences>(); 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeName = name; 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref = parent; 1575e23b687ef8b3c696d54d1880b454942875665b7Elliott Hughes lock = new Object(); 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project userNode = root.userNode; 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of all cached child nodes. 168f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of cached child nodes. 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final AbstractPreferences[] cachedChildren() { 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return cachedNode.values().toArray(new AbstractPreferences[cachedNode.size()]); 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the child node with the specified name or {@code null} if it 1775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * doesn't exist. Implementers can assume that the name supplied to this 1785cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * method will be a valid node name string (conforming to the node naming 1795cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * format) and will not correspond to a node that has been cached or 1805cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * removed. 181f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the desired child node. 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the child node with the given name or {@code null} if it doesn't 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exist. 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AbstractPreferences getChild(String name) 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws BackingStoreException { 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences result = null; 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] childrenNames = childrenNames(); 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < childrenNames.length; i++) { 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (childrenNames[i].equals(name)) { 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = childSpi(name); 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this node has been removed by invoking the method {@code 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removeNode()}. 2105cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true}, if this node has been removed, {@code false} 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected boolean isRemoved() { 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isRemoved; 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Flushes changes of this node to the backing store. This method should 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only flush this node and should not include the descendant nodes. Any 2235cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * implementation that wants to provide functionality to flush all nodes 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * at once should override the method {@link #flush() flush()}. 2255cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void flushSpi() throws BackingStoreException; 231f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2335cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Returns the names of all of the child nodes of this node or an empty 2345cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * array if this node has no children. The names of cached children are not 2355cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * required to be returned. 2365cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the names of this node's children. 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String[] childrenNamesSpi() throws BackingStoreException; 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the child preference node with the given name, creating it 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if it does not exist. The caller of this method should ensure that the 2475cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * given name is valid and that this node has not been removed or cached. 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the named node has just been removed, the implementation 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this method must create a new one instead of reactivating the removed 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one. 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The new creation is not required to be persisted immediately until the 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * flush method will be invoked. 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </p> 255f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the child preference to be returned. 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the child preference node. 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract AbstractPreferences childSpi(String name); 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Puts the given key-value pair into this node. Caller of this method 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * should ensure that both of the given values are valid and that this 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * node has not been removed. 2675cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given preference key. 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given preference value. 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void putSpi(String name, String value); 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Gets the preference value mapped to the given key. The caller of this 2775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * method should ensure that the given key is valid and that this node has 2785cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * not been removed. This method should not throw any exceptions but if it 2795cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * does, the caller will ignore the exception, regarding it as a {@code 2805cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * null} return value. 2815cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given key to be searched for. 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the preference value mapped to the given key. 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String getSpi(String key); 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of all preference keys of this node or an empty array if 2915cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * no preferences have been found. The caller of this method should ensure 2925cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * that this node has not been removed. 2935cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of all preference keys. 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String[] keysSpi() throws BackingStoreException; 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes this node from the preference hierarchy tree. The caller of this 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method should ensure that this node has no child nodes, which means the 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method {@link Preferences#removeNode() Preferences.removeNode()} should 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invoke this method multiple-times in bottom-up pattern. The removal is 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not required to be persisted until after it is flushed. 3075cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void removeNodeSpi() throws BackingStoreException; 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes the preference with the specified key. The caller of this method 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * should ensure that the given key is valid and that this node has not been 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removed. 318f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key of the preference that is to be removed. 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void removeSpi(String key); 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Synchronizes this node with the backing store. This method should only 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * synchronize this node and should not include the descendant nodes. An 3275cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * implementation that wants to provide functionality to synchronize all 3285cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * nodes at once should override the method {@link #sync() sync()}. 329f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void syncSpi() throws BackingStoreException; 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods inherited from Preferences 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String absolutePath() { 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentPref == null) { 34403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return "/"; 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (parentPref == root) { 34603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return "/" + nodeName; 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 34803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return parentPref.absolutePath() + "/" + nodeName; 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] childrenNames() throws BackingStoreException { 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project TreeSet<String> result = new TreeSet<String>(cachedNode.keySet()); 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] names = childrenNamesSpi(); 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < names.length; i++) { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(names[i]); 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3605cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return result.toArray(new String[result.size()]); 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() throws BackingStoreException { 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] keyList = keys(); 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < keyList.length; i++) { 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project remove(keyList[i]); 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 37503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes public void exportNode(OutputStream ostream) throws IOException, BackingStoreException { 37603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (ostream == null) { 37703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new NullPointerException("Stream is null"); 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project XMLParser.exportPrefs(this, ostream, false); 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 38403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes public void exportSubtree(OutputStream ostream) throws IOException, BackingStoreException { 38503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (ostream == null) { 38603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new NullPointerException("Stream is null"); 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project XMLParser.exportPrefs(this, ostream, true); 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void flush() throws BackingStoreException { 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project flushSpi(); 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences[] cc = cachedChildren(); 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i; 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (i = 0; i < cc.length; i++) { 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cc[i].flush(); 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String get(String key, String deflt) { 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key == null) { 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4095cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson String result = null; 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = getSpi(key); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 4155cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignored 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (result == null ? deflt : result); 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getBoolean(String key, boolean deflt) { 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 4265cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 42703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if ("true".equalsIgnoreCase(result)) { 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 42903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } else if ("false".equalsIgnoreCase(result)) { 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getByteArray(String key, byte[] deflt) { 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String svalue = get(key, null); 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (svalue == null) { 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 442f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (svalue.length() == 0) { 443693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes return EmptyArray.BYTE; 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 446e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes byte[] bavalue = svalue.getBytes(Charsets.US_ASCII); 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bavalue.length % 4 != 0) { 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4505cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Base64.decode(bavalue); 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 4525cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public double getDouble(String key, double deflt) { 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4635cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Double.parseDouble(result); 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4655cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public float getFloat(String key, float deflt) { 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Float.parseFloat(result); 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4785cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getInt(String key, int deflt) { 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4895cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Integer.parseInt(result); 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4915cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getLong(String key, long deflt) { 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 5025cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Long.parseLong(result); 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 5045cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isUserNode() { 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return root == Preferences.userRoot(); 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] keys() throws BackingStoreException { 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return keysSpi(); 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String name() { 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return nodeName; 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Preferences node(String name) { 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences startNode = null; 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validateName(name); 53280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes if (name.isEmpty()) { 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 53403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } else if ("/".equals(name)) { 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return root; 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 53703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.startsWith("/")) { 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = root; 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.substring(1); 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = this; 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 5455cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return startNode.nodeImpl(name, true); 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (BackingStoreException e) { 5475cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // should not happen 5485cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return null; 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void validateName(String name) { 55303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.endsWith("/") && name.length() > 1) { 55403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name cannot end with '/'"); 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 55603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.indexOf("//") >= 0) { 55703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name cannot contain consecutive '/' characters"); 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences nodeImpl(String path, boolean createNew) 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws BackingStoreException { 563fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes String[] names = path.split("/"); 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences currentNode = this; 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences temp = null; 5665cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (null != currentNode) { 5675cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson for (int i = 0; i < names.length; i++) { 5685cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson String name = names[i]; 5695cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson synchronized (currentNode.lock) { 5705cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson temp = currentNode.cachedNode.get(name); 5715cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (temp == null) { 5725cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson temp = getNodeFromBackend(createNew, currentNode, name); 5735cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 5745cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 5755cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson currentNode = temp; 5765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (null == currentNode) { 5775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson break; 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return currentNode; 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences getNodeFromBackend(boolean createNew, 58503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes AbstractPreferences currentNode, String name) throws BackingStoreException { 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name.length() > MAX_NAME_LENGTH) { 58703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name '" + name + "' too long"); 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 5895cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson AbstractPreferences temp; 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (createNew) { 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project temp = currentNode.childSpi(name); 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentNode.cachedNode.put(name, temp); 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (temp.newNode && currentNode.nodeChangeListeners.size() > 0) { 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentNode.notifyChildAdded(temp); 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project temp = currentNode.getChild(name); 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return temp; 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean nodeExists(String name) throws BackingStoreException { 6045cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson if (null == name) { 6055cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson throw new NullPointerException(); 6065cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences startNode = null; 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isRemoved()) { 61003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.isEmpty()) { 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 61303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalStateException("This node has been removed"); 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validateName(name); 61603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.isEmpty() || "/".equals(name)) { 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 61903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.startsWith("/")) { 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = root; 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.substring(1); 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = this; 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences result = startNode.nodeImpl(name, false); 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null == result ? false : true; 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch(IllegalArgumentException e) { 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Preferences parent() { 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return parentPref; 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkState() { 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isRemoved()) { 64203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalStateException("This node has been removed"); 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void put(String key, String value) { 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == key || null == value) { 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key.length() > MAX_KEY_LENGTH || value.length() > MAX_VALUE_LENGTH) { 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project putSpi(key, value); 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project notifyPreferenceChange(key, value); 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putBoolean(String key, boolean value) { 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = String.valueOf(value); 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putByteArray(String key, byte[] value) { 669b1b8fbeeae579e9f49c41166bb5d9b2e60b75438Elliott Hughes put(key, Base64.encode(value, Charsets.US_ASCII)); 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putDouble(String key, double value) { 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Double.toString(value); 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putFloat(String key, float value) { 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Float.toString(value); 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putInt(String key, int value) { 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Integer.toString(value); 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putLong(String key, long value) { 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String sval = Long.toString(value); 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project put(key, sval); 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void remove(String key) { 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeSpi(key); 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project notifyPreferenceChange(key, null); 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeNode() throws BackingStoreException { 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (root == this) { 70803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new UnsupportedOperationException("Cannot remove root node"); 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (parentPref.lock) { 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeNodeImpl(); 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void removeNodeImpl() throws BackingStoreException { 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] childrenNames = childrenNamesSpi(); 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < childrenNames.length; i++) { 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == cachedNode.get(childrenNames[i])) { 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences child = childSpi(childrenNames[i]); 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cachedNode.put(childrenNames[i], child); 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 725f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 7265cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson final Collection<AbstractPreferences> values = cachedNode.values(); 7275cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson final AbstractPreferences[] children = values.toArray(new AbstractPreferences[values.size()]); 7285cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson for (AbstractPreferences child : children) { 7295cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson child.removeNodeImpl(); 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeNodeSpi(); 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isRemoved = true; 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref.cachedNode.remove(nodeName); 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentPref.nodeChangeListeners.size() > 0) { 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref.notifyChildRemoved(this); 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addNodeChangeListener(NodeChangeListener ncl) { 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == ncl) { 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners.add(ncl); 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addPreferenceChangeListener(PreferenceChangeListener pcl) { 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (null == pcl) { 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners.add(pcl); 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeNodeChangeListener(NodeChangeListener ncl) { 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos; 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((pos = nodeChangeListeners.indexOf(ncl)) == -1) { 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners.remove(pos); 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removePreferenceChangeListener(PreferenceChangeListener pcl) { 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos; 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((pos = preferenceChangeListeners.indexOf(pcl)) == -1) { 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners.remove(pos); 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void sync() throws BackingStoreException { 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project syncSpi(); 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 79203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes for (AbstractPreferences child : cachedChildren()) { 79303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes child.sync(); 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 799328f533a177f7579a9ea916f5569053ec9c149b8Elliott Hughes return (isUserNode() ? "User" : "System") + " Preference Node: " + absolutePath(); 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyChildAdded(Preferences child) { 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeEvent nce = new NodeAddEvent(this, child); 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(nce); 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyChildRemoved(Preferences child) { 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeEvent nce = new NodeRemoveEvent(this, child); 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(nce); 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyPreferenceChange(String key, String newValue) { 81903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes PreferenceChangeEvent pce = new PreferenceChangeEvent(this, key, newValue); 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(pce); 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class EventDispatcher extends Thread { 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventDispatcher(String name){ 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(name); 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 830f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void run() { 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventObject event = null; 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project event = getEventObject(); 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InterruptedException e) { 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e.printStackTrace(); 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences pref = (AbstractPreferences) event 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .getSource(); 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (event instanceof NodeAddEvent) { 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchNodeAdd((NodeChangeEvent) event, 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.nodeChangeListeners); 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (event instanceof NodeRemoveEvent) { 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchNodeRemove((NodeChangeEvent) event, 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.nodeChangeListeners); 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (event instanceof PreferenceChangeEvent) { 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchPrefChange((PreferenceChangeEvent) event, 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.preferenceChangeListeners); 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private EventObject getEventObject() throws InterruptedException { 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (events.isEmpty()) { 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.wait(); 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventObject event = events.get(0); 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.remove(0); 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return event; 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchPrefChange(PreferenceChangeEvent event, 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> preferenceChangeListeners) { 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<EventListener> i = preferenceChangeListeners.iterator(); 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (i.hasNext()) { 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project PreferenceChangeListener pcl = (PreferenceChangeListener) i 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .next(); 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pcl.preferenceChange(event); 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchNodeRemove(NodeChangeEvent event, 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> nodeChangeListeners) { 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Iterator<EventListener> i = nodeChangeListeners.iterator(); 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (i.hasNext()) { 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeListener ncl = (NodeChangeListener) i.next(); 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ncl.childRemoved(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 dispatchNodeAdd(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.childAdded(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 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class NodeAddEvent extends NodeChangeEvent { 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //The base class is NOT serializable, so this class isn't either. 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 1L; 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeAddEvent(Preferences p, Preferences c) { 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(p, c); 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class NodeRemoveEvent extends NodeChangeEvent { 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //The base class is NOT serializable, so this class isn't either. 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 1L; 914f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeRemoveEvent(Preferences p, Preferences c) { 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(p, c); 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 920