Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.ow2.bonita.util.Misc Maven / Gradle / Ivy
/**
* Copyright (C) 2007 Bull S. A. S.
* Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation
* version 2.1 of the License.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
*
* Modified by Matthieu Chaffotte, Elias Ricken de Medeiros - BonitaSoft S.A.
**/
package org.ow2.bonita.util;
import static org.ow2.bonita.util.GroovyExpression.START_DELIMITER;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.TypeVariable;
import java.net.InetAddress;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Permission;
import java.security.Permissions;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.Random;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MalformedObjectNameException;
import javax.management.ReflectionException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.facade.uuid.ProcessInstanceUUID;
import org.ow2.bonita.util.xml.Problem;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* @author Marc Blachon, Guillaume Porcher, Charles Souillard, Miguel Valdes, Pierre Vigneras
*/
public final class Misc {
private static final Logger LOG = Logger.getLogger(Misc.class.getName());
private static Object formatterLock = new Object();
public static final String ATTACHMENT_INDEX_NAME_SEPARATOR = "_____";
public static final int BASE64_BYTES_FRAGMENT_LENGTH = 65536;
public static final String BASE64_BYTES_FRAGMENT_SEPARATOR = "::";
private Misc() {
}
/**
* A RANDOM instance. Prevent creation of many instances.
*/
public static final Random RANDOM = new Random();
/**
* The line separator as defined by the property line.separator
.
*/
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
// Time formatter
private static final DateFormat DELAY_FORMATTER = new SimpleDateFormat("HH:mm:ss.SSS");
static {
Misc.DELAY_FORMATTER.setTimeZone(TimeZone.getTimeZone("GMT"));
}
/**
* Number of milliseconds in a given day
*/
public static final long DAY = 1000 * 60 * 60 * 24; // one day
private static final AtomicLong SEQUENCE_NUMBER = new AtomicLong(0);
public static boolean isOnWindows() {
return System.getProperty("os.name").contains("Windows");
}
public static List subList(final Class clazz, final List list, final int fromIndex, final int toIndex) {
if (list == null || list.isEmpty()) {
return Collections.emptyList();
}
int validToIndex = toIndex;
if (toIndex > list.size()) {
validToIndex = list.size();
}
if (fromIndex >= validToIndex) {
return Collections.emptyList();
}
return new ArrayList(list.subList(fromIndex, validToIndex));
}
public static boolean isSetter(final String methodName) {
return methodName.startsWith("set") && methodName.length() >= 4 && Character.isUpperCase(methodName.charAt(3));
}
public static Document generateDocument(final String s) throws ParserConfigurationException, SAXException,
IOException, XPathExpressionException {
final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
final InputStream contentStream = new ByteArrayInputStream(s.getBytes());
Document doc = null;
try {
doc = builder.parse(contentStream, null);
} finally {
if (contentStream != null) {
contentStream.close();
}
}
return doc;
}
public static Date getDate(final long time) {
if (time == 0) {
return null;
}
return new Date(time);
}
public static long getTime(final Date date) {
if (date == null) {
return 0;
}
return date.getTime();
}
public static List> splitCollection(final Collection extends Object> initial, final int size) {
if (initial == null || initial.isEmpty()) {
return Collections.emptyList();
}
final List> result = new ArrayList>();
final Iterator extends Object> it = initial.iterator();
int i = 0;
Set set = null;
while (it.hasNext()) {
if (i == size) {
i = 0;
}
if (i == 0) {
set = new HashSet();
result.add(set);
}
set.add(it.next());
i++;
}
return result;
}
public static String getXPath(final String s) {
if (s.contains(BonitaConstants.XPATH_VAR_SEPARATOR)) {
final String[] segments = s.split("\\" + BonitaConstants.XPATH_VAR_SEPARATOR);
return segments[1];
} else {
return null;
}
}
public static String getVariableName(final String s) {
if (s.contains(BonitaConstants.XPATH_VAR_SEPARATOR)) {
final String[] segments = s.split("\\" + BonitaConstants.XPATH_VAR_SEPARATOR);
return segments[0];
} else if (s.contains(BonitaConstants.JAVA_VAR_SEPARATOR)) {
final String[] segments = s.split(BonitaConstants.JAVA_VAR_SEPARATOR);
return segments[0];
} else {
return s;
}
}
public static boolean isXMLAppend(final String s) {
final String[] segments = s.split("\\" + BonitaConstants.XPATH_VAR_SEPARATOR);
return segments.length >= 3 && segments[2].equals(BonitaConstants.XPATH_APPEND_FLAG);
}
public static int getGroovyExpressionEndIndex(final String expression) {
int open = 0;
final char[] characters = expression.toCharArray();
for (int i = 1; i < characters.length; i++) {
if (characters[i] == '{') {
open++;
} else if (characters[i] == '}') {
open--;
}
if (open == 0) {
return i + 1;
}
}
return -1;
}
public static boolean isJustAGroovyExpression(final String expression) {
return expression.startsWith(START_DELIMITER) && getGroovyExpressionEndIndex(expression) == expression.length();
}
public static boolean containsAGroovyExpression(final String expression) {
final int begin = expression.indexOf(START_DELIMITER);
int end = -1;
if (begin >= 0) {
end = begin + getGroovyExpressionEndIndex(expression.substring(begin));
}
return begin < end;
}
public static String getHostName() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (final Exception e) {
return "unknown";
}
}
public static Map getJarEntries(final JarInputStream jis, final String jarFile) {
final Map jarEntries = new HashMap();
JarEntry jarEntry = null;
try {
while ((jarEntry = jis.getNextJarEntry()) != null) {
String jarEntryName = jarEntry.getName();
if (jarEntryName.startsWith("/")) {
jarEntryName = jarEntryName.substring(1);
}
final byte[] content = Misc.getJarEntriesContent(jis);
jarEntries.put(jarEntryName, content);
}
} catch (final IOException e) {
throw new BonitaRuntimeException("Unable to load class: " + jarEntry.getName() + " from jar file: " + jarFile, e);
}
return jarEntries;
}
private static byte[] getJarEntriesContent(final JarInputStream jis) throws IOException {
int c;
final byte[] buffer = new byte[512];
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
while ((c = jis.read(buffer)) != -1) {
baos.write(buffer, 0, c);
}
baos.flush();
} finally {
baos.close();
}
return baos.toByteArray();
}
public static Map getJarEntries(final String jarFile, final byte[] jar) {
JarInputStream jis = null;
try {
jis = new JarInputStream(new ByteArrayInputStream(jar));
return getJarEntries(jis, jarFile);
} catch (final IOException e) {
throw new BonitaRuntimeException("Unable to load jar entries from jar file: " + jarFile, e);
} finally {
Misc.close(jis);
}
}
/**
* Generate a unique identifier prefixed by the given String.
*
* @param prefix
* the prefix String
* @return an UUID String prefixed by prefix
* @see UUID
*/
public static String getUniqueId(final String prefix) {
return prefix + java.util.UUID.randomUUID();
}
public static boolean isJavaIdentifier(final String s) {
if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0))) {
return false;
}
for (int i = 1; i < s.length(); i++) {
if (!Character.isJavaIdentifierPart(s.charAt(i))) {
return false;
}
}
return true;
}
public static String convertToJavaIdentifier(final String name) {
final StringBuilder tmp = new StringBuilder();
char car;
int i = 0;
if (name != null) {
while (i < name.length()) {
car = name.charAt(i);
if (i == 0 && Character.isJavaIdentifierStart(car)) {
tmp.append(car);
} else if (i != 0 && Character.isJavaIdentifierPart(car)) {
tmp.append(car);
} else {
tmp.append("_");
}
i++;
}
return tmp.toString();
}
return "";
}
/**
* Generates a human readable id prefixed by the given String.
*
* The generated identifier is unique only for the duration of the existence of this class.
*
* @param prefix
* the string prefiy
* @return a human readable id prefixed by prefix
.
*/
public static String getHumanReadableId(final String prefix) {
return prefix + Misc.getHumanReadableId();
}
public static List getBusinessArchiveCategories(final ProcessDefinitionUUID processUUID) {
final List categories = new ArrayList();
categories.add("BusinessArchives");
categories.add(Misc.convertToJavaIdentifier(processUUID.getValue()));
return categories;
}
public static List getGlobalClassDataCategories() {
final List categories = new ArrayList();
categories.add("GlobalClasses");
return categories;
}
public static List getAttachmentCategories(final ProcessDefinitionUUID processUUID) {
final List categories = new ArrayList();
categories.add("Attachments");
categories.add(Misc.convertToJavaIdentifier(processUUID.getValue()));
return categories;
}
public static List getAttachmentCategories(final ProcessInstanceUUID instanceUUID) {
final List categories = new ArrayList();
categories.add("Attachments");
categories.add(Misc.convertToJavaIdentifier(instanceUUID.getValue()));
return categories;
}
public static List stringToList(final String s, final String separator) {
if (s == null) {
return Collections.emptyList();
}
final String[] array = s.split(separator);
final List result = new ArrayList();
for (final String st : array) {
result.add(st);
}
return result;
}
public static String listToString(final List list, final String separator) {
if (list == null || list.isEmpty()) {
return null;
}
final StringBuffer buf = new StringBuffer();
for (final String s : list) {
buf.append(separator).append(s);
}
return buf.toString().substring(separator.length());
}
public static Map stringToMap(final String s) {
if (s == null) {
return Collections.emptyMap();
}
final String[] couples = s.split(";");
final Map result = new HashMap();
for (final String couple : couples) {
final String[] st = couple.split(",");
result.put(st[0], st[1]);
}
return result;
}
public static String mapToString(final Map map) {
if (map == null || map.isEmpty()) {
return null;
}
final StringBuffer buf = new StringBuffer();
for (final Map.Entry entry : map.entrySet()) {
buf.append(';').append(entry.getKey()).append(',').append(entry.getValue());
}
return buf.toString().substring(";".length());
}
/**
* Generates a human readable id as a long.
*
* The generated identifier is unique only for the duration of the existence of this class.
*
* @return a unique id as a long.
*/
public static long getHumanReadableId() {
return Misc.SEQUENCE_NUMBER.getAndIncrement();
}
/**
* Returns a random number between min and max value
*
* @param min
* a positive integer
* @param max
* a positive integer
* @return a random number between min and max value
* @throws IllegalArgumentException
* if min >= max
*/
public static int random(final int min, final int max) {
if (min >= max) {
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_1", min, max);
throw new IllegalArgumentException(message);
}
final int n = max - min;
if (n < 0) {
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_2", min, max);
throw new IllegalArgumentException(message);
}
return Misc.RANDOM.nextInt(max - min) + min;
}
/**
* Generate a RANDOM String of the given size.
*
* @param size
* the size of the generated string
* @return the RANDOM String
*/
public static String getRandomString(final int size) {
final char[] s = new char[size];
int c = 'A';
int r1 = 0;
final Random r = new Random();
for (int i = 0; i < size; i++) {
r1 = r.nextInt(3);
switch (r1) {
case 0:
c = '0' + (int) (Math.random() * 10);
break;
case 1:
c = 'a' + (int) (Math.random() * 26);
break;
case 2:
c = 'A' + (int) (Math.random() * 26);
break;
}
s[i] = (char) c;
}
return new String(s);
}
/**
*
* Format a delay.
*
*
*
* This method returns a human readable string for delay such as the one used in benchmarks.
*
* This method is thread safe.
*
*
* @param delay
* a long
value
* @return a String
value
*/
public static final String formatDelay(final long delay) {
// Don't use Math.abs() here !!
// Math.abs(Long.MIN_VALUE) returns Long.MIN_VALUE !
if (delay == Long.MAX_VALUE) {
return "INFINITY";
}
if (delay == Long.MIN_VALUE) {
return "-INFINITY";
}
if (Math.abs(delay) >= Misc.DAY) {
final long days = delay / Misc.DAY;
return days + " day" + (days > 1 ? "s" : "");
}
// Formatter are not thread safe. See Sun Bugs #6231579 and Sun Bug
// #6178997.
synchronized (Misc.formatterLock) {
return delay < 0 ? "-" + Misc.DELAY_FORMATTER.format(new Date(-delay)) : Misc.DELAY_FORMATTER.format(new Date(
delay));
}
}
/**
*
* Equivalent to {@link #formatDelay(long)}.
*
*
* @param delay
* a double
value
* @return a String
value
*/
public static final String formatDelay(final double delay) {
return Misc.formatDelay((long) delay);
}
/**
*
* Return the list of Class
objects representing every types a given class implements.
*
*
* @param type
* a Class
value
* @return a Set
value
*/
public static Set> findAllTypes(final Class> type) {
final Set> superTypes = Misc.findAllSuperTypes(type);
final Set> result = new HashSet>(superTypes);
for (final Class> i : superTypes) {
result.addAll(Misc.findAllInterfaces(i));
}
result.addAll(Misc.findAllInterfaces(type));
return result;
}
/**
* Return the generic name of a given class.
*
* For example, given java.util.Map.class, it returns string java.util.Map
*
* @param clazz
* the class
* @return the generic name of a given class.
*/
public static String getGenericFullName(final Class> clazz) {
final StringBuilder sb = new StringBuilder(clazz.getCanonicalName());
final TypeVariable>[] types = clazz.getTypeParameters();
// This algorithm is weak! It only works for basic type. It will not work
// for type such as: Type< A > or Type extends B> ...
// Please fix it!
// TODO: Fix.
if (types.length != 0) {
sb.append('<');
for (final TypeVariable> type : types) {
sb.append(type.getName());
sb.append(',');
}
sb.replace(sb.length() - 1, sb.length(), ">");
}
return new String(sb);
}
/**
*
* Return the list of Class
objects representing all super type a given class implements.
*
*
* @param type
* a Class
value
* @return a Set
value
*/
public static Set> findAllSuperTypes(final Class> type) {
final Set> classes = new HashSet>();
for (Class> c = type; c != null; c = c.getSuperclass()) {
classes.add(c);
}
return classes;
}
/**
*
* Return the list of Class
objects representing all interfaces a given class implements.
*
*
* @param type
* a Class
value
* @return a List
value
*/
public static Set> findAllInterfaces(final Class> type) {
final Set> classes = new HashSet>();
final Class>[] interfaces = type.getInterfaces();
for (final Class> i : interfaces) {
classes.add(i);
classes.addAll(Misc.findAllInterfaces(i));
}
final Class> superClass = type.getSuperclass();
if (superClass != null) {
classes.addAll(Misc.findAllInterfaces(superClass));
}
return classes;
}
/**
*
* Return the Class[]
array representing the types a given method take as parameters.
*
*
* @param subClasses
* the classes which are to be subclasses of parameters
* @param classToTest
* the class which declares the given method
* @param methodName
* the method name
*
* @return the formal parameters class array
* @throws NoSuchMethodException
* if a method cannot be found.
*/
@SuppressWarnings("unchecked")
public static Class>[] findMethodClassArgs(final Class>[] subClasses, final Class> classToTest,
final String methodName) throws NoSuchMethodException {
final Set>[] classesList = new Set[subClasses.length];
for (int i = 0; i < classesList.length; i++) {
classesList[i] = Misc.findAllTypes(subClasses[i]);
}
final Method[] methods = classToTest.getDeclaredMethods();
for (int i = methods.length - 1; i >= 0; i--) {
// Same method name?
if (!methods[i].getName().equals(methodName)) {
continue;
}
// Same number of arguments?
final Class>[] formal = methods[i].getParameterTypes();
if (formal.length != subClasses.length) {
continue;
}
if (Misc.checkFormal(formal, classesList)) {
return formal;
}
}
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_3",
Misc.componentsToString(subClasses, false), classToTest, methodName);
throw new NoSuchMethodException(message);
}
/**
*
* Return the Class[]
array representing the types a constructor take as parameters.
*
*
* @param subClasses
* the classes which are to be subclasses of parameters
* @param classToTest
* the class which declares the constructor
*
* @return the formal parameters class array
* @throws NoSuchMethodException
* if a constructor cannot be found
*/
@SuppressWarnings("unchecked")
public static Class>[] findConstructorClassArgs(final Class>[] subClasses, final Class> classToTest)
throws NoSuchMethodException {
final Set>[] classesList = new Set[subClasses.length];
for (int i = 0; i < classesList.length; i++) {
classesList[i] = Misc.findAllTypes(subClasses[i]);
}
final Constructor>[] constructors = classToTest.getDeclaredConstructors();
for (int i = constructors.length - 1; i >= 0; i--) {
// Same number of arguments?
final Class>[] formal = constructors[i].getParameterTypes();
if (formal.length != subClasses.length) {
continue;
}
if (Misc.checkFormal(formal, classesList)) {
return formal;
}
}
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_4",
Misc.componentsToString(subClasses, false), classToTest);
throw new NoSuchMethodException(message);
}
private static boolean checkFormal(final Class>[] formal, final Set>[] types) {
for (int i = 0; i < formal.length; i++) {
final Iterator> iterator = types[i].iterator();
boolean found = false;
while (iterator.hasNext()) {
final Class> type = iterator.next();
if (type.equals(formal[i])) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
/**
*
* Return an "identity string" for a given object.
*
*
*
* The string returned is:
*
* "null" if o == null
* Otherwise, o.getClass().getName() + "#" + System.identityHashCode(o)
*
*
*
* @param o
* the object to return the identity string of
* @return the identity string as defined above
*/
public static String identityToString(final Object o) {
if (o == null) {
return "null";
}
return o.getClass().getName() + "#" + System.identityHashCode(o);
}
/**
*
* Smart toString() implementation of arrays.
*
*
* @param args
* the array to return a smart string of.
* @return the smart string of the given array.
*/
public static String componentsToString(final Object[] args, final boolean deepToString) {
if (args == null) {
return "null";
}
Class> componentType = args.getClass().getComponentType();
final StringBuilder string = new StringBuilder(componentType.getName());
string.append("[");
final int length = args.length;
if (length != 0) {
final int max = length - 1;
for (int i = 0; i < max; i++) {
if (args[i] == null) {
string.append("null");
} else if (args[i].getClass().isArray()) {
componentType = args[i].getClass().getComponentType();
if (componentType.isPrimitive()) {
string.append(Misc.primitiveComponentsToString(args[i]));
} else {
string.append(Misc.componentsToString((Object[]) args[i], deepToString));
}
} else {
string.append(deepToString ? Misc.deepToString(args[i]) : args[i].toString());
}
string.append("; ");
}
if (args[max] == null) {
string.append("null");
} else if (args[max].getClass().isArray()) {
componentType = args[max].getClass().getComponentType();
if (componentType.isPrimitive()) {
string.append(Misc.primitiveComponentsToString(args[max]));
} else {
string.append(Misc.componentsToString((Object[]) args[max], deepToString));
}
} else {
string.append(deepToString ? Misc.deepToString(args[max]) : args[max].toString());
}
}
string.append("]");
return new String(string);
}
/**
*
* Smart toString() implementation of an array of primitive types.
*
*
* @param array
* the array to return a smart string of.
* @return the smart string of the given array.
*/
public static String primitiveComponentsToString(final Object array) {
if (array == null) {
return "null";
}
final Class> c = array.getClass();
if (!c.isArray() || !c.getComponentType().isPrimitive()) {
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_5");
throw new IllegalArgumentException(message);
}
final StringBuilder string = new StringBuilder(c.getComponentType().getName());
string.append("[");
final int length = Array.getLength(array);
if (length != 0) {
final int max = length - 1;
for (int i = 0; i < max; i++) {
string.append(Array.get(array, i));
string.append("; ");
}
string.append(Array.get(array, max));
}
string.append("]");
return new String(string);
}
/**
* Equivalent to {@link #getAllContentFrom(InputStream) getAllContentFrom(new FileInputStream(file))};
*
* @param file
* the file to read
* @return the whole content of the file in a single String.
* @throws IOException
* If an I/O exception occurs
*/
public static byte[] getAllContentFrom(final File file) throws IOException {
InputStream in = null;
try {
in = new FileInputStream(file);
return Misc.getAllContentFrom(in);
} finally {
Misc.close(in);
}
}
/**
* Equivalent to {@link #getAllContentFrom(InputStream) getAllContentFrom(source.getByteStream(source))};
*
* @param source
* the file to read
* @return the whole content of the file in a single String.
* @throws IOException
* IOException If an I/O exception occurs
*/
public static byte[] getAllContentFrom(final InputSource source) throws IOException {
InputStream in = null;
try {
in = source.getByteStream();
return Misc.getAllContentFrom(in);
} finally {
Misc.close(in);
}
}
/**
* Return the whole underlying stream content into a single String.
*
* Warning: the whole content of stream will be kept in memory!! Use with care!
*
* @param url
* the URL to read
* @return the whole content of the stream in a single String.
* @throws IOException
* if an I/O exception occurs
*/
public static byte[] getAllContentFrom(final URL url) throws IOException {
final InputStream in = url.openStream();
try {
return Misc.getAllContentFrom(in);
} finally {
in.close();
}
}
/**
* Return the whole underlying stream content into a single String.
*
* Warning: the whole content of stream will be kept in memory!! Use with care!
*
* @param in
* the stream to read
* @return the whole content of the stream in a single String.
* @throws IOException
* if an I/O exception occurs
*/
public static byte[] getAllContentFrom(final InputStream in) throws IOException {
if (in == null) {
throw new IOException("The InputStream is null!");
}
final BufferedInputStream bis = new BufferedInputStream(in);
final ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] resultArray = null;
try {
int c;
while ((c = bis.read()) != -1) {
result.write(c);
}
resultArray = result.toByteArray();
result.flush();
} finally {
result.close();
bis.close();
}
return resultArray;
}
public static void getFile(final File file, final byte[] fileAsByteArray) throws IOException {
final FileOutputStream fos = new FileOutputStream(file);
try {
fos.write(fileAsByteArray);
fos.flush();
} finally {
fos.close();
}
}
/**
* Equivalent to {@link #reflectClose(Object)}
*/
public static Exception close(final Closeable closeable) {
return Misc.reflectClose(closeable);
}
/**
* Equivalent to {@link #reflectClose(Object)}
*/
public static Exception close(final XMLEncoder encoder) {
return Misc.reflectClose(encoder);
}
/**
* Equivalent to {@link #reflectClose(Object)}
*/
public static Exception close(final XMLDecoder decoder) {
return Misc.reflectClose(decoder);
}
/**
* Invoke the close() method on the given object.
*
* This method uses the reflection API to find a close() method with no arguments. Any exception thrown (including
* NoSuchMethodException) will be both logged using {@link #LOG} and returned. If the parameter is null, nothing is
* done and null is returned.
*
* @param o
* the object to call the close() method on.
* @return the exception thrown if any, null otherwise.
*/
public static Exception reflectClose(final Object o) {
if (o == null) {
return null;
}
try {
final Method m = o.getClass().getMethod("close", new Class[0]);
m.invoke(o, new Object[0]);
} catch (final Exception e) {
final StringBuilder sb = new StringBuilder("Exception thrown during close() on: ");
sb.append(o.toString());
sb.append(Misc.LINE_SEPARATOR);
sb.append("Exception message is: ");
sb.append(e.getMessage());
sb.append(Misc.LINE_SEPARATOR);
sb.append(Misc.getStackTraceFrom(e));
Misc.LOG.warning(sb.toString());
return e;
}
return null;
}
/**
* @param permissions
* @return the permissions size
*/
public static int getPermissionsSize(final Permissions permissions) {
int size = 0;
final Enumeration p = permissions.elements();
while (p.hasMoreElements()) {
size++;
}
return size;
}
/**
* Return a proxy implementing all the interfaces specified that forward method invocations to the specified MBean.
*
* @param
* @param mbeanInterface
* the interface the proxy should implement (the MBean should obviously also implement that interface).
* @param jmxServiceUrl
* the JMX service URL
* @param jmxObjectName
* the name the MBean has been registered to
* @return a proxy implementing the specified interface and that forward method invocations to the specified MBean.
*
* @throws IOException
* for any IO problem
* @throws MalformedObjectNameException
* for any JMX Naming problem
* @throws MBeanException
* for any MBean problem
* @throws ReflectionException
* for any problem related to reflection
*/
@SuppressWarnings("unchecked")
public static T getMBeanProxy(final Class mbeanInterface, final String jmxServiceUrl,
final String jmxObjectName) throws IOException, MalformedObjectNameException, InstanceNotFoundException,
MBeanException, ReflectionException {
return (T) Proxy.newProxyInstance(Misc.class.getClassLoader(), new Class[] { mbeanInterface },
new MBeanInvocationHandler(jmxServiceUrl, jmxObjectName));
}
/**
* Return a proxy that forward void-method invocations to each object specified in the list
* elements
.
*
* The invocation order follows the given list order.
*
* @param
* the interface type of the returned proxy and of each elements.
* @param elements
* the elements to forward method invocations to
* @return the forwarding chaining proxy
* @see Chainer
* @see InvocationHandler
* @see Proxy
*/
@SuppressWarnings("unchecked")
public static T getChainOf(final List elements) {
Misc.checkArgsNotNull(elements);
final Chainer chain = new Chainer();
final Set> classes = new HashSet>();
final Set> initial = Misc.findAllInterfaces(elements.get(0).getClass());
classes.addAll(initial);
for (final T element : elements) {
chain.add(element);
// We can't find the generic type T at runtime.
// But this is required by Proxy.newProxyInstance().
// So, we find the common interfaces implemented by all elements.
final Set> interfaces = Misc.findAllInterfaces(element.getClass());
classes.retainAll(interfaces);
}
if (classes.size() == 0) {
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_6", elements);
throw new IllegalArgumentException(message);
}
return (T) Proxy.newProxyInstance(Misc.class.getClassLoader(), classes.toArray(new Class[classes.size()]), chain);
}
/**
* Return a proxy that log method invocations through the provided logger.
*
* @param
* the target object type
* @param target
* the target object method invocations should be forwarded to
* @param logger
* the logger to use for logging
* @return a proxy that log method invocations through the provided logger.
* @see LoggingInvocationHandler
* @see InvocationHandler
* @see Proxy
*/
@SuppressWarnings("unchecked")
public static T getLoggerProxyFor(final T target, final Logger logger) {
final Set> classes = Misc.findAllInterfaces(target.getClass());
return (T) Proxy.newProxyInstance(Misc.class.getClassLoader(), classes.toArray(new Class[classes.size()]),
new LoggingInvocationHandler(target, logger));
}
/**
* Represents null value returned by {@link Misc#findNull(Object...)}.
*
* @see Misc#findNull(Object...)
* @author Pierre Vigneras
*/
public static class NullCheckResult {
private final int size;
private final BitSet bitSet;
NullCheckResult(final BitSet bitSet, final int size) {
this.bitSet = bitSet;
this.size = size;
}
/**
* Returns true if some parameters given to {@link Misc#findNull(Object...)} were null.
*
* @return true if some parameters given to {@link Misc#findNull(Object...)} were null.
* @see Misc#findNull(Object...)
*/
public boolean hasNull() {
return bitSet.cardinality() != 0;
}
/**
* Returns the number of parameters given to {@link Misc#findNull(Object...)}
*
* @return the number of parameters given to {@link Misc#findNull(Object...)}
* @see Misc#findNull(Object...)
*/
public int getSize() {
return size;
}
/**
* Returns true if the i th parameter given to {@link Misc#findNull(Object...)} was null.
*
* @param i
* the rank of the parameter given to {@link Misc#findNull(Object...)}.
* @return true if the i th parameter given to {@link Misc#findNull(Object...)} was null.
*/
public boolean isNull(final int i) {
return bitSet.get(i);
}
}
/**
* Find null parameters in the given list.
*
* This method returns a {@link NullCheckResult}.
*
*
* @param params
* the parameters to check
* @return a {@link NullCheckResult} representing null parameters.
* @see NullCheckResult
*/
public static NullCheckResult findNull(final Object... params) {
if (params == null) {
final BitSet bitSet = new BitSet(1);
bitSet.set(0);
return new NullCheckResult(bitSet, 1);
}
final BitSet bitSet = new BitSet(params.length);
for (int i = 0; i < params.length; i++) {
if (params[i] == null) {
bitSet.set(i, true);
} else {
bitSet.set(i, false);
}
}
return new NullCheckResult(bitSet, params.length);
}
/**
* Check that the given parameters are not null.
*
* This method should only be used to check that some parameters given to a given method are not null. The exception
* message tries its best to produce a helpful message by scanning the stack trace.
*
* @param params
* the parameters to check
* @throws an
* IllegalArgumentException if at least one of the parameters is null
*/
public static void checkArgsNotNull(final Object... params) {
Misc.checkArgsNotNull(1, params);
}
/**
* Check that the given parameters are not null.
*
* This method should only be used to check that some parameters given to a given method are not null. The exception
* message tries its best to produce a helpful message by scanning the stack trace.
*
* @param offset
* the offset to use in the stack trace to produce error message
* @param params
* the parameters to check
* @throws an
* IllegalArgumentException if at least one of the parameters is null
*/
public static void checkArgsNotNull(final int offset, final Object... params) {
final NullCheckResult result = Misc.findNull(params);
if (result.hasNull()) {
// Guess the signature of the caller
final StackTraceElement callerSTE = Misc.getCaller(offset + 1);
final String className = callerSTE.getClassName();
final String methodName = callerSTE.getMethodName();
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.getSize(); i++) {
if (result.isNull(i)) {
sb.append("null");
} else {
sb.append(params[i].getClass().getName());
}
if (i < result.getSize() - 1) {
sb.append(", ");
}
}
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_7", className, methodName,
sb.toString());
throw new IllegalArgumentException(message);
}
}
/**
* Return the StackTraceElement at the given offset from this method invocation.
*
* @param offset
* @return a StackTraceElement
*/
public static StackTraceElement getCaller(final int offset) {
final StackTraceElement[] stes = Thread.currentThread().getStackTrace();
StackTraceElement callerSTE = null;
for (int i = 0; i < stes.length - offset - 1; i++) {
if (stes[i].getClassName().equals(Misc.class.getName()) && stes[i].getMethodName().equals("getCaller")) {
callerSTE = stes[i + 1 + offset];
break;
}
}
Misc.badStateIfNull(callerSTE, "Ouch! Can't get the stack trace back to the caller of this method!");
return callerSTE;
}
/**
* Return strings mapped to null values in a given @{link {@link NullCheckResult}. .
*
* If the returned @{link List} of String is called l
then, it verifies:
* l.contains(names[i])
if and only if nullCheckResult.isNull(i)
returns true
.
*
* Note that the number of String names given should be of the same size that the one used to get the given
* {@link NullCheckResult} using {@link #findNull(Object...)}. An {@link IllegalArgumentException} is thrown
* otherwise.
*
* @param nullCheckResult
* the result as returned by {@link #findNull(Object...)}
* @param names
* the strings that should be mapped to null values
* @return a List of string mapped to the given {@link NullCheckResult}.
* @throws IllegalArgumentException
* if the number of given names is different from {@link NullCheckResult#getSize()}
*
* @see #findNull(Object...)
* @see NullCheckResult
*/
public static List getStringFrom(final NullCheckResult nullCheckResult, final String... names) {
final int n = names.length;
if (nullCheckResult.getSize() != n) {
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_8", n, nullCheckResult.getSize());
throw new IllegalArgumentException(message);
}
final List list = new ArrayList();
if (!nullCheckResult.hasNull()) {
return list;
}
for (int i = 0; i < n; i++) {
if (nullCheckResult.isNull(i)) {
list.add(names[i]);
}
}
return list;
}
/**
* This method throw an IllegalStateException if the given parameter is null
*
* @param valueToCheck
* the value to check
* @param msg
* the message for the thrown exception
*
* @see IllegalStateException
*/
public static void badStateIfNull(final Object valueToCheck, final String msg) {
Misc.badStateIfTrue(valueToCheck == null, msg);
}
/**
* This method throw an IllegalStateException if the given parameter is not null
*
* @param valueToCheck
* the value to check
* @param msg
* the message for the thrown exception
*
* @see IllegalStateException
*/
public static void badStateIfNotNull(final Object valueToCheck, final String msg) {
Misc.badStateIfTrue(valueToCheck != null, msg);
}
/**
* This method throw an IllegalStateException if the given parameter is true
*
* @param valueToCheck
* the value to check
* @param msg
* the message for the thrown exception
*
* @see IllegalStateException
*/
public static void badStateIfTrue(final boolean valueToCheck, final String msg) {
if (valueToCheck) {
throw new IllegalStateException(msg);
}
}
/**
* This method throw an IllegalStateException if the given parameter is false
*
* @param valueToCheck
* the value to check
* @param msg
* the message for the thrown exception
*
* @see IllegalStateException
*/
public static void badStateIfFalse(final boolean valueToCheck, final String msg) {
Misc.badStateIfTrue(!valueToCheck, msg);
}
/**
* This method throw an IllegalStateException if the given parameters are equals (using {@link Object#equals(Object)}
*
* @param a
* the first object
* @param b
* the second object
* @param msg
* the message for the thrown exception
*
* @see IllegalStateException
*/
public static void badStateIfEquals(final Object a, final Object b, final String msg) {
Misc.badStateIfTrue(a.equals(b), msg);
}
/**
* Log a message to the logger of the caller at the given offset in the stack trace.
*
* If A.f()
calls B.g()
that finally calls dynamicLog(1, msg)
then, the msg
* will be logged with a code similar to:
* getLogger(B.getClass().getName()).log(level, msg);
*
* If the call was dynamicLog(2, msg)
then, the code would be:
* getLogger(A.getClass().getName()).log(level, msg);
*
* @param offset
* the offset in the stack trace
* @param level
* the level to log the message to
* @param msg
* the message to log
*/
public static void dynamicLog(final int offset, final Level level, final String msg) {
final StackTraceElement callerSTE = Misc.getCaller(offset);
final String className = callerSTE.getClassName();
final String methodName = callerSTE.getMethodName();
final Logger logger = Logger.getLogger(className);
final LogRecord record = new LogRecord(level, msg);
record.setSourceClassName(className);
record.setSourceMethodName(methodName);
record.setLoggerName(logger.getName());
logger.log(record);
}
/**
* Log the given message at the given level using caller's Logger.
*
* @param level
* a level
* @param msg
* the message
* @see #dynamicLog(int, Level, String)
*/
public static void log(final Level level, final String msg) {
Misc.dynamicLog(2, level, msg);
}
/**
* This method logs at the given level a "warning message" if the given parameter is null
*
* @param level
* a log level
* @param valueToCheck
* the value to check
* @param variableName
* the variable name holding valueToCheck. Can be null.
*
*/
public static void warnIfNull(final Level level, final Object valueToCheck, final String variableName) {
if (valueToCheck == null) {
final String msg = "Warning: " + (variableName == null ? "a variable" : variableName) + " is null!";
Misc.dynamicLog(1, level, msg);
}
}
/**
* This method logs at the given level a "warning" if the given parameter is not null
*
* @param level
* a log level
* @param valueToCheck
* the value to check
* @param variableName
* the variable name holding valueToCheck. Can be null.
*/
public static void warnIfNotNull(final Level level, final Object valueToCheck, final String variableName) {
if (valueToCheck != null) {
final String msg = "Warning: " + (variableName == null ? "a variable" : variableName) + " is not null!";
Misc.dynamicLog(1, level, msg);
}
}
/**
* This method logs at the given level a "warning" if the given parameter is true
*
* @param level
* a log level
* @param valueToCheck
* the value to check
* @param variableName
* the variable name holding valueToCheck. Can be null.
*/
public static void warnIfTrue(final Level level, final boolean valueToCheck, final String variableName) {
if (valueToCheck) {
final String msg = "Warning: " + (variableName == null ? "a variable" : variableName) + " is true!";
Misc.dynamicLog(1, level, msg);
}
}
/**
* This method logs at the given level a "warning" if the given parameter is false
*
* @param level
* a log level
* @param valueToCheck
* the value to check
* @param variableName
* the variable name holding valueToCheck. Can be null.
*/
public static void warnIfFalse(final Level level, final boolean valueToCheck, final String variableName) {
if (!valueToCheck) {
final String msg = "Warning: " + (variableName == null ? "a variable" : variableName) + " is false!";
Misc.dynamicLog(1, level, msg);
}
}
/**
* This method logs at the given level a "warning" if the given parameter are equals
*
* @param level
* a log level
* @param a
* an object
* @param b
* another object
*/
public static void warnIfEquals(final Level level, final Object a, final Object b) {
if (a.equals(b)) {
Misc.dynamicLog(1, level, "Warning: equals objects: " + Misc.LINE_SEPARATOR + Misc.details(a, b));
}
}
private static String details(final Object a, final Object b) {
return "a.toString(): " + a.toString() + Misc.LINE_SEPARATOR + "b.toString(): " + b.toString()
+ Misc.LINE_SEPARATOR + "a.idendityToString(): " + Misc.identityToString(a) + Misc.LINE_SEPARATOR
+ "b.identityToString(): " + Misc.identityToString(b);
}
/**
* This method logs at the given level a "warning" if the given parameter are not equals
*
* @param level
* a log level
* @param a
* an object
* @param b
* another object
*/
public static void warnIfNotEquals(final Level level, final Object a, final Object b) {
if (!a.equals(b)) {
Misc.dynamicLog(1, level, "Warning: non-equals objects: " + Misc.LINE_SEPARATOR + Misc.details(a, b));
}
}
public static String getCurrentThreadStackTrace() {
final StackTraceElement[] elements = Thread.currentThread().getStackTrace();
final StringBuilder stringBuilder = new StringBuilder();
for (final StackTraceElement element : elements) {
stringBuilder.append(element.toString());
stringBuilder.append(Misc.LINE_SEPARATOR);
}
return stringBuilder.toString();
}
public static String getStackTraceFrom(final Throwable aThrowable) {
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
aThrowable.printStackTrace(printWriter);
return result.toString();
}
public static String deepToString(final Object o) {
return Misc.recursiveDeepToString(o, new HashMap());
}
private static String recursiveDeepToString(final Object o, final Map cache) {
String result = cache.get(o);
final String id = "@" + Integer.toHexString(System.identityHashCode(o));
if (result != null && result != id) {
return result;
}
if (o == null) {
result = "null";
} else {
cache.put(o, id);
final Class> clazz = o.getClass();
final Package pack = clazz.getPackage();
if (clazz.isPrimitive() || pack != null && pack.getName().startsWith("java.") || clazz.isEnum()) {
result = o.toString();
} else if (clazz.isArray()) {
final Class> componentType = clazz.getComponentType();
if (componentType.isPrimitive()) {
result = Misc.primitiveComponentsToString(o);
} else {
result = Misc.componentsToString((Object[]) o, true);
}
} else {
final StringBuilder sb = new StringBuilder(clazz.getName());
sb.append('(').append(id).append(')').append("[");
final Field[] fields = clazz.getDeclaredFields();
for (final Field field : fields) {
try {
field.setAccessible(true);
sb.append(field.getName()).append(": ");
final Object f = field.get(o);
final String v = cache.get(f);
if (v == id) {
sb.append(id);
} else {
sb.append(Misc.recursiveDeepToString(f, cache));
}
} catch (final IllegalAccessException e) {
Misc.LOG.warning("An exception occured during information fetching on field: " + field
+ Misc.LINE_SEPARATOR + "Stack trace is: " + Misc.getStackTraceFrom(e)
+ "Fallbacking to non-intrusive algorithm for toString().");
sb.append("(*").append(field.toGenericString()).append("*)");
}
sb.append(", ");
}
if (fields.length != 0) {
sb.delete(sb.length() - 2, sb.length());
}
sb.append("]");
result = new String(sb);
}
}
cache.put(o, result);
return result;
}
public static boolean deleteDir(final File dir) {
return deleteDir(dir, 1, 0);
}
public static boolean deleteDir(final File dir, final int attempts, final long sleepTime) {
Misc.checkArgsNotNull(dir);
boolean result = true;
if (!dir.exists()) {
return false;
}
if (!dir.isDirectory()) {
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_9", dir.getAbsolutePath());
throw new IllegalArgumentException(message);
}
final File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDir(files[i], attempts, sleepTime);
} else {
result = result && deleteFile(files[i], attempts, sleepTime);
}
}
result = result && deleteFile(dir, attempts, sleepTime);
return result;
}
public static boolean deleteFile(final File f, final int attempts, final long sleepTime) {
int retries = attempts;
while (retries > 0) {
if (f.delete()) {
break;
}
retries--;
try {
Thread.sleep(sleepTime);
} catch (final InterruptedException e) {
}
}
return retries > 0;
}
public static void unreachableStatement() {
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_10");
Misc.unreachableStatement(message);
}
public static void unreachableStatement(final String reason) {
throw new IllegalStateException(reason);
}
// This code has been taken from:
// http://forum.java.sun.com/thread.jspa?threadID=760266&messageID=4340490
// It has been slightly adapted to our needs.
public static > E stringToEnum(final Class c, final String s) {
final EnumSet set = EnumSet.allOf(c);
for (final E e : set) {
if (e.toString().equals(s)) {
return e;
}
}
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_11", c.getName(), s, set.toString());
throw new IllegalArgumentException(message);
}
public static byte[] serialize(final Serializable object) throws IOException, ClassNotFoundException {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(object);
out.flush();
Misc.close(out);
// Get the bytes of the serialized object
return bos.toByteArray();
}
public static Serializable deserialize(final byte[] buf) throws IOException, ClassNotFoundException {
final ByteArrayInputStream bais = new ByteArrayInputStream(buf);
final ObjectInputStream ois = new ObjectInputStream(bais) {
@Override
protected Class> resolveClass(final ObjectStreamClass desc) throws IOException, ClassNotFoundException {
final String className = desc.getName();
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
return Class.forName(className, true, classLoader);
}
};
final Serializable newObject = (Serializable) ois.readObject();
ois.close();
bais.close();
return newObject;
}
/**
* Check that the given object is actually serializable.
*
* Implementation tries to serialize and deserialize the given object (in memory). Note that null is returned
* when the given object is serializable. It returns the throwable thrown by either the serialization or the
* deserialization process. This means, that the object is not really serializable. Therefore the pattern for checking
* should be written like:
*
* final Throwable error = checkReallySerializable(myObject);
* if (error == null) {
* // success
* } else {
* // failure, do something with error...
* error.printStackTrace();
* }
*
*
* @param
* A type (usually extending {@link Serializable}
* @param object
* the object to check
* @return null on success, the exception thrown on error
*/
public static Throwable checkReallySerializable(final T object) {
try {
final byte[] buf = Misc.serialize(object);
Misc.deserialize(buf);
return null;
} catch (final Throwable t) {
return t;
}
}
/**
* Write the given String to the given file using the default encoding.
*
* @param s
* the string to be written
* @param f
* the file to write the given string to
* @throws IOException
* if an IO error is encountered (file not found, read-only file, and so on).
*/
public static void write(final String s, final File f) throws IOException {
Misc.checkArgsNotNull(s, f);
final FileWriter writer = new FileWriter(f);
try {
writer.write(s);
writer.flush();
} finally {
Misc.close(writer);
}
}
public static void write(final File file, final byte[] fileContent) throws IOException {
Misc.checkArgsNotNull(file, fileContent);
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
OutputStream os = null;
try {
os = new FileOutputStream(file);
os.write(fileContent);
os.flush();
} finally {
Misc.close(os);
}
}
/**
* Perform java.io.File.createTempFile with retries when it fail (limit of 10 retries) (Use to by-pass bug #6325169 on
* SUN JDK 1.5 on windows) Same parameters as {@link java.io.File#createTempFile(String, String, File)} method
*
* @param prefix
* Prefix of the file
* @param suffix
* Suffix of the file
* @param directory
* Target directory
* @return An abstract pathname denoting a newly-created empty file
* @throws IOException
* If a file could not be created
*/
public static File createTempFile(final String prefix, final String suffix, final File directory) throws IOException {
// By-pass for the bug #6325169 on SUN JDK 1.5 on windows
// The createTempFile could fail while creating a file with the same name of
// an existing directory
// So if the file creation fail, it retry (with a limit of 10 retry)
// Rethrow the IOException if all retries failed
File tmpDir = null;
final int retryNumber = 10;
int j = 0;
boolean succeded = false;
do {
try {
/*
* If the prefix contained file separator we need to create the parent directories if missing
*/
final int lastIndexOfSeparatorChar = prefix.lastIndexOf('/');
String fileName = prefix;
if (lastIndexOfSeparatorChar > -1) {
final String dirToCreate = prefix.substring(0, lastIndexOfSeparatorChar);
new File(directory.getAbsolutePath() + File.separator + dirToCreate).mkdirs();
fileName = prefix.substring(lastIndexOfSeparatorChar, prefix.length());
}
if (!directory.exists()) {
directory.mkdirs();
}
/* Create the file */
tmpDir = File.createTempFile(fileName, suffix, directory);
succeded = true;
} catch (final IOException e) {
if (j == retryNumber) {
throw e;
}
try {
Thread.sleep(100);
} catch (final InterruptedException e1) {
}
j++;
}
} while (!succeded);
return tmpDir;
}
public static byte[] generateJar(final Class>... classes) throws IOException {
return Misc.generateJar(Misc.getResources(classes));
}
public static Map getResources(final Class>... classes) throws IOException {
if (classes == null || classes.length == 0) {
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_13");
throw new IOException(message);
}
final Map resources = new HashMap();
for (final Class> clazz : classes) {
resources.put(clazz.getName().replace(".", "/") + ".class", ClassDataTool.getClassData(clazz));
}
return resources;
}
public static byte[] generateJar(final Map resources) throws IOException {
if (resources == null || resources.size() == 0) {
final String message = ExceptionManager.getInstance().getFullMessage("buc_M_14");
throw new IOException(message);
}
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final JarOutputStream out = new JarOutputStream(new BufferedOutputStream(baos));
for (final Map.Entry resource : resources.entrySet()) {
out.putNextEntry(new JarEntry(resource.getKey()));
out.write(resource.getValue());
}
out.flush();
Misc.close(out);
final byte[] jar = baos.toByteArray();
Misc.close(baos);
return jar;
}
public static Map getResourcesFromZip(final byte[] barContent) throws IOException {
final Map resources = new HashMap();
final InputStream in = new ByteArrayInputStream(barContent);
final ZipInputStream zis = new ZipInputStream(in);
ZipEntry zipEntry = null;
while ((zipEntry = zis.getNextEntry()) != null) {
if (!zipEntry.isDirectory()) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
int c;
final byte[] buffer = new byte[512];
while ((c = zis.read(buffer)) != -1) {
baos.write(buffer, 0, c);
}
baos.flush();
resources.put(zipEntry.getName(), baos.toByteArray());
Misc.close(baos);
}
}
Misc.close(zis);
Misc.close(in);
return resources;
}
@SuppressWarnings("unchecked")
public static T lookup(final String name, final Hashtable environment) throws NamingException {
InitialContext initialContext = null;
if (environment != null) {
initialContext = new InitialContext(environment);
} else {
initialContext = new InitialContext();
}
return (T) initialContext.lookup(name);
}
/**
* Return a new string based on the given message string where all lines are prefixed by the given prefix.
*
*
* @param message
* the message to transform
* @param prefix
* the prefix to use
* @return the prefixed string
*/
public static String prefixAllLines(final String message, final String prefix) {
Misc.checkArgsNotNull(message, prefix);
if (message.length() == 0) {
return prefix;
}
final BufferedReader reader = new BufferedReader(new StringReader(message));
final StringBuilder builder = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
if (builder.length() != 0) {
builder.append(Misc.LINE_SEPARATOR);
}
builder.append(prefix).append(line);
}
} catch (final IOException e) {
final String msg = ExceptionManager.getInstance().getFullMessage("buc_M_15");
Misc.unreachableStatement(msg);
} finally {
Misc.close(reader);
}
return builder.toString();
}
public static void showProblems(final Collection problems, final String description) {
if (problems != null) {
StringBuffer errorMsg = null;
for (final Problem p : problems) {
if (p.getSeverity().equals(Problem.SEVERITY_ERROR) || p.getSeverity().equals(Problem.SEVERITY_FATALERROR)) {
if (errorMsg == null) {
errorMsg = new StringBuffer();
}
errorMsg.append(Misc.LINE_SEPARATOR);
errorMsg.append(" ");
errorMsg.append(p.toString());
if (p.getCause() != null) {
LOG.severe(p.toString() + ". Cause: " + p.getCause());
} else {
LOG.severe(p.toString());
}
} else {
LOG.info("WARNING: " + p.toString());
}
}
if (errorMsg != null) {
final String message = ExceptionManager.getInstance().getFullMessage("bp_Pa_1", description, errorMsg);
throw new BonitaRuntimeException(message);
}
}
}
public static Object convertIfPossible(final String variableId, final Object variableValue,
final String dataTypeClassName) {
if (variableValue == null) {
return null;
}
try {
final Class> destTypeClass = Class.forName(dataTypeClassName, true, Thread.currentThread()
.getContextClassLoader());
final Class> valueClass = variableValue.getClass();
final boolean assignmentOK = destTypeClass.isAssignableFrom(valueClass);
// manage inner classes
if (assignmentOK || destTypeClass.getName().equals(valueClass.getName())) {
return variableValue;
} else {
// try to convert it
if ("java.lang".equals(valueClass.getPackage().getName())
&& "java.lang".equals(destTypeClass.getPackage().getName())) {
// we can convert it
final String varValueAsString = variableValue.toString();
if (destTypeClass.equals(String.class)) {
return varValueAsString;
} else if (destTypeClass.equals(Boolean.class)) {
if ("true".equals(varValueAsString) || "false".equals(varValueAsString)) {
return Boolean.valueOf(varValueAsString);
}
} else if (destTypeClass.equals(Character.class)) {
if (varValueAsString != null && varValueAsString.length() == 1) {
return Character.valueOf(variableValue.toString().charAt(0));
}
} else {
// Short, Long, Double, Float, Integer : all of them have a
// valueOf(String) method
Method valueOf;
try {
valueOf = destTypeClass.getMethod("valueOf", new Class>[] { String.class });
return valueOf.invoke(destTypeClass, new Object[] { varValueAsString });
} catch (final Exception e) {
}
}
}
return variableValue;
}
} catch (final ClassNotFoundException e) {
throw new BonitaRuntimeException(e);
}
}
public static String getAttachmentIndexName(final String name, final Date versionDate) {
Misc.checkArgsNotNull(name, versionDate);
return name + ATTACHMENT_INDEX_NAME_SEPARATOR + versionDate.getTime();
}
public static String getAttachmentName(final String indexName) {
Misc.checkArgsNotNull(indexName);
return indexName.substring(0, indexName.lastIndexOf(ATTACHMENT_INDEX_NAME_SEPARATOR));
}
public static String getActivityPriority(final int priority) {
return getActivityPriority(priority, Locale.getDefault());
}
public static String getActivityPriority(final int priority, final Locale locale) {
final ResourceBundle bundle = ResourceBundle.getBundle("org.ow2.bonita.util.Priority", locale);
try {
if (priority < 0 || priority > 2) {
return bundle.getString(String.valueOf(0));
}
return bundle.getString(String.valueOf(priority));
} catch (final MissingResourceException e) {
throw new IllegalArgumentException("Priority: " + priority + " has no label", e);
}
}
/**
* @param decodeAndGather
* @param contextProperties
* @return
* @throws ClassNotFoundException
* @throws IOException
*/
public static Object deserialize(final byte[] buf, final Properties contextProperties) throws IOException,
ClassNotFoundException {
final Object res = deserialize(buf);
if (res == null) {
return null;
} else if (res instanceof String && contextProperties != null) {
return ProcessBuilder.resolveWithContext((String) res, contextProperties);
} else if (res.getClass().isArray() && contextProperties != null) {
final Object[] array = (Object[]) res;
for (int i = 0; i < array.length; i++) {
if (array[i] instanceof String) {
array[i] = ProcessBuilder.resolveWithContext((String) array[i], contextProperties);
}
}
return array;
} else {
return res;
}
}
public static String fragmentAndBase64Encode(final byte[] bytes) throws IOException {
final StringBuilder encodedString = new StringBuilder();
final int bytesFragmentLength = BASE64_BYTES_FRAGMENT_LENGTH;
int nbFragment = bytes.length / bytesFragmentLength;
final int remainingBytes = bytes.length % bytesFragmentLength;
if (remainingBytes > 0) {
nbFragment++;
}
int bytesPosition = 0;
for (int nbFragmentsProcessed = 0; nbFragmentsProcessed < nbFragment; nbFragmentsProcessed++) {
ByteArrayOutputStream byteArrayOutputStream = null;
if (nbFragmentsProcessed + 1 < nbFragment) {
byteArrayOutputStream = new ByteArrayOutputStream(bytesFragmentLength);
byteArrayOutputStream.write(bytes, bytesPosition, bytesFragmentLength);
} else {
byteArrayOutputStream = new ByteArrayOutputStream(remainingBytes);
byteArrayOutputStream.write(bytes, bytesPosition, remainingBytes);
}
final String stringFragment = Base64.encodeBytes(byteArrayOutputStream.toByteArray());
if (bytesPosition != 0) {
encodedString.append(BASE64_BYTES_FRAGMENT_SEPARATOR);
}
encodedString.append(stringFragment);
byteArrayOutputStream.close();
bytesPosition += bytesFragmentLength;
}
return encodedString.toString();
}
public static byte[] base64DecodeAndGather(final String encodedString) throws IOException {
final String[] encodedFragments = encodedString.split(BASE64_BYTES_FRAGMENT_SEPARATOR);
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
for (final String encodedFragment : encodedFragments) {
final byte[] decodedFragment = Base64.decode(encodedFragment);
byteArrayOutputStream.write(decodedFragment);
}
final byte[] decodedBytes = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.close();
return decodedBytes;
}
public static String hash(final String text) {
if (text == null) {
return null;
} else {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
} catch (final NoSuchAlgorithmException e) {
throw new BonitaRuntimeException(e);
}
byte[] hash = null;
try {
hash = md.digest(text.getBytes("UTF-8"));
} catch (final UnsupportedEncodingException e) {
throw new BonitaRuntimeException(e);
}
final StringBuilder sb = new StringBuilder(hash.length * 2);
for (final byte b : hash) {
sb.append(String.format("%x", b));
}
return sb.toString();
}
}
/**
* @param variableId
* @return
*/
public static String getGroovyPlaceholderAccessExpression(final String variableId) {
final String[] segments = variableId.split(BonitaConstants.JAVA_VAR_SEPARATOR);
return segments[1];
}
/**
* @return
*/
public static String getSetterName(final String variableId) {
final String[] segments = variableId.split(BonitaConstants.JAVA_VAR_SEPARATOR);
return segments[2];
}
public static File createDirectories(final String path) {
final File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return file;
}
}