123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- /*******************************************************************************
- * Copyright (c) 2012 Contributors.
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Lyor Goldstein (vmware) add support for weaved class being re-defined
- *******************************************************************************/
- package org.aspectj.weaver.tools.cache;
-
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.ObjectOutputStream;
- import java.io.StreamCorruptedException;
- import java.net.MalformedURLException;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.net.URL;
- import java.security.CodeSource;
- import java.security.ProtectionDomain;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.Collections;
-
- import org.aspectj.util.FileUtil;
- import org.aspectj.util.LangUtil;
- import org.aspectj.weaver.tools.cache.AbstractIndexedFileCacheBacking.IndexEntry;
-
- import junit.framework.TestCase;
-
- /**
- */
- public abstract class AbstractCacheBackingTestSupport extends TestCase {
- public static final String JAR_FILE_SUFFIX=".jar";
- /**
- * Prefix used in URL(s) that reference a resource inside a JAR
- */
- public static final String JAR_URL_PREFIX="jar:";
- /**
- * Separator used in URL(s) that reference a resource inside a JAR
- * to denote the sub-path inside the JAR
- */
- public static final char RESOURCE_SUBPATH_SEPARATOR='!';
-
- private File targetFolder;
- private File testTempFolder;
- protected File root;
-
- public static final String TEMP_SUBFOLDER_NAME="temp";
-
- protected AbstractCacheBackingTestSupport() {
- super();
- }
-
- protected AbstractCacheBackingTestSupport(String name) {
- super(name);
- }
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- if (root == null) {
- root = createTempFile("aspectj", "testdir");
- FileUtil.deleteContents(root);
- }
- }
-
- @Override
- public void tearDown() throws Exception {
- if (root != null) {
- FileUtil.deleteContents(root);
- root = null;
- }
-
- if (targetFolder != null) {
- FileUtil.deleteContents(targetFolder);
- }
-
- super.tearDown();
- }
-
- protected File ensureTempFolderExists () throws IllegalStateException {
- synchronized(TEMP_SUBFOLDER_NAME) {
- if (testTempFolder == null) {
- File parent=detectTargetFolder();
- testTempFolder = new File(parent, TEMP_SUBFOLDER_NAME);
- }
- }
-
- return ensureFolderExists(testTempFolder);
- }
-
- protected File detectTargetFolder () throws IllegalStateException {
- synchronized(TEMP_SUBFOLDER_NAME) {
- if (targetFolder == null) {
- try {
- File targetFolder = File.createTempFile("ajc", "TmpCacheDir");
- targetFolder.delete();
- targetFolder.mkdirs();
- } catch (IOException e) {
- throw new IllegalStateException("Unable to create cache dir",e);
- }
-
-
- // if ((targetFolder=detectTargetFolder(getClass())) == null) {
- //
- //// throw new IllegalStateException("Failed to detect target folder");
- // }
- }
- }
-
- return targetFolder;
- }
-
- protected File createTempFile (String prefix, String suffix) throws IOException {
- File destFolder=ensureTempFolderExists();
- return File.createTempFile(prefix, suffix, destFolder);
- }
-
- public static final File ensureFolderExists (File folder) throws IllegalStateException {
- if (folder == null) {
- throw new IllegalArgumentException("No folder to ensure existence");
- }
-
- if ((!folder.exists()) && (!folder.mkdirs())) {
- throw new IllegalStateException("Failed to create " + folder.getAbsolutePath());
- }
-
- return folder;
- }
- /**
- * @param anchor An anchor {@link Class} whose container we want to use
- * as the starting point for the "target" folder lookup up the
- * hierarchy
- * @return The "target" <U>folder</U> - <code>null</code> if not found
- * @see #detectTargetFolder(File)
- */
- public static final File detectTargetFolder (Class<?> anchor) {
- return detectTargetFolder(getClassContainerLocationFile(anchor));
- }
-
- /**
- * @param anchorFile An anchor {@link File) we want to use
- * as the starting point for the "target" folder lookup up the
- * hierarchy
- * @return The "target" <U>folder</U> - <code>null</code> if not found
- */
- public static final File detectTargetFolder (File anchorFile) {
- for (File file=anchorFile; file != null; file=file.getParentFile()) {
- if (!file.isDirectory()) {
- continue;
- }
-
- String name=file.getName();
- if ("target".equals(name) || "bin".equals(name) || "src".equals(name)) {
- File parent=file.getParentFile();
- return new File(parent, "target2");
- }
- }
-
- return null;
- }
-
- /**
- * @param clazz A {@link Class} object
- * @return A {@link File} of the location of the class bytes container
- * - e.g., the root folder, the containing JAR, etc.. Returns
- * <code>null</code> if location could not be resolved
- * @throws IllegalArgumentException If location is not a valid
- * {@link File} location
- * @see #getClassContainerLocationURI(Class)
- * @see File#File(URI)
- */
- public static File getClassContainerLocationFile (Class<?> clazz)
- throws IllegalArgumentException {
- try {
- URI uri=getClassContainerLocationURI(clazz);
- return (uri == null) ? null : new File(uri);
- } catch(URISyntaxException e) {
- throw new IllegalArgumentException(e.getClass().getSimpleName() + ": " + e.getMessage(), e);
- }
- }
-
- /**
- * @param clazz A {@link Class} object
- * @return A {@link URI} to the location of the class bytes container
- * - e.g., the root folder, the containing JAR, etc.. Returns
- * <code>null</code> if location could not be resolved
- * @throws URISyntaxException if location is not a valid URI
- * @see #getClassContainerLocationURL(Class)
- */
- public static URI getClassContainerLocationURI (Class<?> clazz) throws URISyntaxException {
- URL url=getClassContainerLocationURL(clazz);
- return (url == null) ? null : url.toURI();
- }
-
- /**
- * @param clazz A {@link Class} object
- * @return A {@link URL} to the location of the class bytes container
- * - e.g., the root folder, the containing JAR, etc.. Returns
- * <code>null</code> if location could not be resolved
- */
- public static URL getClassContainerLocationURL (Class<?> clazz) {
- ProtectionDomain pd=clazz.getProtectionDomain();
- CodeSource cs=(pd == null) ? null : pd.getCodeSource();
- URL url=(cs == null) ? null : cs.getLocation();
- if (url == null) {
- ClassLoader cl=getDefaultClassLoader(clazz);
- String className=clazz.getName().replace('.', '/') + ".class";
- if ((url=cl.getResource(className)) == null) {
- return null;
- }
-
- String srcForm=getURLSource(url);
- if (LangUtil.isEmpty(srcForm)) {
- return null;
- }
-
- try {
- url = new URL(srcForm);
- } catch(MalformedURLException e) {
- throw new IllegalArgumentException("getClassContainerLocationURL(" + clazz.getName() + ")"
- + "Failed to create URL=" + srcForm + " from " + url.toExternalForm()
- + ": " + e.getMessage());
- }
- }
-
- return url;
- }
- /**
- * @param anchor An "anchor" {@link Class} to be used in case
- * no thread context loader is available
- * @return A {@link ClassLoader} to be used by the caller. The loader is
- * resolved in the following manner:</P></BR>
- * <UL>
- * <LI>
- * If a non-<code>null</code> loader is returned from the
- * {@link Thread#getContextClassLoader()} call then use it.
- * </LI>
- *
- * <LI>
- * Otherwise, use the same loader that was used to load the anchor class.
- * </LI>
- * </UL>
- * @throws IllegalArgumentException if no anchor class provided (regardless of
- * whether it is used or not)
- */
- public static ClassLoader getDefaultClassLoader(Class<?> anchor) {
- if (anchor == null) {
- throw new IllegalArgumentException("No anchor class provided");
- }
-
- Thread t=Thread.currentThread();
- ClassLoader cl=t.getContextClassLoader();
- if (cl == null) {
- // No thread context class loader -> use class loader of this class.
- cl = anchor.getClassLoader();
- }
-
- if (cl == null) { // no class loader - assume system
- cl = ClassLoader.getSystemClassLoader();
- }
-
- return cl;
-
- }
- public static final String getURLSource (File file) {
- return getURLSource((file == null) ? null : file.toURI());
- }
-
- public static final String getURLSource (URI uri) {
- return getURLSource((uri == null) ? null : uri.toString());
- }
-
- /**
- * @param url The {@link URL} value - ignored if <code>null</code>
- * @return The URL(s) source path where {@link #JAR_URL_PREFIX} and
- * any sub-resource are stripped
- * @see #getURLSource(String)
- */
- public static final String getURLSource (URL url) {
- return getURLSource((url == null) ? null : url.toExternalForm());
- }
-
- /**
- * @param externalForm The {@link URL#toExternalForm()} string - ignored if
- * <code>null</code>/empty
- * @return The URL(s) source path where {@link #JAR_URL_PREFIX} and
- * any sub-resource are stripped
- */
- public static final String getURLSource (String externalForm) {
- String url=externalForm;
- if (LangUtil.isEmpty(url)) {
- return url;
- }
-
- url = stripJarURLPrefix(externalForm);
- if (LangUtil.isEmpty(url)){
- return url;
- }
-
- int sepPos=url.indexOf(RESOURCE_SUBPATH_SEPARATOR);
- if (sepPos < 0) {
- return adjustURLPathValue(url);
- } else {
- return adjustURLPathValue(url.substring(0, sepPos));
- }
- }
-
- /**
- * @param path A URL path value
- * @return The path after stripping any trailing '/' provided the path
- * is not '/' itself
- */
- public static final String adjustURLPathValue(final String path) {
- final int pathLen=LangUtil.isEmpty(path) ? 0 : path.length();
- if ((pathLen <= 1) || (path.charAt(pathLen - 1) != '/')) {
- return path;
- }
-
- return path.substring(0, pathLen - 1);
- }
-
- public static final String adjustURLPathValue(URL url) {
- return adjustURLPathValue((url == null) ? null : url.getPath());
- }
-
- public static String stripJarURLPrefix(String externalForm) {
- String url=externalForm;
- if (LangUtil.isEmpty(url)) {
- return url;
- }
-
- if (url.startsWith(JAR_URL_PREFIX)) {
- return url.substring(JAR_URL_PREFIX.length());
- }
-
- return url;
- }
-
- protected static final void writeIndex (File indexFile, IndexEntry ... entries) throws IOException {
- writeIndex(indexFile, LangUtil.isEmpty(entries) ? Collections.<IndexEntry>emptyList() : Arrays.asList(entries));
- }
-
- protected static final void writeIndex (File indexFile, Collection<? extends IndexEntry> entries) throws IOException {
- File indexDir=indexFile.getParentFile();
- if ((!indexDir.exists()) && (!indexDir.mkdirs())) {
- throw new IOException("Failed to create path to " + indexFile.getAbsolutePath());
- }
-
- int numEntries=LangUtil.isEmpty(entries) ? 0 : entries.size();
- IndexEntry[] entryValues=(numEntries <= 0) ? null : entries.toArray(new IndexEntry[numEntries]);
- // if no entries, simply delete the index file
- if (LangUtil.isEmpty(entryValues)) {
- if (indexFile.exists() && (!indexFile.delete())) {
- throw new StreamCorruptedException("Failed to clean up index file at " + indexFile.getAbsolutePath());
- }
-
- return;
- }
-
- ObjectOutputStream oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(indexFile), 4096));
- try {
- oos.writeObject(entryValues);
- } finally {
- oos.close();
- }
- }
-
- public static final void assertArrayEquals (String msg, byte[] expected, byte[] actual) {
- int eLen=LangUtil.isEmpty(expected) ? 0 : expected.length;
- int aLen=LangUtil.isEmpty(actual) ? 0 : expected.length;
- assertEquals(msg + "[mismatched length]", eLen, aLen);
-
- for (int index=0; index < eLen; index++) {
- byte eb=expected[index], ab=actual[index];
- if (eb != ab) {
- fail(msg + ": Mismatched value at index=" + index
- + " - " + ab + " instead of " + eb
- + ": expected=" + Arrays.toString(expected) + ", actual=" + Arrays.toString(actual));
- }
- }
- }
- }
|