| /* -*- C++ -*- */ |
| |
| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 2003 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 apache@apache.org. |
| * |
| * 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. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| |
| /* |
| * |
| * |
| * @author Lilantha Darshana (lilantha@virtusa.com) |
| * |
| */ |
| |
| #include "libAxiscpp.h" |
| #include "Packet.h" |
| #include "Axis.h" |
| #include <new> |
| #include <exception> |
| |
| #if defined (_DEBUG) |
| #include <iostream> |
| #define Trace(x) std::cout << x << std::endl; |
| #else |
| #define Trace(x) |
| #endif |
| |
| #define MIN(X,Y) (((X)<(Y))?(X):(Y)) |
| |
| /* Inaccessible static: DEBUG */ |
| /* |
| * Class: AxisCppContentHandler |
| * Method: processContent |
| * Signature: (Ljava/io/InputStream;Ljava/util/Vector;Ljava/io/OutputStream;)V |
| */ |
| JNIEXPORT void JNICALL Java_AxisCppContentHandler_processContent |
| (JNIEnv * p_Env, jclass, |
| jobject p_jBodyReader, |
| jobject p_jvHeaders, |
| jobject p_jBodyWriter, |
| jint p_jnContentLength) |
| { |
| //TODO: populate soapstream with the headers & the body; |
| // invoke to process the contents |
| axstream* paxstream = new axstream; |
| |
| JNIInputStream inputBody(p_Env,p_jBodyReader); |
| JNIOutputStream outputBody(p_Env,p_jBodyWriter); |
| paxstream->m_pInputContent = new std::istream(&inputBody); |
| paxstream->m_pOutputContent = new std::ostream(&outputBody); |
| |
| paxstream->m_nContentLen = p_jnContentLength; |
| |
| JNIVector jvHeader(p_Env, p_jvHeaders); |
| //set method name as a http header. |
| int nHeaderCount = jvHeader.size()/2; |
| paxstream->m_pHeaders = new axstream::PROT_HEADER[nHeaderCount]; |
| |
| for(int i=0;i < nHeaderCount; i++) |
| { |
| paxstream->m_pHeaders[i].pchName = jvHeader[i*2]; |
| paxstream->m_pHeaders[i].pchValue = jvHeader[i*2+1]; |
| Trace(paxstream->m_pHeaders[i].pchName ); |
| Trace(paxstream->m_pHeaders[i].pchValue); |
| } |
| paxstream->m_nHeaderCount = nHeaderCount; |
| |
| paxstream->m_enProtocolType = axstream::HTTP; |
| paxstream->m_pExtendedInfo = new axstream::EXTENDED_INFO; |
| paxstream->m_pExtendedInfo->infHttp.enMethod = axstream::HTTP_INFO::POST; |
| |
| //just add some sessionid |
| paxstream->m_pchSessionId = strdup("tmp session id"); |
| |
| AxisContentHandler::Init(); |
| if(0 != AxisContentHandler::HandleContent(*paxstream)) |
| { |
| throw "SOAP Engine failed to response"; |
| } |
| |
| jvHeader.clear(); |
| nHeaderCount = paxstream->m_nHeaderCount; |
| |
| for(int j=0;j < nHeaderCount; j++) |
| { |
| jvHeader.push_back(paxstream->m_pHeaders[j].pchName); |
| jvHeader.push_back(paxstream->m_pHeaders[j].pchValue); |
| Trace(paxstream->m_pHeaders[j].pchName ); |
| Trace(paxstream->m_pHeaders[j].pchValue); |
| } |
| |
| *paxstream->m_pOutputContent << std::flush; |
| |
| delete paxstream; |
| } |
| |
| |
| JNIVector::JNIVector(JNIEnv* p_Env, jobject p_jVector) |
| : m_pEnv(p_Env), m_jVector(p_jVector) |
| { |
| jclass clazz = p_Env->FindClass("java/util/Vector"); |
| JNI_ASSERT(clazz != NULL, "java/lang/NoClassDefFoundError", "java.util.Vector"); |
| |
| JNI_ASSERT(p_Env->IsInstanceOf(p_jVector, clazz), |
| "java/lang/IllegalArgumentException", |
| "p_jVector not a java.util.Vector object!"); |
| |
| m_jmGet = p_Env->GetMethodID(clazz, "get", "(I)Ljava/lang/Object;"); |
| |
| JNI_ASSERT(m_jmGet != NULL, |
| "java/lang/NoSuchMethodError", |
| "method 'public Object get(int index)' not found!"); |
| |
| m_jmAdd = p_Env->GetMethodID(clazz, "addElement", "(Ljava/lang/Object;)V"); |
| |
| JNI_ASSERT(m_jmGet != NULL, |
| "java/lang/NoSuchMethodError", |
| "method 'public void addElement(Object obj)' not found!"); |
| |
| m_jmClear = p_Env->GetMethodID(clazz, "clear", "()V"); |
| |
| JNI_ASSERT(m_jmGet != NULL, |
| "java/lang/NoSuchMethodError", |
| "method 'public void clear()' not found!"); |
| |
| m_jmSize = p_Env->GetMethodID(clazz, "size", "()I"); |
| JNI_ASSERT(m_jmGet != NULL, |
| "java/lang/NoSuchMethodError", |
| "method 'public void size()' not found!"); |
| |
| } |
| ///Destructor |
| JNIVector::~JNIVector() |
| { |
| |
| } |
| |
| char* JNIVector::operator [] (int i) const |
| { |
| jboolean isCopy; |
| jobject obj = m_pEnv->CallObjectMethod(m_jVector, m_jmGet, i); |
| jstring str = (jstring) obj; |
| const char *pch = m_pEnv->GetStringUTFChars(str, &isCopy); |
| if (m_pEnv->ExceptionOccurred()) |
| throw std::bad_alloc(); |
| return (char*)pch; |
| } |
| |
| void JNIVector::push_back(const char* str) |
| { |
| m_pEnv->CallVoidMethod(m_jVector, m_jmAdd, m_pEnv->NewStringUTF(str)); |
| if (m_pEnv->ExceptionOccurred()) |
| throw std::bad_exception("can't push_back"); //need to set up a exception |
| } |
| |
| void JNIVector::clear() |
| { |
| m_pEnv->CallVoidMethod(m_jVector, m_jmClear); |
| if (m_pEnv->ExceptionOccurred()) |
| throw std::bad_exception("Can't clear the vector"); //need to set up a exception |
| } |
| |
| int JNIVector::size() |
| { |
| int size = m_pEnv->CallIntMethod(m_jVector, m_jmSize); |
| if (m_pEnv->ExceptionOccurred()) |
| throw std::bad_exception("Don't know the vector size"); //need to set up a exception |
| return size; |
| } |
| |
| |
| JNIOutputStream::JNIOutputStream(JNIEnv* p_pEnv, |
| jobject stream, |
| unsigned bufsize) |
| : std::strstreambuf(bufsize), |
| m_pEnv(p_pEnv), |
| _output(stream), |
| _write(NULL), |
| _flush(NULL), |
| _bufsize(bufsize), |
| _jbuf(NULL) |
| { |
| jclass clazz = m_pEnv->FindClass("java/io/OutputStream"); |
| JNI_ASSERT(clazz != NULL, |
| "java/lang/NoClassDefFoundError", |
| "java.io.OutputStream"); |
| |
| JNI_ASSERT(m_pEnv->IsInstanceOf(stream, clazz), |
| "java/lang/IllegalArgumentException", |
| "stream not a java.io.OutputStream object!"); |
| |
| _write = m_pEnv->GetMethodID(clazz, |
| "write", |
| "([BII)V"); // void write(byte[], int, int) |
| JNI_ASSERT(_write != NULL, |
| "java/lang/NoSuchMethodError", |
| "method 'void java.io.OutputStream.write(byte[], int, int)' not found!"); |
| |
| _flush = m_pEnv->GetMethodID(clazz, |
| "flush", |
| "()V"); // void flush() |
| JNI_ASSERT(_flush != NULL, |
| "java/lang/NoSuchMethodError", |
| "method 'void java.io.OutputStream.flush()' not found!"); |
| |
| _jbuf = m_pEnv->NewByteArray(_bufsize); |
| JNI_ASSERT(_jbuf != NULL, |
| "java/lang/OutOfMemoryError", |
| ""); |
| } |
| |
| JNIOutputStream::~JNIOutputStream() |
| { |
| m_pEnv->DeleteLocalRef(_jbuf); |
| } |
| |
| int |
| JNIOutputStream::overflow(int c) |
| { |
| // WIN32 has a bug in nested scope resolution - it can't |
| // handle std::strstreambuf::overflow - so we pull in the |
| // std namespace here. |
| using namespace std; |
| |
| if (m_pEnv->ExceptionOccurred()) |
| return EOF; |
| |
| unsigned count = pcount(); |
| for (unsigned start = 0, n; |
| count > 0; |
| count -= n, start += n) |
| { |
| n = MIN(count, _bufsize); |
| |
| m_pEnv->SetByteArrayRegion(_jbuf, 0, n, (jbyte*)pbase() + start); |
| if (m_pEnv->ExceptionOccurred()) |
| return EOF; |
| |
| m_pEnv->CallVoidMethod(_output, _write, _jbuf, 0, n); |
| if (m_pEnv->ExceptionOccurred()) |
| return EOF; |
| } |
| |
| setp(pbase(), epptr()); // (put) buffer is empty |
| |
| return strstreambuf::overflow(c); |
| } |
| |
| int |
| JNIOutputStream::sync() |
| { |
| if (m_pEnv->ExceptionOccurred()) |
| return EOF; |
| |
| overflow(EOF); // empty buffer... |
| |
| if (_output) |
| { |
| m_pEnv->CallVoidMethod(_output, _flush); |
| if (m_pEnv->ExceptionOccurred()) |
| return EOF; |
| } |
| |
| return 0; |
| } |
| |
| JNIInputStream::JNIInputStream(JNIEnv* env, |
| jobject stream, |
| unsigned bufsize) |
| : std::strstreambuf(_buf = new char[bufsize], bufsize), |
| m_pEnv(env), |
| _input(stream), |
| _read(NULL), |
| _close(NULL), |
| _bufsize(bufsize), |
| _jbuf(NULL) |
| { |
| jclass clazz = m_pEnv->FindClass("java/io/InputStream"); |
| JNI_ASSERT(clazz != NULL, |
| "java/lang/NoClassDefFoundError", |
| "java.io.InputStream"); |
| |
| JNI_ASSERT(m_pEnv->IsInstanceOf(stream, clazz), |
| "java/lang/IllegalArgumentException", |
| "stream not a java.io.InputStream object!"); |
| |
| _read = m_pEnv->GetMethodID(clazz, |
| "read", |
| "([BII)I"); // int read(byte[], int, int) |
| JNI_ASSERT(_read != NULL, |
| "java/lang/NoSuchMethodError", |
| "method 'int java.io.InputStream.read(byte[], int, int)' not found!"); |
| |
| _close = m_pEnv->GetMethodID(clazz, |
| "close", |
| "()V"); // void close() |
| JNI_ASSERT(_read != NULL, |
| "java/lang/NoSuchMethodError", |
| "method 'int java.io.InputStream.read(byte[], int, int)' not found!"); |
| |
| _available = m_pEnv->GetMethodID(clazz, |
| "available", |
| "()I"); // int available() |
| JNI_ASSERT(_available != NULL, |
| "java/lang/NoSuchMethodError", |
| "method 'int java.io.InputStream.available()' not found!"); |
| |
| _jbuf = m_pEnv->NewByteArray(_bufsize); |
| JNI_ASSERT(_jbuf != NULL, |
| "java/lang/OutOfMemoryError", |
| ""); |
| |
| setg(eback(), egptr(), egptr()); // (get) buffer is empty |
| |
| |
| } |
| |
| JNIInputStream::~JNIInputStream() |
| { |
| delete[] _buf; |
| m_pEnv->DeleteLocalRef(_jbuf); |
| |
| m_pEnv->CallVoidMethod(_input, _close); |
| } |
| |
| int |
| JNIInputStream::available() |
| { |
| int n = m_pEnv->CallIntMethod(_input,_available); |
| if (m_pEnv->ExceptionOccurred()) |
| { |
| return EOF; |
| } |
| |
| return n; |
| } |
| |
| int |
| JNIInputStream::underflow() |
| { |
| // WIN32 has a bug in nested scope resolution - it can't |
| // handle std::strstreambuf::overflow - so we pull in the |
| // std namespace here. |
| using namespace std; |
| |
| if (m_pEnv->ExceptionOccurred()) |
| return EOF; |
| |
| int n = m_pEnv->CallIntMethod(_input, _read, _jbuf, 0, _bufsize); |
| if (m_pEnv->ExceptionOccurred() || n == -1) |
| return EOF; |
| |
| setg(eback(), egptr() - n, egptr()); // (get) buffer has n chars |
| |
| m_pEnv->GetByteArrayRegion(_jbuf, 0, n, (jbyte*)gptr()); |
| if (m_pEnv->ExceptionOccurred()) |
| return EOF; |
| |
| return strstreambuf::underflow(); |
| } |
| |
| |
| JNIEXPORT jint JNICALL |
| JNI_OnLoad( JavaVM *jvm, void *reserved ) |
| { |
| return JNI_VERSION_1_2; |
| } |
| |
| |
| JNIEXPORT void JNICALL |
| JNI_OnUnload( JavaVM *jvm, void *reserved ) |
| { |
| } |
| |
| |