| /** |
| * |
| * 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._java_class; |
| |
| 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); |
| } |
| } |