SimpleJavaFileObject.java revision 2571:10fc81ac75b4
1/*
2 * Copyright (c) 2005, 2006, 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.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.tools;
27
28import java.io.*;
29import java.net.URI;
30import java.nio.CharBuffer;
31import javax.lang.model.element.Modifier;
32import javax.lang.model.element.NestingKind;
33import javax.tools.JavaFileObject.Kind;
34
35/**
36 * Provides simple implementations for most methods in JavaFileObject.
37 * This class is designed to be subclassed and used as a basis for
38 * JavaFileObject implementations.  Subclasses can override the
39 * implementation and specification of any method of this class as
40 * long as the general contract of JavaFileObject is obeyed.
41 *
42 * @author Peter von der Ahé
43 * @since 1.6
44 */
45public class SimpleJavaFileObject implements JavaFileObject {
46    /**
47     * A URI for this file object.
48     */
49    protected final URI uri;
50
51    /**
52     * The kind of this file object.
53     */
54    protected final Kind kind;
55
56    /**
57     * Construct a SimpleJavaFileObject of the given kind and with the
58     * given URI.
59     *
60     * @param uri  the URI for this file object
61     * @param kind the kind of this file object
62     */
63    protected SimpleJavaFileObject(URI uri, Kind kind) {
64        // null checks
65        uri.getClass();
66        kind.getClass();
67        if (uri.getPath() == null)
68            throw new IllegalArgumentException("URI must have a path: " + uri);
69        this.uri = uri;
70        this.kind = kind;
71    }
72
73    public URI toUri() {
74        return uri;
75    }
76
77    public String getName() {
78        return toUri().getPath();
79    }
80
81    /**
82     * This implementation always throws {@linkplain
83     * UnsupportedOperationException}.  Subclasses can change this
84     * behavior as long as the contract of {@link FileObject} is
85     * obeyed.
86     */
87    public InputStream openInputStream() throws IOException {
88        throw new UnsupportedOperationException();
89    }
90
91    /**
92     * This implementation always throws {@linkplain
93     * UnsupportedOperationException}.  Subclasses can change this
94     * behavior as long as the contract of {@link FileObject} is
95     * obeyed.
96     */
97    public OutputStream openOutputStream() throws IOException {
98        throw new UnsupportedOperationException();
99    }
100
101    /**
102     * Wraps the result of {@linkplain #getCharContent} in a Reader.
103     * Subclasses can change this behavior as long as the contract of
104     * {@link FileObject} is obeyed.
105     *
106     * @param  ignoreEncodingErrors {@inheritDoc}
107     * @return a Reader wrapping the result of getCharContent
108     * @throws IllegalStateException {@inheritDoc}
109     * @throws UnsupportedOperationException {@inheritDoc}
110     * @throws IOException {@inheritDoc}
111     */
112    public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
113        CharSequence charContent = getCharContent(ignoreEncodingErrors);
114        if (charContent == null)
115            throw new UnsupportedOperationException();
116        if (charContent instanceof CharBuffer) {
117            CharBuffer buffer = (CharBuffer)charContent;
118            if (buffer.hasArray())
119                return new CharArrayReader(buffer.array());
120        }
121        return new StringReader(charContent.toString());
122    }
123
124    /**
125     * This implementation always throws {@linkplain
126     * UnsupportedOperationException}.  Subclasses can change this
127     * behavior as long as the contract of {@link FileObject} is
128     * obeyed.
129     */
130    public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
131        throw new UnsupportedOperationException();
132    }
133
134    /**
135     * Wraps the result of openOutputStream in a Writer.  Subclasses
136     * can change this behavior as long as the contract of {@link
137     * FileObject} is obeyed.
138     *
139     * @return a Writer wrapping the result of openOutputStream
140     * @throws IllegalStateException {@inheritDoc}
141     * @throws UnsupportedOperationException {@inheritDoc}
142     * @throws IOException {@inheritDoc}
143     */
144    public Writer openWriter() throws IOException {
145        return new OutputStreamWriter(openOutputStream());
146    }
147
148    /**
149     * This implementation returns {@code 0L}.  Subclasses can change
150     * this behavior as long as the contract of {@link FileObject} is
151     * obeyed.
152     *
153     * @return {@code 0L}
154     */
155    public long getLastModified() {
156        return 0L;
157    }
158
159    /**
160     * This implementation does nothing.  Subclasses can change this
161     * behavior as long as the contract of {@link FileObject} is
162     * obeyed.
163     *
164     * @return {@code false}
165     */
166    public boolean delete() {
167        return false;
168    }
169
170    /**
171     * @return {@code this.kind}
172     */
173    public Kind getKind() {
174        return kind;
175    }
176
177    /**
178     * This implementation compares the path of its URI to the given
179     * simple name.  This method returns true if the given kind is
180     * equal to the kind of this object, and if the path is equal to
181     * {@code simpleName + kind.extension} or if it ends with {@code
182     * "/" + simpleName + kind.extension}.
183     *
184     * <p>This method calls {@link #getKind} and {@link #toUri} and
185     * does not access the fields {@link #uri} and {@link #kind}
186     * directly.
187     *
188     * <p>Subclasses can change this behavior as long as the contract
189     * of {@link JavaFileObject} is obeyed.
190     */
191    public boolean isNameCompatible(String simpleName, Kind kind) {
192        String baseName = simpleName + kind.extension;
193        return kind.equals(getKind())
194            && (baseName.equals(toUri().getPath())
195                || toUri().getPath().endsWith("/" + baseName));
196    }
197
198    /**
199     * This implementation returns {@code null}.  Subclasses can
200     * change this behavior as long as the contract of
201     * {@link JavaFileObject} is obeyed.
202     */
203    public NestingKind getNestingKind() { return null; }
204
205    /**
206     * This implementation returns {@code null}.  Subclasses can
207     * change this behavior as long as the contract of
208     * {@link JavaFileObject} is obeyed.
209     */
210    public Modifier getAccessLevel()  { return null; }
211
212    @Override
213    public String toString() {
214        return getClass().getName() + "[" + toUri() + "]";
215    }
216}
217