Skip to content
Permalink
Browse files
Merge branch 'disable-repid-class-cache' into 'ibm-trunk'
Disable TypeDescriptorCache lookup for ClassDesc to Class resolution

Doing this requires creating a standard utility for converting from repid to class names / classes in yoko-util, which can then be used by code in both yoko-core and yoko-rmi-impl (thus eliminating duplication and inconsistency).

See merge request !50
  • Loading branch information
ngmr committed May 28, 2015
2 parents 3d11ccd + 84e3770 commit fecb90d58274bf549b360f4ae836a9b9a9655277
Showing 7 changed files with 302 additions and 399 deletions.
@@ -337,253 +337,6 @@ public static String getExceptionId(Exception ex) {
}
}

//
// Convert a repository ID into a class name.
// See the IDL-to-Java mapping, section 1.13.8.
//
public static String idToClassName(String id, String suffix) {
String result = null;

if (id.startsWith("IDL:")) {
try {
StringBuffer buf = new StringBuffer();

int end = id.lastIndexOf(':');
String s;
if (end < 0)
s = id.substring(4);
else
s = id.substring(4, end);

//
// If the ID contains a prefix, then fix each of the
// dotted components of the prefix
//
int slash = s.indexOf('/');
if (slash > 0) {
String prefix = s.substring(0, slash);
String rest = s.substring(slash + 1);
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(
prefix, ".");
while (tokenizer.hasMoreTokens()) {
String tok = tokenizer.nextToken();
buf.append(fixName(tok));
buf.append('.');
}
s = rest;
}

//
// "Fix" the remainder of the ID
//
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(
s, "/");
while (tokenizer.hasMoreTokens()) {
String tok = tokenizer.nextToken();
buf.append(fixName(tok));
if (tokenizer.hasMoreTokens())
buf.append('.');
}

result = buf.toString() + suffix;
} catch (IndexOutOfBoundsException ex) // if id has bad format
{
result = null;
}
}
else if (id.startsWith ("RMI:")) {
int end = id.indexOf (':', 4);
result = end < 0
? id.substring (4)
: id.substring (4, end);
}
if (result != null) {
result = removeUnicodeEscapes(result);
}
return result;
}


/**
* Remove Unicode \Uxxxx escape sequences from a string
* received from the client ORB.
*
* @param in The input string.
*
* @return The string with any unicode escape sequences converted
* into the appropriate character values.
*/
public static String removeUnicodeEscapes(String in) {
// if no escape sequences are in the string, this is easy
int escape = in.indexOf("\\U");
if (escape < 0) {
return in;
}

// get a string buffer at least as long as the input string
StringBuffer out = new StringBuffer(in.length());
int start = 0;

while (escape >= 0) {
// add the next real segment to the buffer
out.append(in.substring(start, escape));
// step over the escape sequence
escape += 2;

int value = 0;
for (int i=0; i<4; i++) {
char ch = in.charAt(escape++);
switch (ch) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value = (value << 4) + ch - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value = (value << 4) + 10 + ch - 'a';
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
value = (value << 4) + 10 + ch - 'A';
break;
default:
// not sure what to do here. Just treat it as a 0 nibble
value = (value << 4);
}
}
// now append this as a char value
out.append((char)value);
// now step and find the next one
start = escape;
escape = in.indexOf("\\U", escape);
}
// don't forget the trailing segment
if (start < in.length()) {
out.append(in.substring(start));
}
return out.toString();
}

//
// Convert a repository ID into a class.
// See the IDL-to-Java mapping, section 1.13.8.
//
public static Class idToClass(String id, String suffix) {
logger.fine("Searching for class from " + id + " using suffix " + suffix);
Class result = null;
String className = idToClassName(id, suffix);

logger.fine("Converted class name is " + className);

if (className != null) {
try {
// get the appropriate class for the loading.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
result = javax.rmi.CORBA.Util.loadClass(className, null, loader);
} catch (ClassNotFoundException ex) {
logger.fine("Converted class name not found");
// ignore
}
}

return result;
}

//
// Check the given name against Java keywords and reserved suffixes
//
public static String fixName(String name) {
Assert._OB_assert(name.indexOf('.') == -1); // Not for absolute names

int nameLen = name.length();
if (nameLen == 0)
return name;

final String[] kwds = {
//
// Note: This list must be sorted alphabetically
//
"abstract", "assert", "boolean", "break", "byte", "case",
"catch", "char", "class", "clone", "const", "continue",
"default", "do", "double", "else", "equals", "extends",
"false", "final", "finalize", "finally", "float", "for",
"getClass", "goto", "hashCode", "if", "implements", "import",
"instanceof", "int", "interface", "long", "native", "new",
"notify", "notifyAll", "null", "package", "private",
"protected", "public", "return", "short", "static", "super",
"switch", "synchronized", "this", "throw", "throws",
"toString", "transient", "true", "try", "void", "volatile",
"wait", "while" };

int l = 0;
int r = kwds.length;

while (l < r) {
int m = (l + r) / 2;
int res = kwds[m].compareTo(name);
if (res == 0)
return "_" + name;
else if (res > 0)
r = m;
else
l = m + 1;
}

//
// Prepend an underscore for each of the reserved suffixes below
//
final String[] reserved = { "Helper", "Holder", "Operations", "POA",
"POATie", "Package", "ValueFactory" };

String result = name;
String curr = name;

boolean match;
do {
int currLen = curr.length();

match = false;
for (int i = 0; i < reserved.length; i++) {
if (curr.endsWith(reserved[i])) {
//
// Prepend an underscore to result
//
result = "_" + result;

//
// Remove suffix from curr
//
int resLen = reserved[i].length();
if (currLen > resLen)
curr = curr.substring(0, currLen - resLen);
else
curr = "";

match = true;
break;
}
}
} while (match);

return result;
}

public static void insertException(org.omg.CORBA.Any any,
java.lang.Exception ex) {
//
@@ -20,6 +20,8 @@
import java.util.logging.Logger;
import java.util.logging.Level;

import org.apache.yoko.util.cmsf.RepIds;

public final class ValueFactoryManager {
static final Logger logger = Logger.getLogger(ValueFactoryManager.class.getName());
//
@@ -176,7 +178,7 @@ public org.omg.CORBA.portable.ValueFactory lookupValueFactoryWithClass(String id
//
// Try to convert the repository ID into a class name.
//
Class c = Util.idToClass(id, "DefaultFactory");
Class c = RepIds.query(id).suffix("DefaultFactory").toClass();
if (c != null) {
try {
logger.finer("Attempting to create value factory from class " + c.getName());
@@ -29,6 +29,7 @@
import org.apache.yoko.orb.CORBA.InputStream;
import org.apache.yoko.orb.CORBA.OutputStream;
import org.apache.yoko.orb.OCI.Buffer;
import org.apache.yoko.util.cmsf.RepIds;
import org.omg.CORBA.Any;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.CustomMarshal;
@@ -272,7 +273,7 @@ private BoxedValueHelper getBoxedHelper(String id) {
if (WStringValueHelper.id().equals(id))
return new WStringValueHelper();

final Class helperClass = Util.idToClass(id, "Helper");
final Class helperClass = RepIds.query(id).suffix("Helper").toClass();

if (helperClass != null) {
try {
@@ -942,7 +943,7 @@ private Serializable readRMIValue(Header h, Class<? extends Serializable> clz, S
}
}

final String className = Util.idToClassName(repid, "");
final String className = RepIds.query(repid).toClassName();
String codebase = h.codebase;

if (codebase == null) {
@@ -1319,14 +1320,14 @@ public TypeCode remarshalValue(TypeCode tc, OutputStream out) {
// that is compatible with the base type. This will require resolving the classes.
if (id == null) {
// see if we can resolve the type for the stored type code
final Class<?> baseType = Util.idToClass(tcId, "");
final Class<?> baseType = RepIds.query(tcId).toClass();
if (baseType != null) {
for (idPos = 0; idPos < h.ids.length; idPos++) {
if (logger.isLoggable(Level.FINER))
logger.finer(String.format(
"Considering base types of id \"%s\" against \"%s\"",
tcId, h.ids[idPos]));
final Class idType = Util.idToClass(h.ids[idPos], "");
final Class idType = RepIds.query(h.ids[idPos]).toClass();
if (idType != null) {
// if these classes are assignment compatible, go with that as the type.
if (logger.isLoggable(Level.FINER))
@@ -22,6 +22,7 @@
import javax.rmi.CORBA.ValueHandler;

import org.apache.yoko.orb.CORBA.ORB;
import org.apache.yoko.util.cmsf.RepIds;
import org.apache.yoko.util.osgi.ProviderLocator;
import org.omg.CORBA.WStringValueHelper;
import org.omg.CORBA.portable.BoxedValueHelper;
@@ -218,7 +219,7 @@ private BoxedValueHelper getHelper(java.io.Serializable value,
org.omg.CORBA.TypeCode origType = org.apache.yoko.orb.CORBA.TypeCode
._OB_getOrigType(type);
String id = origType.id();
helperClass = Util.idToClass(id, "Helper");
helperClass = RepIds.query(id).suffix("Helper").toClass();
} catch (org.omg.CORBA.TypeCodePackage.BadKind ex) {
Assert._OB_assert(ex);
}
@@ -10,6 +10,7 @@
import javax.rmi.CORBA.ClassDesc;
import javax.rmi.CORBA.Util;

import org.apache.yoko.util.cmsf.RepIds;
import org.omg.CORBA.MARSHAL;

public class ClassDescDescriptor extends ClassBaseDescriptor {
@@ -40,21 +41,10 @@ public Class<?> run() {
String repid = (String) repid_field.get(desc);
String codebase = (String) codebase_field.get(desc);

TypeDescriptor typeDesc = repository.getDescriptor(repid);
if (null != typeDesc) {
Class<?> type = typeDesc.getJavaClass();
if (null != type) return type;
}
Class<?> result = RepIds.query(repid).codebase(codebase).toClass();
if (null != result) return result;

int beg = repid.indexOf(':');
int end = repid.indexOf(':', beg + 1);

className = repid.substring(beg + 1, end);
ClassLoader loader = Thread.currentThread().getContextClassLoader();

return Util.loadClass(className, codebase, loader);
} catch (ClassNotFoundException ex) {
throw (MARSHAL)new MARSHAL("cannot load class " + className).initCause(ex);
throw new MARSHAL(String.format("Cannot load class \"%s\"", className));
} catch (IllegalAccessException ex) {
throw (MARSHAL)new MARSHAL("no such field: " + ex).initCause(ex);
}

0 comments on commit fecb90d

Please sign in to comment.