Added
Link Here
|
1 |
/******************************************************************************** |
2 |
* Copyright (c) 2008 IBM Corporation. All rights reserved. |
3 |
* This program and the accompanying materials are made available under the terms |
4 |
* of the Eclipse Public License v1.0 which accompanies this distribution, and is |
5 |
* available at http://www.eclipse.org/legal/epl-v10.html |
6 |
* |
7 |
* <p> |
8 |
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as |
9 |
* part of a work in progress. There is no guarantee that this API will |
10 |
* work or that it will remain the same. Please do not use this API without |
11 |
* consulting with the <Your Team Name> team. |
12 |
* </p> |
13 |
* |
14 |
* |
15 |
* Contributors: |
16 |
* Rupen Mardirossian (IBM) [221556] - Create HostPath.java based on org.eclipse.core.runtime.Path (code taken from Path class and modified). |
17 |
********************************************************************************/ |
18 |
|
19 |
package org.eclipse.rse.internal.services; |
20 |
|
21 |
import org.eclipse.core.runtime.Assert; |
22 |
|
23 |
import org.eclipse.rse.services.clientserver.PathUtility; |
24 |
|
25 |
public class HostPath implements IHostPath, Cloneable { |
26 |
|
27 |
protected char separator; |
28 |
|
29 |
/** The path segments */ |
30 |
private String[] segments; |
31 |
|
32 |
/** Constant value indicating if the current platform is Windows */ |
33 |
private static final boolean WINDOWS = java.io.File.separatorChar == '\\'; |
34 |
|
35 |
/** Constant value indicating no segments */ |
36 |
private static final String[] NO_SEGMENTS = new String[0]; |
37 |
|
38 |
/** The device id string. May be null if there is no device. */ |
39 |
private String device = null; |
40 |
|
41 |
/** Constant empty string value. */ |
42 |
private static final String EMPTY_STRING = ""; //$NON-NLS-1$ |
43 |
|
44 |
/** |
45 |
* Constructs a new path from the given string path. |
46 |
* The string path must represent a valid file system path |
47 |
* on the local/remote file system. |
48 |
* segment delimiters (separators) are determined, and any |
49 |
* segment and device delimiters for the local file system are |
50 |
* also respected (such as colon (':') and backslash ('\') on some file systems). |
51 |
* |
52 |
* @param fullPath the string path |
53 |
*/ |
54 |
public HostPath(String fullPath) { |
55 |
Assert.isNotNull(fullPath); |
56 |
String devicePart = null; |
57 |
String stringSep = PathUtility.getSeparator(fullPath); |
58 |
if (stringSep.equals("/")) //$NON-NLS-1$ |
59 |
{ |
60 |
this.separator = '/'; |
61 |
} |
62 |
else if (stringSep.equals("\\")) //$NON-NLS-1$ |
63 |
{ |
64 |
this.separator = '\\'; |
65 |
} |
66 |
if (WINDOWS) { |
67 |
//extract device |
68 |
int i = fullPath.indexOf(DEVICE_SEPARATOR); |
69 |
if (i != -1) { |
70 |
//remove leading slash from device part to handle output of URL.getFile() |
71 |
int start = fullPath.charAt(0) == this.separator ? 1 : 0; |
72 |
devicePart = fullPath.substring(start, i + 1); |
73 |
fullPath = fullPath.substring(i + 1, fullPath.length()); |
74 |
} |
75 |
} |
76 |
initialize(devicePart, fullPath); |
77 |
} |
78 |
|
79 |
/* |
80 |
* Private constructor. |
81 |
*/ |
82 |
private HostPath(String device, String[] segments, char separator) { |
83 |
// no segment validations are done for performance reasons |
84 |
this.segments = segments; |
85 |
this.device = device; |
86 |
this.separator = separator; |
87 |
} |
88 |
|
89 |
//---------------------------------------------------------------------- |
90 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
91 |
//---------------------------------------------------------------------- |
92 |
/* |
93 |
* Clones this object. |
94 |
*/ |
95 |
public Object clone() { |
96 |
try { |
97 |
return super.clone(); |
98 |
} catch (CloneNotSupportedException e) { |
99 |
return null; |
100 |
} |
101 |
} |
102 |
|
103 |
//---------------------------------------------------------------------- |
104 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
105 |
//---------------------------------------------------------------------- |
106 |
/* |
107 |
* Compares objects for equality. |
108 |
*/ |
109 |
public boolean equals(Object obj) { |
110 |
if (this == obj) |
111 |
return true; |
112 |
if (!(obj instanceof HostPath)) |
113 |
return false; |
114 |
HostPath target = (HostPath) obj; |
115 |
String[] targetSegments = target.segments; |
116 |
int i = segments.length; |
117 |
//check segment count |
118 |
if (i != targetSegments.length) |
119 |
return false; |
120 |
//check segments in reverse order - later segments more likely to differ |
121 |
while (--i >= 0) |
122 |
if (!segments[i].equals(targetSegments[i])) |
123 |
return false; |
124 |
//check device last (least likely to differ) |
125 |
return device == target.device || (device != null && device.equals(target.device)); |
126 |
} |
127 |
|
128 |
|
129 |
//---------------------------------------------------------------------- |
130 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
131 |
//---------------------------------------------------------------------- |
132 |
/** |
133 |
* Computes the segment array for the given canonicalized path. |
134 |
*/ |
135 |
private String[] computeSegments(String path) { |
136 |
// performance sensitive --- avoid creating garbage |
137 |
int segmentCount = computeSegmentCount(path); |
138 |
if (segmentCount == 0) |
139 |
return NO_SEGMENTS; |
140 |
String[] newSegments = new String[segmentCount]; |
141 |
int len = path.length(); |
142 |
// check for initial slash |
143 |
int firstPosition = (path.charAt(0) == separator) ? 1 : 0; |
144 |
// check for UNC |
145 |
if (firstPosition == 1 && len > 1 && (path.charAt(1) == separator)) |
146 |
firstPosition = 2; |
147 |
int lastPosition = (path.charAt(len - 1) != separator) ? len - 1 : len - 2; |
148 |
// for non-empty paths, the number of segments is |
149 |
// the number of slashes plus 1, ignoring any leading |
150 |
// and trailing slashes |
151 |
int next = firstPosition; |
152 |
for (int i = 0; i < segmentCount; i++) { |
153 |
int start = next; |
154 |
int end = path.indexOf(separator, next); |
155 |
if (end == -1) { |
156 |
newSegments[i] = path.substring(start, lastPosition + 1); |
157 |
} else { |
158 |
newSegments[i] = path.substring(start, end); |
159 |
} |
160 |
next = end + 1; |
161 |
} |
162 |
return newSegments; |
163 |
} |
164 |
|
165 |
//---------------------------------------------------------------------- |
166 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
167 |
//---------------------------------------------------------------------- |
168 |
/* |
169 |
* Returns the size of the string that will be created by toString or toOSString. |
170 |
*/ |
171 |
private int computeLength() { |
172 |
int length = 0; |
173 |
if (device != null) |
174 |
length += device.length(); |
175 |
//add the segment lengths |
176 |
int max = segments.length; |
177 |
if (max > 0) { |
178 |
for (int i = 0; i < max; i++) { |
179 |
length += segments[i].length(); |
180 |
} |
181 |
//add the separator lengths |
182 |
length += max; |
183 |
} |
184 |
return length; |
185 |
} |
186 |
|
187 |
//---------------------------------------------------------------------- |
188 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
189 |
//---------------------------------------------------------------------- |
190 |
/* |
191 |
* Returns the number of segments in the given path |
192 |
*/ |
193 |
private int computeSegmentCount(String path) { |
194 |
int len = path.length(); |
195 |
if (len == 0 || (len == 1 && path.charAt(0) == separator)) { |
196 |
return 0; |
197 |
} |
198 |
int count = 1; |
199 |
int prev = -1; |
200 |
int i; |
201 |
while ((i = path.indexOf(separator, prev + 1)) != -1) { |
202 |
if (i != prev + 1 && i != len) { |
203 |
++count; |
204 |
} |
205 |
prev = i; |
206 |
} |
207 |
if (path.charAt(len - 1) == separator) { |
208 |
--count; |
209 |
} |
210 |
return count; |
211 |
} |
212 |
|
213 |
/* |
214 |
* @see IHostPath#getDevice |
215 |
*/ |
216 |
public String getDevice() { |
217 |
return device; |
218 |
} |
219 |
|
220 |
/* |
221 |
* Initialize the current path with the given string. |
222 |
*/ |
223 |
private void initialize(String device, String path) |
224 |
{ |
225 |
this.device = device; |
226 |
this.segments = computeSegments(path); |
227 |
} |
228 |
|
229 |
/* |
230 |
* return the number of segments in the path |
231 |
*/ |
232 |
public int segmentCount() { |
233 |
return segments.length; |
234 |
} |
235 |
|
236 |
//---------------------------------------------------------------------- |
237 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
238 |
//---------------------------------------------------------------------- |
239 |
/* |
240 |
* @see IHostPath#removeFirstSegments(int) |
241 |
*/ |
242 |
public IHostPath removeFirstSegments(int count) { |
243 |
if (count == 0) |
244 |
return this; |
245 |
if (count >= segments.length) { |
246 |
return new HostPath(device, NO_SEGMENTS, separator); |
247 |
} |
248 |
Assert.isLegal(count > 0); |
249 |
int newSize = segments.length - count; |
250 |
String[] newSegments = new String[newSize]; |
251 |
System.arraycopy(this.segments, count, newSegments, 0, newSize); |
252 |
|
253 |
//result is always a relative path |
254 |
return new HostPath(device, newSegments, separator); |
255 |
} |
256 |
|
257 |
//---------------------------------------------------------------------- |
258 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
259 |
//---------------------------------------------------------------------- |
260 |
/* |
261 |
* @see IHostPath#removeLastSegments(int) |
262 |
*/ |
263 |
public IHostPath removeLastSegments(int count) { |
264 |
if (count == 0) |
265 |
return this; |
266 |
if (count >= segments.length) { |
267 |
//result will have no trailing separator |
268 |
return new HostPath(device, NO_SEGMENTS, separator); |
269 |
} |
270 |
Assert.isLegal(count > 0); |
271 |
int newSize = segments.length - count; |
272 |
String[] newSegments = new String[newSize]; |
273 |
System.arraycopy(this.segments, 0, newSegments, 0, newSize); |
274 |
return new HostPath(device, newSegments, separator); |
275 |
} |
276 |
|
277 |
|
278 |
/* |
279 |
* return the segment at specified location in array |
280 |
*/ |
281 |
public String segment(int index) { |
282 |
if (index >= segments.length) |
283 |
return null; |
284 |
return segments[index]; |
285 |
} |
286 |
|
287 |
//---------------------------------------------------------------------- |
288 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
289 |
//---------------------------------------------------------------------- |
290 |
/* |
291 |
* return segments of the path in an array |
292 |
*/ |
293 |
public String[] segments() { |
294 |
String[] segmentCopy = new String[segments.length]; |
295 |
System.arraycopy(segments, 0, segmentCopy, 0, segments.length); |
296 |
return segmentCopy; |
297 |
} |
298 |
|
299 |
//---------------------------------------------------------------------- |
300 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
301 |
//---------------------------------------------------------------------- |
302 |
/* |
303 |
* @see IHostPath#setDevice(String) |
304 |
*/ |
305 |
public IHostPath setDevice(String value) { |
306 |
if (value != null) { |
307 |
Assert.isTrue(value.indexOf(IHostPath.DEVICE_SEPARATOR) == (value.length() - 1), "Last character should be the device separator"); //$NON-NLS-1$ |
308 |
} |
309 |
//return the receiver if the device is the same |
310 |
if (value == device || (value != null && value.equals(device))) |
311 |
return this; |
312 |
|
313 |
return new HostPath(value, this.segments, this.separator); |
314 |
} |
315 |
|
316 |
//---------------------------------------------------------------------- |
317 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
318 |
//---------------------------------------------------------------------- |
319 |
/* |
320 |
* @see IHostPath#toString() |
321 |
*/ |
322 |
public String toString() { |
323 |
int resultSize = computeLength(); |
324 |
if (resultSize <= 0) |
325 |
return EMPTY_STRING; |
326 |
char[] result = new char[resultSize]; |
327 |
int offset = 0; |
328 |
if (device != null) { |
329 |
int size = device.length(); |
330 |
device.getChars(0, size, result, offset); |
331 |
offset += size; |
332 |
result[offset++] = separator; |
333 |
} |
334 |
int len = segments.length - 1; |
335 |
if (len >= 0) { |
336 |
//append all but the last segment, with separators |
337 |
for (int i = 0; i < len; i++) { |
338 |
int size = segments[i].length(); |
339 |
segments[i].getChars(0, size, result, offset); |
340 |
offset += size; |
341 |
result[offset++] = separator; |
342 |
} |
343 |
//append the last segment |
344 |
int size = segments[len].length(); |
345 |
segments[len].getChars(0, size, result, offset); |
346 |
offset += size; |
347 |
} |
348 |
return new String(result); |
349 |
} |
350 |
//---------------------------------------------------------------------- |
351 |
// <taken from org.eclipse.core.runtime.Path and modified (Copyright IBM)> |
352 |
//---------------------------------------------------------------------- |
353 |
/* |
354 |
* @see IHostPath#uptoSegment(int) |
355 |
*/ |
356 |
public IHostPath uptoSegment(int count) { |
357 |
if (count == 0) |
358 |
return new HostPath(device, NO_SEGMENTS, separator); |
359 |
if (count >= segments.length) |
360 |
return this; |
361 |
Assert.isTrue(count > 0, "Invalid parameter to Path.uptoSegment"); //$NON-NLS-1$ |
362 |
String[] newSegments = new String[count]; |
363 |
System.arraycopy(segments, 0, newSegments, 0, count); |
364 |
return new HostPath(device, newSegments, separator); |
365 |
} |
366 |
} |