THRIFT-1011. as3: Error generating package imports when using classes from other packages

Patch: Usman Ismail

git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1075916 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_as3_generator.cc b/compiler/cpp/src/generate/t_as3_generator.cc
index 47532e1..cabf512 100644
--- a/compiler/cpp/src/generate/t_as3_generator.cc
+++ b/compiler/cpp/src/generate/t_as3_generator.cc
@@ -176,6 +176,8 @@
   std::string as3_package();
   std::string as3_type_imports();
   std::string as3_thrift_imports();
+  std::string as3_thrift_gen_imports(t_struct* tstruct, string& imports); 
+  std::string as3_thrift_gen_imports(t_service* tservice); 
   std::string type_name(t_type* ttype, bool in_container=false, bool in_init=false);
   std::string base_type_name(t_base_type* tbase, bool in_container=false);
   std::string declare_field(t_field* tfield, bool init=false);
@@ -275,6 +277,63 @@
 }
 
 /**
+ * Prints imports needed for a given type
+ *
+ * @return List of imports necessary for a given t_struct
+ */
+string t_as3_generator::as3_thrift_gen_imports(t_struct* tstruct, string& imports) {
+
+  const vector<t_field*>& members = tstruct->get_members();
+  vector<t_field*>::const_iterator m_iter;
+
+  //For each type check if it is from a differnet namespace
+  for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
+    t_program* program = (*m_iter)->get_type()->get_program();
+    if (program != NULL && program != program_) {
+      string package = program->get_namespace("as3");
+      if (!package.empty()) {
+        if (imports.find(package + "." + (*m_iter)->get_type()->get_name()) == string::npos) {
+          imports.append("import " + package + "." + (*m_iter)->get_type()->get_name() + ";\n");
+        }
+      }
+    }
+  }
+  return imports;  
+}
+
+
+/**
+ * Prints imports needed for a given type
+ *
+ * @return List of imports necessary for a given t_service
+ */
+string t_as3_generator::as3_thrift_gen_imports(t_service* tservice) {
+  string imports;
+  const vector<t_function*>& functions = tservice->get_functions();
+  vector<t_function*>::const_iterator f_iter;
+
+  //For each type check if it is from a differnet namespace
+  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+    t_program* program = (*f_iter)->get_returntype()->get_program();
+    if (program != NULL && program != program_) {
+      string package = program->get_namespace("as3");
+      if (!package.empty()) {
+        if (imports.find(package + "." + (*f_iter)->get_returntype()->get_name()) == string::npos) {
+          imports.append("import " + package + "." + (*f_iter)->get_returntype()->get_name() + ";\n");
+        }
+      }
+    }
+
+    as3_thrift_gen_imports((*f_iter)->get_arglist(), imports);	    
+    as3_thrift_gen_imports((*f_iter)->get_xceptions(), imports);	    
+
+  }
+ 
+  return imports;
+
+}
+
+/**
  * Nothing in As3
  */
 void t_as3_generator::close_generator() {}
@@ -587,9 +646,12 @@
   scope_up(f_struct);
   f_struct << endl;
   
+  string imports;
+
   f_struct <<
     as3_type_imports() <<
-    as3_thrift_imports();
+    as3_thrift_imports() << 
+    as3_thrift_gen_imports(tstruct, imports) << endl;
   
   if (bindable_ && ! is_exception) {
     f_struct << "import flash.events.Event;" << endl <<
@@ -1355,7 +1417,8 @@
   
   f_service_ << endl <<
     as3_type_imports() <<
-    as3_thrift_imports();
+    as3_thrift_imports() <<
+    as3_thrift_gen_imports(tservice) << endl;
 
   generate_service_interface(tservice);
 
@@ -1373,13 +1436,15 @@
   
   f_service_ << endl <<
   as3_type_imports() <<
-  as3_thrift_imports();
+  as3_thrift_imports() <<
+  as3_thrift_gen_imports(tservice) << endl;
   
   generate_service_client(tservice);
   scope_down(f_service_);
   
   f_service_ << as3_type_imports();
   f_service_ << as3_thrift_imports();
+  f_service_ << as3_thrift_gen_imports(tservice);
   f_service_ << "import " << package_name_ << ".*;" << endl;
   
   generate_service_helpers(tservice);
@@ -1397,13 +1462,15 @@
   
   f_service_ << endl <<
   as3_type_imports() <<
-  as3_thrift_imports();
+  as3_thrift_imports() <<
+  as3_thrift_gen_imports(tservice) << endl;
   
   generate_service_server(tservice);
   scope_down(f_service_);
   
   f_service_ << as3_type_imports();
   f_service_ << as3_thrift_imports();
+  f_service_ << as3_thrift_gen_imports(tservice) <<endl;
   f_service_ << "import " << package_name_ << ".*;" << endl;
   
   generate_service_helpers(tservice);
@@ -1823,21 +1890,23 @@
   vector<t_field*>::const_iterator f_iter;
 
   f_service_ << indent();
-  if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) {
-    f_service_ << "result.success = ";
-  }
-  f_service_ <<
-    "iface_." << tfunction->get_name() << "(";
-  bool first = true;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    if (first) {
-      first = false;
-    } else {
-      f_service_ << ", ";
+  if (tfunction->is_oneway()){
+    f_service_ <<
+      "iface_." << tfunction->get_name() << "(";
+    bool first = true;
+    for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+      if (first) {
+        first = false;
+      } else {
+        f_service_ << ", ";
+      } 
+      f_service_ << "args." << (*f_iter)->get_name();
     }
-    f_service_ << "args." << (*f_iter)->get_name();
+    f_service_ << ");" << endl;
+  } else {
+    f_service_ << "// sorry this operation is not supported yet" << endl;
+    f_service_ << indent() << "throw new Error(\"This is not yet supported\");" << endl;
   }
-  f_service_ << ");" << endl;
 
   // Set isset on success field
   if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void() && !type_can_be_null(tfunction->get_returntype())) {
@@ -1849,7 +1918,7 @@
     indent_down();
     f_service_ << indent() << "}";
     for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-      f_service_ << " catch (" << type_name((*x_iter)->get_type(), false, false) << " " << (*x_iter)->get_name() << ") {" << endl;
+      f_service_ << " catch (" << (*x_iter)->get_name() << ":" << type_name((*x_iter)->get_type(), false, false) << ") {" << endl;
       if (!tfunction->is_oneway()) {
         indent_up();
         f_service_ <<
@@ -1860,10 +1929,10 @@
         f_service_ << "}";
       }
     }
-    f_service_ << " catch (Throwable th) {" << endl;
+    f_service_ << " catch (th:Error) {" << endl;
     indent_up();
     f_service_ <<
-      indent() << "LOGGER.error(\"Internal error processing " << tfunction->get_name() << "\", th);" << endl <<
+      indent() << "trace(\"Internal error processing " << tfunction->get_name() << "\", th);" << endl <<
       indent() << "var x:TApplicationError = new TApplicationError(TApplicationError.INTERNAL_ERROR, \"Internal error processing " << tfunction->get_name() << "\");" << endl <<
       indent() << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name() << "\", TMessageType.EXCEPTION, seqid));" << endl <<
       indent() << "x.write(oprot);" << endl <<
diff --git a/lib/as3/src/org/apache/thrift/TApplicationError.as b/lib/as3/src/org/apache/thrift/TApplicationError.as
index 039d9b9..93ef946 100644
--- a/lib/as3/src/org/apache/thrift/TApplicationError.as
+++ b/lib/as3/src/org/apache/thrift/TApplicationError.as
@@ -40,6 +40,7 @@
     public static const WRONG_METHOD_NAME:int = 3;
     public static const BAD_SEQUENCE_ID:int = 4;
     public static const MISSING_RESULT:int = 5;
+    public static const INTERNAL_ERROR:int = 6;
 
     public function TApplicationError(type:int = UNKNOWN, message:String = "") {
       super(message, type);
diff --git a/lib/as3/src/org/apache/thrift/transport/THttpClient.as b/lib/as3/src/org/apache/thrift/transport/THttpClient.as
index a63e314..435f911 100644
--- a/lib/as3/src/org/apache/thrift/transport/THttpClient.as
+++ b/lib/as3/src/org/apache/thrift/transport/THttpClient.as
@@ -27,6 +27,7 @@
   import flash.net.URLLoaderDataFormat;
   import flash.net.URLRequest;
   import flash.net.URLRequestMethod;
+  import flash.system.Capabilities;
   import flash.utils.ByteArray;
   
   /**
@@ -38,14 +39,19 @@
     private var request_:URLRequest = null;
     private var requestBuffer_:ByteArray = new ByteArray();
     private var responseBuffer_:ByteArray = null;
+    private var traceBuffers_:Boolean = Capabilities.isDebugger;
+
     
     public function getBuffer():ByteArray {
       return requestBuffer_;
     }
     
-    public function THttpClient(request:URLRequest):void {
+    public function THttpClient(request:URLRequest, traceBuffers:Boolean=true):void {
       request.contentType = "application/x-thrift";
       request_ = request;
+      if(traceBuffers == false) {
+        traceBuffers_ = traceBuffers;
+      }
     }
     
     public override function open():void {
@@ -64,9 +70,16 @@
       }
         try {
             responseBuffer_.readBytes(buf, off, len);
+            if (traceBuffers_) {
+              dumpBuffer(buf, "READ");
+            }
             return len;
           }
           catch (e:EOFError) {
+            if (traceBuffers_) {
+              dumpBuffer(requestBuffer_, "FAILED-RESPONSE-REQUEST");
+              dumpBuffer(responseBuffer_, "FAILED-RESPONSE");
+            }
             throw new TTransportError(TTransportError.UNKNOWN, "No more data available.");
         }
         return 0;
@@ -81,6 +94,9 @@
       if (callback != null) {
         loader.addEventListener(Event.COMPLETE, function(event:Event):void {
          responseBuffer_ = URLLoader(event.target).data;
+         if (traceBuffers_) {
+           dumpBuffer(responseBuffer_, "RESPONSE_BUFFER");
+         }
          callback(null);
          responseBuffer_ = null;
         });
@@ -99,5 +115,20 @@
       request_.data = requestBuffer_;
       loader.load(request_);
     }
+
+    private function dumpBuffer(buf:ByteArray, prefix:String):String {
+      var debugString : String = prefix + " BUFFER ";
+      if (buf != null) {
+        debugString += "length: " + buf.length + ", ";
+        for (var i : int = 0; i < buf.length; i++) {
+          debugString += "[" + buf[i].toString(16) + "]";
+        }
+      } else {
+        debugString = "null";
+      }
+      trace(debugString);
+      return debugString;
+    }
+
   }
 }
diff --git a/lib/cocoa/src/TSharedProcessorFactory.h b/lib/cocoa/src/TSharedProcessorFactory.h
index d3e55c4..cf4a462 100644
--- a/lib/cocoa/src/TSharedProcessorFactory.h
+++ b/lib/cocoa/src/TSharedProcessorFactory.h
@@ -23,5 +23,5 @@
 @interface TSharedProcessorFactory : NSObject <TProcessorFactory> {
   id<TProcessor> mSharedProcessor;
 }
-
+- (id) initWithSharedProcessor: (id<TProcessor>) sharedProcessor;
 @end