| 155 | |
| 156 | ==== !DeepCopy Function ==== |
| 157 | |
| 158 | The actual process of copying or cloning individual elements within an FDO schema shall be accomplished with the addition of a standard !DeepCopy method that will be added to all types that derive from !FdoSchemaElement. It shall be the responsibility of the !DeepCopy method to copy itself and all its contained objects and data. |
| 159 | |
| 160 | The following !DeepCopy function will be added to the set of schema class definitions listed in the subsequent section. |
| 161 | |
| 162 | |
| 163 | {{{ |
| 164 | /// \brief |
| 165 | /// Deep copy this instance of class Fdo[ClassName]. |
| 166 | /// |
| 167 | /// \param context |
| 168 | /// An schema copy context which will contain previously copied elements |
| 169 | /// from the schema being cloned |
| 170 | /// |
| 171 | /// \return |
| 172 | /// Returns a cloned instance of class Fdo[ClassName] |
| 173 | /// |
| 174 | FDO_API virtual Fdo[ClassName]* DeepCopy( FdoSchemaCopyContext* context = NULL ); |
| 175 | }}} |
| 176 | |
| 177 | The following schema classes will have a !DeepCopy function added to their class definition. |
| 178 | |
| 179 | |
| 180 | {{{ |
| 181 | FdoAssociationPropertyDefinition |
| 182 | FdoClass |
| 183 | FdoClassDefinition |
| 184 | FdoClassCollection |
| 185 | FdoDataPropertyDefinition |
| 186 | FdoDataPropertyDefinitionCollection |
| 187 | FdoFeatureClass |
| 188 | FdoFeatureClassCollection |
| 189 | FdoFeatureSchema |
| 190 | FdoFeatureSchemaCollection |
| 191 | FdoGeometricPropertyDefinition |
| 192 | FdoObjectPropertyDefinition |
| 193 | FdoPropertyDefinition |
| 194 | FdoPropertyDefinitionCollection |
| 195 | FdoNetworkClass |
| 196 | FdoNetworkFeatureClass |
| 197 | FdoNetworkLayerClass |
| 198 | FdoNetworkLinkFeatureClass |
| 199 | FdoNetworkNodeFeatureClass |
| 200 | FdoRasterPropertyDefinition |
| 201 | FdoReadOnlyDataPropertyDefinitionCollection |
| 202 | FdoReadOnlyPropertyDefinitionCollection |
| 203 | FdoSchemaCollection |
| 204 | FdoTopoFeaturePropertyDefinition |
| 205 | FdoTopoGeometryPropertyDefinition |
| 206 | }}} |
| 207 | |
| 208 | NOTE: This list may have to be expanded depending on additional requirements |
| 209 | |
| 210 | ===== Example Implementation ===== |
| 211 | |
| 212 | The following example demonstrates how the !DeepCopy method might be implemented for class !FdoFeatureSchema |
| 213 | |
| 214 | |
| 215 | {{{ |
| 216 | FdoFeatureSchema * FdoFeatureSchema::DeepCopy( FdoSchemaCopyContext * context ) |
| 217 | { |
| 218 | FdoSchemaCopyContextP copyContext = FDO_SAFE_ADDREF(context); |
| 219 | if (copyContext == NULL) { |
| 220 | copyContext = FdoSchemaCopyContext::Create(); |
| 221 | } |
| 222 | |
| 223 | FdoFeatureSchemaP retSchema = localSchemaContext->FindSchemaElement(this); |
| 224 | if (retSchema != NULL) { |
| 225 | return FDO_SAFE_ADDREF(retSchema.p); |
| 226 | } |
| 227 | |
| 228 | FdoFeatureSchemaP clonedSchema = FdoFeatureSchema::Create( |
| 229 | GetName(), |
| 230 | GetDescription()); |
| 231 | |
| 232 | FdoInt32 length = 0; |
| 233 | FdoSADP sourceAttributes = this->GetAttributes (); |
| 234 | FdoSADP copyAttributes = clonedSchema->GetAttributes (); |
| 235 | FdoString** sourceAttributeNames = sourceAttributes->GetAttributeNames (length); |
| 236 | |
| 237 | for (FdoInt32 i = 0; i < length; i++) { |
| 238 | FdoString* name = sourceAttributeNames[i]; |
| 239 | FdoString* value = sourceAttributes->GetAttributeValue (name) |
| 240 | copyAttributes->Add (name, value); |
| 241 | } |
| 242 | |
| 243 | FdoClassesP classes = schema->GetClasses(); |
| 244 | FdoClassesP newClasses = clonedSchema->GetClasses(); |
| 245 | |
| 246 | for (FdoInt32 i=0; i<classes->GetCount(); i++) { |
| 247 | FdoClassDefinitionP class = classes->GetItem(i); |
| 248 | FdoClassDefinitionP newClass = class->DeepCopy(copyContext); |
| 249 | newClasses->Add(newClass); |
| 250 | } |
| 251 | |
| 252 | clonedSchema->AcceptChanges(); |
| 253 | copyContext->InsertSchemaElement(this, clonedSchema); |
| 254 | |
| 255 | return FDO_SAFE_ADDREF(clonedSchema.p); |
| 256 | } |
| 257 | }}} |
| 258 | |
| 259 | ===== Example Usage ===== |
| 260 | |
| 261 | The following example demonstrates how the !DeepCopy method might be used by a client such as the SDF Provider. |
| 262 | |
| 263 | |
| 264 | {{{ |
| 265 | FdoClassDefinition* CloneAndPruneClass( |
| 266 | FdoClassDefinition *classDef, |
| 267 | FdoIdentifierCollection *ids, |
| 268 | FdoPropertyDefinitionCollection* computedProps) |
| 269 | { |
| 270 | // Create a copy context |
| 271 | FdoPtr<FdoSchemaCopyContext> copyContext = NULL; |
| 272 | if (ids != NULL && ids->GetCount() > 0) { |
| 273 | copyContext = FdoSchemaCopyContext::Create(ids); |
| 274 | } |
| 275 | |
| 276 | // Clone the class definition, copying only the class identifiers |
| 277 | // listed in the 'ids' collection |
| 278 | FdoClassDefinitionP classDefPruned = classDef->DeepCopy(copyContext); |
| 279 | FdoPropertiesP properties = classDefPruned->GetProperties (); |
| 280 | |
| 281 | // If there are additional computed properties that |
| 282 | // need to be added to the cloned class definition |
| 283 | if (computedProps != NULL) { |
| 284 | // Add the computed properties to the class |
| 285 | for (GdoInt32 i=0; i<computedProps->GetCount(); i++) { |
| 286 | FdoPtr<FdoPropertyDefinition> computedProp = computedProps->GetItem(i); |
| 287 | properties->Add(pd); |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | // Returned the pruned class definition that also |
| 292 | // includes the referenced computed properties |
| 293 | return FDO_SAFE_ADDREF(classDefPruned.p); |
| 294 | } |
| 295 | }}} |
| 296 | |
| 297 | |