blob: 6bfb65aa2591762c8f4068a9b951fbcba7d2dfd9 [file] [log] [blame]
/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.yoko.rmi.impl;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.rmi.CORBA.Stub;
import javax.rmi.CORBA.ValueHandler;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.ValueDefPackage.FullValueDescription;
import org.omg.SendingContext.RunTime;
public class ValueHandlerImpl implements ValueHandler {
static final Logger logger = Logger.getLogger(ValueHandlerImpl.class
.getName());
TypeRepository repository;
RunTimeCodeBaseImpl codeBase;
private TypeRepository getRepository() {
return RMIState.current().getTypeRepository(); // repository;
}
ValueHandlerImpl(TypeRepository rep) {
this.repository = rep;
}
private ValueDescriptor desc(Class clz) {
return (ValueDescriptor) getRepository().getDescriptor(clz);
}
private ValueDescriptor desc(String repId) {
return (ValueDescriptor)getRepository().getDescriptor(repId);
}
private ValueDescriptor desc(Class clz, String repid, RunTime runtime) {
try {
return (ValueDescriptor) getRepository().getDescriptor(clz, repid,
runtime);
} catch (ClassNotFoundException ex) {
MARSHAL m = new MARSHAL("class not found " + ex.getMessage());
m.initCause(ex);
throw m;
}
}
public void writeValue(org.omg.CORBA.portable.OutputStream out,
java.io.Serializable val) {
desc(val.getClass()).writeValue(out, val);
}
java.util.Map streamMap = new java.util.HashMap();
public java.io.Serializable readValue(
org.omg.CORBA.portable.InputStream in, int offset,
java.lang.Class clz, java.lang.String repid,
org.omg.SendingContext.RunTime codebase) {
try {
return readValue0(in, offset, clz, repid, codebase);
} catch (Error ex) {
logger.log(Level.FINE, "Exception reading value of type " + repid, ex);
throw ex;
} catch (RuntimeException ex) {
logger.log(Level.FINE, "Exception reading value of type " + repid, ex);
throw ex;
}
}
public java.io.Serializable readValue0(
org.omg.CORBA.portable.InputStream in, int offset,
java.lang.Class clz, java.lang.String repid,
org.omg.SendingContext.RunTime codebase) {
java.io.Serializable obj = null;
ValueDescriptor desc = repid == null ? desc(clz) : desc(clz, repid,
codebase);
Integer key = new Integer(offset);
boolean remove = false;
java.util.Map offsetMap = null;
try {
synchronized (streamMap) {
offsetMap = (java.util.Map) streamMap.get(in);
if (offsetMap == null) {
offsetMap = new java.util.HashMap();
streamMap.put(in, offsetMap);
remove = true;
}
}
obj = desc.readValue(in, offsetMap, key);
/*
* // lazy initialization of recursive fields... for (ValueBox box =
* (ValueBox) offsetMap.get (key); box != null; box = box.next) {
* box.set (obj); }
*/
} finally {
if (remove) {
synchronized (streamMap) {
streamMap.remove(in);
}
}
}
return obj;
}
public java.lang.String getRMIRepositoryID(java.lang.Class clz) {
return getRepository().getDescriptor(clz).getRepositoryID();
}
@Override
public boolean isCustomMarshaled(java.lang.Class clz) {
return desc(clz).isChunked();
}
public synchronized org.omg.SendingContext.RunTime getRunTimeCodeBase() {
logger.finer("getRunTimeCodeBase");
if (codeBase == null) {
codeBase = new RunTimeCodeBaseImpl(this);
}
org.omg.CORBA.ORB orb = RMIState.current().getORB();
org.omg.PortableServer.POA poa = RMIState.current().getPOA();
try {
org.omg.CORBA.Object ref = poa.servant_to_reference(codeBase);
return org.omg.SendingContext.CodeBaseHelper.narrow(ref);
} catch (org.omg.PortableServer.POAPackage.ServantNotActive ex) {
// ignore //
} catch (org.omg.PortableServer.POAPackage.WrongPolicy ex) {
throw (org.omg.CORBA.INTERNAL)new org.omg.CORBA.INTERNAL("should not happen").initCause(ex);
}
try {
byte[] id = poa.activate_object(codeBase);
org.omg.CORBA.Object ref = poa.id_to_reference(id);
return org.omg.SendingContext.CodeBaseHelper.narrow(ref);
} catch (org.omg.PortableServer.POAPackage.ServantAlreadyActive ex) {
throw (org.omg.CORBA.INTERNAL)new org.omg.CORBA.INTERNAL("should not happen").initCause(ex);
} catch (org.omg.PortableServer.POAPackage.ObjectNotActive ex) {
throw (org.omg.CORBA.INTERNAL)new org.omg.CORBA.INTERNAL("should not happen").initCause(ex);
} catch (org.omg.PortableServer.POAPackage.WrongPolicy ex) {
throw (org.omg.CORBA.INTERNAL)new org.omg.CORBA.INTERNAL("should not happen").initCause(ex);
}
}
public java.io.Serializable writeReplace(java.io.Serializable val) {
if (val instanceof RMIStub) {
RMIStub stub = (RMIStub) val;
Class type = stub._descriptor.type;
RMIState state = RMIState.current();
Stub result = state.getStaticStub(stub._get_codebase(), type);
if (result != null) {
result._set_delegate(stub._get_delegate());
logger.finer("replacing with stub " + result.getClass().getName());
return result;
}
return new org.apache.yoko.rmi.impl.RMIPersistentStub(stub, type);
} else {
ValueDescriptor desc = desc(val.getClass());
java.io.Serializable result = desc.writeReplace(val);
if (result != val) {
logger.finer("replacing with value of type " + val.getClass().getName() + " with " + result.getClass().getName());
}
return result;
}
}
static Class getClassFromRepositoryID(String id) {
String className = null;
if (logger.isLoggable(Level.FINER)) {
logger.finer("getClassFromRepositoryID => " + id);
}
try {
if (id.startsWith("RMI:")) {
className = id.substring(4, id.indexOf(':', 4));
} else if (id.startsWith("IDL:")) {
className = id.substring(4, id.indexOf(':', 4));
} else {
if (logger.isLoggable(Level.FINER)) {
logger.finer("getClassFromRepositoryID =>> " + null);
}
return null;
}
if (logger.isLoggable(Level.FINER)) {
logger.finer("getClassFromRepositoryID =>> " + className);
}
ClassLoader loader = RMIState.current().getClassLoader();
return loader.loadClass(className);
} catch (Throwable ex) {
logger.log(Level.FINE, "error resolving class from id", ex);
return null;
}
}
String getImplementation(String id) {
try {
String result = "";
Class clz = getClassFromRepositoryID(id);
if (clz != null) {
result = javax.rmi.CORBA.Util.getCodebase(clz);
if (result == null) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("failed to find implementation " + id);
}
return "";
}
}
if (logger.isLoggable(Level.FINER)) {
logger.finer("getImplementation " + id + " => " + result);
}
return result;
} catch (RuntimeException ex) {
logger.log(Level.FINE, "error implementation class from id", ex);
throw ex;
}
}
String[] getImplementations(String[] ids) {
if (ids == null)
return new String[0];
String[] result = new String[ids.length];
for (int i = 0; i < ids.length; i++) {
result[i] = getImplementation(ids[i]);
}
return result;
}
FullValueDescription meta(String repId) {
if (logger.isLoggable(Level.FINER))
logger.finer(String.format("meta \"%s\"", repId));
try {
ValueDescriptor desc = desc(repId);
if (null == desc) {
Class clz = getClassFromRepositoryID(repId);
if (clz == null) {
logger.warning("class not found: " + repId);
throw new org.omg.CORBA.MARSHAL(0x4f4d0001,
CompletionStatus.COMPLETED_MAYBE);
}
desc = desc(clz);
}
return desc.getFullValueDescription();
} catch (Throwable ex) {
logger.log(Level.WARNING, "exception in meta", ex);
throw (org.omg.CORBA.OBJECT_NOT_EXIST)new org.omg.CORBA.OBJECT_NOT_EXIST()
.initCause(ex);
}
}
String[] getBases(String id) {
try {
Class clz = getClassFromRepositoryID(id);
if (clz == null)
return new String[0];
Class[] ifaces = clz.getInterfaces();
Class superClz = clz.getSuperclass();
java.util.ArrayList supers = new java.util.ArrayList();
if (superClz != Object.class) {
addIfRMIClass(supers, superClz);
}
for (int i = 0; i < ifaces.length; i++) {
addIfRMIClass(supers, ifaces[i]);
}
String[] result = new String[supers.size()];
for (int i = 0; i < supers.size(); i++) {
result[i] = ((TypeDescriptor) supers.get(i)).getRepositoryID();
}
if (logger.isLoggable(Level.FINER)) {
logger.finer("getBases " + id + " => " + result);
}
return result;
} catch (Throwable ex) {
logger.log(Level.WARNING, "exception in CodeBase::bases", ex);
return new String[0];
}
}
private void addIfRMIClass(java.util.List list, Class clz) {
TypeDescriptor desc = getRepository().getDescriptor(clz);
if (desc instanceof RemoteDescriptor)
list.add(desc);
else if (desc instanceof ValueDescriptor)
list.add(desc);
}
}