Merge pull request #1551 from DOCGroup/plm_jira_333
[ACE_TAO.git] / TAO / tao / Policy_Set.cpp
blobbd3507cfebb076c2b175a16f72c4ec81512b1b61
1 // -*- C++ -*-
2 #include "tao/Policy_Set.h"
3 #include "tao/SystemException.h"
4 #include "tao/debug.h"
5 #include "ace/CORBA_macros.h"
7 #if !defined (__ACE_INLINE__)
8 # include "tao/Policy_Set.inl"
9 #endif /* ! __ACE_INLINE__ */
11 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
13 TAO_Policy_Set::TAO_Policy_Set (TAO_Policy_Scope scope)
14 : scope_ (scope)
16 for (unsigned int i = 0; i < TAO_CACHED_POLICY_MAX_CACHED; ++i)
17 this->cached_policies_[i] = 0;
20 TAO_Policy_Set::~TAO_Policy_Set (void)
22 try
24 this->cleanup_i ();
26 catch (const ::CORBA::Exception&)
28 // Ignore exceptions...
32 TAO_Policy_Set::TAO_Policy_Set (const TAO_Policy_Set &rhs)
33 : scope_ (rhs.scope_)
35 // Initialize the cache.
36 for (int i = 0; i < TAO_CACHED_POLICY_MAX_CACHED; ++i)
38 this->cached_policies_[i] = 0;
41 // Copy over the policy list.
42 this->policy_list_.length (rhs.policy_list_.length ());
44 try
46 for (CORBA::ULong i = 0; i < rhs.policy_list_.length (); ++i)
48 CORBA::Policy_ptr policy = rhs.policy_list_[i];
50 if (CORBA::is_nil (policy))
52 continue;
55 CORBA::Policy_var copy = policy->copy ();
57 TAO_Cached_Policy_Type const cached_type = copy->_tao_cached_type ();
59 // Add the "cacheable" policies into the cache.
60 if (cached_type != TAO_CACHED_POLICY_UNCACHED && cached_type >= 0)
62 this->cached_policies_[cached_type] = copy.ptr ();
65 this->policy_list_[i] = copy._retn ();
68 catch (const ::CORBA::Exception& ex)
70 if (TAO_debug_level > 4)
71 ex._tao_print_exception ("TAO_Policy_Set::TAO_Policy_Set");
73 // "Try" to make this recoverable as we must have run out of memory.
74 this->policy_list_.length (0);
78 void
79 TAO_Policy_Set::copy_from (TAO_Policy_Set *source)
81 if (source == 0)
83 return;
86 this->cleanup_i ();
88 for (CORBA::ULong i = 0; i < source->policy_list_.length (); ++i)
90 CORBA::Policy_ptr policy = source->policy_list_[i];
92 if (CORBA::is_nil (policy))
94 continue;
97 if (! this->compatible_scope (policy->_tao_scope()))
99 throw ::CORBA::NO_PERMISSION ();
102 CORBA::Policy_var copy = policy->copy ();
104 CORBA::ULong const length = this->policy_list_.length ();
105 this->policy_list_.length (length + 1);
107 TAO_Cached_Policy_Type const cached_type =
108 copy->_tao_cached_type ();
110 // Add the "cacheable" policies into the cache.
111 if (cached_type != TAO_CACHED_POLICY_UNCACHED
112 && cached_type >= 0)
114 this->cached_policies_[cached_type] = copy.ptr ();
117 this->policy_list_[length] = copy._retn ();
121 void
122 TAO_Policy_Set::cleanup_i (void)
124 CORBA::ULong const len = this->policy_list_.length ();
125 // Cleanup the policy list.
126 for (CORBA::ULong i = 0; i < len; ++i)
128 this->policy_list_[i]->destroy ();
129 this->policy_list_[i] = CORBA::Policy::_nil ();
132 this->policy_list_.length (0);
134 // Cleanup the cache.
135 for (CORBA::ULong j = 0; j < TAO_CACHED_POLICY_MAX_CACHED; ++j)
137 this->cached_policies_[j] = 0;
141 // @@ !!! Add comments regarding Policy lifetimes, etc.
142 void
143 TAO_Policy_Set::set_policy_overrides (const CORBA::PolicyList &policies,
144 CORBA::SetOverrideType set_add)
146 // @@ The spec does not say what to do on this case.
147 if (set_add != CORBA::SET_OVERRIDE && set_add != CORBA::ADD_OVERRIDE)
149 throw ::CORBA::BAD_PARAM ();
152 if (set_add == CORBA::SET_OVERRIDE)
154 this->cleanup_i ();
157 // Flag, indicating whether we have already overridden
158 // RTCORBA::ServerProtocolPolicy during this call.
159 bool server_protocol_set = false;
161 CORBA::ULong const plen = policies.length ();
163 for (CORBA::ULong i = 0; i < plen; ++i)
165 CORBA::Policy_ptr policy = policies[i];
167 if (CORBA::is_nil (policy))
169 continue;
172 CORBA::PolicyType const policy_type = policy->policy_type ();
174 if (policy_type == TAO_RT_SERVER_PROTOCOL_POLICY_TYPE)
176 // Only one ServerProtocolPolicy should be included in a
177 // given PolicyList (section 4.15.2 of RTCORBA 1.0, i.e.,
178 // ptc/99-05-03).
179 // User-caused exceptional conditions can leave the Policy
180 // Manager in an inconsistent state. It is the
181 // responsibility of the user to return it to consistent state.
182 if (server_protocol_set)
184 throw ::CORBA::INV_POLICY ();
187 server_protocol_set = true;
190 this->set_policy (policy);
194 void
195 TAO_Policy_Set::set_policy (const CORBA::Policy_ptr policy)
197 if (! this->compatible_scope (policy->_tao_scope()))
199 throw ::CORBA::NO_PERMISSION ();
202 CORBA::PolicyType const policy_type = policy->policy_type ();
204 CORBA::Policy_var copy = policy->copy ();
206 CORBA::ULong j = 0;
207 CORBA::ULong const length = this->policy_list_.length ();
209 while (j != length)
211 CORBA::ULong const current =
212 this->policy_list_[j]->policy_type ();
214 if (current == policy_type)
216 this->policy_list_[j]->destroy ();
218 this->policy_list_[j] = copy.ptr ();
219 break;
222 ++j;
225 if (j == length)
227 this->policy_list_.length (length + 1);
228 this->policy_list_[j] = copy.ptr ();
231 // If this is a policy that gets accessed on the critical path,
232 // save a pointer to it in the cache.
233 TAO_Cached_Policy_Type const cached_policy_type =
234 policy->_tao_cached_type ();
236 if (cached_policy_type != TAO_CACHED_POLICY_UNCACHED
237 && cached_policy_type >= 0)
239 this->cached_policies_[cached_policy_type] = copy.ptr ();
242 // Transfer ownership to the policy list.
243 (void) copy._retn ();
246 CORBA::PolicyList *
247 TAO_Policy_Set::get_policy_overrides (const CORBA::PolicyTypeSeq &types)
249 CORBA::ULong const slots = types.length ();
250 CORBA::PolicyList *policy_list_ptr = 0;
252 if (slots == 0)
254 // Copy our own policy list.
255 ACE_NEW_THROW_EX (policy_list_ptr,
256 CORBA::PolicyList (this->policy_list_),
257 CORBA::NO_MEMORY ());
259 return policy_list_ptr;
262 ACE_NEW_THROW_EX (policy_list_ptr,
263 CORBA::PolicyList (slots),
264 CORBA::NO_MEMORY ());
266 CORBA::PolicyList_var policy_list (policy_list_ptr);
267 policy_list->length (slots);
268 CORBA::ULong n = 0;
270 for (CORBA::ULong j = 0; j < slots; ++j)
272 CORBA::ULong const slot = types[j];
273 CORBA::ULong const length = this->policy_list_.length ();
275 for (CORBA::ULong i = 0; i < length; ++i)
277 CORBA::ULong const current =
278 this->policy_list_[i]->policy_type ();
280 if (current != slot)
282 continue;
285 policy_list[n++] =
286 CORBA::Policy::_duplicate (this->policy_list_[i]);
287 break;
291 policy_list->length (n); // Truncate buffer if necessary.
293 return policy_list._retn ();
296 CORBA::Policy_ptr
297 TAO_Policy_Set::get_policy (CORBA::PolicyType type)
299 CORBA::ULong const length = this->policy_list_.length ();
301 for (CORBA::ULong i = 0; i < length; ++i)
303 CORBA::PolicyType const current = this->policy_list_[i]->policy_type ();
305 if (current == type)
307 return CORBA::Policy::_duplicate (this->policy_list_[i]);
311 return CORBA::Policy::_nil ();
314 CORBA::Policy_ptr
315 TAO_Policy_Set::get_cached_const_policy (TAO_Cached_Policy_Type type) const
317 if (type != TAO_CACHED_POLICY_UNCACHED && type < TAO_CACHED_POLICY_MAX_CACHED)
319 return this->cached_policies_[type];
322 return CORBA::Policy::_nil ();
325 CORBA::Policy_ptr
326 TAO_Policy_Set::get_cached_policy (TAO_Cached_Policy_Type type)
328 if (type != TAO_CACHED_POLICY_UNCACHED && type < TAO_CACHED_POLICY_MAX_CACHED)
330 return CORBA::Policy::_duplicate (this->cached_policies_[type]);
333 return CORBA::Policy::_nil ();
336 TAO_END_VERSIONED_NAMESPACE_DECL