Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / examples / Content_Server / AMI_Observer / Callback_i.cpp
blob1741f68d52e5fab1f6b21678ae2be69c72f89c87
1 // -*- C++ -*-
2 // Ossama Othman <ossama@uci.edu>
4 #include "ace/FILE_Connector.h"
5 #include "ace/Log_Msg.h"
6 #include "ace/Process_Manager.h"
7 #include "Callback_i.h"
8 #include "ace/OS_NS_strings.h"
9 #include "ace/OS_NS_string.h"
11 Callback_i::Callback_i (int *request_count)
12 : file_ (ACE_sap_any_cast (ACE_FILE_Addr &)),
13 file_io_ (),
14 ami_handler_ (),
15 metadata_ (),
16 last_chunk_ (0),
17 lock_ (),
18 request_count_ (request_count)
20 // Create a temporary file to store the retrieved data.
21 ACE_FILE_Connector connector;
23 if (connector.connect (this->file_io_,
24 this->file_,
26 ACE_Addr::sap_any,
28 O_CREAT | O_TRUNC | O_WRONLY,
29 ACE_DEFAULT_FILE_PERMS) == -1)
31 ACE_ERROR ((LM_ERROR,
32 ACE_TEXT ("Could not open file \"%s\"%p\n"),
33 this->file_.get_path_name ()));
35 else
36 (*this->request_count_)++;
39 Callback_i::~Callback_i (void)
41 (void) this->file_io_.close ();
44 void
45 Callback_i::next_chunk (const Web_Server::Chunk_Type & chunk_data,
46 CORBA::Boolean last_chunk)
48 if (!last_chunk)
50 Web_Server::Chunk_Type_var chunk = chunk_data;
52 // Append the received data to the corresponding
53 // buffer/temporary file.
54 if (this->file_io_.send (chunk->get_buffer (),
55 chunk->length ()) == -1)
57 (*this->request_count_)--; // Don't wait for more data.
59 ACE_ERROR ((LM_ERROR,
60 ACE_TEXT ("%p\n"),
61 ACE_TEXT ("Unable to write retrieved data to ")
62 ACE_TEXT ("file <%s>"),
63 this->file_.get_path_name ()));
64 return;
67 else
70 ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX,
71 guard,
72 this->lock_));
74 this->last_chunk_ = 1; // Received entire content.
77 ACE_DEBUG ((LM_INFO,
78 ACE_TEXT ("Wrote retrieved data to file <%s>\n"),
79 this->file_.get_path_name ()));
81 (*this->request_count_)--; // No more data.
83 // File retrieval has completed, so spawn an external viewer to
84 // display its contents.
86 // If the entire metadata has been received, then spawn an
87 // external viewer to display the received file.
88 if (this->metadata_received ())
90 (void) this->file_io_.close ();
91 this->deactivate ();
93 (void) this->spawn_viewer ();
98 void
99 Callback_i::metadata (const Web_Server::Metadata_Type &metadata)
104 ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX,
105 guard,
106 this->lock_));
107 this->metadata_ = metadata;
110 ACE_DEBUG ((LM_INFO,
111 ACE_TEXT ("Retrieved file has the following ")
112 ACE_TEXT ("characteristics:\n")
113 ACE_TEXT (" Modification Date: %s\n")
114 ACE_TEXT (" Content Type: %s\n"),
115 this->metadata_.modification_date.in (),
116 this->metadata_.content_type.in ()));
118 // If the entire content of the data has been received, then spawn
119 // an external viewer to display it.
120 if (this->content_received ())
122 this->deactivate ();
124 (void) this->spawn_viewer ();
127 catch (const CORBA::Exception& ex)
129 ex._tao_print_exception (
130 ACE_TEXT ("Caught unexpected exception ")
131 ACE_TEXT ("in Callback_i::metdata(...):"));
136 Callback_i::metadata_received (void)
138 ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
139 guard,
140 this->lock_,
141 0));
143 return (this->metadata_.content_type.in () != 0);
147 Callback_i::content_received (void)
149 ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
150 guard,
151 this->lock_,
152 0));
154 return this->last_chunk_;
158 Callback_i::get_viewer (char *viewer,
159 size_t length)
161 const char *content_type =
162 this->metadata_.content_type.in ();
164 if (ACE_OS::strcasecmp (content_type, "text/html") == 0)
166 const char lynx[] = "lynx";
167 if (length <= sizeof (lynx))
168 return -1;
169 else
170 ACE_OS::strcpy (viewer, lynx);
172 else if (ACE_OS::strcasecmp (content_type,
173 "text/plain") == 0)
175 const char more[] = "more";
176 if (length <= sizeof (more))
177 return -1;
178 else
179 ACE_OS::strcpy (viewer, more);
181 else if (ACE_OS::strcasecmp (content_type,
182 "application/postscript") == 0)
184 const char ghostview[] = "ghostview";
185 if (length <= sizeof (ghostview))
186 return -1;
187 else
188 ACE_OS::strcpy (viewer, ghostview);
190 else if (ACE_OS::strcasecmp (content_type,
191 "application/pdf") == 0)
193 const char acroread[] = "acroread";
194 if (length <= sizeof (acroread))
195 return -1;
196 else
197 ACE_OS::strcpy (viewer, acroread);
199 else if (ACE_OS::strcasecmp (content_type,
200 "image/jpeg") == 0
201 || ACE_OS::strcasecmp (content_type,
202 "image/gif") == 0
203 || ACE_OS::strcasecmp (content_type,
204 "image/tiff") == 0
205 || ACE_OS::strcasecmp (content_type,
206 "image/png") == 0)
208 const char xv[] = "xv";
209 if (length <= sizeof (xv))
210 return -1;
211 else
212 ACE_OS::strcpy (viewer, xv);
214 else
215 ACE_ERROR_RETURN ((LM_ERROR,
216 ACE_TEXT ("Unsupported MIME type: <%s>\n"),
217 content_type),
218 -1);
220 return 0;
224 Callback_i::spawn_viewer (void)
226 char viewer[BUFSIZ];
228 if (this->get_viewer (viewer,
229 sizeof (viewer)) != 0)
230 ACE_ERROR_RETURN ((LM_ERROR,
231 ACE_TEXT ("Problem determining which external ")
232 ACE_TEXT ("viewer to use.\n")),
233 -1);
235 // Set up the command line that will be used when spawning the
236 // external viewer.
237 ACE_Process_Options opts;
238 opts.command_line (ACE_TEXT ("%s %s"),
239 viewer,
240 this->file_.get_path_name ());
242 pid_t result = ACE_Process_Manager::instance ()->spawn (opts);
244 switch (result)
246 case 0:
247 // Child
248 return 0;
249 case ACE_INVALID_PID:
250 ACE_ERROR_RETURN ((LM_ERROR,
251 ACE_TEXT ("Error during viewer spawn of %p\n"),
252 opts.command_line_buf ()),
253 -1);
254 default:
255 // Parent
256 ACE_DEBUG ((LM_INFO,
257 ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),
258 viewer,
259 result));
260 break;
263 return 0;
266 void
267 Callback_i::deactivate (void)
269 // Get the POA used when activating the Reply Handler object.
270 PortableServer::POA_var poa = this->_default_POA ();
272 // Get the object ID associated with this servant.
273 PortableServer::ObjectId_var oid =
274 poa->servant_to_id (this);
276 // Now deactivate the iterator object.
277 poa->deactivate_object (oid.in ());