001: /*
002: * @(#)Utils.java 1.4 06/08/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.jumpimpl.ixc;
028:
029: import java.lang.reflect.Method;
030: import java.util.*;
031: import java.security.*;
032: import java.io.*;
033: import java.rmi.*;
034: import javax.microedition.xlet.ixc.StubException;
035:
036: import com.sun.jump.os.JUMPOSInterface;
037:
038: /*
039: * This is a class with various (mostly static) utility methods.
040: */
041:
042: public class Utils {
043:
044: /**
045: * Compute the "method hash" of a remote method. The method hash
046: * is a long containing the first 64 bits of the SHA digest from
047: * the UTF encoded string of the method name and descriptor.
048: */
049: static long computeMethodHash(Method m) {
050: long hash = 0;
051: ByteArrayOutputStream sink = new ByteArrayOutputStream(127);
052: try {
053: MessageDigest md = MessageDigest.getInstance("SHA");
054: DataOutputStream out = new DataOutputStream(
055: new DigestOutputStream(sink, md));
056:
057: String s = getMethodNameAndDescriptor(m);
058:
059: out.writeUTF(s);
060:
061: // use only the first 64 bits of the digest for the hash
062: out.flush();
063: byte hasharray[] = md.digest();
064: for (int i = 0; i < Math.min(8, hasharray.length); i++) {
065: hash += ((long) (hasharray[i] & 0xFF)) << (i * 8);
066: }
067: } catch (IOException ignore) {
068: /* can't happen, but be deterministic anyway. */
069: hash = -1;
070: } catch (NoSuchAlgorithmException complain) {
071: throw new SecurityException(complain.getMessage());
072: }
073: return hash;
074: }
075:
076: /**
077: * Return a string consisting of the given method's name followed by
078: * its "method descriptor", as appropriate for use in the computation
079: * of the "method hash".
080: *
081: * See section 4.3.3 of The Java(TM) Virtual Machine Specification
082: * for the definition of a "method descriptor".
083: */
084: private static String getMethodNameAndDescriptor(Method m) {
085: StringBuffer desc = new StringBuffer(m.getName());
086: desc.append('(');
087: Class[] paramTypes = m.getParameterTypes();
088: for (int i = 0; i < paramTypes.length; i++) {
089: desc.append(getTypeDescriptor(paramTypes[i]));
090: }
091: desc.append(')');
092: Class returnType = m.getReturnType();
093: if (returnType == void.class) { // optimization: handle void here
094: desc.append('V');
095: } else {
096: desc.append(getTypeDescriptor(returnType));
097: }
098: return desc.toString();
099: }
100:
101: /**
102: * Get the descriptor of a particular type, as appropriate for either
103: * a parameter or return type in a method descriptor.
104: */
105: private static String getTypeDescriptor(Class type) {
106: if (type.isPrimitive()) {
107: if (type == int.class) {
108: return "I";
109: } else if (type == boolean.class) {
110: return "Z";
111: } else if (type == byte.class) {
112: return "B";
113: } else if (type == char.class) {
114: return "C";
115: } else if (type == short.class) {
116: return "S";
117: } else if (type == long.class) {
118: return "J";
119: } else if (type == float.class) {
120: return "F";
121: } else if (type == double.class) {
122: return "D";
123: } else if (type == void.class) {
124: return "V";
125: } else {
126: throw new Error("unrecognized primitive type: " + type);
127: }
128: } else if (type.isArray()) {
129: /*
130: * According to JLS 20.3.2, the getName() method on Class does
131: * return the VM type descriptor format for array classes (only);
132: * using that should be quicker than the otherwise obvious code:
133: *
134: * return "[" + getTypeDescriptor(type.getComponentType());
135: */
136: return type.getName().replace('.', '/');
137: } else {
138: return "L" + type.getName().replace('.', '/') + ";";
139: }
140: }
141:
142: private static int mtaskServerID = -1;
143: private static int mtaskClientID = -1;
144:
145: public static int getMtaskServerID() {
146:
147: if (mtaskServerID == -1) {
148: try {
149:
150: JUMPOSInterface os = JUMPOSInterface.getInstance();
151: mtaskServerID = os.getExecutiveProcessID();
152:
153: //new Exception("serverID="+mtaskServerID).printStackTrace();
154:
155: } catch (Exception e) {
156: e.printStackTrace();
157: mtaskServerID = 0;
158: }
159: }
160:
161: return mtaskServerID;
162: }
163:
164: public static int getMtaskClientID() {
165:
166: if (mtaskClientID == -1) {
167: try {
168:
169: JUMPOSInterface os = JUMPOSInterface.getInstance();
170: mtaskClientID = os.getProcessID();
171:
172: //new Exception("clientID="+mtaskClientID).printStackTrace();
173: } catch (Exception e) {
174: e.printStackTrace();
175: mtaskClientID = 0;
176: }
177: }
178:
179: return mtaskClientID;
180: }
181: }
|