1/*
2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24import java.io.File;
25import java.nio.file.*;
26import java.nio.file.attribute.BasicFileAttributes;
27import java.nio.file.attribute.FileAttribute;
28import java.nio.file.attribute.FileAttributeView;
29import java.nio.file.attribute.UserPrincipalLookupService;
30import java.nio.file.spi.FileSystemProvider;
31import java.nio.channels.SeekableByteChannel;
32import java.net.URI;
33import java.io.IOException;
34import java.util.Collections;
35import java.util.Iterator;
36import java.util.Map;
37import java.util.Set;
38
39public class TestProvider extends FileSystemProvider {
40
41    private final FileSystemProvider defaultProvider;
42    private final TestFileSystem theFileSystem;
43
44    public TestProvider(FileSystemProvider defaultProvider) {
45        this.defaultProvider = defaultProvider;
46        FileSystem fs = defaultProvider.getFileSystem(URI.create("file:/"));
47        this.theFileSystem = new TestFileSystem(fs, this);
48    }
49
50    FileSystemProvider defaultProvider() {
51        return defaultProvider;
52    }
53
54    @Override
55    public String getScheme() {
56        return "file";
57    }
58
59    @Override
60    public FileSystem newFileSystem(URI uri, Map<String,?> env) throws IOException {
61        return defaultProvider.newFileSystem(uri, env);
62    }
63
64    @Override
65    public FileSystem getFileSystem(URI uri) {
66        return theFileSystem;
67    }
68
69    @Override
70    public Path getPath(URI uri) {
71        Path path = defaultProvider.getPath(uri);
72        return theFileSystem.wrap(path);
73    }
74
75    @Override
76    public void setAttribute(Path file, String attribute, Object value,
77                             LinkOption... options)
78        throws IOException
79    {
80        throw new RuntimeException("not implemented");
81    }
82
83    @Override
84    public Map<String,Object> readAttributes(Path file, String attributes,
85                                             LinkOption... options)
86        throws IOException
87    {
88        Path delegate = theFileSystem.unwrap(file);
89        return defaultProvider.readAttributes(delegate, attributes, options);
90    }
91
92    @Override
93    public <A extends BasicFileAttributes> A readAttributes(Path file,
94                                                            Class<A> type,
95                                                            LinkOption... options)
96        throws IOException
97    {
98        Path delegate = theFileSystem.unwrap(file);
99        return defaultProvider.readAttributes(delegate, type, options);
100    }
101
102    @Override
103    public <V extends FileAttributeView> V getFileAttributeView(Path file,
104                                                                Class<V> type,
105                                                                LinkOption... options)
106    {
107        Path delegate = theFileSystem.unwrap(file);
108        return defaultProvider.getFileAttributeView(delegate, type, options);
109    }
110
111    @Override
112    public void delete(Path file) throws IOException {
113        Path delegate = theFileSystem.unwrap(file);
114        defaultProvider.delete(delegate);
115    }
116
117    @Override
118    public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
119        throws IOException
120    {
121        throw new RuntimeException("not implemented");
122    }
123
124    @Override
125    public void createLink(Path link, Path existing) throws IOException {
126        throw new RuntimeException("not implemented");
127    }
128
129    @Override
130    public Path readSymbolicLink(Path link) throws IOException {
131        Path delegate = theFileSystem.unwrap(link);
132        Path target = defaultProvider.readSymbolicLink(delegate);
133        return theFileSystem.wrap(target);
134    }
135
136    @Override
137    public void copy(Path source, Path target, CopyOption... options)
138        throws IOException
139    {
140        throw new RuntimeException("not implemented");
141    }
142
143    @Override
144    public void move(Path source, Path target, CopyOption... options)
145        throws IOException
146    {
147        throw new RuntimeException("not implemented");
148    }
149
150    @Override
151    public DirectoryStream<Path> newDirectoryStream(Path dir,
152                                                    DirectoryStream.Filter<? super Path> filter)
153        throws IOException
154    {
155        throw new RuntimeException("not implemented");
156    }
157
158    @Override
159    public void createDirectory(Path dir, FileAttribute<?>... attrs)
160        throws IOException
161    {
162        Path delegate = theFileSystem.unwrap(dir);
163        defaultProvider.createDirectory(delegate, attrs);
164    }
165
166    @Override
167    public SeekableByteChannel newByteChannel(Path file,
168                                              Set<? extends OpenOption> options,
169                                              FileAttribute<?>... attrs)
170        throws IOException
171    {
172        Path delegate = theFileSystem.unwrap(file);
173        return defaultProvider.newByteChannel(delegate, options, attrs);
174    }
175
176    @Override
177    public boolean isHidden(Path file) throws IOException {
178        throw new ReadOnlyFileSystemException();
179    }
180
181    @Override
182    public FileStore getFileStore(Path file) throws IOException {
183        throw new RuntimeException("not implemented");
184    }
185
186    @Override
187    public boolean isSameFile(Path file, Path other) throws IOException {
188        throw new RuntimeException("not implemented");
189    }
190
191    @Override
192    public void checkAccess(Path file, AccessMode... modes)
193        throws IOException
194    {
195        throw new RuntimeException("not implemented");
196    }
197
198    static class TestFileSystem extends FileSystem {
199        private final FileSystem delegate;
200        private final TestProvider provider;
201
202        TestFileSystem(FileSystem delegate, TestProvider provider) {
203            this.delegate = delegate;
204            this.provider = provider;
205        }
206
207        Path wrap(Path path) {
208            return (path != null) ? new TestPath(this, path) : null;
209        }
210
211        Path unwrap(Path wrapper) {
212            if (wrapper == null)
213                throw new NullPointerException();
214            if (!(wrapper instanceof TestPath))
215                throw new ProviderMismatchException();
216            return ((TestPath)wrapper).unwrap();
217        }
218
219        @Override
220        public FileSystemProvider provider() {
221            return provider;
222        }
223
224        @Override
225        public void close() throws IOException {
226            throw new RuntimeException("not implemented");
227        }
228
229        @Override
230        public boolean isOpen() {
231            return true;
232        }
233
234        @Override
235        public boolean isReadOnly() {
236            return false;
237        }
238
239        @Override
240        public String getSeparator() {
241            return delegate.getSeparator();
242        }
243
244        @Override
245        public Iterable<Path> getRootDirectories() {
246            throw new RuntimeException("not implemented");
247        }
248
249        @Override
250        public Iterable<FileStore> getFileStores() {
251            throw new RuntimeException("not implemented");
252        }
253
254        @Override
255        public Set<String> supportedFileAttributeViews() {
256            return delegate.supportedFileAttributeViews();
257        }
258
259        @Override
260        public Path getPath(String first, String... more) {
261            Path path = delegate.getPath(first, more);
262            return wrap(path);
263        }
264
265        @Override
266        public PathMatcher getPathMatcher(String syntaxAndPattern) {
267            return delegate.getPathMatcher(syntaxAndPattern);
268        }
269
270        @Override
271        public UserPrincipalLookupService getUserPrincipalLookupService() {
272            return delegate.getUserPrincipalLookupService();
273        }
274
275        @Override
276        public WatchService newWatchService() throws IOException {
277            throw new UnsupportedOperationException();
278        }
279    }
280
281    static class TestPath implements Path {
282        private final TestFileSystem fs;
283        private final Path delegate;
284
285        TestPath(TestFileSystem fs, Path delegate) {
286            this.fs = fs;
287            this.delegate = delegate;
288        }
289
290        Path unwrap() {
291            return delegate;
292        }
293
294        @Override
295        public FileSystem getFileSystem() {
296            return fs;
297        }
298
299        @Override
300        public boolean isAbsolute() {
301            return delegate.isAbsolute();
302        }
303
304        @Override
305        public Path getRoot() {
306            return fs.wrap(delegate.getRoot());
307        }
308
309        @Override
310        public Path getParent() {
311            return fs.wrap(delegate.getParent());
312        }
313
314        @Override
315        public int getNameCount() {
316            return delegate.getNameCount();
317        }
318
319        @Override
320        public Path getFileName() {
321            return fs.wrap(delegate.getFileName());
322        }
323
324        @Override
325        public Path getName(int index) {
326            return fs.wrap(delegate.getName(index));
327        }
328
329        @Override
330        public Path subpath(int beginIndex, int endIndex) {
331            return fs.wrap(delegate.subpath(beginIndex, endIndex));
332        }
333
334        @Override
335        public boolean startsWith(Path other) {
336            return delegate.startsWith(fs.unwrap(other));
337        }
338
339        @Override
340        public boolean startsWith(String other) {
341            return delegate.startsWith(other);
342        }
343
344        @Override
345        public boolean endsWith(Path other) {
346            return delegate.endsWith(fs.unwrap(other));
347        }
348
349        @Override
350        public boolean endsWith(String other) {
351            return delegate.endsWith(other);
352        }
353
354        @Override
355        public Path normalize() {
356            return fs.wrap(delegate.normalize());
357        }
358
359        @Override
360        public Path resolve(Path other) {
361            return fs.wrap(delegate.resolve(fs.unwrap(other)));
362        }
363
364        @Override
365        public Path resolve(String other) {
366            return fs.wrap(delegate.resolve(other));
367        }
368
369        @Override
370        public Path resolveSibling(Path other) {
371            return fs.wrap(delegate.resolveSibling(fs.unwrap(other)));
372        }
373
374        @Override
375        public Path resolveSibling(String other) {
376            return fs.wrap(delegate.resolveSibling(other));
377        }
378
379        @Override
380        public Path relativize(Path other) {
381            return fs.wrap(delegate.relativize(fs.unwrap(other)));
382        }
383
384        @Override
385        public boolean equals(Object other) {
386            if (!(other instanceof TestPath))
387                return false;
388            return delegate.equals(fs.unwrap((TestPath) other));
389        }
390
391        @Override
392        public int hashCode() {
393            return delegate.hashCode();
394        }
395
396        @Override
397        public String toString() {
398            return delegate.toString();
399        }
400
401        @Override
402        public URI toUri() {
403            String ssp = delegate.toUri().getSchemeSpecificPart();
404            return URI.create(fs.provider().getScheme() + ":" + ssp);
405        }
406
407        @Override
408        public Path toAbsolutePath() {
409            return fs.wrap(delegate.toAbsolutePath());
410        }
411
412        @Override
413        public Path toRealPath(LinkOption... options) throws IOException {
414            return fs.wrap(delegate.toRealPath(options));
415        }
416
417        @Override
418        public File toFile() {
419            return new File(toString());
420        }
421
422        @Override
423        public Iterator<Path> iterator() {
424            final Iterator<Path> itr = delegate.iterator();
425            return new Iterator<Path>() {
426                @Override
427                public boolean hasNext() {
428                    return itr.hasNext();
429                }
430                @Override
431                public Path next() {
432                    return fs.wrap(itr.next());
433                }
434                @Override
435                public void remove() {
436                    itr.remove();
437                }
438            };
439        }
440
441        @Override
442        public int compareTo(Path other) {
443            return delegate.compareTo(fs.unwrap(other));
444        }
445
446        @Override
447        public WatchKey register(WatchService watcher,
448                                 WatchEvent.Kind<?>[] events,
449                                 WatchEvent.Modifier... modifiers)
450        {
451            throw new UnsupportedOperationException();
452        }
453
454        @Override
455        public  WatchKey register(WatchService watcher,
456                                  WatchEvent.Kind<?>... events)
457        {
458            throw new UnsupportedOperationException();
459        }
460    }
461}
462