/******************************************************************************* * 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://www.eclipse.org/legal/epl-v10.html. * * This file is a derivative of code released by the University of * California under the terms listed below. * * Refinement Analysis Tools is Copyright (c) 2007 The Regents of the * University of California (Regents). Provided that this notice and * the following two paragraphs are included in any distribution of * Refinement Analysis Tools or its derivative work, Regents agrees * not to assert any of Regents' copyright rights in Refinement * Analysis Tools against recipient for recipient's reproduction, * preparation of derivative works, public display, public * performance, distribution or sublicensing of Refinement Analysis * Tools and derivative works, in source code and object code form. * This agreement not to assert does not confer, by implication, * estoppel, or otherwise any license or rights in any intellectual * property of Regents, including, but not limited to, any patents * of Regents or Regents' employees. * * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, * INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE * AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE AND FURTHER DISCLAIMS ANY STATUTORY * WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE AND ACCOMPANYING * DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS * IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ package com.ibm.wala.util.collections; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.lang.reflect.Field; import java.security.Permission; import java.util.ArrayList; import java.util.BitSet; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import com.ibm.wala.util.Predicate; import com.ibm.wala.util.functions.Function; /** * Miscellaneous utility functions. */ public class Util { /** The empty {@link BitSet}. */ public static final BitSet EMPTY_BITSET = new BitSet(); /** * Get a {@link String} representation of a {@link Throwable}. * * @throws IllegalArgumentException if thrown == null */ public static String str(Throwable thrown) throws IllegalArgumentException { if (thrown == null) { throw new IllegalArgumentException("thrown == null"); } // create a memory buffer to which to dump the trace ByteArrayOutputStream traceDump = new ByteArrayOutputStream(); PrintWriter w = new PrintWriter(traceDump); thrown.printStackTrace(w); w.close(); return traceDump.toString(); } /** * Return those elements of <code>c</code> that are assignable to <code>klass</code>. */ @SuppressWarnings("unchecked") public static <S, T> Set<T> filterByType(Iterable<S> c, Class<T> klass) { Set<T> result = HashSetFactory.make(); for(S s : c) if(klass.isAssignableFrom(s.getClass())) result.add((T)s); return result; } /** * Test whether <em>some</em> element of the given {@link Collection} satisfies the given {@link Predicate}. * * @throws IllegalArgumentException if c == null */ public static <T> boolean forSome(Collection<T> c, Predicate<T> p) throws IllegalArgumentException { if (c == null) { throw new IllegalArgumentException("c == null"); } for (T t : c) { if (p.test(t)) { return true; } } return false; } /** * Test whether <em>some</em> element of the given {@link Collection} satisfies the given {@link Predicate}. * * @return The first element satisfying the predicate; otherwise null. * @throws IllegalArgumentException if c == null */ public static <T> T find(Collection<T> c, Predicate<T> p) throws IllegalArgumentException { if (c == null) { throw new IllegalArgumentException("c == null"); } for (Iterator<T> iter = c.iterator(); iter.hasNext();) { T obj = iter.next(); if (p.test(obj)) return obj; } return null; } /** * Test whether <em>all</em> elements of the given {@link Collection} satisfy the given {@link Predicate}. * * @throws NullPointerException if c == null */ public static <T> boolean forAll(Collection<T> c, Predicate<T> p) throws NullPointerException { for (T t : c) { if (!p.test(t)) return false; } return true; } /** * Perform an action for all elements in a collection. * * @param c the collection * @param v the visitor defining the action * @throws IllegalArgumentException if c == null */ public static <T> void doForAll(Collection<T> c, ObjectVisitor<T> v) throws IllegalArgumentException { if (c == null) { throw new IllegalArgumentException("c == null"); } for (Iterator<T> iter = c.iterator(); iter.hasNext();) v.visit(iter.next()); } /** * Map a list: generate a new list with each element mapped. The new list is always an {@link ArrayList}; it would have been more * precise to use {@link java.lang.reflect reflection} to create a list of the same type as 'srcList', but reflection works really * slowly in some implementations, so it's best to avoid it. * * @throws IllegalArgumentException if srcList == null */ public static <T, U> List<U> map(List<T> srcList, Function<T, U> f) throws IllegalArgumentException { if (srcList == null) { throw new IllegalArgumentException("srcList == null"); } ArrayList<U> result = new ArrayList<U>(); for (Iterator<T> srcIter = srcList.iterator(); srcIter.hasNext();) { result.add(f.apply(srcIter.next())); } return result; } /** * Map a set: generate a new set with each element mapped. The new set is always a {@link HashSet}; it would have been more * precise to use {@link java.lang.reflect reflection} to create a set of the same type as 'srcSet', but reflection works really * slowly in some implementations, so it's best to avoid it. * * @throws IllegalArgumentException if srcSet == null */ public static <T, U> Set<U> mapToSet(Collection<T> srcSet, Function<T, U> f) throws IllegalArgumentException { if (srcSet == null) { throw new IllegalArgumentException("srcSet == null"); } HashSet<U> result = HashSetFactory.make(); for (Iterator<T> srcIter = srcSet.iterator(); srcIter.hasNext();) { result.add(f.apply(srcIter.next())); } return result; } /* * Grow an int[] -- i.e. allocate a new array of the given size, with the initial segment equal to this int[]. */ public static int[] realloc(int[] data, int newSize) throws IllegalArgumentException { if (data == null) { throw new IllegalArgumentException("data == null"); } if (data.length < newSize) { int[] newData = new int[newSize]; System.arraycopy(data, 0, newData, 0, data.length); return newData; } else return data; } /** Generate strings with fully qualified names or not */ public static final boolean FULLY_QUALIFIED_NAMES = false; /** * Write object fields to string * * @throws IllegalArgumentException if obj == null */ public static String objectFieldsToString(Object obj) throws IllegalArgumentException { if (obj == null) { throw new IllegalArgumentException("obj == null"); } // Temporarily disable the security manager SecurityManager oldsecurity = System.getSecurityManager(); System.setSecurityManager(new SecurityManager() { @Override public void checkPermission(Permission perm) { } }); Class<?> c = obj.getClass(); StringBuffer buf = new StringBuffer(FULLY_QUALIFIED_NAMES ? c.getName() : removePackageName(c.getName())); while (c != Object.class) { Field[] fields = c.getDeclaredFields(); if (fields.length > 0) buf = buf.append(" ("); for (int i = 0; i < fields.length; i++) { // Make this field accessible fields[i].setAccessible(true); try { Class<?> type = fields[i].getType(); String name = fields[i].getName(); Object value = fields[i].get(obj); // name=value : type buf = buf.append(name); buf = buf.append("="); buf = buf.append(value == null ? "null" : value.toString()); buf = buf.append(" : "); buf = buf.append(FULLY_QUALIFIED_NAMES ? type.getName() : removePackageName(type.getName())); } catch (IllegalAccessException e) { e.printStackTrace(); } buf = buf.append(i + 1 >= fields.length ? ")" : ","); } c = c.getSuperclass(); } // Reinstate the security manager System.setSecurityManager(oldsecurity); return buf.toString(); } /** Remove the package name from a fully qualified class name */ public static String removePackageName(String fully_qualified_name_) { if (fully_qualified_name_ == null) return null; int lastdot = fully_qualified_name_.lastIndexOf('.'); if (lastdot < 0) { return ""; } else { return fully_qualified_name_.substring(lastdot + 1); } } /** * checks if two sets have a non-empty intersection * * @return <code>true</code> if the sets intersect; <code>false</code> otherwise */ public static <T> boolean intersecting(final Set<T> s1, final Set<T> s2) { return forSome(s1, new Predicate<T>() { @Override public boolean test(T obj) { return s2.contains(obj); } }); } /** * given the name of a class C, returns the name of the top-most enclosing class of class C. For example, given A$B$C, the method * returns A * * @return String name of top-most enclosing class * @throws IllegalArgumentException if typeStr == null */ public static String topLevelTypeString(String typeStr) throws IllegalArgumentException { if (typeStr == null) { throw new IllegalArgumentException("typeStr == null"); } int dollarIndex = typeStr.indexOf('$'); String topLevelTypeStr = dollarIndex == -1 ? typeStr : typeStr.substring(0, dollarIndex); return topLevelTypeStr; } public static <T> void addIfNotNull(T val, Collection<T> vals) { if (val != null) { vals.add(val); } } /** * @return the amount of memory currently being used, in bytes. Often inaccurate, but there's no better thing to do from within * the JVM. */ public static long getUsedMemory() { gc(); long totalMemory = Runtime.getRuntime().totalMemory(); gc(); long freeMemory = Runtime.getRuntime().freeMemory(); long usedMemory = totalMemory - freeMemory; return usedMemory; } private static void gc() { try { for (int i = 0; i < 2; i++) { System.gc(); Thread.sleep(100); System.runFinalization(); Thread.sleep(100); } } catch (Exception e) { e.printStackTrace(); } } } // class Util