public class ImageUtil { private static final Logger logger = LogUtil.getLogger(ImageUtil.class); /** fileName capture screen shot */ public static void captureScreenshot(WebDriver driver, String fileName) { String screenshotPath = System.getProperty("user.dir") + File.separator + "screenshot"; if (!new File(screenshotPath).exists()) { new File(screenshotPath).mkdir(); } // Add date and time in current picture file name SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss"); String currentDateTime = sdf.format(new Date()); fileName = fileName + "-" + currentDateTime; String imagePath = screenshotPath + File.separator + fileName + ".png"; try { String base64Screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BASE64); byte[] decodedScreenshot = Base64.decodeBase64(base64Screenshot.getBytes()); File imageFile = new File(imagePath); if (!imageFile.exists()) { if (imageFile.createNewFile()) { logger.debug("New File: " + imageFile.getName() + " has been created!"); } } FileOutputStream fos = new FileOutputStream(imageFile); fos.write(decodedScreenshot); fos.close(); logger.debug("Put screen shot to " + imagePath); } catch (Exception e) { e.printStackTrace(); } } }
/** * 字符解码 * * @see 该方法通常用于对中文进行解码 * @see 若系统不支持指定的解码字符集,则直接将<code>chinese</code>原样返回 */ public static String URLDecode(String chinese, String charset) { chinese = (chinese == null ? "" : chinese); try { return URLDecoder.decode(chinese, charset); } catch (UnsupportedEncodingException e) { LogUtil.getLogger().error("解码字符串[" + chinese + "]时发生异常:系统不支持该字符集[" + charset + "]"); return chinese; } }
/** * 字符串转为字节数组 * * @see 如果系统不支持所传入的<code>charset</code>字符集,则按照系统默认字符集进行转换 */ public static byte[] getBytes(String data, String charset) { data = (data == null ? "" : data); if (isEmpty(charset)) { return data.getBytes(); } try { return data.getBytes(charset); } catch (UnsupportedEncodingException e) { LogUtil.getLogger().error("将字符串[" + data + "]转为byte[]时发生异常:系统不支持该字符集[" + charset + "]"); return data.getBytes(); } }
/** * 字节数组转为字符串 * * @see 如果系统不支持所传入的<code>charset</code>字符集,则按照系统默认字符集进行转换 */ public static String getString(byte[] data, String charset) { if (isEmpty(data)) { return ""; } if (isEmpty(charset)) { return new String(data); } try { return new String(data, charset); } catch (UnsupportedEncodingException e) { LogUtil.getLogger().error("将byte数组[" + data + "]转为String时发生异常:系统不支持该字符集[" + charset + "]"); return new String(data); } }
/** * Abstract Base Class for Simple Pooling Mechanism. Subclasses must at least implement the method * newInstance. To use a Object call lendObject. After use the Object must be returned with * returnObject(Object). An Object must not be used after it has been returned to its pool! * * <p>This class needs a two phase initialization: configure MUST be invoked before an instance can * be used. * * @author Alphonse Bendt * @version $Id: AbstractObjectPool.java,v 1.26 2011-05-10 15:40:39 nick.cross Exp $ */ public abstract class AbstractObjectPool implements Runnable, Configurable { public static final boolean DEBUG = false; /** time the cleaner thread sleeps between two cleanups */ public static final long SLEEP = 5000L; public static final int LOWER_WATERMARK_DEFAULT = 5; public static final int SIZE_INCREASE_DEFAULT = 3; public static final int INITIAL_SIZE_DEFAULT = 10; public static final int MAXIMUM_WATERMARK_DEFAULT = 20; public static final int MAXIMUM_SIZE_DEFAULT = 0; /** non synchronized as all accessing methods are synchronized. */ private static final List sPoolsToLookAfter = new ArrayList(); private static AbstractObjectPool[] asArray; private static boolean modified = true; private static final AbstractObjectPool[] ARRAY_TEMPLATE = new AbstractObjectPool[0]; private static Thread sCleanerThread; private static final Logger sLogger_ = LogUtil.getLogger(AbstractObjectPool.class.getName()); private static ListCleaner sListCleaner; private static boolean sUseListCleaner = true; private static AbstractObjectPool[] getAllPools() { synchronized (sPoolsToLookAfter) { if (modified) { asArray = (AbstractObjectPool[]) sPoolsToLookAfter.toArray(ARRAY_TEMPLATE); modified = false; } } return asArray; } private static void registerPool(AbstractObjectPool pool) { synchronized (sPoolsToLookAfter) { sPoolsToLookAfter.add(pool); modified = true; startListCleaner(); } } private static void deregisterPool(AbstractObjectPool pool) { synchronized (sPoolsToLookAfter) { sPoolsToLookAfter.remove(pool); modified = true; if (sPoolsToLookAfter.isEmpty()) { // this cleans up the asArray_ array for the GC. getAllPools(); stopListCleaner(); } } } private static class ListCleaner extends Thread { private AtomicBoolean active_ = new AtomicBoolean(true); public void setInactive() { active_.set(false); interrupt(); } private void ensureIsActive() throws InterruptedException { if (!active_.get()) { throw new InterruptedException(); } } public void run() { try { while (active_.get()) { try { runLoop(); } catch (InterruptedException e) { sLogger_.info("PoolCleaner was interrupted"); } catch (Exception e) { sLogger_.error("Error cleaning Pool", e); } } } finally { synchronized (AbstractObjectPool.class) { sCleanerThread = null; } } } private void runLoop() throws InterruptedException { while (true) { try { sleep(SLEEP); } catch (InterruptedException ie) { // ignore here. // ensureIsActive is called below to see if this Thread should // still be active. } ensureIsActive(); Runnable[] poolsToCheck = getAllPools(); for (int x = 0; x < poolsToCheck.length; ++x) { try { poolsToCheck[x].run(); } catch (Exception t) { // should not happen sLogger_.error("Error cleaning up Pool", t); } } } } } private static ListCleaner getListCleaner() { synchronized (AbstractObjectPool.class) { if (sListCleaner == null) { sListCleaner = new ListCleaner(); } return sListCleaner; } } private static void stopListCleaner() { synchronized (AbstractObjectPool.class) { if (sCleanerThread != null) { sListCleaner.setInactive(); } } } private static void startListCleaner() { synchronized (AbstractObjectPool.class) { if (sCleanerThread == null && sUseListCleaner) { sCleanerThread = new Thread(getListCleaner()); sCleanerThread.setName("ObjectPoolCleaner"); sCleanerThread.setPriority(Thread.MIN_PRIORITY + 1); sCleanerThread.setDaemon(true); sCleanerThread.start(); } } } private final String name_; private final LinkedList pool_; private boolean isInitialized_; /** * Set that contains all objects that were created by this pool and are in use. Problems occured * as access to this member used to be non-synchronized see * news://news.gmane.org:119/[email protected] */ private final Set active_ = Collections.synchronizedSet(new WeakHashSet()); /** lower watermark. if pool size is below that value, create sizeIncrease_ new elements. */ private int lowerWatermark_; /** * how many instances should the pool maximal keep. instances that are returned to a pool which * size is greater than maxWatermark_ are discarded and left for the Garbage Collector. */ private int maxWatermark_; /** how many instances should be created if pool size falls below lowerWatermark_. */ private int sizeIncrease_; /** how many instances should be created at startup of the pool. */ private int initialSize_; private int maximumSize_; protected final Logger logger_ = LogUtil.getLogger(getClass().getName()); protected Configuration config_; public void configure(Configuration conf) { config_ = conf; init(); } protected AbstractObjectPool(String name) { this( name, LOWER_WATERMARK_DEFAULT, SIZE_INCREASE_DEFAULT, INITIAL_SIZE_DEFAULT, MAXIMUM_WATERMARK_DEFAULT, MAXIMUM_SIZE_DEFAULT); } protected AbstractObjectPool( String name, int lowerWatermark, int sizeincrease, int initialsize, int maxWatermark, int maximumSize) { if (maximumSize > 0 && initialsize > maximumSize) { throw new IllegalArgumentException( "InitialSize: " + initialsize + " may not be larger than MaximumSize: " + maximumSize); } name_ = name; pool_ = new LinkedList(); lowerWatermark_ = lowerWatermark; sizeIncrease_ = sizeincrease; initialSize_ = initialsize; maxWatermark_ = maxWatermark; maximumSize_ = maximumSize; } public void run() { final int maxToBeCreated; synchronized (pool_) { if (pool_.size() > lowerWatermark_) { return; } maxToBeCreated = getNumberOfCreationsAllowed(); } final int sizeIncrease = Math.min(sizeIncrease_, maxToBeCreated); if (sizeIncrease > 0) { List os = new ArrayList(sizeIncrease); for (int x = 0; x < sizeIncrease; ++x) { Object _i = createInstance(); os.add(_i); } synchronized (pool_) { pool_.addAll(os); } } } /** * check the number of instances that are allowed to be created. * * <p><b>preCondition:</b> lock pool_ must be held. */ private int getNumberOfCreationsAllowed() { final int maxToBeCreated; if (maximumSize_ > 0) { maxToBeCreated = maximumSize_ - active_.size() - pool_.size(); } else { maxToBeCreated = Integer.MAX_VALUE; } return maxToBeCreated; } private Object createInstance() { if (logger_.isDebugEnabled()) { logger_.debug("created newInstance " + getInfo()); } return newInstance(); } /** Initialize this Pool. An initial Number of Objects is created. Cleanup Thread is started. */ private void init() { registerPool(this); synchronized (pool_) { if (isInitialized_) { throw new IllegalStateException("Already Initialized"); } for (int x = 0; x < initialSize_; ++x) { Object _i = createInstance(); pool_.add(_i); } isInitialized_ = true; } } /** Release this Pool. */ public void dispose() { deregisterPool(this); disposeCollection(pool_); pool_.clear(); disposeCollection(active_); active_.clear(); } private void disposeCollection(Collection collection) { final Iterator i = collection.iterator(); while (i.hasNext()) { final Object o = i.next(); try { Disposable disposable = (Disposable) o; try { ((AbstractPoolable) o).setObjectPool(null); } catch (ClassCastException e) { // ignored } disposable.dispose(); } catch (ClassCastException e) { // ignored } } } /** lend an object from the pool. */ public Object lendObject() { checkIsInitialized(); Object _result = null; synchronized (pool_) { if (!pool_.isEmpty()) { _result = pool_.removeFirst(); } if (_result == null) { while (!isCreationAllowed()) { poolIsEmpty(); } } } if (_result == null) { _result = createInstance(); } try { ((Configurable) _result).configure(this.config_); } catch (ClassCastException cce) { // no worries, just don't configure } catch (ConfigurationException ce) { throw new RuntimeException("Could not configure instance"); } doActivateObject(_result); active_.add(_result); return _result; } /** */ private void checkIsInitialized() { synchronized (pool_) { if (!isInitialized_) { throw new IllegalStateException("Not initialized"); } } } /** * check if it is allowed to create more instances. * * <p><b>preCondition:</b> lock pool_ must be held. */ protected boolean isCreationAllowed() { return getNumberOfCreationsAllowed() > 0; } /** */ protected void poolIsEmpty() { throw new RuntimeException(getInfo() + ": No more Elements allowed. "); } /** return an Object to the pool. */ public void returnObject(Object o) { checkIsInitialized(); if (active_.remove(o)) { doPassivateObject(o); if (pool_.size() < maxWatermark_) { synchronized (pool_) { pool_.add(o); pool_.notifyAll(); } } else { doDestroyObject(o); } } else { throw new IllegalArgumentException("Object " + o + " was not created by this pool"); } } public String toString() { return getInfo(); } private String getInfo() { return "[" + name_ + "] Active=" + active_.size() + " Pooled=" + pool_.size() + " MaximumSize=" + ((maximumSize_ > 0) ? Integer.toString(maximumSize_) : "unlimited"); } /** * This method is called by the Pool to create a new Instance. Subclasses must override * appropiately . */ public abstract Object newInstance(); /** Is called after Object is returned to pool. No Op. */ public void doPassivateObject(Object o) { // No Op } /** Is called before Object is returned to Client (lendObject). No Op */ public void doActivateObject(Object o) { // No Op } /** Is called if Pool is full and returned Object is discarded. No Op. */ public void doDestroyObject(Object o) { // No Op } }
public class ClassUtil { private static final Logger logger = LogUtil.getLogger(); public static final String CLASS_FILE_EXTENSION = ".class"; public static int BYTE_COUNT_IN_A_ROW_FOR_PRINT = 16; // Not final, it can be set directly private ClassUtil() {} public static String getPathOfClass(Class<?> clazz) { return clazz.getResource(clazz.getSimpleName() + CLASS_FILE_EXTENSION).getPath(); } public static InputStream getInputStreamOfClass(Class<?> clazz) { return clazz.getResourceAsStream(clazz.getSimpleName() + CLASS_FILE_EXTENSION); } public static File getFileOfClass(Class<?> clazz) { try { return new File(clazz.getResource(clazz.getSimpleName() + CLASS_FILE_EXTENSION).toURI()); } catch (URISyntaxException e) { logger.error("Error occured while getting file of class " + clazz.getName(), e); return null; } } public static byte[] getContentOfClass(Class<?> clazz) { File classFile = getFileOfClass(clazz); if (classFile.exists()) { try { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(classFile)); byte[] buffer = new byte[(int) classFile.length()]; bis.read(buffer); return buffer; } catch (IOException e) { logger.error("Error occured while reading content of class " + clazz.getName(), e); } } else { logger.error("Class file for path " + classFile.getAbsolutePath() + " couldn't be found"); } return null; } public static void printContentOfClassFile(Class<?> clazz) { byte[] classContent = getContentOfClass(clazz); if (classContent != null) { for (int i = 0; i < classContent.length; i++) { if (i % BYTE_COUNT_IN_A_ROW_FOR_PRINT == 0) { System.out.print(String.format("[0x%04x]: ", i)); } System.out.print(String.format("%02x ", classContent[i])); if ((i + 1) % BYTE_COUNT_IN_A_ROW_FOR_PRINT == 0) { System.out.println(); } } System.out.println(); } } public static void printContentOfClassFileByShowingPrintableCharacters(Class<?> clazz) { byte[] classContent = getContentOfClass(clazz); if (classContent != null) { for (int i = 0; i < classContent.length; i++) { if (i % BYTE_COUNT_IN_A_ROW_FOR_PRINT == 0) { System.out.print(String.format("[0x%04x]: ", i)); } System.out.print(String.format("%02x ", classContent[i])); if ((i + 1) % BYTE_COUNT_IN_A_ROW_FOR_PRINT == 0) { for (int j = i + 1 - BYTE_COUNT_IN_A_ROW_FOR_PRINT; j <= i; j++) { byte b = classContent[j]; // If non printable character, don't print it, just print dot character if (Util.isPrintableChacter((char) b)) { System.out.print((char) b); } else { System.out.print('.'); } } System.out.println(); } } int remaining = classContent.length % BYTE_COUNT_IN_A_ROW_FOR_PRINT; int complementary = BYTE_COUNT_IN_A_ROW_FOR_PRINT - remaining; if (complementary != 0) { for (int i = 0; i < complementary; i++) { System.out.print(" "); } int start = classContent.length - remaining; for (int j = 0; j < remaining; j++) { byte b = classContent[start + j]; // If non printable character, don't print it, just print dot character if (Util.isPrintableChacter((char) b)) { System.out.print((char) b); } else { System.out.print('.'); } } } System.out.println(); } } }