ETCH-198 Changed remote compiler template

Implemented initial client answers

Change-Id: I2bc036e131e9b5e90ffd1a204b14f9b49c0cafc2

git-svn-id: https://svn.apache.org/repos/asf/incubator/etch/trunk@1376587 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/remote_cpp.vm b/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/remote_cpp.vm
index 67b1f97..0a5e241 100644
--- a/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/remote_cpp.vm
+++ b/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/remote_cpp.vm
@@ -35,8 +35,9 @@
 #foreach($n in $intf.iterator())
 #if($n.isMsgDir($mc))
 #if(!$n.isHidden())
-$clname::$n.name()AsyncResultRemote::$n.name()AsyncResultRemote(EtchRuntime* runtime, EtchMailbox* mailbox) 
-  : #if($n.hasReturn())EtchAsyncResult<$helper.getEtchTypeName($n.type(), false)>(runtime, mailbox)#{else}EtchAsyncResultNone(runtime, mailbox)#end {
+$clname::$n.name()AsyncResultRemote::$n.name()AsyncResultRemote($clname* base, EtchMailbox* mailbox) 
+  : #if($n.hasReturn())EtchAsyncResult<$helper.getEtchTypeName($n.type(), false)>(base->mRuntime, mailbox)#{else}EtchAsyncResultNone(base->mRuntime, mailbox)#end {
+  mBase = base;
 }
 
 $clname::$n.name()AsyncResultRemote::~$n.name()AsyncResultRemote() {
@@ -44,7 +45,28 @@
 
 
 status_t $clname::$n.name()AsyncResultRemote::mailboxStatus(EtchMailbox* mb, EtchObject* state, capu::bool_t closed) {
-  //TODO implemented callback
+#if(!$n.isOneway())
+  status_t status;
+
+  if(!closed) {
+    capu::SmartPointer<EtchObject> result;
+    status = mBase->endcall(mb, $vfname::$n.getResultMessage().vname($helper), result);
+    if(status != ETCH_OK) {
+      // TODO set result to a runtime exception 
+      return ETCH_OK;
+    }
+    if(result->isInstanceOf(EtchException::TYPE())) {
+      setException(result);
+    }
+#if($n.hasReturn())
+    else {
+      setResult(result);
+    }
+#end
+
+  }
+
+#end
   return ETCH_OK;
 }
 
@@ -70,7 +92,7 @@
     // TODO log error
   }
 
-  $n.name()AsyncResultRemote* result = new $n.name()AsyncResultRemote(base->mRuntime, mb); 
+  $n.name()AsyncResultRemote* result = new $n.name()AsyncResultRemote(base, mb); 
   return result;
 }
 
@@ -103,27 +125,18 @@
 #if(!$methodList.contains($n.name().name()))
 #set ( $addMethodListStatus = $methodList.add($n.name().name()))
 
-#if(!$n.isMsgDirBoth())
-#if($n.isOneway())
-$intfname::$n.name()AsyncResultPtr $clname::$n.name()(#set( $sep = "" )#foreach( $p in $n.iterator() )$sep$helper.getEtchTypeName( $p.type(), true ) $p.name() #set( $sep = ", " )#end) {
-  $n.name()AsyncResultPtr result = $clname::$n.name()AsyncResultRemote::Begin(this, #set($sep = "")#foreach($p in $n.iterator())$p.name() #set( $sep = ", ")#end);
-  return result;
-}
-
-#else
-$intfname::$n.name()AsyncResultPtr $clname::$n.name()(#set( $sep = "" )#foreach( $p in $n.iterator() )$sep$helper.getEtchTypeName( $p.type(), true ) $p.name() #set( $sep = ", " )#end) {
-  $n.name()AsyncResultPtr result = $clname::$n.name()AsyncResultRemote::Begin(this, #set($sep = "")#foreach($p in $n.iterator())$p.name() #set( $sep = ", ")#end);
-  return result;
-}
-
-#end
-#else
+#if($hasBaseClass && $n.isMsgDirBoth())
 $intfname::$n.name()AsyncResultPtr $clname::$n.name()(#set( $sep = "" )#foreach( $p in $n.iterator() )$sep$helper.getEtchTypeName( $p.type(), true ) $p.name() #set( $sep = ", " )#end) {
   return Remote$i::$n.name()(#set( $sep = "" )#foreach( $p in $n.iterator() )$sep$p.name() #set( $sep = ", " )#end);
 }
-#end
+#else
+$intfname::$n.name()AsyncResultPtr $clname::$n.name()(#set( $sep = "" )#foreach( $p in $n.iterator() )$sep$helper.getEtchTypeName( $p.type(), true ) $p.name() #set( $sep = ", " )#end) {
+  $n.name()AsyncResultPtr result = $clname::$n.name()AsyncResultRemote::Begin(this, #set($sep = "")#foreach($p in $n.iterator())$p.name() #set( $sep = ", ")#end);
+  return result;
+}
 
 #end
 #end
 #end
+#end
 #end
\ No newline at end of file
diff --git a/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/remote_h.vm b/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/remote_h.vm
index 05d458c..2e5bce7 100644
--- a/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/remote_h.vm
+++ b/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/remote_h.vm
@@ -64,7 +64,7 @@
       /**
        * Create a new instance from $clname class
        */
-      $n.name()AsyncResultRemote(EtchRuntime* runtime, EtchMailbox* mailbox);
+      $n.name()AsyncResultRemote($clname* base, EtchMailbox* mailbox);
 
       /**
        * Destructor
@@ -80,6 +80,9 @@
        * Create a new instance from $clname class
        */
        static $n.name()AsyncResultPtr Begin($clname* base, #set($sep = "")#foreach($p in $n.iterator())$sep$helper.getEtchTypeName($p.type(), true) $p.name()#set($sep = ", ")#end);
+
+    private:
+        $clname* mBase;
     };
 
 #end
diff --git a/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/stub_h.vm b/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/stub_h.vm
index 8f37e67..8105003 100644
--- a/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/stub_h.vm
+++ b/binding-cpp/compiler/src/main/resources/org/apache/etch/bindings/cpp/compiler/stub_h.vm
@@ -80,9 +80,7 @@
     // create result message
 #if($mthd.hasReturn())
     if(ar->hasResult()) {
-        capu::SmartPointer<$helper.getEtchTypeName($mthd.type(), false)> result;
-        ar->getResult(result);
-        _rmsg->put(ValueFactory$i::_mf_result(), result);
+        _rmsg->put(ValueFactory$i::_mf_result(), ar->getResult());
     } else
 #end
     if(ar->hasException()) {
diff --git a/binding-cpp/runtime/include/common/EtchObject.h b/binding-cpp/runtime/include/common/EtchObject.h
index 2c496c4..e6ade83 100644
--- a/binding-cpp/runtime/include/common/EtchObject.h
+++ b/binding-cpp/runtime/include/common/EtchObject.h
@@ -20,7 +20,7 @@
 #define __ETCHOBJECT_H__

 

 #include "capu/util/SmartPointer.h"

-#include "capu/container/List.h"

+#include "capu/container/List.h"
 #include "EtchError.h"

 

 class EtchObjectType;

@@ -49,17 +49,16 @@
   virtual ~EtchObject();

 

   /**

-  * Returns object type id of this type.

-  */

+   */
   virtual const EtchObjectType* getObjectType() const;

 

-  /**

-   * Returns true if the type hierarchy of this instance

-   * is from the given type.

-   * @param type to check

-   * @return true if the instance is compatible to the given type

-   */

-   virtual capu::bool_t isInstanceOf(const EtchObjectType* type) const;

+  /**
+   * Returns true if the type hierarchy of this instance
+   * is from the given type.
+   * @param type to check
+   * @return true if the instance is compatible to the given type
+   */
+  virtual capu::bool_t isInstanceOf(const EtchObjectType* type) const;
 

   /**

    * Returns hash code

@@ -72,19 +71,19 @@
    */

   virtual capu::bool_t equals(const EtchObject * other) const;

 

-  protected:

-    /**

-     * Adds the object type to the type hierachy of this instance.

-     * @param type that should be added to type hierachy of this instance.

-     */

-    virtual status_t addObjectType(const EtchObjectType* type);

-

-    // TODO remove me if object hierachy was refactored

-    virtual status_t setObjectType(const EtchObjectType* type);

-

-  private:

-    const EtchObjectType* mType;

-    capu::List<const EtchObjectType*> mTypes;

+protected:
+  /**
+   * Adds the object type to the type hierachy of this instance.
+   * @param type that should be added to type hierachy of this instance.
+   */
+  virtual status_t addObjectType(const EtchObjectType* type);
+
+  // TODO remove me if object hierachy was refactored
+  virtual status_t setObjectType(const EtchObjectType* type);
+
+private:
+  const EtchObjectType* mType;
+  capu::List<const EtchObjectType*> mTypes;
 };

 

 typedef capu::SmartPointer<EtchObject> EtchObjectPtr;

diff --git a/binding-cpp/runtime/include/support/EtchAsyncResult.h b/binding-cpp/runtime/include/support/EtchAsyncResult.h
index 07e1f7e..2af7b83 100644
--- a/binding-cpp/runtime/include/support/EtchAsyncResult.h
+++ b/binding-cpp/runtime/include/support/EtchAsyncResult.h
@@ -75,15 +75,14 @@
   /**
    * Returns the result
    */
-  status_t getResult(capu::SmartPointer<T> &result) {
+  capu::SmartPointer<T> getResult() {
     if(hasException()) {
-      return ETCH_ERROR;
-    }
+      return NULL;
+    } else
     if(hasResult()) {
-      result = mResult;
-      return ETCH_OK;
+      return mResult;
     }
-    return ETCH_OK;
+    return NULL;
   }
 
 private:
diff --git a/binding-cpp/runtime/include/support/EtchAsyncResultNone.h b/binding-cpp/runtime/include/support/EtchAsyncResultNone.h
index 49f0afc..5af2090 100644
--- a/binding-cpp/runtime/include/support/EtchAsyncResultNone.h
+++ b/binding-cpp/runtime/include/support/EtchAsyncResultNone.h
@@ -62,7 +62,7 @@
   /**
    * @see EtchNotify
    */
-  virtual status_t mailboxStatus(EtchMailbox* mb, EtchObject* state, capu::bool_t closed);
+  virtual status_t mailboxStatus(EtchMailbox* mb, EtchObject* state, capu::bool_t closed) {return ETCH_OK;};
 
 protected:
   EtchRuntime* mRuntime;
diff --git a/binding-cpp/runtime/src/main/common/EtchException.cpp b/binding-cpp/runtime/src/main/common/EtchException.cpp
index e2bec11..719bb60 100644
--- a/binding-cpp/runtime/src/main/common/EtchException.cpp
+++ b/binding-cpp/runtime/src/main/common/EtchException.cpp
@@ -23,13 +23,17 @@
 }
 
 EtchException::EtchException()
-: EtchObject(EtchException::TYPE()), mErrorMessage(""), mErrorcode(0), mExcptype(0) {
-
+: EtchObject(), mErrorMessage(""), mErrorcode(0), mExcptype(0) {
+  EtchObject::addObjectType(EtchException::TYPE());
+  // TODO change object hierachy
+  EtchObject::setObjectType(EtchException::TYPE());
 }
 
 EtchException::EtchException(EtchString msg, status_t errcode, EtchExceptionType type)
-: EtchObject(EtchException::TYPE()), mErrorMessage(msg), mErrorcode(errcode), mExcptype(type) {
-
+: EtchObject(), mErrorMessage(msg), mErrorcode(errcode), mExcptype(type) {
+  EtchObject::addObjectType(EtchException::TYPE());
+  // TODO change object hierachy
+  EtchObject::setObjectType(EtchException::TYPE());
 }
 
 EtchException::EtchException(EtchString msg, status_t errcode, EtchExceptionType type, const EtchObjectType* type_id)
diff --git a/binding-cpp/runtime/src/main/support/EtchAsyncResultNone.cpp b/binding-cpp/runtime/src/main/support/EtchAsyncResultNone.cpp
index ba79ec4..a43982c 100644
--- a/binding-cpp/runtime/src/main/support/EtchAsyncResultNone.cpp
+++ b/binding-cpp/runtime/src/main/support/EtchAsyncResultNone.cpp
@@ -38,8 +38,6 @@
 capu::bool_t EtchAsyncResultNone::hasException() {
   mMutex.lock();
   while(!mHasMailboxStatus) {
-    // TODO wait
-    break;
     mCond.wait(&mMutex);
   }
   mMutex.unlock();
@@ -61,17 +59,3 @@
   mCond.signal();
   mMutex.unlock();
 }
-
-status_t EtchAsyncResultNone::mailboxStatus(EtchMailbox* mb, EtchObject* state, capu::bool_t closed) {
-
-  // TODO get data or exception from mailbox
-  // TODO call onResult( EtchObject* state);
-  // TODO call onEception( EtchObject* state);
-  // TODO setException(NULL);
-  // TODO call delegate
-  mMutex.lock();
-  mHasMailboxStatus = true;
-  mCond.signal();
-  mMutex.unlock();
-  return ETCH_OK;
-}
diff --git a/binding-cpp/runtime/src/main/support/EtchPlainMailbox.cpp b/binding-cpp/runtime/src/main/support/EtchPlainMailbox.cpp
index 1ed0cf1..9321cf2 100644
--- a/binding-cpp/runtime/src/main/support/EtchPlainMailbox.cpp
+++ b/binding-cpp/runtime/src/main/support/EtchPlainMailbox.cpp
@@ -66,12 +66,12 @@
   n = mNotify;
   s = mState;
   c = mQueue.isClosed();
+  
+  mMutex.unlock();
 
   if (n != NULL) {
     n->mailboxStatus(this, s, c);
   }
-  // TODO: check if the unlock must be so late
-  mMutex.unlock();
 }
 
 status_t EtchPlainMailbox::read(EtchMailbox::EtchElement*& result) {
@@ -120,11 +120,60 @@
 }
 
 status_t EtchPlainMailbox::registerNotify(EtchMailbox::EtchNotify* notify, EtchObject* state, capu::int32_t maxDelay) {
-  return ETCH_EUNIMPL;
+  if(notify == NULL) {
+    return ETCH_EINVAL;
+  }
+
+  if(maxDelay < 0) {
+    return ETCH_EINVAL;
+  }
+
+  capu::bool_t isNotEmptyOrIsClosed;
+
+  mMutex.lock();
+
+  if(mNotify != NULL) {
+    mMutex.unlock();
+    return ETCH_EINVAL;
+  }
+
+  mNotify = notify;
+  mState = state;
+
+  isNotEmptyOrIsClosed = !mQueue.isEmpty() || mQueue.isClosed();
+
+  mMutex.unlock();
+
+  if(isNotEmptyOrIsClosed) {
+    fireNotify();
+  }
+
+  return ETCH_OK;
 }
 
 status_t EtchPlainMailbox::unregisterNotify(EtchMailbox::EtchNotify* notify) {
-  return ETCH_EUNIMPL;
+
+  if(mNotify == NULL) {
+    return ETCH_EINVAL;
+  }
+
+  if(notify == NULL) {
+    return ETCH_OK;
+  }
+
+  mMutex.lock();
+
+  if(mNotify !=  notify) {
+    mMutex.unlock();
+    return ETCH_EINVAL;
+  }
+
+  mNotify = NULL;
+  mState = NULL;
+
+  mMutex.unlock();
+
+  return ETCH_OK;
 }
 
 capu::bool_t EtchPlainMailbox::isEmpty() {
diff --git a/binding-cpp/runtime/src/test/common/EtchObjectTest.cpp b/binding-cpp/runtime/src/test/common/EtchObjectTest.cpp
index ce92b43..4327be7 100644
--- a/binding-cpp/runtime/src/test/common/EtchObjectTest.cpp
+++ b/binding-cpp/runtime/src/test/common/EtchObjectTest.cpp
@@ -19,9 +19,61 @@
 #include <gtest/gtest.h>
 #include "common/EtchString.h"
 
+class EtchObjectMy1Object : public EtchObject {
+public:
+
+   /**
+   * EtchObjectType for EtchObjectMyObject.
+   */
+  static const EtchObjectType* TYPE() {
+    const static EtchObjectType TYPE(11, NULL);
+    return &TYPE;
+  }
+
+  /**
+   * Constructor
+   */
+  EtchObjectMy1Object()
+    : EtchObject() {
+      EtchObject::addObjectType(TYPE());
+  }
+
+};
+
+class EtchObjectMy2Object : public EtchObject {
+public:
+
+   /**
+   * EtchObjectType for EtchObjectMyObject.
+   */
+  static const EtchObjectType* TYPE() {
+    const static EtchObjectType TYPE(12, NULL);
+    return &TYPE;
+  }
+
+  /**
+   * Constructor
+   */
+  EtchObjectMy2Object()
+    : EtchObject() {
+      EtchObject::addObjectType(TYPE());
+  }
+
+};
+
+
 TEST(EtchObjectTest, getTypeTrait) {
   EXPECT_EQ(EtchObjectType::VALUE, EtchObjectType::getTypeTrait<EtchString>());
   EXPECT_EQ(EtchObjectType::POINTER, EtchObjectType::getTypeTrait<EtchString*>());
   EXPECT_EQ(EtchObjectType::SMART_POINTER, EtchObjectType::getTypeTrait<capu::SmartPointer<EtchString> >());
 
 }
+
+TEST(EtchObjectTest, isInstanceOf) {
+  EtchObjectMy1Object* o1 = new EtchObjectMy1Object();
+  EXPECT_EQ(true, o1->isInstanceOf(EtchObjectMy1Object::TYPE()));
+  EXPECT_EQ(true, o1->isInstanceOf(EtchObject::TYPE()));
+  EXPECT_EQ(false, o1->isInstanceOf(EtchObjectMy2Object::TYPE()));
+
+  delete o1;
+}
\ No newline at end of file
diff --git a/examples/helloworld/cpp/src/main/include/MainHelloWorldClient.h b/examples/helloworld/cpp/src/main/include/MainHelloWorldClient.h
index 76a740b..12a0d39 100644
--- a/examples/helloworld/cpp/src/main/include/MainHelloWorldClient.h
+++ b/examples/helloworld/cpp/src/main/include/MainHelloWorldClient.h
@@ -19,11 +19,11 @@
    * Main program for HelloWorldClient. This program makes a connection to the
    * listener created by MainHelloWorldListener.
    */
-  class MainHelloWorldClient
+  class MainHelloWorldClientFactory
    : public HelloWorldHelper::HelloWorldClientFactory
   {
   public:
-    virtual ~MainHelloWorldClient() {}
+    virtual ~MainHelloWorldClientFactory() {}
     HelloWorldClient* newHelloWorldClient(RemoteHelloWorldServer* server);
   };
 }
diff --git a/examples/helloworld/cpp/src/main/src/MainHelloWorldClient.cpp b/examples/helloworld/cpp/src/main/src/MainHelloWorldClient.cpp
index 83acd27..137e699 100644
--- a/examples/helloworld/cpp/src/main/src/MainHelloWorldClient.cpp
+++ b/examples/helloworld/cpp/src/main/src/MainHelloWorldClient.cpp
@@ -16,7 +16,7 @@
 
 using namespace org_apache_etch_examples_helloworld_HelloWorld;
 
-HelloWorldClient* MainHelloWorldClient::newHelloWorldClient(RemoteHelloWorldServer* server)
+HelloWorldClient* MainHelloWorldClientFactory::newHelloWorldClient(RemoteHelloWorldServer* server)
 {
   return new ImplHelloWorldClient(server);
 }
@@ -35,16 +35,15 @@
   // TODO Change to correct URI
   EtchString uri("tcp://127.0.0.1:4001");
 
-  MainHelloWorldClient mc;
-  status_t result;
+  MainHelloWorldClientFactory mc;
 
+  status_t result;
   RemoteHelloWorldServer *remote = NULL;
   result = HelloWorldHelper::newServer(runtime, uri, NULL, mc, remote);
   if (result != ETCH_OK) {
     //TODO Handle error
   }
 
-
   // Connect to the service
   result = remote->transportControl(new EtchString(EtchTransportData::START_AND_WAIT_UP()), new EtchInt32(4000));
   if (result != ETCH_OK) {
@@ -52,8 +51,16 @@
   }
 
   HelloWorld::userPtr myUser = new HelloWorld::user(new EtchInt32(1),new EtchString("World"));
-  remote->say_hello(myUser);
-  
+  HelloWorldServer::say_helloAsyncResultPtr say_helloResult = remote->say_hello(myUser);
+  if(say_helloResult->hasException()) {
+    capu::SmartPointer<EtchException> exception = say_helloResult->getException();
+    printf("say_hello FAILED: exception=%s \n", exception->getErrorMessage().c_str());
+  }
+  if(say_helloResult->hasResult()) {
+    capu::SmartPointer<EtchString> result = say_helloResult->getResult();
+    printf("say_hello OK: result=%s\n", result->c_str());
+  }
+
   // Disconnect from the service
   remote->transportControl(new EtchString(EtchTransportData::STOP_AND_WAIT_DOWN()), new EtchInt32(4000));
 
diff --git a/examples/helloworld/java/.classpath b/examples/helloworld/java/.classpath
new file mode 100644
index 0000000..afc4293
--- /dev/null
+++ b/examples/helloworld/java/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main"/>
+	<classpathentry kind="src" path="target/generated-sources/java"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="var" path="ETCH_HOME/binding-java/lib/apache-etch-java-runtime-1.3.0-incubating.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/helloworld/java/.project b/examples/helloworld/java/.project
new file mode 100644
index 0000000..f4b091f
--- /dev/null
+++ b/examples/helloworld/java/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.apache.etch.binding-java.examples.helloworld</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>