CacheFSInfo.java revision 2571:10fc81ac75b4
1193326Sed/*
2193326Sed * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
3193326Sed * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4193326Sed *
5193326Sed * This code is free software; you can redistribute it and/or modify it
6193326Sed * under the terms of the GNU General Public License version 2 only, as
7193326Sed * published by the Free Software Foundation.  Oracle designates this
8193326Sed * particular file as subject to the "Classpath" exception as provided
9193326Sed * by Oracle in the LICENSE file that accompanied this code.
10193326Sed *
11193326Sed * This code is distributed in the hope that it will be useful, but WITHOUT
12193326Sed * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13193326Sed * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14193326Sed * version 2 for more details (a copy is included in the LICENSE file that
15193326Sed * accompanied this code).
16193326Sed *
17199482Srdivacky * You should have received a copy of the GNU General Public License version
18252723Sdim * 2 along with this work; if not, write to the Free Software Foundation,
19193326Sed * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20252723Sdim *
21263509Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22245431Sdim * or visit www.oracle.com if you need additional information or have any
23193326Sed * questions.
24193326Sed */
25193326Sed
26193326Sedpackage com.sun.tools.javac.file;
27193326Sed
28206084Srdivackyimport java.io.File;
29206084Srdivackyimport java.io.IOException;
30263509Sdimimport java.util.List;
31263509Sdimimport java.util.Map;
32193326Sedimport java.util.concurrent.ConcurrentHashMap;
33193326Sed
34263509Sdimimport com.sun.tools.javac.util.Context;
35226890Sdim
36193326Sed/**
37263509Sdim * Caching implementation of FSInfo.
38263509Sdim *
39263509Sdim * <p><b>This is NOT part of any supported API.
40263509Sdim * If you write code that depends on this, you do so at your own risk.
41212904Sdim * This code and its internal interfaces are subject to change or
42263509Sdim * deletion without notice.</b>
43263509Sdim */
44263509Sdimpublic class CacheFSInfo extends FSInfo {
45193326Sed
46193326Sed    /**
47212904Sdim     * Register a Context.Factory to create a CacheFSInfo.
48193326Sed     */
49193326Sed    public static void preRegister(Context context) {
50212904Sdim        context.put(FSInfo.class, new Context.Factory<FSInfo>() {
51263509Sdim            public FSInfo make(Context c) {
52263509Sdim                FSInfo instance = new CacheFSInfo();
53193326Sed                c.put(FSInfo.class, instance);
54198092Srdivacky                return instance;
55193326Sed            }
56193326Sed        });
57212904Sdim    }
58193326Sed
59193326Sed    public void clearCache() {
60198092Srdivacky        cache.clear();
61193326Sed    }
62212904Sdim
63193326Sed    @Override
64193326Sed    public File getCanonicalFile(File file) {
65212904Sdim        Entry e = getEntry(file);
66263509Sdim        return e.canonicalFile;
67193326Sed    }
68193326Sed
69198092Srdivacky    @Override
70212904Sdim    public boolean exists(File file) {
71198092Srdivacky        Entry e = getEntry(file);
72193326Sed        return e.exists;
73212904Sdim    }
74193326Sed
75193326Sed    @Override
76263509Sdim    public boolean isDirectory(File file) {
77263509Sdim        Entry e = getEntry(file);
78263509Sdim        return e.isDirectory;
79263509Sdim    }
80212904Sdim
81263509Sdim    @Override
82193326Sed    public boolean isFile(File file) {
83193326Sed        Entry e = getEntry(file);
84263509Sdim        return e.isFile;
85263509Sdim    }
86263509Sdim
87263509Sdim    @Override
88263509Sdim    public List<File> getJarClassPath(File file) throws IOException {
89263509Sdim        // don't bother to lock the cache, because it is thread-safe, and
90263509Sdim        // because the worst that can happen would be to create two identical
91263509Sdim        // jar class paths together and have one overwrite the other.
92263509Sdim        Entry e = getEntry(file);
93263509Sdim        if (e.jarClassPath == null)
94263509Sdim            e.jarClassPath = super.getJarClassPath(file);
95263509Sdim        return e.jarClassPath;
96263509Sdim    }
97263509Sdim
98263509Sdim    private Entry getEntry(File file) {
99193326Sed        // don't bother to lock the cache, because it is thread-safe, and
100193326Sed        // because the worst that can happen would be to create two identical
101212904Sdim        // entries together and have one overwrite the other.
102212904Sdim        Entry e = cache.get(file);
103212904Sdim        if (e == null) {
104212904Sdim            e = new Entry();
105212904Sdim            e.canonicalFile = super.getCanonicalFile(file);
106193326Sed            e.exists = super.exists(file);
107193326Sed            e.isDirectory = super.isDirectory(file);
108200583Srdivacky            e.isFile = super.isFile(file);
109200583Srdivacky            cache.put(file, e);
110200583Srdivacky        }
111200583Srdivacky        return e;
112200583Srdivacky    }
113212904Sdim
114200583Srdivacky    // could also be a Map<File,SoftReference<Entry>> ?
115200583Srdivacky    private Map<File,Entry> cache = new ConcurrentHashMap<>();
116200583Srdivacky
117212904Sdim    private static class Entry {
118212904Sdim        File canonicalFile;
119200583Srdivacky        boolean exists;
120200583Srdivacky        boolean isFile;
121200583Srdivacky        boolean isDirectory;
122212904Sdim        List<File> jarClassPath;
123200583Srdivacky    }
124200583Srdivacky}
125200583Srdivacky