dims        2002/12/06 10:17:42

  Added:       proposals/COMBridge deploy.wsdd
               proposals/COMBridge/CPP COMBridge.cpp COMBridge.dep
                        COMBridge.dsp COMBridge.dsw COMBridge.h
                        COMBridge.ncb COMBridge.opt COMBridge.plg
                        org_apache_axis_components_bridge_COMBridge.h
               proposals/COMBridge/CPP/Debug COMBridge.dll
               proposals/COMBridge/java/org/apache/axis/components/bridge
                        COMBridge.java
  Log:
  Porting COMProvider in Apache SOAP to Apache Axis (Stripped down, componentized and 
renamed to COMBridge)
  
  Note:
  - Since this has a mixture of C++ and java code. Am adding this to Proposals 
directory.
  
  Revision  Changes    Path
  1.1                  xml-axis/proposals/COMBridge/deploy.wsdd
  
  Index: deploy.wsdd
  ===================================================================
  <deployment
      xmlns="http://xml.apache.org/axis/wsdd/";
      xmlns:java="http://xml.apache.org/axis/wsdd/providers/java";>
    <service name="comadd" provider="java:COM" style="rpc" use="encoded">
        <parameter name="ProgID" value="Apacheadder.adder"/>
        <parameter name="wsdlTargetNamespace" value="urn:javascript"/>
        <parameter name="wsdlServiceElement" value="JSService"/>
        <parameter name="wsdlServicePort" value="add"/>
        <parameter name="wsdlPortType" value="add"/>
        <operation name="add" qname="operNS:add" 
xmlns:operNS="http://DefaultNamespace"; returnQName="addReturn" returnType="rtns:short" 
xmlns:rtns="http://www.w3.org/2001/XMLSchema"; >
          <parameter name="in0" type="tns:short" 
xmlns:tns="http://www.w3.org/2001/XMLSchema"/>
          <parameter name="in1" type="tns:short" 
xmlns:tns="http://www.w3.org/2001/XMLSchema"/>
        </operation>
        <parameter name="allowedMethods" value="add"/>
    </service>
  </deployment>
  
  
  1.1                  xml-axis/proposals/COMBridge/CPP/COMBridge.cpp
  
  Index: COMBridge.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "SOAP" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, International
   * Business Machines, Inc., http://www.apache.org.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  #pragma warning(disable:4786) /*Very annoying warning that symbol exceeds debug info 
size */
  #include <cstdlib>
  #include <sstream>
  
  #include <string.h>
  #include <iostream>
  #include <deque>
  #include <string>
  #include <cassert>
  #include <new>
  #include <new.h>
  #include <algorithm>
  
  #include <jni.h>
  #include <process.h>
  #include <windows.h>
  #include <objbase.h>
  #include "COMBridge.h"
  
  using namespace std;
  
  HRESULT variant2object (JNIEnv * jenv, const VARIANT & var, jobject & ret,
                        bool * localRefCreated = NULL);
  
  wchar_t ModuleName[MAX_PATH * 2] = { 0 };
  HANDLE thisModule;
  
  BOOL WINAPI
  DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID fImpLoad)
  {
    if (fdwReason == DLL_PROCESS_ATTACH)
      {
        thisModule = hinstDll;
        GetModuleFileName (hinstDll, ModuleName, sizeof ModuleName);
      }
  
    return true;
  }
  
  void
  dumpVariant (VARIANT & v)
  {
    switch (v.vt)
      {
      case VT_I4:
        fwprintf (stderr, L"Integer: %d\n", v.lVal);
        break;
      case VT_BSTR:
        fwprintf (stderr, L"BStr: %s\n", v.bstrVal);
        break;
      case VT_BOOL:
        fwprintf (stderr, L"Boolean: %d\n", v.boolVal);
        break;
      }
  }
  
  /*These can someday go into a msg resource file for NLS translation */
  int msgCLSID2stringfailed =
    (int) L"Failed to convert string to clsid hr= 0x%1!lx!";
  int msgNoParms = (int) L"The number of parameters I got is: %1!u!";
  int msgComInitfailed = (int) L"COM Initialize failed hr= 0x%1!lx!";
  int msgCLSIDnMethod = (int) L"CLSID is:%1, method to execute is:%2";
  int msgPROGIDnMethod = (int) L"Progid is:%1, method to execute is:%2";
  int msgPROGID2CLSID = (int) L"Failed to convert progid to clsid hr= 0x%1!lx!";
  int msgFailedCoCreate =
    (int) L"Failed to create instance and interface IID_Dispatch hr=0x%1!lx!";
  int msgFailedGetdipid = (int) L"Failed to get dispid for method %1";
  int msgFailedDIInvoke = (int) L"Invoke of method %1 failed.  hr=0x%2!lx!";
  int msgSuccess = (int) L"Success! Return back to java.";
  int msgCoTaskMemAllocFail =
    (int) L"Insufficient resources CoTaskMemAlloc failed.";
  int msgCalledDLL = (int) L"In DLL:%1!s!";
  int msgInvokeFailedParms =
    (int)
    L"COMBridge: method:%1!s! received error %2!lu!. Error source: %3!ls!\t. 
Description:%4!s!";
  int msgInvokeFailedParms2 =
    (int) L"Bad argument:%1!lu! method %2!ls!.  hr=0x%3!lx!";
  int msgInvokeFailed = (int) L"Invoke of method %1!s! failed.  hr=0x%2!lx!";
  int msgUnknowCPPException = (int) L"An unknown CPP exception has occurred";
  int msgFailedConvertReturn =
    (int)
    L"Failed to convert return parameter, variant type:0x%1!lx!, Object:%2!s!, 
Method:%3!s!";
  int msgFailedMemory = (int) L"Failed to allocate memory!";
  
  const short LOG_INFORMATION = 0x1000;
  const short LOG_SUCCESS = 0x100;
  const short LOG_WARNING = 0x10;
  const short LOG_ERROR = 1;
  short eventLevel = LOG_ERROR;
  
  /*
   *  Undoes an action when exiting scope.
   */
  struct Undoit
  {
    void (__stdcall * coinit) (void);
    IDispatch *idisp;
    VARIANT *vp;
  
     ~Undoit ()
    {
      if (NULL != idisp)
        {
        idisp->Release ();
        idisp = NULL;
        }
      if (NULL != vp)
        {
        CoTaskMemFree (vp);
        vp = NULL;
        }
      if (NULL != coinit)
        {
        coinit ();
        coinit = NULL;
        }
    }
  };
  
  /*
   *  The actual provider.
   */
  class COMBridge
  {
    jobject jPP;                        //the java pluggable provider
    JNIEnv *env;
    static const char *javaClass;
  public:
    /*
     * Constructor that initializes member variables.
     */
      COMBridge (JNIEnv * e, jobject jthis):jPP (jthis), env (e)
    {
    };
    /*
     * Gets the dispatch type to handle property get/set as
     * well as straight method calls.
     */
    WORD getMethodDispatchType (const wchar_t * mname)
    {
      WORD ret = DISPATCH_METHOD;
      if (0 == wcsncmp (L"get_", mname, 4))
        ret = DISPATCH_PROPERTYGET;
      else if (0 == wcsncmp (L"set_", mname, 4))
        ret = DISPATCH_PROPERTYPUT;
      return ret;
    }
    /*
     * Invokes a method on a COM object, translating parameters and results
     * between Java types and COM types.
     */
    jobject invoke (jstring jthreadingModel, jstring jprogid,
                  jstring jmethodName, jbyteArray parms_in)
    {
      eventlog (LOG_SUCCESS, msgCalledDLL, ModuleName);
      wchar_t progid[256];
      Undoit undoit;
      ZeroIt (undoit);
      //
      // Get a local copy of parameters.  The Java code for the
      // Bridge has already munged the Java parameters into the
      // byte array (which is really a VARIANT array) we use here.
      //
      jsize noParmsBytes =
        NULL == parms_in ? 0 : env->GetArrayLength (parms_in);
      unsigned noParms = noParmsBytes / sizeof VARIANT;
      eventlog (LOG_SUCCESS, msgNoParms, noParms);
      char *x = NULL;
      if (noParms)
        {
        x = (char *) CoTaskMemAlloc (noParmsBytes);
        if (NULL == x)
          {
            throwException (msgCoTaskMemAllocFail);
            return NULL;
          }
        memset (x, 0, noParmsBytes);
        jboolean iscopy;
        jbyte *jpeer = env->GetByteArrayElements (parms_in, &iscopy);
        memcpy (x, jpeer, noParmsBytes);
        if (iscopy == JNI_TRUE)
          env->ReleaseByteArrayElements (parms_in, jpeer, 0);
        }
      // VARIANT *vp= (VARIANT *)x;
      undoit.vp = (VARIANT *) x;
      /*
         for(int i=0; i< noParms; ++i)
         {
         dumpVariant(vp[i]);
         }
       */
      //
      // Initialize COM
      //
      DWORD coInit = COINIT_MULTITHREADED;      //The default.
      bool oleInit = false;
      jboolean isCopy;
      wchar_t *cstr =
        (wchar_t *) env->GetStringChars (jthreadingModel, &isCopy);
      if (0 == wcscmp (cstr, L"MULTITHREADED"))
        {                               //just
        coInit = COINIT_MULTITHREADED;  //Just recognize it.
        }
      else if (0 == wcscmp (cstr, L"APARTMENTTHREADED"))
        {
        coInit = COINIT_APARTMENTTHREADED;
        }
      else if (0 == wcscmp (cstr, L"SINGLEAPARTMENTTHREADED"))
        {
        oleInit = true;
        }
  
      if (isCopy == JNI_TRUE)
        env->ReleaseStringChars (jthreadingModel, cstr);
      HRESULT hr;
      if (oleInit)
        {
        hr = OleInitialize (NULL);
        if (ASSERT_FAILED (hr))
          {
            eventlog (LOG_WARNING, msgComInitfailed, hr);
            throwException (msgComInitfailed, hr);
            return NULL;
          }
        undoit.coinit = OleUninitialize;        //Ensure we uninitialize.
        }
      else
        {
        hr = CoInitializeEx (NULL, coInit);
        if (ASSERT_FAILED (hr))
          {
            eventlog (LOG_WARNING, msgComInitfailed, hr);
            throwException (msgComInitfailed, hr);
            return NULL;
          }
        undoit.coinit = CoUninitialize; //Ensure we uninitialize.
        }
      //
      // Get the method name
      //
      cstr = (wchar_t *) env->GetStringChars (jmethodName, &isCopy);
      wchar_t *methodName = _wcsdup (cstr);
      if (isCopy == JNI_TRUE)
        env->ReleaseStringChars (jmethodName, cstr);
      if (!methodName)
        {
        eventlog (LOG_ERROR, msgFailedMemory);
        throwException (msgFailedMemory);
        return NULL;
        }
      //
      // Get the CLSID
      //
      CLSID clsid;
      cstr = (wchar_t *) env->GetStringChars (jprogid, &isCopy);
      if (L'{' == cstr[0])      //clsid is specified as a string
        {
        hr = CLSIDFromString (cstr, &clsid);
        if (ASSERT_FAILED (hr))
          {
            throwException (msgCLSID2stringfailed, hr);
            if (isCopy == JNI_TRUE)
              env->ReleaseStringChars (jprogid, cstr);
            if (methodName)
              free (methodName);
            return NULL;
          }
        eventlog (LOG_INFORMATION, msgCLSIDnMethod, cstr, methodName);
        }
      else
        {
        eventlog (LOG_INFORMATION, msgPROGIDnMethod, cstr, methodName);
        hr = CLSIDFromProgID (cstr, &clsid);
        if (ASSERT_FAILED (hr))
          {
            eventlog (LOG_WARNING, msgPROGID2CLSID, hr);
            if (isCopy == JNI_TRUE)
              env->ReleaseStringChars (jprogid, cstr);
            throwException (msgPROGID2CLSID, hr);
            if (methodName)
              free (methodName);
            return NULL;
          }
        }
      ZeroIt (progid);
      wcsncpy (progid, cstr, (sizeof (progid) / (sizeof progid[0])) - 1);
      if (isCopy == JNI_TRUE)
        env->ReleaseStringChars (jprogid, cstr);
  
      //
      // Create an instance of the COM object
      //
      hr =
        CoCreateInstance (clsid, NULL, CLSCTX_ALL, IID_IDispatch,
                        (void **) &undoit.idisp);
  
      if (ASSERT_FAILED (hr))
        {
        eventlog (LOG_WARNING, msgFailedCoCreate, hr);
        throwException (msgFailedCoCreate, hr);
        if (methodName)
          free (methodName);
        return NULL;
        }
      //
      // Get the dispatch id of the method
      //
      DISPID dispid;
      ZeroIt (dispid);
      bool isSet = false;
      unsigned nameOffset = 0;
      if (0 == wcsncmp (L"get_", methodName, 4))
        nameOffset = 4;
      else if (0 == wcsncmp (L"set_", methodName, 4))
        {
        nameOffset = 4;
        isSet = true;
        }
      wchar_t *mname = methodName + nameOffset;
  
      hr =
        undoit.idisp->GetIDsOfNames (IID_NULL, &mname, 1, GetUserDefaultLCID (),
                                   &dispid);
  
      if (ASSERT_FAILED (hr))
        {
        eventlog (LOG_WARNING, msgFailedGetdipid, methodName);
        throwException (msgFailedGetdipid, methodName);
        if (methodName)
          free (methodName);
        return NULL;
        }
      //
      // Initialize the parameter info
      //
      DISPPARAMS dispparams;
      ZeroIt (dispparams);
      dispparams.rgvarg = undoit.vp;
      dispparams.cArgs = noParms;
      DISPID didpp = DISPID_PROPERTYPUT;
      if (isSet)
        {
        dispparams.cNamedArgs = 1;
        dispparams.rgdispidNamedArgs = &didpp;
        }
      //
      // Invoke the COM method
      //
      VARIANT result;
      ZeroIt (result);
      EXCEPINFO expInfo;
      ZeroIt (expInfo);
      unsigned parg;
      ZeroIt (parg);
      hr =
        undoit.idisp->Invoke (dispid, IID_NULL, GetUserDefaultLCID (),
                            getMethodDispatchType (methodName), &dispparams,
                            &result, &expInfo, &parg);
      //
      // Translate COM errors or exceptions to Java
      //
      if (hr == DISP_E_EXCEPTION)
        {
        unsigned long err = (unsigned long) expInfo.wCode;
        if (err == 0l)
          err = (unsigned long) expInfo.scode;
        wchar_t *source = expInfo.bstrSource ? expInfo.bstrSource : L"";
        wchar_t *desc =
          expInfo.bstrDescription ? expInfo.bstrDescription : L"";
        throwException (msgInvokeFailedParms, methodName, err, source, desc);
        if (methodName)
          free (methodName);
        return NULL;
        }
  
      if (ASSERT_FAILED (hr))
        {
        if (hr == DISP_E_TYPEMISMATCH || hr == DISP_E_PARAMNOTFOUND)
          {
            throwException (msgInvokeFailedParms2, noParms - parg, methodName,
                            hr);
            if (methodName)
              free (methodName);
            return NULL;
          }
        eventlog (LOG_WARNING, msgFailedDIInvoke, methodName, hr);
        throwException (msgInvokeFailed, methodName, hr);
        if (methodName)
          free (methodName);
        return NULL;
        }
      //
      // Convert the result to a variant
      //
      jobject jresult = NULL;
  
      hr = variant2object (env, result, jresult);
      if (ASSERT_FAILED (hr))
        {
        eventlog (LOG_ERROR, msgFailedConvertReturn, V_VT (&result), progid,
                  methodName);
        throwException (msgFailedConvertReturn, V_VT (&result), progid,
                        methodName);
        if (methodName)
          free (methodName);
        ::VariantClear (&result);
        return NULL;
        }
  
      if (methodName)
        free (methodName);
      eventlog (LOG_SUCCESS, msgSuccess);
      ::VariantClear (&result);
      return jresult;
    }
    /*
     * Throws a exception for a UNICODE string.
     */
    BOOL throwException (const wchar_t * msg)
    {
      if (NULL == msg)
        msg = L"Exception thrown by COMBridge";
      jclass Exception = env->FindClass ("java/lang/Exception");
      env->ThrowNew (Exception, ws2mbs (msg));
      return true;
    }
    /*
     * Throws a SOAP exception for a string.
     */
    BOOL throwException (const char *msg)
    {
      if (NULL == msg)
        msg = "Exception thrown by COMBridge";
      jclass Exception = env->FindClass ("java/lang/Exception");
      env->ThrowNew (Exception, msg);
      return true;
    }
    /*
     * Throws a SOAP exception for a Win32 message id.
     */
    BOOL throwException (int id, ...)
    {
      va_list a;
      va_start (a, id);
      wchar_t *msgbuf = NULL;
      FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
                   FORMAT_MESSAGE_FROM_STRING, (wchar_t *) id, 0, 3,
                   (wchar_t *) & msgbuf, 10000, &a);
  
      return throwException (msgbuf);
    }
  
    /*
     * Logs an event
     */
    BOOL eventlog (short eventtype, int id, ...)
    {
      if ((eventtype & eventLevel) == 0)
        return false;
      va_list a;
      va_start (a, id);
      wchar_t *msgbuf;
      FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
                   FORMAT_MESSAGE_FROM_STRING, (wchar_t *) id, 0, 3,
                   (wchar_t *) & msgbuf, 10000, &a);
  
      // fwprintf( stderr,  L"%s\n", msgbuf);
      jclass spClass = env->GetObjectClass (jPP);
  //   jstring jmsg= env->NewStringUTF(ws2mbs(msgbuf));
      jstring jmsg = env->NewString (msgbuf, wcslen (msgbuf));
      jmethodID mid =
        env->GetMethodID (spClass, "logit", "(ILjava/lang/String;)V");
      env->CallVoidMethod (jPP, mid, (jint) eventtype, jmsg);
      env->DeleteLocalRef (jmsg);
      LocalFree (msgbuf);
  
      return true;
    }
  };                            //class COMBridge
  
  /*
   * org.apache.axis.components.bridge.COMBridge#invoke
   *
   * Invokes the COM method as the SOAP service.
   */
  extern
    "C"
    JNIEXPORT
    jobject
    JNICALL
  Java_org_apache_axis_components_bridge_COMBridge_invoke
    (JNIEnv * env, jobject jo, jstring threadingModel, jstring jprogid,
     jstring jmethodName, jbyteArray parms_in)
  {
    // Instantiate a COMBridge (see above) and call its invoke member function.
    CRTDBGBRK COMBridge cp (env, jo);
  #ifdef NDEBUG                 //This also will to debug on demand so if we are 
debugging don't do the catch.
    try
    {
  #endif
      env->ExceptionClear ();   //Ignore all previous errors.
      return cp.invoke (threadingModel, jprogid, jmethodName, parms_in);
  #ifdef NDEBUG
    }
    catch (wchar_t * wstr)
    {
      env->ExceptionClear ();   //Ignore all previous errors.
      cp.throwException (wstr);
      return NULL;
    }
    catch (char *str)
    {
      env->ExceptionClear ();   //Ignore all previous errors.
      cp.throwException (str);
      return NULL;
    }
    catch (unsigned int ui)
    {
      env->ExceptionClear ();   //Ignore all previous errors.
      wchar_t
        numbuf[16];
      cp.throwException (_ultow (ui, numbuf, 10));
      return NULL;
    }
    catch (...)
    {                           //Main point here is not to trap the JVM!
      env->ExceptionClear ();   //Ignore all previous errors.
      cp.throwException (msgUnknowCPPException);
      return NULL;
    }
  #endif
  }
  
  /*
   * org.apache.axis.components.bridge.COMBridge#nativeConvertToBString
   *
   * Converts a Java string to a BSTR.
   */
  extern
    "C"
    JNIEXPORT
    jbyteArray
    JNICALL
  Java_org_apache_axis_components_bridge_COMBridge_nativeConvertToBString
    (JNIEnv * env, jclass jc, jstring s)
  {
    env->ExceptionClear ();     //Let a calling thread to invoke a call record the 
error.
    jboolean
      isCopy;
    const wchar_t *
      cs =
      env->
      GetStringChars (s, &isCopy);
    BSTR
      bstrS =
      SysAllocString (cs);
    if (isCopy == JNI_TRUE)
      env->ReleaseStringChars (s, cs);
    jbyteArray
      jByteArray =
      env->
      NewByteArray (sizeof bstrS);
    jbyte *
      jr =
      env->
      GetByteArrayElements (jByteArray, &isCopy);
    void *
      x =
      bstrS;
    memcpy (jr, &x, sizeof x);
    if (isCopy == JNI_TRUE)
      env->ReleaseByteArrayElements (jByteArray, jr, 0);
    return jByteArray;
  }
  
  /*
   * Functions to create a Java Object from primitive types.
   */
  jobject
  bsf_makeBoolean (JNIEnv * jenv, int val)
  {
    jclass
      classobj =
      jenv->
      FindClass ("java/lang/Boolean");
    jmethodID
      constructor =
      jenv->
      GetMethodID (classobj, "<init>", "(Z)V");
    return jenv->NewObject (classobj, constructor, (jboolean) val);
  }
  
  jobject
  bsf_makeByte (JNIEnv * jenv, int val)
  {
    jclass
      classobj =
      jenv->
      FindClass ("java/lang/Byte");
    jmethodID
      constructor =
      jenv->
      GetMethodID (classobj, "<init>", "(B)V");
    return jenv->NewObject (classobj, constructor, (jbyte) val);
  }
  
  jobject
  bsf_makeShort (JNIEnv * jenv, int val)
  {
    jclass
      classobj =
      jenv->
      FindClass ("java/lang/Short");
    jmethodID
      constructor =
      jenv->
      GetMethodID (classobj, "<init>", "(S)V");
    return jenv->NewObject (classobj, constructor, (jshort) val);
  }
  
  jobject
  bsf_makeInteger (JNIEnv * jenv, int val)
  {
    jclass
      classobj =
      jenv->
      FindClass ("java/lang/Integer");
    jmethodID
      constructor =
      jenv->
      GetMethodID (classobj, "<init>", "(I)V");
    return jenv->NewObject (classobj, constructor, (jint) val);
  }
  
  jobject
  bsf_makeLong (JNIEnv * jenv, long val)
  {
    jclass
      classobj =
      jenv->
      FindClass ("java/lang/Long");
    jmethodID
      constructor =
      jenv->
      GetMethodID (classobj, "<init>", "(J)V");
    return jenv->NewObject (classobj, constructor, (jlong) val);
  }
  
  jobject
  bsf_makeFloat (JNIEnv * jenv, float val)
  {
    jclass
      classobj =
      jenv->
      FindClass ("java/lang/Float");
    jmethodID
      constructor =
      jenv->
      GetMethodID (classobj, "<init>", "(F)V");
    return jenv->NewObject (classobj, constructor, (jfloat) val);
  }
  
  jobject
  bsf_makeDouble (JNIEnv * jenv, double val)
  {
    jclass
      classobj =
      jenv->
      FindClass ("java/lang/Double");
    jmethodID
      constructor =
      jenv->
      GetMethodID (classobj, "<init>", "(D)V");
    return jenv->NewObject (classobj, constructor, (jdouble) val);
  }
  
  /*
   * Create a Java Object from VARIANT types.
   */
  HRESULT
  variant2object (JNIEnv * jenv, const VARIANT & var, jobject & jresult,
                bool * localRefCreated)
  {
    HRESULT
      result =
      S_OK;
    char *
      buf =
      NULL;
    if (localRefCreated)
      *localRefCreated = true;  //this is mostly the case.
    switch (V_VT (&var))
      {
      case VT_ERROR:
      case VT_EMPTY:
      case VT_NULL:
        if (localRefCreated)
        *localRefCreated = false;
        jresult = NULL;
        break;
      case VT_I1:
        jresult = bsf_makeByte (jenv, (int) V_I1 (&var));
        break;
      case VT_I2:
        jresult = bsf_makeShort (jenv, (int) V_I2 (&var));
        break;
      case VT_I4:
        jresult = bsf_makeInteger (jenv, (int) V_I4 (&var));
        break;
      case VT_I8:
        /* where's V_I8??? */
        jresult = bsf_makeLong (jenv, (long) V_I4 (&var));
        break;
      case VT_R4:
        jresult = bsf_makeFloat (jenv, (float) V_R4 (&var));
        break;
      case VT_R8:
        jresult = bsf_makeDouble (jenv, (double) V_R8 (&var));
        break;
      case VT_BSTR:
        /* if its a string with the right stuff, retract the object */
  //  buf= ws2mbs(var.bstrVal);
  //  jresult = jenv->NewStringUTF (buf);
        jresult = jenv->NewString (var.bstrVal, wcslen (var.bstrVal));
        break;
      case VT_BOOL:
        jresult = bsf_makeBoolean (jenv, (int) V_BOOL (&var));
        break;
      case VT_VARIANT:
        result =
        variant2object (jenv, *(V_VARIANTREF (&var)), jresult,
                        localRefCreated);
        break;
      case VT_UI1:
        jresult = bsf_makeShort (jenv, (int) V_UI1 (&var));
        break;
      case VT_UI2:
        jresult = bsf_makeInteger (jenv, (int) V_UI2 (&var));
        break;
      case VT_UI4:
        jresult = bsf_makeLong (jenv, (long) V_UI4 (&var));
        break;
      case VT_UI8:
        /* where's V_UI8??? */
        jresult = bsf_makeLong (jenv, (long) V_UI4 (&var));
        break;
      case VT_INT:
        jresult = bsf_makeInteger (jenv, V_INT (&var));
        break;
      case VT_UINT:
        jresult = bsf_makeLong (jenv, (long) V_UINT (&var));
        break;
      default:
        if (V_ISBYREF (&var))
        {
          if ((var.vt & (VT_BYREF | VT_ARRAY)) == (VT_BYREF | VT_ARRAY))
            {                   //It is an array by reference.
              result = DISP_E_BADVARTYPE;       //rrfoo can support needs work.
              /*
                 //var.vt&= (~VT_BYREF);
                 VARIANT arraybyref;
                 ZeroIt(arraybyref);
                 arraybyref.vt = VT_ARRAY;
                 arraybyref.parray= *var.pparray;
                 result= variant2object(jenv, arraybyref, jresult localRefCreated);
               */
            }
          else
            {                   //This is a reference ... dereference.
              result =
                variant2object (jenv, *((VARIANT *) var.byref), jresult,
                                localRefCreated);
            }
        }
        else
        {
          result = DISP_E_BADVARTYPE;
          break;
        }
      }                         //endswitch to variant.
  
    if (!jresult && localRefCreated)
      *localRefCreated = false;
    return result;
  }
  
  
  
  1.1                  xml-axis/proposals/COMBridge/CPP/COMBridge.dep
  
  Index: COMBridge.dep
  ===================================================================
  # Microsoft Developer Studio Generated Dependency File, included by COMBridge.mak
  
  .\COMBridge.cpp : \
        "..\..\jdk13\include\jni.h"\
        "..\..\jdk13\include\win32\jni_md.h"\
        "..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
        ".\COMBridge.h"\
        ".\org_apache_axis_components_bridge_COMBridge.h"\
        
  
  
  
  1.1                  xml-axis/proposals/COMBridge/CPP/COMBridge.dsp
  
  Index: COMBridge.dsp
  ===================================================================
  # Microsoft Developer Studio Project File - Name="COMBridge" - Package Owner=<4>
  # Microsoft Developer Studio Generated Build File, Format Version 6.00
  # ** DO NOT EDIT **
  
  # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
  
  CFG=COMBridge - Win32 Debug
  !MESSAGE This is not a valid makefile. To build this project using NMAKE,
  !MESSAGE use the Export Makefile command and run
  !MESSAGE 
  !MESSAGE NMAKE /f "COMBridge.mak".
  !MESSAGE 
  !MESSAGE You can specify a configuration when running NMAKE
  !MESSAGE by defining the macro CFG on the command line. For example:
  !MESSAGE 
  !MESSAGE NMAKE /f "COMBridge.mak" CFG="COMBridge - Win32 Debug"
  !MESSAGE 
  !MESSAGE Possible choices for configuration are:
  !MESSAGE 
  !MESSAGE "COMBridge - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
  !MESSAGE "COMBridge - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
  !MESSAGE 
  
  # Begin Project
  # PROP AllowPerConfigDependencies 0
  # PROP Scc_ProjName ""
  # PROP Scc_LocalPath ""
  CPP=cl.exe
  MTL=midl.exe
  RSC=rc.exe
  
  !IF  "$(CFG)" == "COMBridge - Win32 Release"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 0
  # PROP BASE Output_Dir "Release"
  # PROP BASE Intermediate_Dir "Release"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 0
  # PROP Output_Dir "Release"
  # PROP Intermediate_Dir "Release"
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D 
"_MBCS" /D "_USRDLL" /D "COMBRIDGE_EXPORTS" /YX /FD /c
  # ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" 
/D "UNICODE" /D "_USRDLL" /D "COMBRIDGE_EXPORTS" /D "_WIN32_DCOM" /YX /FD /c
  # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
  # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
  # ADD BASE RSC /l 0x409 /d "NDEBUG"
  # ADD RSC /l 0x409 /d "NDEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 
/nologo /dll /machine:I386
  # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 
/nologo /dll /machine:I386
  
  !ELSEIF  "$(CFG)" == "COMBridge - Win32 Debug"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 1
  # PROP BASE Output_Dir "Debug"
  # PROP BASE Intermediate_Dir "Debug"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 1
  # PROP Output_Dir "Debug"
  # PROP Intermediate_Dir "Debug"
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" 
/D "_MBCS" /D "_USRDLL" /D "COMBRIDGE_EXPORTS" /YX /FD /GZ /c
  # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "c:\jdk13\include" /I 
"c:\jdk13\include\win32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D 
"UNICODE" /D "_USRDLL" /D "COMBRIDGE_EXPORTS" /D "_WIN32_DCOM" /YX /FD /GZ /c
  # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
  # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
  # ADD BASE RSC /l 0x409 /d "_DEBUG"
  # ADD RSC /l 0x409 /d "_DEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 
/nologo /dll /debug /machine:I386 /pdbtype:sept
  # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 
/nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\jdk13\lib"
  
  !ENDIF 
  
  # Begin Target
  
  # Name "COMBridge - Win32 Release"
  # Name "COMBridge - Win32 Debug"
  # Begin Group "Source Files"
  
  # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
  # Begin Source File
  
  SOURCE=.\COMBridge.cpp
  # End Source File
  # Begin Source File
  
  SOURCE=.\COMBridge.h
  # End Source File
  # Begin Source File
  
  SOURCE=.\org_apache_axis_components_bridge_COMBridge.h
  # End Source File
  # End Group
  # Begin Group "Header Files"
  
  # PROP Default_Filter "h;hpp;hxx;hm;inl"
  # End Group
  # Begin Group "Resource Files"
  
  # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
  # End Group
  # End Target
  # End Project
  
  
  
  1.1                  xml-axis/proposals/COMBridge/CPP/COMBridge.dsw
  
  Index: COMBridge.dsw
  ===================================================================
  Microsoft Developer Studio Workspace File, Format Version 6.00
  # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
  
  ###############################################################################
  
  Project: "COMBridge"=.\COMBridge.dsp - Package Owner=<4>
  
  Package=<5>
  {{{
  }}}
  
  Package=<4>
  {{{
  }}}
  
  ###############################################################################
  
  Global:
  
  Package=<5>
  {{{
  }}}
  
  Package=<3>
  {{{
  }}}
  
  ###############################################################################
  
  
  
  
  1.1                  xml-axis/proposals/COMBridge/CPP/COMBridge.h
  
  Index: COMBridge.h
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "SOAP" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, International
   * Business Machines, Inc., http://www.apache.org.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  #if !defined I9b76b170db194c3c92c61e375e31a96e
  #define I9b76b170db194c3c92c61e375e31a96e
  #include <deque>
  #include <malloc.h>
  #include <exception>
  #include <new>
  #include <new.h>
  #include <windows.h>
  #include <jni.h>
  #include "org_apache_axis_components_bridge_COMBridge.h"
  
  extern wchar_t ModuleName[MAX_PATH * 2];
  extern HANDLE thisModule;
  
  
  #if !defined(NDEBUG)
  #include <CRTDBG.H>
  #define CRTDBGBRK {if(getenv("CRTDBGBRK")){   _CrtDbgBreak();}}
  #else
  #define CRTDBGBRK
  #endif
  
  #if defined(FAILED)
  #include <cassert>
  #if defined(NDEBUG)
  #define ASSERT_FAILED FAILED
  #else
  #define ASSERT_FAILED(S) ( (true == FAILED((S))) ?((bool) (assert(0),true)) : false)
  #endif
  #endif
  
  inline wchar_t *
  mbs2wsConvert (const char *s, void *d)
  {
    size_t size = strlen (s);
    if (d && !size)
      *(wchar_t *) d = L'\0';
    if (d && size)
      {
        ((wchar_t *) d)[MultiByteToWideChar (CP_ACP,    // code page
                                           MB_COMPOSITE,        // character-type 
options
                                           s,   // address of string to map
                                           size,        // number of bytes in string
                                           (wchar_t *) d,       // address of 
wide-character buffer
                                           ((size << 1) + 1)    // size of buffer
                      )] = L'\0';
      }
    return (wchar_t *) d;
  }
  
  #define mbs2ws(s) (mbs2wsConvert((s),  _alloca( (2+strlen((const char *)(s)))<<1)))
  
  inline LPOLESTR
  mbs2LPOLESTR (const char *s)
  {
    wchar_t *ws = mbs2ws (s);
    if (ws)
      {
        return _wcsdup (ws);
      }
    return NULL;
  }
  
  inline LPOLESTR
  mbs2LPOLESTR (const std::string & s)
  {
    return mbs2LPOLESTR (s.c_str ());
  }
  
  inline char *
  ws2mbsConvert (const wchar_t * s, void *d)
  {
    size_t size = wcslen (s);   //It maybe the same size as the widechar string
    if (!size && d)
      *((char *) d) = '\0';
    if (d && size)
      {
        ((char *) d)[WideCharToMultiByte (CP_ACP,       // code page
                                        WC_COMPOSITECHECK,      // character-type 
options
                                        s,      // address of string to map
                                        size,   // number of chars in string
                                        (char *) d,     // address of mbs-character 
buffer
                                        size << 1,      // size of buffer in bytes ,   
     //Use system default character.
                                        NULL, NULL)] = L'\0';
      }
    return (char *) d;
  }
  
  // TODO: this requires sufficient stack for a copy of the string,
  // which may simply not be available.
  #define ws2mbs(s) (ws2mbsConvert((s),  _alloca( ((2+(wcslen((const wchar_t 
*)(s))<<1))))))
  
  template < class T > inline void
  ZeroIt (T & t)
  {
    memset (&t, 0, sizeof t);
  };
  
  
  #endif /*I9b76b170-db19-4c3c-92c6-1e375e31a96e */
  
  
  
  1.1                  xml-axis/proposals/COMBridge/CPP/COMBridge.ncb
  
  Index: COMBridge.ncb
  ===================================================================
  Microsoft C/C++ program database 2.00
  
  
  
  1.1                  xml-axis/proposals/COMBridge/CPP/COMBridge.opt
  
        <<Binary file>>
  
  
  1.1                  xml-axis/proposals/COMBridge/CPP/COMBridge.plg
  
  Index: COMBridge.plg
  ===================================================================
  <html>
  <body>
  <pre>
  <h1>Build Log</h1>
  <h3>
  --------------------Configuration: COMBridge - Win32 Debug--------------------
  </h3>
  <h3>Command Lines</h3>
  Creating temporary file "C:\TEMP\RSPD9.tmp" with contents
  [
  /nologo /MTd /W3 /Gm /GX /ZI /Od /I "c:\jdk13\include" /I "c:\jdk13\include\win32" 
/D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "_USRDLL" /D 
"COMBRIDGE_EXPORTS" /D "_WIN32_DCOM" /Fp"Debug/COMBridge.pch" /YX /Fo"Debug/" 
/Fd"Debug/" /FD /GZ /c 
  "C:\jakarta\xml-axis\proposals\COMBridge\CPP\COMBridge.cpp"
  ]
  Creating command line "cl.exe @C:\TEMP\RSPD9.tmp" 
  Creating temporary file "C:\TEMP\RSPDA.tmp" with contents
  [
  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib 
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes 
/pdb:"Debug/COMBridge.pdb" /debug /machine:I386 /out:"Debug/COMBridge.dll" 
/implib:"Debug/COMBridge.lib" /pdbtype:sept /libpath:"c:\jdk13\lib" 
  ".\Debug\COMBridge.obj"
  ]
  Creating command line "link.exe @C:\TEMP\RSPDA.tmp"
  <h3>Output Window</h3>
  Compiling...
  COMBridge.cpp
  Linking...
     Creating library Debug/COMBridge.lib and object Debug/COMBridge.exp
  
  
  
  <h3>Results</h3>
  COMBridge.dll - 0 error(s), 0 warning(s)
  </pre>
  </body>
  </html>
  
  
  
  1.1                  
xml-axis/proposals/COMBridge/CPP/org_apache_axis_components_bridge_COMBridge.h
  
  Index: org_apache_axis_components_bridge_COMBridge.h
  ===================================================================
  /* DO NOT EDIT THIS FILE - it is machine generated */
  #include <jni.h>
  /* Header for class org_apache_axis_components_bridge_COMBridge */
  
  #ifndef _Included_org_apache_axis_components_bridge_COMBridge
  #define _Included_org_apache_axis_components_bridge_COMBridge
  #ifdef __cplusplus
  extern "C" {
  #endif
  /* Inaccessible static: dllLoadException */
  #undef org_apache_axis_components_bridge_COMBridge_sizeOfVariant
  #define org_apache_axis_components_bridge_COMBridge_sizeOfVariant 16L
  /*
   * Class:     org_apache_axis_components_bridge_COMBridge
   * Method:    invoke
   * Signature: 
(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B)Ljava/lang/Object;
   */
  JNIEXPORT jobject JNICALL Java_org_apache_axis_components_bridge_COMBridge_invoke
    (JNIEnv *, jobject, jstring, jstring, jstring, jbyteArray);
  
  /*
   * Class:     org_apache_axis_components_bridge_COMBridge
   * Method:    nativeConvertToBString
   * Signature: (Ljava/lang/String;)[B
   */
  JNIEXPORT jbyteArray JNICALL 
Java_org_apache_axis_components_bridge_COMBridge_nativeConvertToBString
    (JNIEnv *, jclass, jstring);
  
  #ifdef __cplusplus
  }
  #endif
  #endif
  
  
  
  1.1                  xml-axis/proposals/COMBridge/CPP/Debug/COMBridge.dll
  
        <<Binary file>>
  
  
  1.1                  
xml-axis/proposals/COMBridge/java/org/apache/axis/components/bridge/COMBridge.java
  
  Index: COMBridge.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "SOAP" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, International
   * Business Machines, Inc., http://www.apache.org.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.axis.components.bridge;
  
  import java.util.Hashtable;
  import java.util.Vector;
  
  /**
   * Class COMBridge
   *
   * @author James Snell <[EMAIL PROTECTED]>
   * @author Davanum Srinivas <[EMAIL PROTECTED]>
   */
  public class COMBridge {
  
      /** Field vp           */
      private byte[] vp = null;
  
      /** Field progid           */
      private String progid = null;
  
      /** Field threadingModel           */
      private String threadingModel = null;
  
      /** Field dllLoadException           */
      static Throwable dllLoadException =
              null;                                       // Can hold an exception on 
from the loading of the c++ dll.
  
      /** Field libName           */
      static final String libName = "COMBridge";    // C++ dll name.
  
      /** Field sizeOfVariant           */
      private static final int sizeOfVariant = 16;
  
      static {
          try {
              System.loadLibrary(libName);
          } catch (java.lang.SecurityException e) {
              dllLoadException = e;
          } catch (java.lang.UnsatisfiedLinkError e) {
              dllLoadException = e;
          }
      }
  
      /**
       * Method execute
       *
       * @param methodName
       * @param parms
       * @param props
       *
       * @return
       *
       * @throws Throwable
       */
      public Object execute(String methodName, Vector parms, Hashtable props)
              throws Throwable {
  
          if (null != dllLoadException) {
              throw dllLoadException;
          }
          int noParms = 0;
          if (parms != null) {
              vp = new byte[sizeOfVariant * parms.size()];
              noParms = parms.size();
          }
          for (int i = 0; i < noParms; ++i) {
              // Yes. Parameters are reversed here.
              objectToVariant((parms.elementAt(noParms - i - 1)), vp,
                      i * sizeOfVariant);
          }
          progid = (String) props.get("progid");
          threadingModel = (String) props.get("threadmodel");
          if (null == threadingModel) {
              threadingModel = "MULTITHREADED";
          }
          return invoke(threadingModel, progid, methodName, vp);
      }    
  
      /**
       * Method logit
       *
       * @param level
       * @param msg
       */
      protected void logit(int level, String msg)     // Called by CPP
      {
          System.out.println("CPP:" + msg);
      }
  
      /**
       * Method invoke
       *
       * @param threadingModel
       * @param progId
       * @param methodName
       * @param parms
       *
       * @return
       *
       * @throws Exception
       */
      private native Object invoke(
              String threadingModel, String progId, String methodName, byte[] parms)
              throws Exception;
  
      /**
       * Method nativeConvertToBString
       *
       * @param o
       *
       * @return
       */
      private static native byte[] nativeConvertToBString(String o);
  
      /**
       * Method objectToVariant
       *
       * @param o
       * @param bo
       * @param os
       *
       * @return
       *
       * @throws Exception
       */
      private final byte[] objectToVariant(Object o, byte[] bo, int os)
              throws Exception {
          byte[] v = bo;
  
          if (null == v) {
              v = new byte[sizeOfVariant];    // Size of a variant
              os = 0;
          }
          if (null == o) {                              // to be safe.
              v[os + 0] = 1;                            // VT_NULL
              v[os + 1] = 0;
          } else if (o instanceof java.lang.Boolean)    // VT_R8
          {
              v[os + 0] = 11;                           // VT_BOOL
              v[os + 1] = 0;
              byte x = (byte) ((((Boolean) o).booleanValue())
                      ? 0xff
                      : 0);
  
              v[os + 8] = x;
              v[os + 9] = x;
              v[os + 10] = x;
              v[os + 11] = x;
          } else if (o instanceof java.lang.Integer)    // VT_R8
          {
              v[os + 0] = 3;                            // VT_I4
              v[os + 1] = 0;
              int x = ((Integer) o).intValue();
  
              v[os + 8] = (byte) x;
              v[os + 9] = (byte) ((x >>> 8) & 0xff);
              v[os + 10] = (byte) ((x >>> 16) & 0xff);
              v[os + 11] = (byte) ((x >>> 24) & 0xff);
          } else if (o instanceof java.lang.String) {
              v[os + 0] = 8;                            // VT_BSTR
              v[os + 1] = 0;
              byte[] pbs = nativeConvertToBString((String) o);
  
              v[os + 8] = pbs[0];
              v[os + 9] = pbs[1];
              v[os + 10] = pbs[2];
              v[os + 11] = pbs[3];
          } else if (o instanceof java.lang.Long)       // VT_R8
          {    // COM has no long type so promote it to double which can contain it.
              v[os + 0] = 5;                            // VT_R8
              v[os + 1] = 0;
              long x = Double.doubleToLongBits((double) (((Long) o).longValue()));
  
              v[os + 8] = (byte) x;
              v[os + 9] = (byte) ((x >>> 8) & 0xff);
              v[os + 10] = (byte) ((x >>> 16) & 0xff);
              v[os + 11] = (byte) ((x >>> 24) & 0xff);
              v[os + 12] = (byte) ((x >>> 32) & 0xff);
              v[os + 13] = (byte) ((x >>> 40) & 0xff);
              v[os + 14] = (byte) ((x >>> 48) & 0xff);
              v[os + 15] = (byte) ((x >>> 56) & 0xff);
          } else if (o instanceof java.lang.Short) {
              v[os + 0] = 2;                            // VT_I2
              v[os + 1] = 0;
              int x = ((Short) o).intValue();
  
              v[os + 8] = (byte) x;
              v[os + 9] = (byte) ((x >>> 8) & 0xff);
              v[os + 10] = (byte) ((x >>> 16) & 0xff);
              v[os + 11] = (byte) ((x >>> 24) & 0xff);
          } else if (o instanceof java.lang.Float) {
              v[os + 0] = 4;                            // VT_R4
              v[os + 1] = 0;
              int x = Float.floatToIntBits(((Float) o).floatValue());
  
              v[os + 8] = (byte) x;
              v[os + 9] = (byte) ((x >>> 8) & 0xff);
              v[os + 10] = (byte) ((x >>> 16) & 0xff);
              v[os + 11] = (byte) ((x >>> 24) & 0xff);
          } else if (o instanceof java.lang.Double)     // VT_R8
          {
              v[os + 0] = 5;                            // VT_R8
              v[os + 1] = 0;
              long x = Double.doubleToLongBits(((Double) o).doubleValue());
  
              v[os + 8] = (byte) x;
              v[os + 9] = (byte) ((x >>> 8) & 0xff);
              v[os + 10] = (byte) ((x >>> 16) & 0xff);
              v[os + 11] = (byte) ((x >>> 24) & 0xff);
              v[os + 12] = (byte) ((x >>> 32) & 0xff);
              v[os + 13] = (byte) ((x >>> 40) & 0xff);
              v[os + 14] = (byte) ((x >>> 48) & 0xff);
              v[os + 15] = (byte) ((x >>> 56) & 0xff);
          } else if (o instanceof java.lang.Byte) {
              v[os + 0] = 17;                           // VT_UI1
              v[os + 1] = 0;
              byte x = ((Byte) o).byteValue();
  
              v[os + 8] = x;
          } else if (o instanceof java.lang.Character) {
              v[os + 0] = 17;                           // VT_UI1
              v[os + 1] = 0;
              byte x = (byte) ((Character) o).charValue();
  
              v[os + 8] = x;
          } else if (o instanceof java.lang.Void) {
              v[os + 0] = 1;                            // VT_NULL
              v[os + 1] = 0;
          } else if (o.getClass().isArray()) {
  
              // ArrayInfo ai= new ArrayInfo(o);
              // v= ai.toVariant();
              throw new Exception(
                      "Currently arrays are unsupported,  type received:"
                      + o.getClass().getName());
          } else {
              throw new Exception("Currently unsupported data type received:"
                      + o.getClass().getName());
          }
          return v;
      }
  
      public static void main(String[] args) throws Throwable {
          org.apache.axis.components.bridge.COMBridge bridge = new 
org.apache.axis.components.bridge.COMBridge();
          Hashtable props = new Hashtable();
          props.put("progid", "Apacheadder.adder");
  
          String  methodName2 = "add";
          Vector  params2 = new Vector();
          params2.add(new Short("6"));
          params2.add(new Short("5"));
          Object ret2 = bridge.execute(methodName2, params2, props);
          System.out.println("return:" + ret2);
      }
  }
  
  
  


Reply via email to