00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "CeylanObjectIdentifier.h"
00028
00029 #include "CeylanOperators.h"
00030 #include "CeylanProcess.h"
00031 #include "CeylanNetwork.h"
00032 #include "CeylanRegularExpression.h"
00033 #include "CeylanStringUtils.h"
00034 #include "CeylanObject.h"
00035 #include "CeylanLogLight.h"
00036 #include "CeylanLogPlug.h"
00037 #include "CeylanNetwork.h"
00038
00039
00040 #ifdef CEYLAN_USES_CONFIG_H
00041 #include "CeylanConfig.h"
00042 #endif // CEYLAN_USES_CONFIG_H
00043
00044
00045 #include <list>
00046
00047 #include <sstream>
00048 using std::stringstream ;
00049
00050 #include <list>
00051 using std::list ;
00052
00053
00054
00055 using std::string ;
00056
00057 using namespace Ceylan::Log ;
00058 using namespace Ceylan::System ;
00059 using namespace Ceylan::Network ;
00060
00061
00062 const char ObjectIdentifier::Separator = '/' ;
00063 const string ObjectIdentifier::PIDTag = "PID-" ;
00064
00065
00066
00074 const string ObjectIdentifier::Pattern = "^([0-2]{0,1}[0-9]{0,1}[0-9]{1,1}"
00075 "[.]{1,1}){3}([0-2]{0,1}[0-9]{0,1}[0-9]{1,1})$" ;
00076
00077
00078
00079 Ceylan::Log::ObjectIdentifier::ObjectIdentifier( const Object & object ) :
00080 TextIdentifier(),
00081 _hostname(),
00082 _pid(),
00083 _address( 0 )
00084 {
00085
00086 CEYLAN_LOG( "Log::ObjectIdentifier constructor: "
00087 "creating a new identifier for "
00088 + object.getClassName() + " instance." ) ;
00089
00090 try
00091 {
00092
00093 _hostname = Network::getMostPreciseLocalHostName() ;
00094
00095 }
00096 catch( const Network::NetworkException & e )
00097 {
00098 throw IdentifierException( "ObjectIdentifier constructor: "
00099 "unable to get local host name: " + e.toString() ) ;
00100 }
00101
00102 try
00103 {
00104
00105 _pid = System::Process::GetHostingPID() ;
00106
00107 }
00108 catch( const ProcessException & e )
00109 {
00110
00111 LogPlug::warning( "ObjectIdentifier constructor: "
00112 "unable to get hosting PID: " + e.toString()
00113 + ", defaulting to null PID" ) ;
00114 _pid = 0 ;
00115
00116 }
00117
00118 _className = object.getClassName() ;
00119
00120 _address = static_cast<const void *>( & object ) ;
00121
00122 CEYLAN_LOG( "Newly created identifier is " + toString() ) ;
00123
00124 }
00125
00126
00127
00128 ObjectIdentifier::ObjectIdentifier( const std::string & hostname, Pid pid,
00129 const std::string & className, const void * address) :
00130 _hostname( hostname ),
00131 _pid( pid ),
00132 _className( className ),
00133 _address( address )
00134 {
00135
00136 }
00137
00138
00139
00140 ObjectIdentifier::~ObjectIdentifier() throw()
00141 {
00142
00143
00144
00145 }
00146
00147
00148
00149 bool ObjectIdentifier::differentButMatches( const ObjectIdentifier & otherID )
00150 const
00151 {
00152
00153
00154
00155
00156
00157
00158
00159 if ( _address != otherID._address )
00160 return false ;
00161
00162 if ( _pid != otherID._pid )
00163 return false ;
00164
00165 if ( _hostname != otherID._hostname )
00166 return false ;
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 if ( _className == otherID._className )
00177 return false ;
00178
00179
00180 return true ;
00181
00182 }
00183
00184
00185
00186 const string ObjectIdentifier::toString( Ceylan::VerbosityLevels level ) const
00187 {
00188
00189 return _hostname + Separator + PIDTag + _pid + Separator
00190 + _className + Separator + _address ;
00191
00192 }
00193
00194
00195
00196 ObjectIdentifier & ObjectIdentifier::generateFromChannelName(
00197 const string & channelName )
00198 {
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 if ( Ceylan::countChars( channelName, Separator ) != 3 )
00231 throw IdentifierException(
00232 "ObjectIdentifier::generateFromChannelName: there are "
00233 "not exactly three separators in channel name "
00234 + channelName + "." ) ;
00235
00236 list<string> subelements = Ceylan::split( channelName, Separator ) ;
00237
00238 if ( subelements.size() != 4 )
00239 throw IdentifierException(
00240 "ObjectIdentifier::generateFromChannelName: there are "
00241 + Ceylan::toString(
00242 static_cast<Ceylan::Uint32>( subelements.size() ) )
00243 + " elements after having split channel name "
00244 + channelName + " instead of four." ) ;
00245
00246 const string hostnameString = subelements.front() ;
00247 subelements.pop_front() ;
00248
00249 if ( ! Ceylan::Network::isAValidHostName( hostnameString ) )
00250 throw IdentifierException(
00251 "ObjectIdentifier::generateFromChannelName: '"
00252 + hostnameString + "' is not a valid host name." ) ;
00253
00254 string pidString = subelements.front() ;
00255 subelements.pop_front() ;
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 Pid pid ;
00271 void * address ;
00272 string classString ;
00273
00274 try
00275 {
00276
00277 pid = static_cast<Pid>(
00278 Ceylan::stringToUnsignedLong( pidString.substr( 4 ) ) ) ;
00279
00280 classString = subelements.front() ;
00281 subelements.pop_front() ;
00282
00283 address = Ceylan::stringToAddress( subelements.front() ) ;
00284
00285 }
00286 catch ( const Ceylan::Exception & e )
00287 {
00288 throw IdentifierException(
00289 "ObjectIdentifier::generateFromChannelName: unable "
00290 "to deserialize channel name " + channelName
00291 + ": " + e.toString() ) ;
00292 }
00293
00294 return * new ObjectIdentifier( hostnameString, pid,
00295 classString, address ) ;
00296
00297 }
00298