~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/openjdk/sun/nio/fs/NetFileSystem.java

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2011 Jeroen Frijters
 
3
 
 
4
  This software is provided 'as-is', without any express or implied
 
5
  warranty.  In no event will the authors be held liable for any damages
 
6
  arising from the use of this software.
 
7
 
 
8
  Permission is granted to anyone to use this software for any purpose,
 
9
  including commercial applications, and to alter it and redistribute it
 
10
  freely, subject to the following restrictions:
 
11
 
 
12
  1. The origin of this software must not be misrepresented; you must not
 
13
     claim that you wrote the original software. If you use this software
 
14
     in a product, an acknowledgment in the product documentation would be
 
15
     appreciated but is not required.
 
16
  2. Altered source versions must be plainly marked as such, and must not be
 
17
     misrepresented as being the original software.
 
18
  3. This notice may not be removed or altered from any source distribution.
 
19
 
 
20
  Jeroen Frijters
 
21
  jeroen@frijters.net
 
22
 
 
23
*/
 
24
 
 
25
package sun.nio.fs;
 
26
 
 
27
import cli.System.IO.DriveInfo;
 
28
import cli.System.IO.ErrorEventArgs;
 
29
import cli.System.IO.ErrorEventHandler;
 
30
import cli.System.IO.FileSystemEventArgs;
 
31
import cli.System.IO.FileSystemEventHandler;
 
32
import cli.System.IO.FileSystemWatcher;
 
33
import cli.System.IO.WatcherChangeTypes;
 
34
import java.io.IOException;
 
35
import java.nio.file.*;
 
36
import java.nio.file.attribute.*;
 
37
import java.nio.file.spi.FileSystemProvider;
 
38
import java.util.ArrayList;
 
39
import java.util.Arrays;
 
40
import java.util.Collections;
 
41
import java.util.concurrent.LinkedBlockingQueue;
 
42
import java.util.concurrent.TimeUnit;
 
43
import java.util.HashSet;
 
44
import java.util.List;
 
45
import java.util.Set;
 
46
import java.util.regex.Pattern;
 
47
import static ikvm.internal.Util.WINDOWS;
 
48
 
 
49
final class NetFileSystem extends FileSystem
 
50
{
 
51
    private static final Set<String> attributes = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("basic")));
 
52
    private final NetFileSystemProvider provider;
 
53
    private final String separator = Character.toString(cli.System.IO.Path.DirectorySeparatorChar);
 
54
 
 
55
    NetFileSystem(NetFileSystemProvider provider)
 
56
    {
 
57
        this.provider = provider;
 
58
    }
 
59
 
 
60
    public FileSystemProvider provider()
 
61
    {
 
62
        return provider;
 
63
    }
 
64
 
 
65
    public void close() throws IOException
 
66
    {
 
67
        throw new UnsupportedOperationException();
 
68
    }
 
69
 
 
70
    public boolean isOpen()
 
71
    {
 
72
        return true;
 
73
    }
 
74
 
 
75
    public boolean isReadOnly()
 
76
    {
 
77
        return false;
 
78
    }
 
79
 
 
80
    public String getSeparator()
 
81
    {
 
82
        return separator;
 
83
    }
 
84
 
 
85
    public Iterable<Path> getRootDirectories()
 
86
    {
 
87
        SecurityManager sm = System.getSecurityManager();
 
88
        ArrayList<Path> list = new ArrayList<>();
 
89
        for (DriveInfo info : DriveInfo.GetDrives())
 
90
        {
 
91
            try
 
92
            {
 
93
                if (sm != null)
 
94
                {
 
95
                    sm.checkRead(info.get_Name());
 
96
                }
 
97
            }
 
98
            catch (SecurityException _)
 
99
            {
 
100
                continue;
 
101
            }
 
102
            list.add(getPath(info.get_Name()));
 
103
        }
 
104
        return list;
 
105
    }
 
106
 
 
107
    public Iterable<FileStore> getFileStores()
 
108
    {
 
109
        SecurityManager sm = System.getSecurityManager();
 
110
        if (sm != null)
 
111
        {
 
112
            try
 
113
            {
 
114
                sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
 
115
            }
 
116
            catch (SecurityException _)
 
117
            {
 
118
                return Collections.emptyList();
 
119
            }
 
120
        }
 
121
        ArrayList<FileStore> list = new ArrayList<>();
 
122
        for (DriveInfo info : DriveInfo.GetDrives())
 
123
        {
 
124
            try
 
125
            {
 
126
                if (sm != null)
 
127
                {
 
128
                    sm.checkRead(info.get_Name());
 
129
                }
 
130
            }
 
131
            catch (SecurityException _)
 
132
            {
 
133
                continue;
 
134
            }
 
135
            try
 
136
            {
 
137
                list.add(provider.getFileStore(info));
 
138
            }
 
139
            catch (IOException _)
 
140
            {
 
141
            }
 
142
        }
 
143
        return list;
 
144
    }
 
145
 
 
146
    public Set<String> supportedFileAttributeViews()
 
147
    {
 
148
        return attributes;
 
149
    }
 
150
 
 
151
    public Path getPath(String first, String... more)
 
152
    {
 
153
        if (more.length == 0)
 
154
        {
 
155
            return new NetPath(this, first);
 
156
        }
 
157
        else
 
158
        {
 
159
            StringBuilder sb = new StringBuilder(first);
 
160
            String sep = sb.length() == 0 ? "" : separator;
 
161
            for (String s : more)
 
162
            {
 
163
                if (s.length() != 0)
 
164
                {
 
165
                    sb.append(sep);
 
166
                    sb.append(s);
 
167
                    sep = separator;
 
168
                }
 
169
            }
 
170
            return new NetPath(this, sb.toString());
 
171
        }
 
172
    }
 
173
 
 
174
    public PathMatcher getPathMatcher(String syntaxAndPattern)
 
175
    {
 
176
        String regex;
 
177
        if (syntaxAndPattern.startsWith("glob:"))
 
178
        {
 
179
            String pattern = syntaxAndPattern.substring(5);
 
180
            if (WINDOWS)
 
181
            {
 
182
                regex = Globs.toWindowsRegexPattern(pattern);
 
183
            }
 
184
            else
 
185
            {
 
186
                regex = Globs.toUnixRegexPattern(pattern);
 
187
            }
 
188
        }
 
189
        else if (syntaxAndPattern.startsWith("regex:"))
 
190
        {
 
191
            regex = syntaxAndPattern.substring(6);
 
192
        }
 
193
        else if (syntaxAndPattern.indexOf(':') <= 0)
 
194
        {
 
195
            throw new IllegalArgumentException();
 
196
        }
 
197
        else
 
198
        {
 
199
            throw new UnsupportedOperationException();
 
200
        }
 
201
        final Pattern pattern = Pattern.compile(regex, WINDOWS ? Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE : 0);
 
202
        return new PathMatcher() {
 
203
            @Override
 
204
            public boolean matches(Path path) {
 
205
                return pattern.matcher(path.toString()).matches();
 
206
            }
 
207
        };
 
208
    }
 
209
 
 
210
    public UserPrincipalLookupService getUserPrincipalLookupService()
 
211
    {
 
212
        throw new UnsupportedOperationException();
 
213
    }
 
214
 
 
215
    static final class NetWatchService implements WatchService
 
216
    {
 
217
        static final WatchEvent<?> overflowEvent = new WatchEvent<Object>() {
 
218
            public Object context() {
 
219
                return null;
 
220
            }
 
221
            public int count() {
 
222
                return 1;
 
223
            }
 
224
            public WatchEvent.Kind<Object> kind() {
 
225
                return StandardWatchEventKinds.OVERFLOW;
 
226
            }
 
227
        };
 
228
        private static final WatchKey CLOSED = new WatchKey() {
 
229
            public boolean isValid() { return false; }
 
230
            public List<WatchEvent<?>> pollEvents() { return null; }
 
231
            public boolean reset() { return false; }
 
232
            public void cancel() { }
 
233
            public Watchable watchable() { return null; }
 
234
        };
 
235
        private boolean closed;
 
236
        private final ArrayList<NetWatchKey> keys = new ArrayList<>();
 
237
        private final LinkedBlockingQueue<WatchKey> queue = new LinkedBlockingQueue<>();
 
238
 
 
239
        public synchronized void close()
 
240
        {
 
241
            if (!closed)
 
242
            {
 
243
                closed = true;
 
244
                for (NetWatchKey key : keys)
 
245
                {
 
246
                    key.close();
 
247
                }
 
248
                enqueue(CLOSED);
 
249
            }
 
250
        }
 
251
 
 
252
        private WatchKey checkClosed(WatchKey key)
 
253
        {
 
254
            if (key == CLOSED)
 
255
            {
 
256
                enqueue(CLOSED);
 
257
                throw new ClosedWatchServiceException();
 
258
            }
 
259
            return key;
 
260
        }
 
261
 
 
262
        public WatchKey poll()
 
263
        {
 
264
            return checkClosed(queue.poll());
 
265
        }
 
266
 
 
267
        public WatchKey poll(long timeout, TimeUnit unit) throws InterruptedException
 
268
        {
 
269
            return checkClosed(queue.poll(timeout, unit));
 
270
        }
 
271
 
 
272
        public WatchKey take() throws InterruptedException
 
273
        {
 
274
            return checkClosed(queue.take());
 
275
        }
 
276
 
 
277
        void enqueue(WatchKey key)
 
278
        {
 
279
            for (;;)
 
280
            {
 
281
                try
 
282
                {
 
283
                    queue.put(key);
 
284
                    return;
 
285
                }
 
286
                catch (InterruptedException _)
 
287
                {
 
288
                }
 
289
            }
 
290
        }
 
291
 
 
292
        private final class NetWatchKey implements WatchKey
 
293
        {
 
294
            private final NetPath path;
 
295
            private FileSystemWatcher fsw;
 
296
            private ArrayList<WatchEvent<?>> list = new ArrayList<>();
 
297
            private HashSet<String> modified = new HashSet<>();
 
298
            private boolean signaled;
 
299
            
 
300
            NetWatchKey(NetPath path)
 
301
            {
 
302
                this.path = path;
 
303
            }
 
304
            
 
305
            synchronized void init(final boolean create, final boolean delete, final boolean modify, final boolean overflow, final boolean subtree)
 
306
            {
 
307
                if (fsw != null)
 
308
                {
 
309
                    // we could reuse the FileSystemWatcher, but for now we just recreate it
 
310
                    // (and we run the risk of missing some events while we're doing that)
 
311
                    fsw.Dispose();
 
312
                    fsw = null;
 
313
                }
 
314
                fsw = new FileSystemWatcher(path.path);
 
315
                if (create)
 
316
                {
 
317
                    fsw.add_Created(new FileSystemEventHandler(new FileSystemEventHandler.Method() {
 
318
                        public void Invoke(Object sender, FileSystemEventArgs e) {
 
319
                            addEvent(createEvent(e), null);
 
320
                        }
 
321
                    }));
 
322
                }
 
323
                if (delete)
 
324
                {
 
325
                    fsw.add_Deleted(new FileSystemEventHandler(new FileSystemEventHandler.Method() {
 
326
                        public void Invoke(Object sender, FileSystemEventArgs e) {
 
327
                            addEvent(createEvent(e), null);
 
328
                        }
 
329
                    }));
 
330
                }
 
331
                if (modify)
 
332
                {
 
333
                    fsw.add_Changed(new FileSystemEventHandler(new FileSystemEventHandler.Method() {
 
334
                        public void Invoke(Object sender, FileSystemEventArgs e) {
 
335
                            synchronized (NetWatchKey.this) {
 
336
                                if (modified.contains(e.get_Name())) {
 
337
                                    // we already have an ENTRY_MODIFY event pending
 
338
                                    return;
 
339
                                }
 
340
                            }
 
341
                            addEvent(createEvent(e), e.get_Name());
 
342
                        }
 
343
                    }));
 
344
                }
 
345
                fsw.add_Error(new ErrorEventHandler(new ErrorEventHandler.Method() {
 
346
                    public void Invoke(Object sender, ErrorEventArgs e) {
 
347
                        if (e.GetException() instanceof cli.System.ComponentModel.Win32Exception
 
348
                            && ((cli.System.ComponentModel.Win32Exception)e.GetException()).get_ErrorCode() == -2147467259) {
 
349
                            // the directory we were watching was deleted
 
350
                            cancelledByError();
 
351
                        } else if (overflow) {
 
352
                            addEvent(overflowEvent, null);
 
353
                        }
 
354
                    }
 
355
                }));
 
356
                if (subtree)
 
357
                {
 
358
                    fsw.set_IncludeSubdirectories(true);
 
359
                }
 
360
                fsw.set_EnableRaisingEvents(true);
 
361
            }
 
362
 
 
363
            WatchEvent<?> createEvent(final FileSystemEventArgs e)
 
364
            {
 
365
                return new WatchEvent<Path>() {
 
366
                    public Path context() {
 
367
                        return new NetPath((NetFileSystem)path.getFileSystem(), e.get_Name());
 
368
                    }
 
369
                    public int count() {
 
370
                        return 1;
 
371
                    }
 
372
                    public WatchEvent.Kind<Path> kind() {
 
373
                        switch (e.get_ChangeType().Value) {
 
374
                            case WatcherChangeTypes.Created:
 
375
                                return StandardWatchEventKinds.ENTRY_CREATE;
 
376
                            case WatcherChangeTypes.Deleted:
 
377
                                return StandardWatchEventKinds.ENTRY_DELETE;
 
378
                            default:
 
379
                                return StandardWatchEventKinds.ENTRY_MODIFY;
 
380
                        }
 
381
                    }
 
382
                };
 
383
            }
 
384
 
 
385
            void cancelledByError()
 
386
            {
 
387
                cancel();
 
388
                synchronized (this)
 
389
                {
 
390
                    if (!signaled)
 
391
                    {
 
392
                        signaled = true;
 
393
                        enqueue(this);
 
394
                    }
 
395
                }
 
396
            }
 
397
 
 
398
            synchronized void addEvent(WatchEvent<?> event, String modified)
 
399
            {
 
400
                list.add(event);
 
401
                if (modified != null)
 
402
                {
 
403
                    this.modified.add(modified);
 
404
                }
 
405
                if (!signaled)
 
406
                {
 
407
                    signaled = true;
 
408
                    enqueue(this);
 
409
                }
 
410
            }
 
411
 
 
412
            public synchronized boolean isValid()
 
413
            {
 
414
                return fsw != null;
 
415
            }
 
416
 
 
417
            public synchronized List<WatchEvent<?>> pollEvents()
 
418
            {
 
419
                ArrayList<WatchEvent<?>> r = list;
 
420
                list = new ArrayList<>();
 
421
                modified.clear();
 
422
                return r;
 
423
            }
 
424
 
 
425
            public synchronized boolean reset()
 
426
            {
 
427
                if (fsw == null)
 
428
                {
 
429
                    return false;
 
430
                }
 
431
                if (signaled)
 
432
                {
 
433
                    if (list.size() == 0)
 
434
                    {
 
435
                        signaled = false;
 
436
                    }
 
437
                    else
 
438
                    {
 
439
                        enqueue(this);
 
440
                    }
 
441
                }
 
442
                return true;
 
443
            }
 
444
 
 
445
            void close()
 
446
            {
 
447
                if (fsw != null)
 
448
                {
 
449
                    fsw.Dispose();
 
450
                    fsw = null;
 
451
                }
 
452
            }
 
453
 
 
454
            public void cancel()
 
455
            {
 
456
                synchronized (NetWatchService.this)
 
457
                {
 
458
                    keys.remove(this);
 
459
                    close();
 
460
                }
 
461
            }
 
462
 
 
463
            public Watchable watchable()
 
464
            {
 
465
                return path;
 
466
            }
 
467
        }
 
468
 
 
469
        synchronized WatchKey register(NetPath path, boolean create, boolean delete, boolean modify, boolean overflow, boolean subtree)
 
470
        {
 
471
            if (closed)
 
472
            {
 
473
                throw new ClosedWatchServiceException();
 
474
            }
 
475
            NetWatchKey existing = null;
 
476
            for (NetWatchKey key : keys)
 
477
            {
 
478
                if (key.watchable().equals(path))
 
479
                {
 
480
                    existing = key;
 
481
                    break;
 
482
                }
 
483
            }
 
484
            if (existing == null)
 
485
            {
 
486
                existing = new NetWatchKey(path);
 
487
                keys.add(existing);
 
488
            }
 
489
            existing.init(create, delete, modify, overflow, subtree);
 
490
            return existing;
 
491
        }
 
492
    }
 
493
 
 
494
    public WatchService newWatchService() throws IOException
 
495
    {
 
496
        return new NetWatchService();
 
497
    }
 
498
}