1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you 5 * may not use this file except in compliance with the License. You may obtain a 6 * copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 package com.android.ide.eclipse.tests; 17 18 import com.android.SdkConstants; 19 import com.android.ide.eclipse.adt.AdtConstants; 20 import com.android.ide.eclipse.adt.AdtPlugin; 21 22 import org.eclipse.core.runtime.FileLocator; 23 import org.eclipse.core.runtime.Platform; 24 25 import java.io.File; 26 import java.io.IOException; 27 import java.net.URL; 28 import java.util.logging.Logger; 29 30 /** 31 * Helper class for retrieving test data 32 * <p/> 33 * All tests which need to retrieve paths to test data files should go through this class. 34 */ 35 public class AdtTestData { 36 37 /** singleton instance */ 38 private static AdtTestData sInstance = null; 39 private static final Logger sLogger = Logger.getLogger(AdtTestData.class.getName()); 40 41 /** The prefered directory separator to use. */ 42 private static final String DIR_SEP_STR = "/"; 43 private static final char DIR_SEP_CHAR = '/'; 44 45 /** The absolute file path to the plugin's contents. */ 46 private String mOsRootDataPath; 47 AdtTestData()48 private AdtTestData() { 49 // can set test_data env variable to override default behavior of 50 // finding data using class loader 51 // useful when running in plugin environment, where test data is inside 52 // bundled jar, and must be extracted to temp filesystem location to be 53 // accessed normally 54 mOsRootDataPath = System.getProperty("test_data"); 55 if (mOsRootDataPath == null) { 56 sLogger.info("Cannot find test_data environment variable, init to class loader"); 57 URL url = this.getClass().getClassLoader().getResource("."); //$NON-NLS-1$ 58 59 if (Platform.isRunning()) { 60 sLogger.info("Running as an Eclipse Plug-in JUnit test, using FileLocator"); 61 try { 62 mOsRootDataPath = FileLocator.resolve(url).getFile(); 63 if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) { 64 // Fix the path returned by the URL resolver 65 // so that it actually works on Windows. 66 67 // First, Windows paths don't start with a / especially 68 // if they contain a drive spec such as C:/... 69 int pos = mOsRootDataPath.indexOf(':'); 70 if (pos > 0 && mOsRootDataPath.charAt(0) == '/') { 71 mOsRootDataPath = mOsRootDataPath.substring(1); 72 } 73 74 // Looking for "." probably inserted a /./, so clean it up 75 mOsRootDataPath = mOsRootDataPath.replace("/./", "/"); 76 } 77 } catch (IOException e) { 78 sLogger.warning("IOException while using FileLocator, reverting to url"); 79 mOsRootDataPath = url.getFile(); 80 } 81 } else { 82 sLogger.info("Running as an plain JUnit test, using url as-is"); 83 mOsRootDataPath = url.getFile(); 84 } 85 } 86 87 if (mOsRootDataPath.equals(AdtConstants.WS_SEP)) { 88 sLogger.warning("Resource data not found using class loader!, Defaulting to no path"); 89 } 90 91 if (File.separatorChar == '\\') { 92 // On Windows, uniformize all separators to use the / convention 93 mOsRootDataPath.replace('\\', DIR_SEP_CHAR); 94 } 95 96 if (!mOsRootDataPath.endsWith(File.separator) && !mOsRootDataPath.endsWith(DIR_SEP_STR)) { 97 sLogger.info("Fixing test_data env variable (does not end with path separator)"); 98 mOsRootDataPath += DIR_SEP_STR; 99 } 100 } 101 102 /** Get the singleton instance of AdtTestData */ getInstance()103 public static AdtTestData getInstance() { 104 if (sInstance == null) { 105 sInstance = new AdtTestData(); 106 } 107 return sInstance; 108 } 109 110 /** 111 * Returns the absolute file path to a file located in this plugin. 112 * 113 * @param osRelativePath {@link String} path to file contained in plugin. Must 114 * use path separators appropriate to host OS 115 * 116 * @return absolute OS path to test file 117 */ getTestFilePath(String osRelativePath)118 public String getTestFilePath(String osRelativePath) { 119 File path = new File(mOsRootDataPath, osRelativePath); 120 121 if (!path.exists()) { 122 // On Windows at least this ends up using the wrong plugin path. 123 String pkgAdt = AdtPlugin .class.getPackage().getName(); 124 String pkgTests = AdtTestData.class.getPackage().getName(); 125 126 if (mOsRootDataPath.contains(pkgAdt)) { 127 path = new File(mOsRootDataPath.replace(pkgAdt, pkgTests), osRelativePath); 128 } 129 130 assert path.exists(); 131 } 132 133 return path.getAbsolutePath(); 134 } 135 } 136