FileManager.java revision 3294:9adfb22ff08f
1321936Shselasky/*
2321936Shselasky * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
3321936Shselasky * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4321936Shselasky *
5321936Shselasky * This code is free software; you can redistribute it and/or modify it
6321936Shselasky * under the terms of the GNU General Public License version 2 only, as
7321936Shselasky * published by the Free Software Foundation.
8321936Shselasky *
9321936Shselasky * This code is distributed in the hope that it will be useful, but WITHOUT
10321936Shselasky * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11321936Shselasky * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12321936Shselasky * version 2 for more details (a copy is included in the LICENSE file that
13321936Shselasky * accompanied this code).
14321936Shselasky *
15321936Shselasky * You should have received a copy of the GNU General Public License version
16321936Shselasky * 2 along with this work; if not, write to the Free Software Foundation,
17321936Shselasky * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18321936Shselasky *
19321936Shselasky * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20321936Shselasky * or visit www.oracle.com if you need additional information or have any
21321936Shselasky * questions.
22321936Shselasky */
23321936Shselasky
24321936Shselaskyimport java.io.File;
25321936Shselaskyimport java.io.IOException;
26321936Shselaskyimport java.io.InputStream;
27321936Shselaskyimport java.io.OutputStream;
28321936Shselaskyimport java.io.Reader;
29321936Shselaskyimport java.io.Writer;
30321936Shselaskyimport java.net.URI;
31321936Shselaskyimport java.util.ArrayList;
32321936Shselaskyimport java.util.Collections;
33321936Shselaskyimport java.util.List;
34321936Shselaskyimport java.util.Objects;
35321936Shselaskyimport java.util.regex.Pattern;
36321936Shselaskyimport javax.lang.model.element.Modifier;
37321936Shselaskyimport javax.lang.model.element.NestingKind;
38321936Shselaskyimport javax.tools.JavaFileManager.Location;
39321936Shselaskyimport javax.tools.JavaFileObject;
40321936Shselaskyimport javax.tools.StandardJavaFileManager;
41321936Shselasky
42321936Shselaskyimport com.sun.tools.javac.api.WrappingJavaFileManager;
43321936Shselasky
44321936Shselasky/**
45321936Shselasky * A JavaFileManager that can throw IOException on attempting to read or write
46321936Shselasky * selected files that match a regular expression.
47321936Shselasky */
48321936Shselaskypublic class FileManager
49321936Shselasky        extends WrappingJavaFileManager<StandardJavaFileManager>
50321936Shselasky        implements StandardJavaFileManager {
51321936Shselasky    private static final String CANT_READ = "cantRead:";
52321936Shselasky    private static final String CANT_WRITE = "cantWrite:";
53321936Shselasky
54321936Shselasky    private Pattern cantRead;
55321936Shselasky    private Pattern cantWrite;
56321936Shselasky
57321936Shselasky    public FileManager(StandardJavaFileManager fm, List<String> opts) {
58321936Shselasky        super(fm);
59321936Shselasky        for (String opt: opts) {
60321936Shselasky            if (opt.startsWith(CANT_READ))
61321936Shselasky                cantRead = Pattern.compile(opt.substring(CANT_READ.length()));
62321936Shselasky            else if (opt.startsWith(CANT_WRITE))
63321936Shselasky                cantWrite = Pattern.compile(opt.substring(CANT_WRITE.length()));
64            else
65                throw new IllegalArgumentException(opt);
66        }
67    }
68
69    @Override
70    protected JavaFileObject wrap(JavaFileObject fo) {
71        return (fo == null) ? null : new WrappedFileObject(fo);
72    }
73
74    @Override
75    protected JavaFileObject unwrap(JavaFileObject fo) {
76        if (fo instanceof WrappedFileObject)
77            return ((WrappedFileObject) fo).delegate;
78        else
79            return fo;
80    }
81
82    public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
83        return wrap2(fileManager.getJavaFileObjectsFromFiles(files));
84    }
85
86    public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
87        return wrap2(fileManager.getJavaFileObjects(files));
88    }
89
90    public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
91        return wrap2(fileManager.getJavaFileObjectsFromStrings(names));
92    }
93
94    public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
95        return wrap2(fileManager.getJavaFileObjects(names));
96    }
97
98    /* This method is regrettably necessary because WrappingJavaFileManager.wrap takes
99     *          Iterable<JavaFileObject> fileObjects
100     * instead of
101     *          Iterable<? extends JavaFileObject> fileObjects
102     */
103    protected Iterable<JavaFileObject> wrap2(Iterable<? extends JavaFileObject> fileObjects) {
104        List<JavaFileObject> mapped = new ArrayList<JavaFileObject>();
105        for (JavaFileObject fileObject : fileObjects)
106            mapped.add(wrap(fileObject));
107        return Collections.unmodifiableList(mapped);
108    }
109
110    public void setLocation(Location location, Iterable<? extends File> path) throws IOException {
111        fileManager.setLocation(location, path);
112    }
113
114    public Iterable<? extends File> getLocation(Location location) {
115        return fileManager.getLocation(location);
116    }
117
118    class WrappedFileObject implements JavaFileObject {
119        WrappedFileObject(JavaFileObject fileObject) {
120            delegate = Objects.requireNonNull(fileObject);
121        }
122
123        public Kind getKind() {
124            return delegate.getKind();
125        }
126
127        public boolean isNameCompatible(String simpleName, Kind kind) {
128            return delegate.isNameCompatible(simpleName, kind);
129        }
130
131        public NestingKind getNestingKind() {
132            return delegate.getNestingKind();
133        }
134
135        public Modifier getAccessLevel() {
136            return delegate.getAccessLevel();
137        }
138
139        public URI toUri() {
140            return delegate.toUri();
141        }
142
143        public String getName() {
144            return delegate.getName();
145        }
146
147        public InputStream openInputStream() throws IOException {
148            checkRead();
149            return delegate.openInputStream();
150        }
151
152        public OutputStream openOutputStream() throws IOException {
153            checkWrite();
154            return delegate.openOutputStream();
155        }
156
157        public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
158            checkRead();
159            return delegate.openReader(ignoreEncodingErrors);
160        }
161
162        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
163            checkRead();
164            return delegate.getCharContent(ignoreEncodingErrors);
165        }
166
167        public Writer openWriter() throws IOException {
168            checkWrite();
169            return delegate.openWriter();
170        }
171
172        public long getLastModified() {
173            return delegate.getLastModified();
174        }
175
176        public boolean delete() {
177            return delegate.delete();
178        }
179
180        void checkRead() throws IOException {
181            String canonName = getName().replace(File.separatorChar, '/');
182            if (cantRead != null && cantRead.matcher(canonName).matches())
183                throw new IOException("FileManager: Can't read");
184        }
185
186        void checkWrite() throws IOException {
187            String canonName = getName().replace(File.separatorChar, '/');
188            if (cantWrite != null && cantWrite.matcher(canonName).matches())
189                throw new IOException("FileManager: Can't write");
190        }
191
192        JavaFileObject delegate;
193    }
194}
195