001: /*
002: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package javax.tools;
027:
028: import java.io.*;
029: import java.net.URI;
030: import java.net.URISyntaxException;
031: import java.nio.CharBuffer;
032: import javax.lang.model.element.Modifier;
033: import javax.lang.model.element.NestingKind;
034: import javax.tools.JavaFileObject.Kind;
035:
036: /**
037: * Provides simple implementations for most methods in JavaFileObject.
038: * This class is designed to be subclassed and used as a basis for
039: * JavaFileObject implementations. Subclasses can override the
040: * implementation and specification of any method of this class as
041: * long as the general contract of JavaFileObject is obeyed.
042: *
043: * @author Peter von der Ahé
044: * @since 1.6
045: */
046: public class SimpleJavaFileObject implements JavaFileObject {
047: /**
048: * A URI for this file object.
049: */
050: protected final URI uri;
051:
052: /**
053: * The kind of this file object.
054: */
055: protected final Kind kind;
056:
057: /**
058: * Construct a SimpleJavaFileObject of the given kind and with the
059: * given URI.
060: *
061: * @param uri the URI for this file object
062: * @param kind the kind of this file object
063: */
064: protected SimpleJavaFileObject(URI uri, Kind kind) {
065: // null checks
066: uri.getClass();
067: kind.getClass();
068: if (uri.getPath() == null)
069: throw new IllegalArgumentException("URI must have a path: "
070: + uri);
071: this .uri = uri;
072: this .kind = kind;
073: }
074:
075: public URI toUri() {
076: return uri;
077: }
078:
079: public String getName() {
080: return toUri().getPath();
081: }
082:
083: /**
084: * This implementation always throws {@linkplain
085: * UnsupportedOperationException}. Subclasses can change this
086: * behavior as long as the contract of {@link FileObject} is
087: * obeyed.
088: */
089: public InputStream openInputStream() throws IOException {
090: throw new UnsupportedOperationException();
091: }
092:
093: /**
094: * This implementation always throws {@linkplain
095: * UnsupportedOperationException}. Subclasses can change this
096: * behavior as long as the contract of {@link FileObject} is
097: * obeyed.
098: */
099: public OutputStream openOutputStream() throws IOException {
100: throw new UnsupportedOperationException();
101: }
102:
103: /**
104: * Wraps the result of {@linkplain #getCharContent} in a Reader.
105: * Subclasses can change this behavior as long as the contract of
106: * {@link FileObject} is obeyed.
107: *
108: * @param ignoreEncodingErrors {@inheritDoc}
109: * @return a Reader wrapping the result of getCharContent
110: * @throws IllegalStateException {@inheritDoc}
111: * @throws UnsupportedOperationException {@inheritDoc}
112: * @throws IOException {@inheritDoc}
113: */
114: public Reader openReader(boolean ignoreEncodingErrors)
115: throws IOException {
116: CharSequence charContent = getCharContent(ignoreEncodingErrors);
117: if (charContent == null)
118: throw new UnsupportedOperationException();
119: if (charContent instanceof CharBuffer) {
120: CharBuffer buffer = (CharBuffer) charContent;
121: if (buffer.hasArray())
122: return new CharArrayReader(buffer.array());
123: }
124: return new StringReader(charContent.toString());
125: }
126:
127: /**
128: * This implementation always throws {@linkplain
129: * UnsupportedOperationException}. Subclasses can change this
130: * behavior as long as the contract of {@link FileObject} is
131: * obeyed.
132: */
133: public CharSequence getCharContent(boolean ignoreEncodingErrors)
134: throws IOException {
135: throw new UnsupportedOperationException();
136: }
137:
138: /**
139: * Wraps the result of openOutputStream in a Writer. Subclasses
140: * can change this behavior as long as the contract of {@link
141: * FileObject} is obeyed.
142: *
143: * @return a Writer wrapping the result of openOutputStream
144: * @throws IllegalStateException {@inheritDoc}
145: * @throws UnsupportedOperationException {@inheritDoc}
146: * @throws IOException {@inheritDoc}
147: */
148: public Writer openWriter() throws IOException {
149: return new OutputStreamWriter(openOutputStream());
150: }
151:
152: /**
153: * This implementation returns {@code 0L}. Subclasses can change
154: * this behavior as long as the contract of {@link FileObject} is
155: * obeyed.
156: *
157: * @return {@code 0L}
158: */
159: public long getLastModified() {
160: return 0L;
161: }
162:
163: /**
164: * This implementation does nothing. Subclasses can change this
165: * behavior as long as the contract of {@link FileObject} is
166: * obeyed.
167: *
168: * @return {@code false}
169: */
170: public boolean delete() {
171: return false;
172: }
173:
174: /**
175: * @return {@code this.kind}
176: */
177: public Kind getKind() {
178: return kind;
179: }
180:
181: /**
182: * This implementation compares the path of its URI to the given
183: * simple name. This method returns true if the given kind is
184: * equal to the kind of this object, and if the path is equal to
185: * {@code simpleName + kind.extension} or if it ends with {@code
186: * "/" + simpleName + kind.extension}.
187: *
188: * <p>This method calls {@link #getKind} and {@link #toUri} and
189: * does not access the fields {@link #uri} and {@link #kind}
190: * directly.
191: *
192: * <p>Subclasses can change this behavior as long as the contract
193: * of {@link JavaFileObject} is obeyed.
194: */
195: public boolean isNameCompatible(String simpleName, Kind kind) {
196: String baseName = simpleName + kind.extension;
197: return kind.equals(getKind())
198: && (baseName.equals(toUri().getPath()) || toUri()
199: .getPath().endsWith("/" + baseName));
200: }
201:
202: /**
203: * This implementation returns {@code null}. Subclasses can
204: * change this behavior as long as the contract of
205: * {@link JavaFileObject} is obeyed.
206: */
207: public NestingKind getNestingKind() {
208: return null;
209: }
210:
211: /**
212: * This implementation returns {@code null}. Subclasses can
213: * change this behavior as long as the contract of
214: * {@link JavaFileObject} is obeyed.
215: */
216: public Modifier getAccessLevel() {
217: return null;
218: }
219:
220: @Override
221: public String toString() {
222: return getClass().getName() + "[" + toUri() + "]";
223: }
224: }
|