Updated license
[anna.git] / source / http / wims20 / Abstract.cpp
1 // ANNA - Anna is Not Nothingness 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/Logger.hpp>
38 #include <anna/core/functions.hpp>
39
40 #include <anna/http/wims20/Abstract.hpp>
41
42 using namespace std;
43 using namespace anna;
44
45 http::wims20::Abstract::Abstract(const char* whatis, const std::string& domain, const std::string& path) :
46   a_whatis(whatis),
47   a_domain(domain) {
48   a_path = createString(path);
49   a_otherLevels = NULL;
50   a_parameters = NULL;
51 }
52
53 http::wims20::Abstract::Abstract(const char* whatis, const std::string& domain) :
54   a_whatis(whatis),
55   a_domain(domain) {
56   a_path = NULL;
57   a_otherLevels = NULL;
58   a_parameters = NULL;
59 }
60
61 /* virtual */
62 http::wims20::Abstract::~Abstract() {
63   destroyString(a_path);
64   clear();
65   delete a_otherLevels;
66   delete a_parameters;
67 }
68
69 /* Calcula la parte fija de la URI, se invoca desde el constructor. */
70 const string& http::wims20::Abstract::calculeFixedPart()
71 throw(RuntimeException) {
72   if(a_serviceID.empty() == true) {
73     string msg(asString());
74     msg += " | ServiceID can not be NULL";
75     throw RuntimeException(msg, ANNA_FILE_LOCATION);
76   }
77
78   if(a_guid.empty() == true) {
79     string msg(asString());
80     msg += " | GUID can not be NULL";
81     throw RuntimeException(msg, ANNA_FILE_LOCATION);
82   }
83
84   if(a_fixedPart.empty() == false)
85     return a_fixedPart;
86
87   calculeShortFixedPart();
88   appendWithSlash(a_fixedPart, a_serviceID);
89   appendWithSlash(a_fixedPart, a_guid);
90   return a_fixedPart;
91 }
92
93 const string& http::wims20::Abstract::calculeShortFixedPart()
94 throw(RuntimeException) {
95   string::size_type pos = a_domain.find("http://");
96
97   if(pos == string::npos) {
98     a_fixedPart = "http://";
99     a_fixedPart += a_domain;
100   } else {
101     if(pos > 0) {
102       string msg("Domain '");
103       msg += a_domain;
104       msg += "' is not valid";
105       throw RuntimeException(msg, ANNA_FILE_LOCATION);
106     }
107
108     a_fixedPart = a_domain;
109   }
110
111   if(a_path != NULL)
112     appendWithSlash(a_fixedPart, *a_path);
113
114   return a_fixedPart;
115 }
116
117 void http::wims20::Abstract::other_level_add(const std::string& otherLevel)
118 throw(RuntimeException) {
119   if(a_otherLevels == NULL)
120     a_otherLevels = new other_level_container;
121
122   a_otherLevels->push_back(createString(otherLevel));
123   LOGDEBUG(
124     string msg("http::wims20::Abstract::other_level_add | Level: ");
125     msg += otherLevel;
126     Logger::debug(msg, ANNA_FILE_LOCATION);
127   );
128 }
129
130 /*virtual*/
131 void http::wims20::Abstract::clearOtherLevels()
132 throw() {
133   if(hasOtherLevels()) {
134     for(other_level_iterator ii = other_level_begin(), maxii = other_level_end(); ii != maxii; ii ++)
135       destroyString(otherLevel(ii));
136
137     a_otherLevels->clear();
138   }
139 }
140
141 void http::wims20::Abstract::parameter_set(const std::string& name, const std::string& value)
142 throw(RuntimeException) {
143   bool exists = false;
144
145   if(a_parameters == NULL)
146     a_parameters = new parameter_container;
147
148   for(parameter_iterator ii = parameter_begin(), maxii = parameter_end(); ii != maxii; ii ++) {
149     if(*parameter_name(ii) == name) {
150       *parameter_value(ii) = value;
151       exists = true;
152       break;
153     }
154   }
155
156   if(exists == false) {
157     string* paramName = createString(name);
158     string* paramValue = createString(value);
159     parameter_pkv item(paramName, paramValue);
160     a_parameters->push_back(item);
161   }
162
163   LOGDEBUG(
164     string msg("http::wims20::Abstract::parameter_set | Name: ");
165     msg += name;
166     msg += " | Value: ";
167     msg += value;
168     msg += " | New: ";
169     msg += functions::asString(!exists);
170     Logger::debug(msg, ANNA_FILE_LOCATION);
171   );
172 }
173
174 void http::wims20::Abstract::clearParameters()
175 throw() {
176   if(hasParameters()) {
177     for(parameter_iterator ii = parameter_begin(), maxii = parameter_end(); ii != maxii; ii ++) {
178       destroyString(parameter_name(ii));
179       destroyString(parameter_value(ii));
180     }
181
182     a_parameters->clear();
183   }
184 }
185
186 string http::wims20::Abstract::asString() const
187 throw() {
188   string result("http::wims20::");
189   result += a_whatis;
190   result += " { Domain: ";
191   result += a_domain;
192   result += " | Path: ";
193   result += (a_path == NULL) ? "<null>" : a_path->c_str();
194   result += " | ServiceID: ";
195   result += a_serviceID;
196   result += " | GUID: ";
197   result += a_guid;
198   result += " | OtherLevels:";
199
200   if(hasOtherLevels() == true) {
201     for(const_other_level_iterator ii = other_level_begin(), maxii = other_level_end(); ii != maxii; ii ++) {
202       result += ' ';
203       result += otherLevel(ii);
204     }
205   } else
206     result += " <null>";
207
208   result += " | Parameters:";
209
210   if(hasParameters() == true) {
211     for(const_parameter_iterator ii = parameter_begin(), maxii = parameter_end(); ii != maxii; ii ++) {
212       result += ' ';
213       result += parameter_name(ii);
214       result += '=';
215       result += parameter_value(ii);
216     }
217   } else
218     result += " <null>";
219
220   return result += " }";
221 }
222
223 /*static*/
224 void http::wims20::Abstract::appendWithSlash(std::string& target, const std::string& other)
225 throw() {
226   const char* str = target.c_str();
227
228   if(str [anna_strlen(str) - 1] != '/')
229     target += '/';
230
231   target += other;
232 }