81 String root,
82 String path)
83 {
84 this.fs = fs;
85 this.type = type;
86 this.root = root;
87 this.path = path;
88 }
89
90 /**
91 * Creates a Path by parsing the given path.
92 */
93 static WindowsPath parse(WindowsFileSystem fs, String path) {
94 WindowsPathParser.Result result = WindowsPathParser.parse(path);
95 return new WindowsPath(fs, result.type(), result.root(), result.path());
96 }
97
98 /**
99 * Creates a Path from a given path that is known to be normalized.
100 */
101 static WindowsPath createFromNormalizedPath(WindowsFileSystem fs,
102 String path,
103 BasicFileAttributes attrs)
104 {
105 try {
106 WindowsPathParser.Result result =
107 WindowsPathParser.parseNormalizedPath(path);
108 if (attrs == null) {
109 return new WindowsPath(fs,
110 result.type(),
111 result.root(),
112 result.path());
113 } else {
114 return new WindowsPathWithAttributes(fs,
115 result.type(),
116 result.root(),
117 result.path(),
118 attrs);
119 }
120 } catch (InvalidPathException x) {
121 throw new AssertionError(x.getMessage());
122 }
123 }
124
125 /**
126 * Creates a WindowsPath from a given path that is known to be normalized.
127 */
128 static WindowsPath createFromNormalizedPath(WindowsFileSystem fs,
129 String path)
130 {
131 return createFromNormalizedPath(fs, path, null);
132 }
133
134 /**
135 * Special implementation with attached/cached attributes (used to quicken
136 * file tree traveral)
137 */
138 private static class WindowsPathWithAttributes
139 extends WindowsPath implements BasicFileAttributesHolder
140 {
141 final WeakReference<BasicFileAttributes> ref;
142
143 WindowsPathWithAttributes(WindowsFileSystem fs,
144 WindowsPathType type,
145 String root,
146 String path,
147 BasicFileAttributes attrs)
148 {
149 super(fs, type, root, path);
150 ref = new WeakReference<BasicFileAttributes>(attrs);
151 }
152
153 @Override
154 public BasicFileAttributes get() {
155 return ref.get();
156 }
157
158 @Override
159 public void invalidate() {
160 ref.clear();
161 }
162
163 // no need to override equals/hashCode.
164 }
165
166 // use this message when throwing exceptions
167 String getPathForExceptionMessage() {
168 return path;
169 }
170
171 // use this path for permission checks
172 String getPathForPermissionCheck() {
173 return path;
174 }
175
176 // use this path for Win32 calls
177 // This method will prefix long paths with \\?\ or \\?\UNC as required.
178 String getPathForWin32Calls() throws WindowsException {
179 // short absolute paths can be used directly
180 if (isAbsolute() && path.length() <= MAX_PATH)
181 return path;
182
183 // return cached values if available
184 WeakReference<String> ref = pathForWin32Calls;
185 String resolved = (ref != null) ? ref.get() : null;
300
301 // -- Path operations --
302
303 private boolean isEmpty() {
304 return path.length() == 0;
305 }
306
307 private WindowsPath emptyPath() {
308 return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", "");
309 }
310
311 @Override
312 public Path getFileName() {
313 int len = path.length();
314 // represents empty path
315 if (len == 0)
316 return this;
317 // represents root component only
318 if (root.length() == len)
319 return null;
320 int off = path.lastIndexOf('\\');
321 if (off < root.length())
322 off = root.length();
323 else
324 off++;
325 return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", path.substring(off));
326 }
327
328 @Override
329 public WindowsPath getParent() {
330 // represents root component only
331 if (root.length() == path.length())
332 return null;
333 int off = path.lastIndexOf('\\');
334 if (off < root.length())
335 return getRoot();
336 else
337 return new WindowsPath(getFileSystem(),
338 type,
339 root,
340 path.substring(0, off));
341 }
342
343 @Override
344 public WindowsPath getRoot() {
345 if (root.length() == 0)
820 // permission check as per spec
821 SecurityManager sm = System.getSecurityManager();
822 if (sm != null) {
823 sm.checkPropertyAccess("user.dir");
824 }
825
826 try {
827 return createFromNormalizedPath(getFileSystem(), getAbsolutePath());
828 } catch (WindowsException x) {
829 throw new IOError(new IOException(x.getMessage()));
830 }
831 }
832
833 @Override
834 public WindowsPath toRealPath(LinkOption... options) throws IOException {
835 checkRead();
836 String rp = WindowsLinkSupport.getRealPath(this, Util.followLinks(options));
837 return createFromNormalizedPath(getFileSystem(), rp);
838 }
839
840 @Override
841 public WatchKey register(WatchService watcher,
842 WatchEvent.Kind<?>[] events,
843 WatchEvent.Modifier... modifiers)
844 throws IOException
845 {
846 if (watcher == null)
847 throw new NullPointerException();
848 if (!(watcher instanceof WindowsWatchService))
849 throw new ProviderMismatchException();
850
851 // When a security manager is set then we need to make a defensive
852 // copy of the modifiers and check for the Windows specific FILE_TREE
853 // modifier. When the modifier is present then check that permission
854 // has been granted recursively.
855 SecurityManager sm = System.getSecurityManager();
856 if (sm != null) {
857 boolean watchSubtree = false;
858 final int ml = modifiers.length;
859 if (ml > 0) {
|
81 String root,
82 String path)
83 {
84 this.fs = fs;
85 this.type = type;
86 this.root = root;
87 this.path = path;
88 }
89
90 /**
91 * Creates a Path by parsing the given path.
92 */
93 static WindowsPath parse(WindowsFileSystem fs, String path) {
94 WindowsPathParser.Result result = WindowsPathParser.parse(path);
95 return new WindowsPath(fs, result.type(), result.root(), result.path());
96 }
97
98 /**
99 * Creates a Path from a given path that is known to be normalized.
100 */
101 static WindowsPath createFromNormalizedPath(
102 WindowsPath parent, String fullPathName, String lastPathName,
103 BasicFileAttributes attrs)
104 {
105 if (attrs == null) {
106 return new WindowsPath(parent.getFileSystem(),
107 parent.type,
108 parent.root,
109 fullPathName);
110 } else {
111 return new WindowsPathWithAttributes(parent.getFileSystem(),
112 parent.type,
113 parent.root,
114 fullPathName,lastPathName,parent,
115 attrs);
116 }
117 }
118 /**
119 * Creates a Path from a given path that is known to be normalized.
120 */
121 static WindowsPath createFromNormalizedPath(WindowsFileSystem fs,
122 String path,
123 BasicFileAttributes attrs)
124 {
125 try {
126 WindowsPathParser.Result result =
127 WindowsPathParser.parseNormalizedPath(path);
128 if (attrs == null) {
129 return new WindowsPath(fs,
130 result.type(),
131 result.root(),
132 result.path());
133 } else {
134 return new WindowsPathWithAttributes(fs,
135 result.type(),
136 result.root(),
137 result.path(),
138 null,null,
139 attrs);
140 }
141 } catch (InvalidPathException x) {
142 throw new AssertionError(x.getMessage());
143 }
144 }
145
146 /**
147 * Creates a WindowsPath from a given path that is known to be normalized.
148 */
149 static WindowsPath createFromNormalizedPath(WindowsFileSystem fs,
150 String path)
151 {
152 return createFromNormalizedPath(fs, path, null);
153 }
154
155
156 /**
157 * Special implementation with attached/cached attributes (used to quicken
158 * file tree traveral)
159 */
160 private static class WindowsPathWithAttributes
161 extends WindowsPath implements BasicFileAttributesHolder
162 {
163 final BasicFileAttributes ref;
164 private final String fileName;
165 private final WindowsPath parent;
166
167 WindowsPathWithAttributes(WindowsFileSystem fs,
168 WindowsPathType type,
169 String root,
170 String path,
171 String fileName,
172 WindowsPath parent,
173 BasicFileAttributes attrs)
174 {
175 super(fs, type, root, path);
176 ref =attrs;
177 this.fileName = fileName;
178 this.parent = parent;
179 }
180
181 @Override
182 public BasicFileAttributes get() {
183 return ref;
184 }
185
186 @Override
187 public void invalidate() {
188 // ref.clear();
189 }
190
191
192 // no need to override equals/hashCode.
193
194 @Override
195 public Path getFileName() {
196 if (fileName != null) {
197 return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", fileName);
198 }
199 return super.getFileName();
200 }
201
202 @Override
203 public WindowsPath getParent() {
204 if (parent != null) {
205 return parent;
206 }
207 return super.getParent();
208 }
209
210 }
211
212 // use this message when throwing exceptions
213 String getPathForExceptionMessage() {
214 return path;
215 }
216
217 // use this path for permission checks
218 String getPathForPermissionCheck() {
219 return path;
220 }
221
222 // use this path for Win32 calls
223 // This method will prefix long paths with \\?\ or \\?\UNC as required.
224 String getPathForWin32Calls() throws WindowsException {
225 // short absolute paths can be used directly
226 if (isAbsolute() && path.length() <= MAX_PATH)
227 return path;
228
229 // return cached values if available
230 WeakReference<String> ref = pathForWin32Calls;
231 String resolved = (ref != null) ? ref.get() : null;
346
347 // -- Path operations --
348
349 private boolean isEmpty() {
350 return path.length() == 0;
351 }
352
353 private WindowsPath emptyPath() {
354 return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", "");
355 }
356
357 @Override
358 public Path getFileName() {
359 int len = path.length();
360 // represents empty path
361 if (len == 0)
362 return this;
363 // represents root component only
364 if (root.length() == len)
365 return null;
366 int off = path.lastIndexOf('\\', len);
367 if (off < root.length())
368 off = root.length();
369 else
370 off++;
371 return new WindowsPath(getFileSystem(), WindowsPathType.RELATIVE, "", path.substring(off, len));
372 }
373
374 @Override
375 public WindowsPath getParent() {
376 // represents root component only
377 if (root.length() == path.length())
378 return null;
379 int off = path.lastIndexOf('\\');
380 if (off < root.length())
381 return getRoot();
382 else
383 return new WindowsPath(getFileSystem(),
384 type,
385 root,
386 path.substring(0, off));
387 }
388
389 @Override
390 public WindowsPath getRoot() {
391 if (root.length() == 0)
866 // permission check as per spec
867 SecurityManager sm = System.getSecurityManager();
868 if (sm != null) {
869 sm.checkPropertyAccess("user.dir");
870 }
871
872 try {
873 return createFromNormalizedPath(getFileSystem(), getAbsolutePath());
874 } catch (WindowsException x) {
875 throw new IOError(new IOException(x.getMessage()));
876 }
877 }
878
879 @Override
880 public WindowsPath toRealPath(LinkOption... options) throws IOException {
881 checkRead();
882 String rp = WindowsLinkSupport.getRealPath(this, Util.followLinks(options));
883 return createFromNormalizedPath(getFileSystem(), rp);
884 }
885
886
887 @Override
888 public WatchKey register(WatchService watcher,
889 WatchEvent.Kind<?>[] events,
890 WatchEvent.Modifier... modifiers)
891 throws IOException
892 {
893 if (watcher == null)
894 throw new NullPointerException();
895 if (!(watcher instanceof WindowsWatchService))
896 throw new ProviderMismatchException();
897
898 // When a security manager is set then we need to make a defensive
899 // copy of the modifiers and check for the Windows specific FILE_TREE
900 // modifier. When the modifier is present then check that permission
901 // has been granted recursively.
902 SecurityManager sm = System.getSecurityManager();
903 if (sm != null) {
904 boolean watchSubtree = false;
905 final int ml = modifiers.length;
906 if (ml > 0) {
|