/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.util;
import java.net.*;
import java.io.*;
import java.util.Properties;
import java.lang.reflect.*;
import javax.naming.*;
import javax.rmi.*;
import javax.rmi.CORBA.*;
import java.util.logging.*;
import com.sun.logging.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.UnsupportedCharsetException;
/**
* Handy class full of static functions.
*/
public final class Utility {
static Logger _logger=LogDomains.getLogger(Utility.class, LogDomains.UTIL_LOGGER);
private static LocalStringManagerImpl localStrings =
new LocalStringManagerImpl(Utility.class);
public static void checkJVMVersion()
{
// do not perform any JVM version checking
}
public static Properties getPropertiesFromFile(String file)
throws IOException
{
InputStream is = ClassLoader.getSystemResourceAsStream(file);
if (is != null) {
Properties config = new Properties();
config.load(is);
return config;
} else {
String remoteclient = "/" + file;
InputStream is2 = Utility.class.getResourceAsStream(remoteclient);
Properties config = new Properties();
config.load(is2);
return config;
}
}
/**
* Return the hostname of the local machine.
*/
public static String getLocalHost() {
String hostname = null;
try {
InetAddress ia = InetAddress.getLocalHost();
hostname = ia.getHostName();
} catch(UnknownHostException e) {
return "localhost";
}
return hostname;
}
/**
* Return the hostname of the local machine.
*/
public static String getLocalAddress() {
String address = null;
try {
InetAddress ia = InetAddress.getLocalHost();
address = ia.getHostAddress();
} catch(UnknownHostException e) {
return "127.0.0.1";
}
return address;
}
/**
* This is a convenience method to lookup a remote object by name within
* the naming context.
* @exception javax.naming.NamingException if the object with that
* name could not be found.
*/
public static java.rmi.Remote lookupObject(String publishedName,
java.lang.Class anInterface)
throws javax.naming.NamingException {
Context ic = new InitialContext();
java.lang.Object objRef = ic.lookup(publishedName);
return (java.rmi.Remote)
PortableRemoteObject.narrow(objRef, anInterface);
}
/** Unmarshal a byte array to an integer.
Assume the bytes are in BIGENDIAN order.
i.e. array[offset] is the most-significant-byte
and array[offset+3] is the least-significant-byte.
@param array The array of bytes.
@param offset The offset from which to start unmarshalling.
*/
public static int bytesToInt(byte[] array, int offset)
{
int b1, b2, b3, b4;
b1 = (array[offset++] << 24) & 0xFF000000;
b2 = (array[offset++] << 16) & 0x00FF0000;
b3 = (array[offset++] << 8) & 0x0000FF00;
b4 = (array[offset++] << 0) & 0x000000FF;
return (b1 | b2 | b3 | b4);
}
/** Marshal an integer to a byte array.
The bytes are in BIGENDIAN order.
i.e. array[offset] is the most-significant-byte
and array[offset+3] is the least-significant-byte.
@param array The array of bytes.
@param offset The offset from which to start marshalling.
*/
public static void intToBytes(int value, byte[] array, int offset)
{
array[offset++] = (byte)((value >>> 24) & 0xFF);
array[offset++] = (byte)((value >>> 16) & 0xFF);
array[offset++] = (byte)((value >>> 8) & 0xFF);
array[offset++] = (byte)((value >>> 0) & 0xFF);
}
/** Unmarshal a byte array to an long.
Assume the bytes are in BIGENDIAN order.
i.e. array[offset] is the most-significant-byte
and array[offset+7] is the least-significant-byte.
@param array The array of bytes.
@param offset The offset from which to start unmarshalling.
*/
public static long bytesToLong(byte[] array, int offset)
{
long l1, l2;
l1 = (long)bytesToInt(array, offset) << 32;
l2 = (long)bytesToInt(array, offset+4) & 0xFFFFFFFFL;
return (l1 | l2);
}
/** Marshal an long to a byte array.
The bytes are in BIGENDIAN order.
i.e. array[offset] is the most-significant-byte
and array[offset+7] is the least-significant-byte.
@param array The array of bytes.
@param offset The offset from which to start marshalling.
*/
public static void longToBytes(long value, byte[] array, int offset)
{
array[offset++] = (byte)((value >>> 56) & 0xFF);
array[offset++] = (byte)((value >>> 48) & 0xFF);
array[offset++] = (byte)((value >>> 40) & 0xFF);
array[offset++] = (byte)((value >>> 32) & 0xFF);
array[offset++] = (byte)((value >>> 24) & 0xFF);
array[offset++] = (byte)((value >>> 16) & 0xFF);
array[offset++] = (byte)((value >>> 8) & 0xFF);
array[offset++] = (byte)((value >>> 0) & 0xFF);
}
/**
* Verify and invoke main if present in the specified class.
*/
public static void invokeApplicationMain(Class mainClass, String[] args)
throws InvocationTargetException, IllegalAccessException,
ClassNotFoundException
{
String err = localStrings.getLocalString ("utility.no.main", "",
new Object[] {mainClass});
// determine the main method using reflection
// verify that it is public static void and takes
// String[] as the only argument
Method mainMethod = null;
try {
mainMethod = mainClass.getMethod("main",
new Class[] { String[].class } );
} catch(NoSuchMethodException msme) {
_logger.log(Level.SEVERE,"enterprise_util.excep_in_utility",msme);
throw new ClassNotFoundException(err);
}
// check modifiers: public static
int modifiers = mainMethod.getModifiers ();
if (!Modifier.isPublic (modifiers) ||
!Modifier.isStatic (modifiers)) {
err = localStrings.getLocalString(
"utility.main.notpublicorstatic",
"The main method is either not public or not static");
_logger.log(Level.SEVERE,"enterprise_util.excep_in_utility_main.notpublicorstatic");
throw new ClassNotFoundException(err);
}
// check return type and exceptions
if (!mainMethod.getReturnType().equals (Void.TYPE)) {
err = localStrings.getLocalString(
"utility.main.notvoid",
"The main method's return type is not void ");
_logger.log(Level.SEVERE,"enterprise_util.excep_in_utility_main.notvoid");
throw new ClassNotFoundException(err);
}
// build args to the main and call it
Object params [] = new Object [1];
params[0] = args;
mainMethod.invoke(null, params);
}
public static void invokeSetMethod(Object obj, String prop, String value)
throws NoSuchMethodException, InvocationTargetException,
IllegalAccessException
{
Class cl = obj.getClass();
// change first letter to uppercase
String setMeth = "set" + prop.substring(0,1).toUpperCase() +
prop.substring(1);
// try string method
try {
Class[] cldef = {String.class};
Method meth = cl.getMethod(setMeth, cldef);
Object[] params = {value};
meth.invoke(obj, params);
return;
} catch (NoSuchMethodException ex) {
try {
// try int method
Class[] cldef = {Integer.TYPE};
Method meth = cl.getMethod(setMeth, cldef);
Object[] params = {Integer.valueOf(value)};
meth.invoke(obj, params);
return;
} catch(NoSuchMethodException nsmex) {
// try boolean method
Class[] cldef = {Boolean.TYPE};
Method meth = cl.getMethod(setMeth, cldef);
Object[] params = {Boolean.valueOf(value)};
meth.invoke(obj, params);
return;
}
}
}
public static void invokeSetMethodCaseInsensitive(Object obj, String prop, String value)
throws NoSuchMethodException, InvocationTargetException,
IllegalAccessException
{
String alternateMethodName = null;
Class cl = obj.getClass();
String setMeth = "set" + prop;
Method[] methodsList = cl.getMethods();
boolean methodFound = false;
int i=0;
for (i =0; i<methodsList.length; ++i)
{
if(methodsList[i].getName().equalsIgnoreCase(setMeth) == true)
{
Class[] parameterTypes = methodsList[i].getParameterTypes();
if(parameterTypes.length == 1 )
{
if(parameterTypes[0].getName().equals("java.lang.String"))
{
methodFound = true;
break;
}
else
alternateMethodName = methodsList[i].getName();
}
}
}
if(methodFound == true)
{
Object[] params = {value};
methodsList[i].invoke(obj, params);
return;
}
if(alternateMethodName != null)
{
try
{
// try int method
Class[] cldef = {Integer.TYPE};
Method meth = cl.getMethod(alternateMethodName, cldef);
Object[] params = {Integer.valueOf(value)};
meth.invoke(obj, params);
return;
}
catch(NoSuchMethodException nsmex)
{
// try boolean method
Class[] cldef = {Boolean.TYPE};
Method meth = cl.getMethod(alternateMethodName, cldef);
Object[] params = {Boolean.valueOf(value)};
meth.invoke(obj, params);
return;
}
}
else
throw new NoSuchMethodException(setMeth);
}
// Ports are marshalled as shorts on the wire. The IDL
// type is unsigned short, which lacks a convenient representation
// in Java in the 32768-65536 range. So, we treat ports as
// ints throught this code, except that marshalling requires a
// scaling conversion. intToShort and shortToInt are provided
// for this purpose.
public static short intToShort(int value)
{
if (value > 32767)
return (short)(value - 65536) ;
return (short)value ;
}
public static int shortToInt(short value)
{
if (value < 0)
return value + 65536 ;
return value ;
}
/**
* Get the current thread's context class loader which is set to
* the CommonClassLoader by ApplicationServer
* @return the thread's context classloader if it exists;
* else the system class loader.
*/
public static ClassLoader getClassLoader() {
if (Thread.currentThread().getContextClassLoader() != null) {
return Thread.currentThread().getContextClassLoader();
} else {
return ClassLoader.getSystemClassLoader();
}
}
/**
* Loads the class with the common class loader.
* @param className the class name
* @return the loaded class
* @exception if the class is not found.
*/
public static Class loadClass(String className) throws ClassNotFoundException {
return getClassLoader().loadClass(className);
}
/**
* Utility routine for setting the context class loader.
* Returns previous class loader.
*/
public static ClassLoader setContextClassLoader(ClassLoader newClassLoader) {
// Can only reference final local variables from dopriveleged block
final ClassLoader classLoaderToSet = newClassLoader;
final Thread currentThread = Thread.currentThread();
ClassLoader originalClassLoader = currentThread.getContextClassLoader();
if (classLoaderToSet != originalClassLoader) {
if (System.getSecurityManager() == null) {
currentThread.setContextClassLoader(classLoaderToSet);
} else {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public java.lang.Object run() {
currentThread.setContextClassLoader(classLoaderToSet);
return null;
}
}
);
}
}
return originalClassLoader;
}
public static void setEnvironment() {
Environment.obtain().activateEnvironment();
}
/**
* Return the value for a given name from the System Properties or the
* Environmental Variables. The former overrides the latter.
* @param name - the name of the System Property or Environmental Variable
* @return the value of the variable or null if it was not found
*/
public static String getEnvOrProp(String name) {
// System properties override env. variables
String envVal = System.getenv(name);
String sysPropVal = System.getProperty(name);
if(sysPropVal != null)
return sysPropVal;
return envVal;
}
/**
* Convert the byte array to char array with respect to given charset.
*
* @param byteArray
* @param charset null or "" means default charset
* @exception CharacterCodingException
*/
public static char[] convertByteArrayToCharArray(byte[] byteArray, String charset)
throws CharacterCodingException {
if (byteArray == null) {
return null;
}
byte[] bArray = (byte[])byteArray.clone();
ByteBuffer byteBuffer = ByteBuffer.wrap(bArray);
Charset charSet;
if (charset == null || "".equals(charset)) {
charSet = Charset.defaultCharset();
} else if (Charset.isSupported(charset)) {
charSet = Charset.forName(charset);
} else {
CharacterCodingException e = new CharacterCodingException();
e.initCause(new UnsupportedCharsetException(charset));
throw e;
}
CharsetDecoder decoder = charSet.newDecoder();
CharBuffer charBuffer = null;
try {
charBuffer = decoder.decode(byteBuffer);
} catch(CharacterCodingException cce) {
throw cce;
} catch(Throwable t) {
CharacterCodingException e = new CharacterCodingException();
e.initCause(t);
throw e;
}
char[] result = (char[])charBuffer.array().clone();
clear(byteBuffer);
clear(charBuffer);
return result;
}
/**
* Convert the char array to byte array with respect to given charset.
*
* @param charArray
* @param strCharset null or "" means default charset
* @exception CharacterCodingException
*/
public static byte[] convertCharArrayToByteArray(char[] charArray, String strCharset)
throws CharacterCodingException {
if (charArray == null) {
return null;
}
char[] cArray = (char[])charArray.clone();
CharBuffer charBuffer = CharBuffer.wrap(cArray);
Charset charSet;
if (strCharset == null || "".equals(strCharset)) {
charSet = Charset.defaultCharset();
} else if (Charset.isSupported(strCharset)) {
charSet = Charset.forName(strCharset);
} else {
CharacterCodingException e = new CharacterCodingException();
e.initCause(new UnsupportedCharsetException(strCharset));
throw e;
}
CharsetEncoder encoder = charSet.newEncoder();
ByteBuffer byteBuffer = null;
try {
byteBuffer = encoder.encode(charBuffer);
} catch(CharacterCodingException cce) {
throw cce;
} catch(Throwable t) {
CharacterCodingException e = new CharacterCodingException();
e.initCause(t);
throw e;
}
byte[] result = new byte[byteBuffer.remaining()];
byteBuffer.get(result);
clear(byteBuffer);
clear(charBuffer);
return result.clone();
}
private static void clear(ByteBuffer byteBuffer) {
byte[] bytes = byteBuffer.array();
for (int i = 0; i < bytes.length; i++) {
bytes[i] = 0;
}
}
private static void clear(CharBuffer charBuffer) {
char[] chars = charBuffer.array();
for (int i = 0; i < chars.length; i++) {
chars[i] = '0';
}
}
}