/** * Copyright 2011-2017 Asakusa Framework Team. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.asakusafw.utils.java.jsr199.testing; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.text.MessageFormat; import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; /** * Represents a Java class file which is stored on the heap. */ public class VolatileClassFile extends SimpleJavaFileObject { /** * The schema name of this kind of resources. */ public static final String SCHEME = VolatileClassFile.class.getName(); private final String binaryName; volatile byte[] contents; /** * Creates a new instance with empty contents. * @param binaryName the binary name of the target class * @throws IllegalArgumentException if the binary name is invalid */ public VolatileClassFile(String binaryName) { this(binaryName, new byte[0]); } /** * Creates a new instance with the specified contents. * @param binaryName the binary name of the target class * @param contents the class file image * @throws IllegalArgumentException if the binary name is invalid */ public VolatileClassFile(String binaryName, byte[] contents) { super(toUri(binaryName), JavaFileObject.Kind.CLASS); assert binaryName != null; if (contents == null) { throw new IllegalArgumentException("contents must not be null"); //$NON-NLS-1$ } this.binaryName = binaryName; this.contents = contents.clone(); } private static URI toUri(String binaryName) { if (binaryName == null) { throw new IllegalArgumentException("binaryName must not be null"); //$NON-NLS-1$ } String path = toPath(binaryName); try { return new URI( SCHEME, null, "/" + path, //$NON-NLS-1$ null); } catch (URISyntaxException e) { throw new IllegalArgumentException( MessageFormat.format( "Invalid binary name \"{0}\"", binaryName), e); } } private static String toPath(String binaryName) { assert binaryName != null; String path = binaryName.replace('.', '/'); return path + JavaFileObject.Kind.CLASS.extension; } @Override public InputStream openInputStream() { return new ByteArrayInputStream(contents); } @Override public OutputStream openOutputStream() { contents = new byte[0]; return new ByteArrayOutputStream() { @Override public void close() { contents = toByteArray(); } }; } /** * Returns the binary name of this class file. * @return the class binary name */ public String getBinaryName() { return binaryName; } /** * Returns the contents of this class file. * @return the class file contents, or an empty array if the contents have never been set */ public byte[] getBinaryContent() { return contents.clone(); } }