KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > resources > PathVariableManager


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.resources;
12
13 import java.net.URI JavaDoc;
14 import java.util.*;
15 import org.eclipse.core.filesystem.URIUtil;
16 import org.eclipse.core.internal.events.PathVariableChangeEvent;
17 import org.eclipse.core.internal.utils.Messages;
18 import org.eclipse.core.resources.*;
19 import org.eclipse.core.runtime.*;
20 import org.eclipse.osgi.util.NLS;
21
22 /**
23  * Core's implementation of IPathVariableManager.
24  */

25 public class PathVariableManager implements IPathVariableManager, IManager {
26
27     static final String JavaDoc VARIABLE_PREFIX = "pathvariable."; //$NON-NLS-1$
28
private Set listeners;
29
30     private Preferences preferences;
31
32     /**
33      * Constructor for the class.
34      */

35     public PathVariableManager() {
36         this.listeners = Collections.synchronizedSet(new HashSet());
37         this.preferences = ResourcesPlugin.getPlugin().getPluginPreferences();
38     }
39
40     /**
41      * @see org.eclipse.core.resources.
42      * IPathVariableManager#addChangeListener(IPathVariableChangeListener)
43      */

44     public void addChangeListener(IPathVariableChangeListener listener) {
45         listeners.add(listener);
46     }
47
48     /**
49      * Throws a runtime exception if the given name is not valid as a path
50      * variable name.
51      */

52     private void checkIsValidName(String JavaDoc name) throws CoreException {
53         IStatus status = validateName(name);
54         if (!status.isOK())
55             throw new CoreException(status);
56     }
57
58     /**
59      * Throws an exception if the given path is not valid as a path variable
60      * value.
61      */

62     private void checkIsValidValue(IPath newValue) throws CoreException {
63         IStatus status = validateValue(newValue);
64         if (!status.isOK())
65             throw new CoreException(status);
66     }
67
68     /**
69      * Fires a property change event corresponding to a change to the
70      * current value of the variable with the given name.
71      *
72      * @param name the name of the variable, to be used as the variable
73      * in the event object
74      * @param value the current value of the path variable or <code>null</code> if
75      * the variable was deleted
76      * @param type one of <code>IPathVariableChangeEvent.VARIABLE_CREATED</code>,
77      * <code>IPathVariableChangeEvent.VARIABLE_CHANGED</code>, or
78      * <code>IPathVariableChangeEvent.VARIABLE_DELETED</code>
79      * @see IPathVariableChangeEvent
80      * @see IPathVariableChangeEvent#VARIABLE_CREATED
81      * @see IPathVariableChangeEvent#VARIABLE_CHANGED
82      * @see IPathVariableChangeEvent#VARIABLE_DELETED
83      */

84     private void fireVariableChangeEvent(String JavaDoc name, IPath value, int type) {
85         if (this.listeners.size() == 0)
86             return;
87         // use a separate collection to avoid interference of simultaneous additions/removals
88
Object JavaDoc[] listenerArray = this.listeners.toArray();
89         final PathVariableChangeEvent pve = new PathVariableChangeEvent(this, name, value, type);
90         for (int i = 0; i < listenerArray.length; ++i) {
91             final IPathVariableChangeListener l = (IPathVariableChangeListener) listenerArray[i];
92             ISafeRunnable job = new ISafeRunnable() {
93                 public void handleException(Throwable JavaDoc exception) {
94                     // already being logged in SafeRunner#run()
95
}
96
97                 public void run() throws Exception JavaDoc {
98                     l.pathVariableChanged(pve);
99                 }
100             };
101             SafeRunner.run(job);
102         }
103     }
104
105     /**
106      * Return a key to use in the Preferences.
107      */

108     private String JavaDoc getKeyForName(String JavaDoc varName) {
109         return VARIABLE_PREFIX + varName;
110     }
111
112     /**
113      * @see org.eclipse.core.resources.IPathVariableManager#getPathVariableNames()
114      */

115     public String JavaDoc[] getPathVariableNames() {
116         List result = new LinkedList();
117         String JavaDoc[] names = preferences.propertyNames();
118         for (int i = 0; i < names.length; i++) {
119             if (names[i].startsWith(VARIABLE_PREFIX)) {
120                 String JavaDoc key = names[i].substring(VARIABLE_PREFIX.length());
121                 // filter out names for preferences which might be valid in the
122
// preference store but does not have valid path variable names
123
// and/or values. We can get in this state if the user has
124
// edited the file on disk or set a preference using the prefix
125
// reserved to path variables (#VARIABLE_PREFIX).
126
// TODO: we may want to look at removing these keys from the
127
// preference store as a garbage collection means
128
if (validateName(key).isOK() && validateValue(getValue(key)).isOK())
129                     result.add(key);
130             }
131         }
132         return (String JavaDoc[]) result.toArray(new String JavaDoc[result.size()]);
133     }
134
135     /**
136      * Note that if a user changes the key in the preferences file to be invalid
137      * and then calls #getValue using that key, they will get the value back for
138      * that. But then if they try and call #setValue using the same key it will throw
139      * an exception. We may want to revisit this behaviour in the future.
140      *
141      * @see org.eclipse.core.resources.IPathVariableManager#getValue(String)
142      */

143     public IPath getValue(String JavaDoc varName) {
144         String JavaDoc key = getKeyForName(varName);
145         String JavaDoc value = preferences.getString(key);
146         return value.length() == 0 ? null : Path.fromPortableString(value);
147     }
148
149     /**
150      * @see org.eclipse.core.resources.IPathVariableManager#isDefined(String)
151      */

152     public boolean isDefined(String JavaDoc varName) {
153         return getValue(varName) != null;
154     }
155
156     /**
157      * @see org.eclipse.core.resources.
158      * IPathVariableManager#removeChangeListener(IPathVariableChangeListener)
159      */

160     public void removeChangeListener(IPathVariableChangeListener listener) {
161         listeners.remove(listener);
162     }
163
164     /**
165      * @see org.eclipse.core.resources.IPathVariableManager#resolvePath(IPath)
166      */

167     public IPath resolvePath(IPath path) {
168         if (path == null || path.segmentCount() == 0 || path.isAbsolute() || path.getDevice() != null)
169             return path;
170         IPath value = getValue(path.segment(0));
171         return value == null ? path : value.append(path.removeFirstSegments(1));
172     }
173
174     public URI JavaDoc resolveURI(URI JavaDoc uri) {
175         if (uri == null || uri.isAbsolute())
176             return uri;
177         IPath raw = new Path(uri.getSchemeSpecificPart());
178         IPath resolved = resolvePath(raw);
179         return raw == resolved ? uri : URIUtil.toURI(resolved);
180     }
181
182     /**
183      * @see org.eclipse.core.resources.IPathVariableManager#setValue(String, IPath)
184      */

185     public void setValue(String JavaDoc varName, IPath newValue) throws CoreException {
186         checkIsValidName(varName);
187         //if the location doesn't have a device, see if the OS will assign one
188
if (newValue != null && newValue.isAbsolute() && newValue.getDevice() == null)
189             newValue = new Path(newValue.toFile().getAbsolutePath());
190         checkIsValidValue(newValue);
191         int eventType;
192         // read previous value and set new value atomically in order to generate the right event
193
synchronized (this) {
194             IPath currentValue = getValue(varName);
195             boolean variableExists = currentValue != null;
196             if (!variableExists && newValue == null)
197                 return;
198             if (variableExists && currentValue.equals(newValue))
199                 return;
200             if (newValue == null) {
201                 preferences.setToDefault(getKeyForName(varName));
202                 eventType = IPathVariableChangeEvent.VARIABLE_DELETED;
203             } else {
204                 preferences.setValue(getKeyForName(varName), newValue.toPortableString());
205                 eventType = variableExists ? IPathVariableChangeEvent.VARIABLE_CHANGED : IPathVariableChangeEvent.VARIABLE_CREATED;
206             }
207         }
208         // notify listeners from outside the synchronized block to avoid deadlocks
209
fireVariableChangeEvent(varName, newValue, eventType);
210     }
211
212     /**
213      * @see org.eclipse.core.internal.resources.IManager#shutdown(IProgressMonitor)
214      */

215     public void shutdown(IProgressMonitor monitor) {
216         // The preferences for this plug-in are saved in the Plugin.shutdown
217
// method so we don't have to do it here.
218
}
219
220     /**
221      * @see org.eclipse.core.internal.resources.IManager#startup(IProgressMonitor)
222      */

223     public void startup(IProgressMonitor monitor) {
224         // since we are accessing the preference store directly, we don't
225
// need to do any setup here.
226
}
227
228     /**
229      * @see org.eclipse.core.resources.IPathVariableManager#validateName(String)
230      */

231     public IStatus validateName(String JavaDoc name) {
232         String JavaDoc message = null;
233         if (name.length() == 0) {
234             message = Messages.pathvar_length;
235             return new ResourceStatus(IResourceStatus.INVALID_VALUE, null, message);
236         }
237
238         char first = name.charAt(0);
239         if (!Character.isLetter(first) && first != '_') {
240             message = NLS.bind(Messages.pathvar_beginLetter, String.valueOf(first));
241             return new ResourceStatus(IResourceStatus.INVALID_VALUE, null, message);
242         }
243
244         for (int i = 1; i < name.length(); i++) {
245             char following = name.charAt(i);
246             if (Character.isWhitespace(following))
247                 return new ResourceStatus(IResourceStatus.INVALID_VALUE, null, Messages.pathvar_whitespace);
248             if (!Character.isLetter(following) && !Character.isDigit(following) && following != '_') {
249                 message = NLS.bind(Messages.pathvar_invalidChar, String.valueOf(following));
250                 return new ResourceStatus(IResourceStatus.INVALID_VALUE, null, message);
251             }
252         }
253         return Status.OK_STATUS;
254     }
255
256     /**
257      * @see IPathVariableManager#validateValue(IPath)
258      */

259     public IStatus validateValue(IPath value) {
260         if (value != null && (!value.isValidPath(value.toString()) || !value.isAbsolute())) {
261             String JavaDoc message = Messages.pathvar_invalidValue;
262             return new ResourceStatus(IResourceStatus.INVALID_VALUE, null, message);
263         }
264         return Status.OK_STATUS;
265     }
266 }
267
Popular Tags