00001 #ifndef _SCHEMACOLLECTION_H_
00002 #define _SCHEMACOLLECTION_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef _WIN32
00022 #pragma once
00023 #endif
00024
00025 #include <FdoStd.h>
00026 #include <Common/NamedCollection.h>
00027 #include <Fdo/Schema/SchemaElement.h>
00028 #include <Fdo/Schema/SchemaException.h>
00029
00030
00031
00032
00033
00034
00035 template <class OBJ> class FdoSchemaCollection : public FdoNamedCollection<OBJ, FdoSchemaException>
00036 {
00037
00038 protected:
00039
00040 FdoSchemaCollection()
00041 {
00042 }
00043
00044 FdoSchemaCollection(FdoSchemaElement* parent) : FdoNamedCollection<OBJ, FdoSchemaException>()
00045 {
00046 m_parent = parent;
00047 m_changeInfoState = 0;
00048 m_listCHANGED = NULL;
00049 m_sizeCHANGED = 0;
00050 if ( m_parent )
00051 m_setItemParent = true;
00052 else
00053 m_setItemParent = false;
00054 }
00055
00056 virtual ~FdoSchemaCollection()
00057 {
00058 if (m_setItemParent && m_parent)
00059 {
00060 for(FdoInt32 i = 0; i < FdoNamedCollection<OBJ, FdoSchemaException>::GetCount(); i++)
00061 {
00062 OBJ* pitem = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(i);
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 pitem->SetParent(NULL);
00075 FDO_SAFE_RELEASE(pitem);
00076 }
00077 }
00078
00079
00080 if (m_listCHANGED)
00081 {
00082 for (FdoInt32 i=0; i < m_sizeCHANGED; i++)
00083 {
00084 FDO_SAFE_RELEASE(m_listCHANGED[i]);
00085 }
00086 delete [] m_listCHANGED;
00087 m_listCHANGED = NULL;
00088 }
00089 }
00090
00091
00092 public:
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 FDO_API virtual void SetItem(FdoInt32 index, OBJ* value)
00105 {
00106 if (index < FdoNamedCollection<OBJ, FdoSchemaException>::GetCount() && index >= 0)
00107 {
00108 if (m_setItemParent && m_parent)
00109 {
00110
00111
00112
00113
00114 FdoSchemaElement* pparent = value->GetParent();
00115 if (pparent)
00116 {
00117
00118 if (pparent == m_parent && (m_changeInfoState & CHANGEINFO_PROCESSING))
00119 pparent->Release();
00120 else
00121 {
00122 pparent->Release();
00123 throw FdoSchemaException::Create(FdoException::NLSGetMessage(FDO_NLSID(SCHEMA_10_OBJECTHASPARENT)));
00124 }
00125 }
00126 }
00127 _StartChanges();
00128
00129 if (m_setItemParent && m_parent)
00130 value->SetParent(m_parent);
00131
00132
00133
00134
00135 if (m_setItemParent
00136 && !(m_changeInfoState & CHANGEINFO_PROCESSING))
00137 {
00138 value->SetElementState(FdoSchemaElementState_Added);
00139 }
00140
00141 OBJ* pitemOld = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(index);
00142 FdoSchemaElement* pparentOldItem = pitemOld->GetParent();
00143 if ( pparentOldItem == m_parent )
00144 {
00145
00146
00147
00148
00149 pitemOld->SetParent(NULL);
00150 pitemOld->SetElementState(FdoSchemaElementState_Detached);
00151 }
00152 FDO_SAFE_RELEASE(pparentOldItem);
00153 FDO_SAFE_RELEASE(pitemOld);
00154 }
00155
00156 FdoNamedCollection<OBJ, FdoSchemaException>::SetItem(index, value);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 FDO_API virtual FdoInt32 Add(OBJ* value)
00169 {
00170 if (m_setItemParent && m_parent)
00171 {
00172
00173
00174
00175
00176 FdoSchemaElement* pparent = value->GetParent();
00177 if (pparent)
00178 {
00179 if (pparent == m_parent && (m_changeInfoState & CHANGEINFO_PROCESSING))
00180 pparent->Release();
00181 else
00182 {
00183 pparent->Release();
00184 throw FdoSchemaException::Create(FdoException::NLSGetMessage(FDO_NLSID(SCHEMA_10_OBJECTHASPARENT)));
00185 }
00186 }
00187 }
00188 _StartChanges();
00189
00190 if (m_setItemParent && m_parent)
00191 value->SetParent(m_parent);
00192
00193
00194
00195
00196 if (m_setItemParent
00197 && !(m_changeInfoState & CHANGEINFO_PROCESSING))
00198 {
00199 value->SetElementState(FdoSchemaElementState_Added);
00200 }
00201 return FdoNamedCollection<OBJ, FdoSchemaException>::Add(value);
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 FDO_API virtual void Insert(FdoInt32 index, OBJ* value)
00218 {
00219 if (m_setItemParent && m_parent)
00220 {
00221
00222
00223
00224
00225 FdoSchemaElement* pparent = value->GetParent();
00226 if (pparent)
00227 {
00228
00229 if (pparent == m_parent && (m_changeInfoState & CHANGEINFO_PROCESSING))
00230 pparent->Release();
00231 else
00232 {
00233 pparent->Release();
00234 throw FdoSchemaException::Create(FdoException::NLSGetMessage(FDO_NLSID(SCHEMA_10_OBJECTHASPARENT)));
00235 }
00236 }
00237 }
00238 _StartChanges();
00239
00240 if (m_setItemParent && m_parent)
00241 value->SetParent(m_parent);
00242
00243
00244
00245
00246 if (m_setItemParent
00247 && !(m_changeInfoState & CHANGEINFO_PROCESSING))
00248 {
00249 value->SetElementState(FdoSchemaElementState_Added);
00250 }
00251 FdoNamedCollection<OBJ, FdoSchemaException>::Insert(index, value);
00252 }
00253
00254
00255
00256
00257
00258
00259
00260 FDO_API virtual void Clear()
00261 {
00262 _StartChanges();
00263
00264 if (m_setItemParent && m_parent)
00265 {
00266 for(FdoInt32 i = 0; i < FdoNamedCollection<OBJ, FdoSchemaException>::GetCount(); i++)
00267 {
00268 OBJ* pitem = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(i);
00269 FdoSchemaElement* pparent = pitem->GetParent();
00270
00271 if ( pparent == m_parent )
00272 {
00273
00274
00275
00276
00277 pitem->SetParent(NULL);
00278 pitem->SetElementState(FdoSchemaElementState_Detached);
00279 }
00280
00281 FDO_SAFE_RELEASE(pparent);
00282 FDO_SAFE_RELEASE(pitem);
00283 }
00284 }
00285
00286 FdoNamedCollection<OBJ, FdoSchemaException>::Clear();
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 FDO_API virtual void Remove(const OBJ* value)
00299 {
00300 _StartChanges();
00301
00302 if (m_setItemParent && m_parent)
00303 {
00304
00305 OBJ* pitem = (OBJ*)value;
00306 FdoSchemaElement* pparent = pitem->GetParent();
00307
00308 if ( pparent == m_parent )
00309 {
00310
00311
00312
00313
00314 pitem->SetParent(NULL);
00315 pitem->SetElementState(FdoSchemaElementState_Detached);
00316 }
00317
00318 FDO_SAFE_RELEASE(pparent);
00319 }
00320
00321 FdoNamedCollection<OBJ, FdoSchemaException>::Remove(value);
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 FDO_API virtual void RemoveAt(FdoInt32 index)
00334 {
00335 _StartChanges();
00336
00337 if (m_setItemParent && m_parent)
00338 {
00339 OBJ* pitem = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(index);
00340 FdoSchemaElement* pparent = pitem->GetParent();
00341
00342 if ( pparent == m_parent )
00343 {
00344
00345
00346
00347
00348 pitem->SetParent(NULL);
00349 pitem->SetElementState(FdoSchemaElementState_Detached);
00350 }
00351
00352 FDO_SAFE_RELEASE(pparent);
00353 FDO_SAFE_RELEASE(pitem);
00354 }
00355
00356 FdoNamedCollection<OBJ, FdoSchemaException>::RemoveAt(index);
00357 }
00358
00359 protected:
00360
00361
00362 static const unsigned int CHANGEINFO_PRESENT = 0x00000001;
00363 static const unsigned int CHANGEINFO_PROCESSING = 0x00000002;
00364 static const unsigned int CHANGEINFO_PROCESSED = 0x00000004;
00365
00366 FdoSchemaElement* m_parent;
00367 bool m_setItemParent;
00368
00369
00370 FdoByte m_changeInfoState;
00371 OBJ** m_listCHANGED;
00372 FdoInt32 m_sizeCHANGED;
00373
00374 virtual void _StartChanges()
00375 {
00376 if (!(m_changeInfoState & (CHANGEINFO_PRESENT|CHANGEINFO_PROCESSING)))
00377 {
00378 m_sizeCHANGED = FdoNamedCollection<OBJ, FdoSchemaException>::GetCount();
00379
00380 if (m_sizeCHANGED > 0)
00381 {
00382 m_listCHANGED = new OBJ*[m_sizeCHANGED];
00383 for (FdoInt32 i=0; i < m_sizeCHANGED; i++)
00384 {
00385 m_listCHANGED[i] = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(i);
00386 }
00387 }
00388
00389 m_changeInfoState |= CHANGEINFO_PRESENT;
00390
00391 if (m_parent)
00392 m_parent->SetElementState(FdoSchemaElementState_Modified);
00393 }
00394 }
00395
00396 virtual void _AcceptChanges()
00397 {
00398
00399 if (m_changeInfoState & CHANGEINFO_PROCESSED)
00400 return;
00401 m_changeInfoState |= CHANGEINFO_PROCESSED;
00402
00403 if (m_changeInfoState & CHANGEINFO_PRESENT)
00404 {
00405
00406 for (FdoInt32 i=0; i < m_sizeCHANGED; i++)
00407 {
00408
00409 m_listCHANGED[i]->_AcceptChanges();
00410
00411
00412 FDO_SAFE_RELEASE(m_listCHANGED[i]);
00413 }
00414 delete [] m_listCHANGED;
00415 m_listCHANGED = NULL;
00416 m_sizeCHANGED = 0;
00417 }
00418
00419
00420 for (FdoInt32 i=0; i < FdoNamedCollection<OBJ, FdoSchemaException>::GetCount(); i++)
00421 {
00422 FdoPtr<OBJ> pitem = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(i);
00423
00424 if (pitem->GetElementState() == FdoSchemaElementState_Deleted)
00425 {
00426
00427 RemoveAt(i);
00428 i--;
00429 }
00430
00431 pitem->_AcceptChanges();
00432 }
00433 }
00434
00435 virtual void _RejectChanges()
00436 {
00437
00438 if (m_changeInfoState & CHANGEINFO_PROCESSED)
00439 return;
00440 m_changeInfoState |= CHANGEINFO_PROCESSED;
00441
00442 if (m_changeInfoState & CHANGEINFO_PRESENT)
00443 {
00444
00445
00446
00447 for (FdoInt32 i=0; i < FdoNamedCollection<OBJ, FdoSchemaException>::GetCount(); i++)
00448 {
00449 OBJ* pitem = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(i);
00450 pitem->_RejectChanges();
00451 FDO_SAFE_RELEASE(pitem);
00452 }
00453
00454 FdoNamedCollection<OBJ, FdoSchemaException>::Clear();
00455 for (FdoInt32 iChanged=0; iChanged < m_sizeCHANGED; iChanged++)
00456 {
00457 Add(m_listCHANGED[iChanged]);
00458 FDO_SAFE_RELEASE(m_listCHANGED[iChanged]);
00459 }
00460
00461
00462 delete [] m_listCHANGED;
00463 m_listCHANGED = NULL;
00464 m_sizeCHANGED = 0;
00465 }
00466
00467
00468 for (FdoInt32 i=0; i < FdoNamedCollection<OBJ, FdoSchemaException>::GetCount(); i++)
00469 {
00470 OBJ* pitem = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(i);
00471 pitem->_RejectChanges();
00472 FDO_SAFE_RELEASE(pitem);
00473 }
00474 }
00475
00476 virtual void _BeginChangeProcessing()
00477 {
00478
00479 if (m_changeInfoState & CHANGEINFO_PROCESSING)
00480 return;
00481
00482 m_changeInfoState |= CHANGEINFO_PROCESSING;
00483
00484 for (FdoInt32 i=0; i < FdoNamedCollection<OBJ, FdoSchemaException>::GetCount(); i++)
00485 {
00486 OBJ* pitem = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(i);
00487 pitem->_BeginChangeProcessing();
00488 FDO_SAFE_RELEASE(pitem);
00489 }
00490 }
00491
00492 virtual void _EndChangeProcessing()
00493 {
00494
00495 if (!(m_changeInfoState & CHANGEINFO_PROCESSING))
00496 return;
00497
00498 for (FdoInt32 i=0; i < FdoNamedCollection<OBJ, FdoSchemaException>::GetCount(); i++)
00499 {
00500 OBJ* pitem = FdoNamedCollection<OBJ, FdoSchemaException>::GetItem(i);
00501 pitem->_EndChangeProcessing();
00502 FDO_SAFE_RELEASE(pitem);
00503 }
00504
00505 m_changeInfoState = 0;
00506 }
00507
00508 };
00509 #endif
00510
00511