summaryrefslogtreecommitdiff
path: root/trunk/TAO/examples/Content_Server/AMI_Observer/Callback_i.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/TAO/examples/Content_Server/AMI_Observer/Callback_i.cpp')
-rw-r--r--trunk/TAO/examples/Content_Server/AMI_Observer/Callback_i.cpp296
1 files changed, 296 insertions, 0 deletions
diff --git a/trunk/TAO/examples/Content_Server/AMI_Observer/Callback_i.cpp b/trunk/TAO/examples/Content_Server/AMI_Observer/Callback_i.cpp
new file mode 100644
index 00000000000..15755e55328
--- /dev/null
+++ b/trunk/TAO/examples/Content_Server/AMI_Observer/Callback_i.cpp
@@ -0,0 +1,296 @@
+// -*- C++ -*-
+// $Id$
+
+// Ossama Othman <ossama@uci.edu>
+
+#include "ace/FILE_Connector.h"
+#include "ace/Log_Msg.h"
+#include "ace/Process_Manager.h"
+#include "Callback_i.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_string.h"
+
+
+ACE_RCSID (AMI_Observer,
+ Callback_i,
+ "$Id$")
+
+
+Callback_i::Callback_i (int *request_count)
+ : file_ (ACE_sap_any_cast (ACE_FILE_Addr &)),
+ file_io_ (),
+ ami_handler_ (),
+ metadata_ (),
+ last_chunk_ (0),
+ lock_ (),
+ request_count_ (request_count)
+{
+ // Create a temporary file to store the retrieved data.
+ ACE_FILE_Connector connector;
+
+ if (connector.connect (this->file_io_,
+ this->file_,
+ 0,
+ ACE_Addr::sap_any,
+ 0,
+ O_CREAT | O_TRUNC | O_WRONLY,
+ ACE_DEFAULT_FILE_PERMS) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Could not open file \"%s\"%p\n"),
+ this->file_.get_path_name ()));
+ }
+ else
+ (*this->request_count_)++;
+}
+
+Callback_i::~Callback_i (void)
+{
+ (void) this->file_io_.close ();
+}
+
+void
+Callback_i::next_chunk (const Web_Server::Chunk_Type & chunk_data,
+ CORBA::Boolean last_chunk
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (!last_chunk)
+ {
+ Web_Server::Chunk_Type_var chunk = chunk_data;
+
+ // Append the received data to the corresponding
+ // buffer/temporary file.
+ if (this->file_io_.send (chunk->get_buffer (),
+ chunk->length ()) == -1)
+ {
+ (*this->request_count_)--; // Don't wait for more data.
+
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("Unable to write retrieved data to ")
+ ACE_TEXT ("file <%s>"),
+ this->file_.get_path_name ()));
+ return;
+ }
+ }
+ else
+ {
+ {
+ ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX,
+ guard,
+ this->lock_));
+
+ this->last_chunk_ = 1; // Received entire content.
+ }
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Wrote retrieved data to file <%s>\n"),
+ this->file_.get_path_name ()));
+
+ (*this->request_count_)--; // No more data.
+
+ // File retrieval has completed, so spawn an external viewer to
+ // display its contents.
+
+ // If the entire metadata has been received, then spawn an
+ // external viewer to display the received file.
+ if (this->metadata_received ())
+ {
+ (void) this->file_io_.close ();
+ this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ (void) this->spawn_viewer ();
+ }
+ }
+}
+
+void
+Callback_i::metadata (const Web_Server::Metadata_Type &metadata)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ {
+ ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX,
+ guard,
+ this->lock_));
+ this->metadata_ = metadata;
+ }
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Retrieved file has the following ")
+ ACE_TEXT ("characteristics:\n")
+ ACE_TEXT (" Modification Date: %s\n")
+ ACE_TEXT (" Content Type: %s\n"),
+ this->metadata_.modification_date.in (),
+ this->metadata_.content_type.in ()));
+
+ // If the entire content of the data has been received, then spawn
+ // an external viewer to display it.
+ if (this->content_received ())
+ {
+ this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ (void) this->spawn_viewer ();
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ ACE_TEXT ("Caught unexpected exception ")
+ ACE_TEXT ("in Callback_i::metdata(...):"));
+ }
+ ACE_ENDTRY;
+}
+
+int
+Callback_i::metadata_received (void)
+{
+ ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ guard,
+ this->lock_,
+ 0));
+
+ return (this->metadata_.content_type.in () != 0);
+}
+
+int
+Callback_i::content_received (void)
+{
+ ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ guard,
+ this->lock_,
+ 0));
+
+ return this->last_chunk_;
+}
+
+int
+Callback_i::get_viewer (char *viewer,
+ size_t length)
+{
+ const char *content_type =
+ this->metadata_.content_type.in ();
+
+ if (ACE_OS::strcasecmp (content_type, "text/html") == 0)
+ {
+ const char lynx[] = "lynx";
+ if (length <= sizeof (lynx))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, lynx);
+ }
+ else if (ACE_OS::strcasecmp (content_type,
+ "text/plain") == 0)
+ {
+ const char more[] = "more";
+ if (length <= sizeof (more))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, more);
+ }
+ else if (ACE_OS::strcasecmp (content_type,
+ "application/postscript") == 0)
+ {
+ const char ghostview[] = "ghostview";
+ if (length <= sizeof (ghostview))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, ghostview);
+ }
+ else if (ACE_OS::strcasecmp (content_type,
+ "application/pdf") == 0)
+ {
+ const char acroread[] = "acroread";
+ if (length <= sizeof (acroread))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, acroread);
+ }
+ else if (ACE_OS::strcasecmp (content_type,
+ "image/jpeg") == 0
+ || ACE_OS::strcasecmp (content_type,
+ "image/gif") == 0
+ || ACE_OS::strcasecmp (content_type,
+ "image/tiff") == 0
+ || ACE_OS::strcasecmp (content_type,
+ "image/png") == 0)
+ {
+ const char xv[] = "xv";
+ if (length <= sizeof (xv))
+ return -1;
+ else
+ ACE_OS::strcpy (viewer, xv);
+ }
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unsupported MIME type: <%s>\n"),
+ content_type),
+ -1);
+
+ return 0;
+}
+
+int
+Callback_i::spawn_viewer (void)
+{
+ char viewer[BUFSIZ];
+
+ if (this->get_viewer (viewer,
+ sizeof (viewer)) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problem determining which external ")
+ ACE_TEXT ("viewer to use.\n")),
+ -1);
+
+ // Set up the command line that will be used when spawning the
+ // external viewer.
+ ACE_Process_Options opts;
+ opts.command_line (ACE_TEXT ("%s %s"),
+ viewer,
+ this->file_.get_path_name ());
+
+ pid_t result = ACE_Process_Manager::instance ()->spawn (opts);
+
+ switch (result)
+ {
+ case 0:
+ // Child
+ return 0;
+ case ACE_INVALID_PID:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Error during viewer spawn of %p\n"),
+ opts.command_line_buf ()),
+ -1);
+ default:
+ // Parent
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),
+ viewer,
+ result));
+ break;
+ }
+
+ return 0;
+}
+
+void
+Callback_i::deactivate (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Get the POA used when activating the Reply Handler object.
+ PortableServer::POA_var poa = this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Get the object ID associated with this servant.
+ PortableServer::ObjectId_var oid =
+ poa->servant_to_id (this
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Now deactivate the iterator object.
+ poa->deactivate_object (oid.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}