First commit
[anna.git] / source / comm / Host.cpp
1 // ANNA - Anna is Not 'N' Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #include <anna/core/tracing/TraceMethod.hpp>
38
39 #include <anna/xml/Node.hpp>
40
41 #include <anna/comm/Host.hpp>
42 #include <anna/comm/Server.hpp>
43 #include <anna/comm/Communicator.hpp>
44 #include <anna/comm/ClientSocket.hpp>
45 #include <anna/comm/Device.hpp>
46 #include <anna/comm/ServerAllocator.hpp>
47
48 using namespace std;
49 using namespace anna;
50
51 comm::Host::~Host() {
52   for(server_iterator ii = server_begin(), maxii = server_end(); ii != maxii; ii ++)
53     delete server(ii);
54
55   a_servers.clear();
56   a_devices.clear();
57 }
58
59 int comm::Host::SortBy::value(const Server* server)
60 throw() {
61   return server->getRemotePort();
62 }
63
64
65 const comm::Server* comm::Host::find_server(const int remotePort) const
66 throw() {
67   return a_servers.find(remotePort);
68 }
69
70 comm::Server* comm::Host::find_server(const int remotePort)
71 throw() {
72   return a_servers.find(remotePort);
73 }
74
75
76 comm::Server* comm::Host::createServer(const string& name, const int remotePort, const bool autoRecovery, comm::TransportFactory* transportFactory, const bool ignoreIncomingMessages, const bool doConnect)
77 throw(RuntimeException) {
78   return add(createServer(ServerAllocator(name, *this, remotePort, autoRecovery, transportFactory, ignoreIncomingMessages)), remotePort, doConnect);
79 }
80
81 //-------------------------------------------------------------------------------
82 // (1) Acelera las posibilidades principales de busqueda => por nombre y por
83 // puerto remoto en que esta atendiendo peticiones.
84 //
85 // Ojo!! Siempre devuelve un Server aunque posiblemente no este conectado al
86 // ServerSocket remoto.
87 //-------------------------------------------------------------------------------
88 comm::Server* comm::Host::createServer(const ServerAllocator& serverAllocator)
89 throw(RuntimeException) {
90   const int remotePort = serverAllocator.getRemotePort();
91   Server* result = serverAllocator.apply();
92   result->setIgnoreIncomingMessages(serverAllocator.getIgnoreIncomingMessages());
93   return result;
94 }
95
96 void comm::Host::assign(const Device* device)
97 throw(RuntimeException) {
98   if(contains(device) == false)
99     a_devices.push_back(device);
100 }
101
102
103 string comm::Host::asString() const
104 throw() {
105   string result;
106   result = "comm::Host { Name: ";
107   result += getName();
108   result += " | Devices: ";
109
110   if(a_devices.empty() == true)
111     result += "(null)";
112   else {
113     for(const_device_iterator ii = device_begin(), maxii = device_end(); ii != maxii; ii ++) {
114       result += device(ii)->asString();
115       result += " ";
116     }
117   }
118
119   return result += " }";
120 }
121
122
123 xml::Node* comm::Host::asXML(xml::Node* parent) const
124 throw(RuntimeException) {
125   xml::Node* host = parent->createChild("comm.Host");
126   xml::Node* node;
127   host->createAttribute("Name", getName());
128   node = host->createChild("Devices");
129
130   for(const_device_iterator ii = device_begin(), maxii = device_end(); ii != maxii; ii ++)
131     device(ii)->asXML(node);
132
133   node = host->createChild("Servers");
134
135   for(const_server_iterator ss = server_begin(), maxss = server_end(); ss != maxss; ss ++)
136     server(ss)->asXML(node);
137
138   return host;
139 }
140
141
142 comm::Server* comm::Host::add(comm::Server* result, const int remotePort, const bool doConnect)
143 throw() {
144   result->a_sequence = a_servers.size();
145   a_servers.add(result);
146
147   try {
148     LOGINFORMATION(
149       string msg("comm::Host::add");
150       msg += (doConnect ? "(server creation and connection) | " : "(server creation, but connection not performed now) | ");
151       msg += result->asString();
152       Logger::information(msg,  ANNA_FILE_LOCATION)
153     );
154
155     if(doConnect) result->connect();
156   } catch(RuntimeException& ex) {
157     ex.trace();
158   }
159
160   return result;
161 }
162