1 /******************************************************************************* 2 * Copyright (c) 2004, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.core.runtime.preferences; 15 16 import java.util.EventObject; 17 import org.osgi.service.prefs.BackingStoreException; 18 import org.osgi.service.prefs.Preferences; 19 20 /** 21 * This interface describes Eclipse extensions to the preference 22 * story. It provides means for both preference and node change 23 * listeners. 24 * <p> 25 * Clients may implement this interface. 26 * </p> 27 * 28 * @see org.osgi.service.prefs.Preferences 29 * @since 3.0 30 */ 31 public interface IEclipsePreferences extends Preferences { 32 33 /** 34 * An event object which describes the details of a change in the 35 * preference node hierarchy. The child node is the one which 36 * was added or removed. 37 * 38 * @see IEclipsePreferences.INodeChangeListener 39 * @since 3.0 40 */ 41 public final class NodeChangeEvent extends EventObject { 42 /** 43 * All serializable objects should have a stable serialVersionUID 44 */ 45 private static final long serialVersionUID = 1L; 46 47 private Preferences child; 48 49 /** 50 * Constructor for a new node change event object. 51 * 52 * @param parent the parent node 53 * @param child the child node 54 */ NodeChangeEvent(Preferences parent, Preferences child)55 public NodeChangeEvent(Preferences parent, Preferences child) { 56 super(parent); 57 this.child = child; 58 } 59 60 /** 61 * Return the parent node for this event. This is the parent 62 * of the node which was added or removed. 63 * 64 * @return the parent node 65 */ getParent()66 public Preferences getParent() { 67 return (Preferences) getSource(); 68 } 69 70 /** 71 * Return the child node for this event. This is the node 72 * which was added or removed. 73 * <p> 74 * Note: The child node may have been removed as a result of 75 * the bundle supplying its implementation being un-installed. In this case 76 * the only method which can safely be called on the child is #name(). 77 * </p> 78 * @return the child node 79 */ getChild()80 public Preferences getChild() { 81 return child; 82 } 83 } 84 85 /** 86 * A listener to be used to receive preference node change events. 87 * <p> 88 * Clients may implement this interface. 89 * </p> 90 * 91 * @since 3.0 92 */ 93 public interface INodeChangeListener { 94 95 /** 96 * Notification that a child node was added to the preference hierarchy. 97 * The given event must not be <code>null</code>. 98 * 99 * @param event an event specifying the details about the new node 100 * @see IEclipsePreferences.NodeChangeEvent 101 * @see IEclipsePreferences#addNodeChangeListener(IEclipsePreferences.INodeChangeListener) 102 * @see IEclipsePreferences#removeNodeChangeListener(IEclipsePreferences.INodeChangeListener) 103 */ added(NodeChangeEvent event)104 public void added(NodeChangeEvent event); 105 106 /** 107 * Notification that a child node was removed from the preference hierarchy. 108 * The given event must not be <code>null</code>. 109 * 110 * @param event an event specifying the details about the removed node 111 * @see IEclipsePreferences.NodeChangeEvent 112 * @see IEclipsePreferences#addNodeChangeListener(IEclipsePreferences.INodeChangeListener) 113 * @see IEclipsePreferences#removeNodeChangeListener(IEclipsePreferences.INodeChangeListener) 114 */ removed(NodeChangeEvent event)115 public void removed(NodeChangeEvent event); 116 } 117 118 /** 119 * An event object describing the details of a change to a preference 120 * in the preference store. 121 * 122 * @see IEclipsePreferences.IPreferenceChangeListener 123 * @since 3.0 124 */ 125 public final class PreferenceChangeEvent extends EventObject { 126 /** 127 * All serializable objects should have a stable serialVersionUID 128 */ 129 private static final long serialVersionUID = 1L; 130 131 private String key; 132 private Object newValue; 133 private Object oldValue; 134 135 /** 136 * Constructor for a new preference change event. The node and the 137 * key must not be <code>null</code>. The old and new preference 138 * values must be either a <code>String</code> or <code>null</code>. 139 * 140 * @param node the node on which the change occurred 141 * @param key the preference key 142 * @param oldValue the old preference value, as a <code>String</code> 143 * or <code>null</code> 144 * @param newValue the new preference value, as a <code>String</code> 145 * or <code>null</code> 146 */ PreferenceChangeEvent(Object node, String key, Object oldValue, Object newValue)147 public PreferenceChangeEvent(Object node, String key, Object oldValue, Object newValue) { 148 super(node); 149 if (key == null || !(node instanceof Preferences)) 150 throw new IllegalArgumentException(); 151 this.key = key; 152 this.newValue = newValue; 153 this.oldValue = oldValue; 154 } 155 156 /** 157 * Return the preference node on which the change occurred. 158 * Must not be <code>null</code>. 159 * 160 * @return the node 161 */ getNode()162 public Preferences getNode() { 163 return (Preferences) source; 164 } 165 166 /** 167 * Return the key of the preference which was changed. 168 * Must not be <code>null</code>. 169 * 170 * @return the preference key 171 */ getKey()172 public String getKey() { 173 return key; 174 } 175 176 /** 177 * Return the new value for the preference encoded as a 178 * <code>String</code>, or <code>null</code> if the 179 * preference was removed. 180 * 181 * @return the new value or <code>null</code> 182 */ getNewValue()183 public Object getNewValue() { 184 return newValue; 185 } 186 187 /** 188 * Return the old value for the preference encoded as a 189 * <code>String</code>, or <code>null</code> if the 190 * preference was removed or if it cannot be determined. 191 * 192 * @return the old value or <code>null</code> 193 */ getOldValue()194 public Object getOldValue() { 195 return oldValue; 196 } 197 } 198 199 /** 200 * A listener used to receive changes to preference values in the preference store. 201 * <p> 202 * Clients may implement this interface. 203 * </p> 204 * 205 * @since 3.0 206 */ 207 public interface IPreferenceChangeListener { 208 209 /** 210 * Notification that a preference value has changed in the preference store. 211 * The given event object describes the change details and must not 212 * be <code>null</code>. 213 * 214 * @param event the event details 215 * @see IEclipsePreferences.PreferenceChangeEvent 216 * @see IEclipsePreferences#addPreferenceChangeListener(IEclipsePreferences.IPreferenceChangeListener) 217 * @see IEclipsePreferences#removePreferenceChangeListener(IEclipsePreferences.IPreferenceChangeListener) 218 */ preferenceChange(PreferenceChangeEvent event)219 public void preferenceChange(PreferenceChangeEvent event); 220 } 221 222 /** 223 * Register the given listener for changes to this node. Duplicate calls 224 * to this method with the same listener will have no effect. The given 225 * listener argument must not be <code>null</code>. 226 * 227 * @param listener the node change listener to add 228 * @throws IllegalStateException if this node or an ancestor has been removed 229 * @see #removeNodeChangeListener(IEclipsePreferences.INodeChangeListener) 230 * @see IEclipsePreferences.INodeChangeListener 231 */ addNodeChangeListener(INodeChangeListener listener)232 public void addNodeChangeListener(INodeChangeListener listener); 233 234 /** 235 * De-register the given listener from receiving event change notifications 236 * for this node. Calling this method with a listener which is not registered 237 * has no effect. The given listener argument must not be <code>null</code>. 238 * 239 * @param listener the node change listener to remove 240 * @throws IllegalStateException if this node or an ancestor has been removed 241 * @see #addNodeChangeListener(IEclipsePreferences.INodeChangeListener) 242 * @see IEclipsePreferences.INodeChangeListener 243 */ removeNodeChangeListener(INodeChangeListener listener)244 public void removeNodeChangeListener(INodeChangeListener listener); 245 246 /** 247 * Register the given listener for notification of preference changes to this node. 248 * Calling this method multiple times with the same listener has no effect. The 249 * given listener argument must not be <code>null</code>. 250 * 251 * @param listener the preference change listener to register 252 * @throws IllegalStateException if this node or an ancestor has been removed 253 * @see #removePreferenceChangeListener(IEclipsePreferences.IPreferenceChangeListener) 254 * @see IEclipsePreferences.IPreferenceChangeListener 255 */ addPreferenceChangeListener(IPreferenceChangeListener listener)256 public void addPreferenceChangeListener(IPreferenceChangeListener listener); 257 258 /** 259 * De-register the given listener from receiving notification of preference changes 260 * to this node. Calling this method multiple times with the same listener has no 261 * effect. The given listener argument must not be <code>null</code>. 262 * 263 * @param listener the preference change listener to remove 264 * @throws IllegalStateException if this node or an ancestor has been removed 265 * @see #addPreferenceChangeListener(IEclipsePreferences.IPreferenceChangeListener) 266 * @see IEclipsePreferences.IPreferenceChangeListener 267 */ removePreferenceChangeListener(IPreferenceChangeListener listener)268 public void removePreferenceChangeListener(IPreferenceChangeListener listener); 269 270 /** 271 * Remove this node from the preference hierarchy. If this node is the scope 272 * root, then do not remove this node, only remove this node's children. 273 * <p> 274 * Functionally equivalent to calling {@link Preferences#removeNode()}. 275 * See the spec of {@link Preferences#removeNode()} for more details. 276 * </p> 277 * <p> 278 * Implementors must send the appropriate {@link NodeChangeEvent} 279 * to listeners who are registered on this node's parent. 280 * </p> 281 * <p> 282 * When this node is removed, its associated preference and node change 283 * listeners should be removed as well. 284 * </p> 285 * @throws BackingStoreException if there was a problem removing this node 286 * @see org.osgi.service.prefs.Preferences#removeNode() 287 * @see NodeChangeEvent 288 */ 289 @Override removeNode()290 public void removeNode() throws BackingStoreException; 291 292 /** 293 * Return the preferences node with the given path. The given path must 294 * not be <code>null</code>. 295 * <p> 296 * See the spec of {@link Preferences#node(String)} for more details. 297 * </p> 298 * <p> 299 * Note that if the node does not yet exist and is created, then the appropriate 300 * {@link NodeChangeEvent} must be sent to listeners who are 301 * registered at this node. 302 * </p> 303 * @param path the path of the node 304 * @return the node 305 * @see org.osgi.service.prefs.Preferences#node(String) 306 * @see NodeChangeEvent 307 */ 308 @Override node(String path)309 public Preferences node(String path); 310 311 /** 312 * Accepts the given visitor. The visitor's <code>visit</code> method 313 * is called with this node. If the visitor returns <code>true</code>, 314 * this method visits this node's children. 315 * 316 * @param visitor the visitor 317 * @see IPreferenceNodeVisitor#visit(IEclipsePreferences) 318 * @throws BackingStoreException if this operation cannot be completed due 319 * to a failure in the backing store, or inability to communicate 320 * with it. 321 */ accept(IPreferenceNodeVisitor visitor)322 public void accept(IPreferenceNodeVisitor visitor) throws BackingStoreException; 323 } 324