import com.ms.com.*; import com.ms.win32.*; import com.ms.activeX.*; // the RMI client classes import java.rmi.*; import java.io.*; /** * An RMI Moniker allows VB/VBA/VBScript to communicate with an * RMI server as if it's a pure DCOM server - without writing any * Java (besides this) on the client; * * Copyright 1999, Dan Adler, danadler@rcn.com * * Once this class is javareg'd with progid 'rmi', * it serves as a COM Moniker for binding to rmi servers * so you can say, in VB: * Set x = GetObject("rmi://host/Servicename") * and you get back an COM Auto-Dispatch wrapper for the * remote server's java.rmi.Remote interface, so you can * invoke on it without any further Java code; * * The basic moniker framework is based on code by Drew Marsh. */ public class RmiMoniker implements IMoniker, IParseDisplayName { protected String m_DisplayName = null; public RmiMoniker() {} public RmiMoniker(String theStr) { m_DisplayName = theStr; } // the full moniker string is actually the java lookup string private String parseDisplayName(String dn) { return dn; } //IMoniker Methods /**Binds to the object named by the moniker. */ public IUnknown BindToObject(IBindCtx p1, IMoniker p2, _Guid p3) { System.out.println("bind:"+m_DisplayName); if (m_DisplayName == null) return null; try { Remote remote = Naming.lookup(m_DisplayName); return (IUnknown)ComLib.makeProxyRef( remote ); } catch (Exception e) { throw new ComFailException(e.toString()); } } /**Binds to the object's storage. */ public IUnknown BindToStorage(IBindCtx p1, IMoniker p2, _Guid p3) { throw new ComFailException(0x800401ED); // MK_E_NOSTORAGE } /**Reduces the moniker to simplest form. */ public IMoniker Reduce(IBindCtx p1, int p2, IMoniker p3[]) { throw new ComFailException(0x80000003); // E_INVALIDARG } /**Composes with another moniker. */ public IMoniker ComposeWith(IMoniker p1, boolean p2) { return this; } /**Enumerates component monikers. */ public IEnumMoniker Enum(boolean p1) { return null; } /**Compares with another moniker. */ public boolean IsEqual(IMoniker p1) { return this.equals(p1); } /**Returns a hash value. */ public int Hash() { return m_DisplayName.hashCode(); } /**Checks whether object is running. */ public boolean IsRunning(IBindCtx p1, IMoniker p2, IMoniker p3) { return true; } /**Returns time the object was last changed. */ public long GetTimeOfLastChange(IBindCtx p1, IMoniker p2) { throw new ComFailException(0x800401E3); // MK_E_UNAVAILABLE } /**Returns the inverse of the moniker. */ public IMoniker Inverse() { return Ole32.CreateAntiMoniker(); } /**Finds the prefix that the moniker has in common with another moniker. */ public void CommonPrefixWith(IMoniker p1, IMoniker p2[]) { throw new ComFailException(0x80000003); // E_INVALIDARG } /**Constructs a relative moniker between the moniker and another. */ public void RelativePathTo(IMoniker p1, IMoniker p2[]) { throw new ComFailException(0x80000003); // E_INVALIDARG } /**Returns the display name. */ public String GetDisplayName(IBindCtx p1, IMoniker p2) { return m_DisplayName; } /**Converts a display name into a moniker. */ public IMoniker ParseDisplayName(IBindCtx p1, IMoniker p2, String p3, int p4[]) { System.out.println("ParseDisplayName:" + p3); p4[0] = p3.length(); return this; } /**Checks whether moniker is one of the system-supplied types. */ public boolean IsSystemMoniker(int p1[]) { p1[0] = 0; return false; } //IParseDisplayName Methods /**Parses the display name returning a moniker corresponding to it. */ public IMoniker ParseDisplayName(IBindCtx p1, String p2, int p3[]) { System.out.println("IParseDisplayName:" + p2); p3[0] = p2.length(); return new RmiMoniker(parseDisplayName(p2)); } //IPersist Methods /**Returns the object's CLSID. */ public _Guid GetClassID() { //Java's equivalent to uuidof() return ComLib.getGuidOf(this.getClass()); } //IPersistStream Methods //Unfortunately, the VM can provide IPersistStreamInit and IPersistStorage, but not IPersistStream /**Checks whether object has been modified. */ public boolean IsDirty() { //Monikers always return S_FALSE throw new ComSuccessException(0x00000001); // S_FALSE } /**Loads the object from a stream. */ public void Load(IStream pstm) { try { ObjectInputStream obj = new ObjectInputStream(new ActiveXInputStream(pstm)); m_DisplayName = (String) obj.readObject(); obj.close(); } catch (IOException e) { throw new ComFailException(0x8000FFFF, e.getMessage()); // E_UNEXPECTED } catch (ClassNotFoundException e) { throw new ComFailException(0x8000FFFF, e.getMessage()); // E_UNEXPECTED } } /**Saves the object to a stream. */ public void Save(IStream pstm, boolean fClearDirty) { //We can ignore the fClearDirty flag.... try { ObjectOutputStream obj = new ObjectOutputStream(new ActiveXOutputStream(pstm)); obj.writeObject(m_DisplayName); obj.flush(); obj.close(); } catch (IOException e) { throw new ComFailException(0x8000FFFF, e.getMessage()); // E_UNEXPECTED } } /**Returns the buffer size needed to save the object. */ public long GetSizeMax() { //HACK: There should be a more elegant way of doing this.... return (long)m_DisplayName.length()*2; } }