Increment OCCT version up to 7.4.0
[occt.git] / src / CDM / CDM_Document.cxx
1 // Created on: 1997-07-30
2 // Created by: Jean-Louis Frenkel
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // Modified by rmi, Tue Nov 18 08:17:41 1997
18
19 #include <CDM_Application.hxx>
20 #include <CDM_DataMapIteratorOfMetaDataLookUpTable.hxx>
21 #include <CDM_Document.hxx>
22 #include <CDM_ListIteratorOfListOfDocument.hxx>
23 #include <CDM_ListOfDocument.hxx>
24 #include <CDM_MetaData.hxx>
25 #include <CDM_NamesDirectory.hxx>
26 #include <CDM_PresentationDirectory.hxx>
27 #include <CDM_Reference.hxx>
28 #include <CDM_ReferenceIterator.hxx>
29 #include <Resource_Manager.hxx>
30 #include <Standard_DomainError.hxx>
31 #include <Standard_Failure.hxx>
32 #include <Standard_GUID.hxx>
33 #include <Standard_NoSuchObject.hxx>
34 #include <Standard_NullObject.hxx>
35 #include <Standard_ProgramError.hxx>
36 #include <Standard_Type.hxx>
37 #include <TCollection_ExtendedString.hxx>
38 #include <UTL.hxx>
39
40 IMPLEMENT_STANDARD_RTTIEXT(CDM_Document,Standard_Transient)
41
42 static CDM_PresentationDirectory& getPresentations() {
43   static CDM_PresentationDirectory thePresentations;
44   return thePresentations;
45 }
46
47 //=======================================================================
48 //function : CDM_Document
49 //purpose  : 
50 //=======================================================================
51
52 CDM_Document::CDM_Document():
53   myResourcesAreLoaded          (Standard_False),
54   myValidPresentation           (Standard_False),
55   myVersion                     (1),
56   myActualReferenceIdentifier   (0),
57   myStorageVersion              (0),
58   myRequestedComment            (""),
59   myRequestedFolderIsDefined    (Standard_False),
60   myRequestedNameIsDefined      (Standard_False),
61   myRequestedPreviousVersionIsDefined(Standard_False),
62   myFileExtensionWasFound       (Standard_False),
63   myDescriptionWasFound         (Standard_False),
64   myStorageFormatVersion        (0)
65 {}
66
67
68 //=======================================================================
69 //function : ~CDM_Document
70 //purpose  : 
71 //=======================================================================
72
73 CDM_Document::~CDM_Document()
74 {
75   if(!myMetaData.IsNull()) myMetaData->UnsetDocument();
76 }
77
78 //=======================================================================
79 //function : Update
80 //purpose  : 
81 //=======================================================================
82
83 void CDM_Document::Update (const Handle(CDM_Document)& /*aToDocument*/,
84                            const Standard_Integer /*aReferenceIdentifier*/,
85                            const Standard_Address /*aModifContext*/)
86 {
87 }
88
89 //=======================================================================
90 //function : Update
91 //purpose  : 
92 //=======================================================================
93
94 void CDM_Document::Update()
95 {
96 }
97
98 //=======================================================================
99 //function : Update
100 //purpose  : 
101 //=======================================================================
102
103 Standard_Boolean CDM_Document::Update(TCollection_ExtendedString& ErrorString)
104 {
105   ErrorString.Clear();
106   Update();
107   return Standard_True;
108 }
109
110 //=======================================================================
111 //function : GetAlternativeDocument
112 //purpose  : 
113 //=======================================================================
114
115 Standard_Boolean CDM_Document::GetAlternativeDocument
116                                 (const TCollection_ExtendedString& aFormat,
117                                  Handle(CDM_Document)& anAlternativeDocument)
118 {
119   anAlternativeDocument = this;
120   return aFormat == StorageFormat();
121 }
122
123 //=======================================================================
124 //function : Extensions
125 //purpose  : 
126 //=======================================================================
127
128 void CDM_Document::Extensions (TColStd_SequenceOfExtendedString& Extensions) const
129 {
130   Extensions.Clear();
131 }
132
133 //=======================================================================
134 //function : CreateReference
135 //purpose  : 
136 //=======================================================================
137
138 Standard_Integer CDM_Document::CreateReference
139                                 (const Handle(CDM_Document)& anOtherDocument)
140 {
141   CDM_ListIteratorOfListOfReferences it(myToReferences);
142   
143   for(; it.More(); it.Next()) {
144     if(anOtherDocument == it.Value()->Document())
145       return it.Value()->ReferenceIdentifier();
146   }
147
148   Handle(CDM_Reference) r = new CDM_Reference (this,
149                                                anOtherDocument,
150                                                ++myActualReferenceIdentifier,
151                                                anOtherDocument->Modifications());
152   AddToReference(r);
153   anOtherDocument->AddFromReference(r);
154   return  r->ReferenceIdentifier();
155 }
156
157 //=======================================================================
158 //function : RemoveAllReferences
159 //purpose  : 
160 //=======================================================================
161
162 void CDM_Document::RemoveAllReferences()
163 {
164   CDM_ListIteratorOfListOfReferences it(myToReferences);
165
166   for(; it.More(); it.Next()) {
167     it.Value()->ToDocument()->RemoveFromReference(it.Value()->ReferenceIdentifier());
168   }
169   myToReferences.Clear();
170 }
171
172 //=======================================================================
173 //function : RemoveReference
174 //purpose  : 
175 //=======================================================================
176
177 void CDM_Document::RemoveReference(const Standard_Integer aReferenceIdentifier)
178 {
179   CDM_ListIteratorOfListOfReferences it(myToReferences);
180   
181   for(; it.More(); it.Next()) {
182     if(aReferenceIdentifier == it.Value()->ReferenceIdentifier()) {
183       it.Value()->ToDocument()->RemoveFromReference(aReferenceIdentifier);
184       myToReferences.Remove(it);
185       return;
186     }
187   }
188 }
189
190 //=======================================================================
191 //function : Document
192 //purpose  : 
193 //=======================================================================
194
195 Handle(CDM_Document) CDM_Document::Document
196                                 (const Standard_Integer aReferenceIdentifier) const
197 {
198   Handle(CDM_Document) theDocument;
199
200   if(aReferenceIdentifier == 0) 
201     theDocument = this;
202   
203   else {
204     Handle(CDM_Reference) theReference = Reference(aReferenceIdentifier);
205     if(!theReference.IsNull()) theDocument = theReference->ToDocument();
206   }
207   return theDocument;
208 }
209
210 //=======================================================================
211 //function : Reference
212 //purpose  : 
213 //=======================================================================
214
215 Handle(CDM_Reference) CDM_Document::Reference
216                                 (const Standard_Integer aReferenceIdentifier) const
217 {
218   Handle(CDM_Reference) theReference;
219
220   CDM_ListIteratorOfListOfReferences it(myToReferences);
221     
222   Standard_Boolean found = Standard_False;
223     
224   for(; it.More() && !found; it.Next()) {
225     found = aReferenceIdentifier == it.Value()->ReferenceIdentifier();
226     if(found) theReference = it.Value();
227   }
228   return theReference;
229 }
230
231 static CDM_ListOfDocument& getListOfDocumentToUpdate() {
232   static CDM_ListOfDocument theListOfDocumentToUpdate;
233   return theListOfDocumentToUpdate;
234 }
235
236 //=======================================================================
237 //function : IsInSession
238 //purpose  : 
239 //=======================================================================
240
241 Standard_Boolean CDM_Document::IsInSession
242                                 (const Standard_Integer aReferenceIdentifier) const
243 {
244   if(aReferenceIdentifier == 0) return Standard_True;
245   Handle(CDM_Reference) theReference=Reference(aReferenceIdentifier);
246   if(theReference.IsNull())
247     throw Standard_NoSuchObject("CDM_Document::IsInSession: "
248                                  "invalid reference identifier");
249   return theReference->IsInSession();
250 }
251
252 //=======================================================================
253 //function : IsStored
254 //purpose  : 
255 //=======================================================================
256
257 Standard_Boolean CDM_Document::IsStored
258                                 (const Standard_Integer aReferenceIdentifier) const
259 {
260   if(aReferenceIdentifier == 0) return IsStored();
261   Handle(CDM_Reference) theReference=Reference(aReferenceIdentifier);
262   if(theReference.IsNull())
263     throw Standard_NoSuchObject("CDM_Document::IsInSession: "
264                                  "invalid reference identifier");
265   return theReference->IsStored();
266 }
267
268 //=======================================================================
269 //function : Name
270 //purpose  : 
271 //=======================================================================
272
273 TCollection_ExtendedString CDM_Document::Name
274                                 (const Standard_Integer aReferenceIdentifier) const
275 {
276   if(!IsStored(aReferenceIdentifier))
277     throw Standard_DomainError("CDM_Document::Name: document is not stored");
278
279   if(aReferenceIdentifier == 0) return myMetaData->Name();
280
281   return Reference(aReferenceIdentifier)->MetaData()->Name();
282 }
283
284 //=======================================================================
285 //function : UpdateFromDocuments
286 //purpose  : 
287 //=======================================================================
288
289 void CDM_Document::UpdateFromDocuments(const Standard_Address aModifContext) const
290 {
291   Standard_Boolean StartUpdateCycle=getListOfDocumentToUpdate().IsEmpty();
292   
293   CDM_ListIteratorOfListOfReferences it(myFromReferences);
294   for(; it.More() ; it.Next()) {
295     Handle(CDM_Document) theFromDocument=it.Value()->FromDocument();
296     CDM_ListIteratorOfListOfDocument itUpdate;
297
298     for(; itUpdate.More(); itUpdate.Next()) {
299       if(itUpdate.Value() == theFromDocument) break;
300       
301       if(itUpdate.Value()->ShallowReferences(theFromDocument)) {
302         getListOfDocumentToUpdate().InsertBefore(theFromDocument,itUpdate);
303         break;
304       }
305     }
306     if(!itUpdate.More()) getListOfDocumentToUpdate().Append(theFromDocument);
307     theFromDocument->Update(this,it.Value()->ReferenceIdentifier(),aModifContext);
308   }
309   
310   if(StartUpdateCycle) {
311
312     Handle(CDM_Document) theDocumentToUpdate;
313     Handle(CDM_Application) theApplication;
314     TCollection_ExtendedString ErrorString;
315
316     while(!getListOfDocumentToUpdate().IsEmpty()) {
317       theDocumentToUpdate=getListOfDocumentToUpdate().First();
318       theApplication=theDocumentToUpdate->Application();
319       ErrorString.Clear();
320       theApplication->BeginOfUpdate(theDocumentToUpdate);
321       theApplication->EndOfUpdate (theDocumentToUpdate,
322                                    theDocumentToUpdate->Update(ErrorString),
323                                    ErrorString);
324       getListOfDocumentToUpdate().RemoveFirst();
325     }
326   }
327 }
328
329 //=======================================================================
330 //function : ToReferencesNumber
331 //purpose  : 
332 //=======================================================================
333
334 Standard_Integer CDM_Document::ToReferencesNumber() const
335 {
336   return myToReferences.Extent();
337 }
338
339 //=======================================================================
340 //function : FromReferencesNumber
341 //purpose  : 
342 //=======================================================================
343
344 Standard_Integer CDM_Document::FromReferencesNumber() const
345 {
346   return myFromReferences.Extent();
347 }
348
349 //=======================================================================
350 //function : ShallowReferences
351 //purpose  : 
352 //=======================================================================
353
354 Standard_Boolean CDM_Document::ShallowReferences
355                                 (const Handle(CDM_Document)& aDocument) const
356 {
357   CDM_ListIteratorOfListOfReferences it(myFromReferences);
358   for(; it.More() ; it.Next()) {
359     if(it.Value()->Document() == aDocument) return Standard_True;
360   }
361   return Standard_False;
362 }
363
364 //=======================================================================
365 //function : DeepReferences
366 //purpose  : 
367 //=======================================================================
368
369 Standard_Boolean CDM_Document::DeepReferences
370                                 (const Handle(CDM_Document)& aDocument) const
371 {
372   CDM_ListIteratorOfListOfReferences it(myFromReferences);
373   for(; it.More() ; it.Next()) {
374     Handle(CDM_Document) theToDocument=it.Value()->Document();
375     if(!theToDocument.IsNull()) {
376       if(theToDocument == aDocument) return Standard_True;
377       if(theToDocument->DeepReferences(aDocument)) return Standard_True;
378     }
379   }
380   return Standard_False;
381 }
382
383 //=======================================================================
384 //function : CopyReference
385 //purpose  : 
386 //=======================================================================
387
388 Standard_Integer CDM_Document::CopyReference
389                                 (const Handle(CDM_Document)& /*aFromDocument*/,
390                                  const Standard_Integer aReferenceIdentifier)
391 {
392   Handle(CDM_Reference) theReference = Reference(aReferenceIdentifier);
393   if(!theReference.IsNull()) {
394     Handle(CDM_Document) theDocument = theReference->Document();
395     if(!theDocument.IsNull()) {
396       return CreateReference(theDocument);
397     }
398     else
399       return CreateReference(theReference->MetaData(),
400                              theReference->Application(),
401                              theReference->DocumentVersion(),
402                              theReference->UseStorageConfiguration());
403   }
404   return 0; //for NT ...
405 }
406
407 //=======================================================================
408 //function : Modify
409 //purpose  : 
410 //=======================================================================
411
412 void CDM_Document::Modify()
413 {
414   myVersion++;
415 }
416
417 //=======================================================================
418 //function : UnModify
419 //purpose  : 
420 //=======================================================================
421
422 void CDM_Document::UnModify()
423 {
424   myVersion = myStorageVersion;
425 }
426
427 //=======================================================================
428 //function : Modifications
429 //purpose  : 
430 //=======================================================================
431
432 Standard_Integer CDM_Document::Modifications() const
433 {
434   return myVersion;
435 }
436
437 //=======================================================================
438 //function : SetModifications
439 //purpose  : 
440 //=======================================================================
441
442 void CDM_Document::SetModifications(const Standard_Integer Modifications)
443 {
444   myVersion = Modifications;
445 }
446
447 //=======================================================================
448 //function : IsUpToDate
449 //purpose  : 
450 //=======================================================================
451
452 Standard_Boolean CDM_Document::IsUpToDate
453                                 (const Standard_Integer aReferenceIdentifier) const
454 {
455   return  Reference(aReferenceIdentifier)->IsUpToDate();
456 }
457
458 //=======================================================================
459 //function : SetIsUpToDate
460 //purpose  : 
461 //=======================================================================
462
463 void CDM_Document::SetIsUpToDate (const Standard_Integer aReferenceIdentifier)
464 {
465   Reference(aReferenceIdentifier)->SetIsUpToDate();
466 }  
467
468 //=======================================================================
469 //function : SetComment
470 //purpose  : 
471 //=======================================================================
472
473 void CDM_Document::SetComment(const TCollection_ExtendedString& aComment)
474 {
475   myComments.Clear();
476   myComments.Append(aComment);
477 }
478
479 //=======================================================================
480 //function : AddComment
481 //purpose  : 
482 //=======================================================================
483
484 void CDM_Document::AddComment(const TCollection_ExtendedString& aComment)
485 {
486   myComments.Append(aComment);
487 }
488
489 //=======================================================================
490 //function : SetComments
491 //purpose  : 
492 //=======================================================================
493
494 void CDM_Document::SetComments(const TColStd_SequenceOfExtendedString& aComments)
495 {
496   myComments = aComments;
497 }
498
499 //=======================================================================
500 //function : Comments
501 //purpose  : 
502 //=======================================================================
503
504 void CDM_Document::Comments(TColStd_SequenceOfExtendedString& aComments) const
505 {
506   aComments = myComments;
507 }
508
509 //=======================================================================
510 //function : Comment
511 //purpose  : 
512 //=======================================================================
513
514 Standard_ExtString CDM_Document::Comment() const
515 {
516   if (myComments.Length() < 1)
517     return 0;
518   return myComments(1).ToExtString();
519 }
520
521 //=======================================================================
522 //function : Presentation
523 //purpose  : 
524 //=======================================================================
525
526 Standard_ExtString CDM_Document::Presentation()
527 {
528   if(!myValidPresentation) ComputePresentation();
529   return myPresentation.ToExtString();
530 }
531
532 //=======================================================================
533 //function : UnvalidPresentation
534 //purpose  : 
535 //=======================================================================
536
537 void CDM_Document::UnvalidPresentation()
538 {
539   if(myValidPresentation) {
540     getPresentations().UnBind(myPresentation);
541     myValidPresentation=Standard_False;
542   }
543 }
544
545 //=======================================================================
546 //function : ComputePresentation
547 //purpose  : 
548 //=======================================================================
549
550 void CDM_Document::ComputePresentation()
551 {
552   TCollection_ExtendedString presentation("");
553   static Standard_Integer theUnnamedDocuments(0);
554   static CDM_NamesDirectory theNames;
555
556   if(!myMetaData.IsNull()) {
557     presentation += myMetaData->Name();
558     if(!theNames.IsBound(presentation)) theNames.Bind(presentation,0);
559     Standard_Integer range = theNames(presentation);
560     range += 1;
561     theNames(presentation) = range;
562     if(range != 1) {
563       presentation += "<";
564       presentation += range;
565       presentation += ">";
566     }
567   }
568   else {
569     presentation = "Document_";
570     presentation += ++theUnnamedDocuments;
571   }
572   
573   if(getPresentations().IsBound(presentation)) {
574     TCollection_ExtendedString Test = presentation;
575     Test += "!";
576     Standard_Integer Count=0;
577     while (getPresentations().IsBound(Test)) {
578       Count++;
579       Test = presentation; Test+= "!"; Test+= Count;
580     }
581     presentation = Test;
582   }
583   
584   
585   myPresentation = TCollection_ExtendedString(presentation);
586   myValidPresentation = Standard_True;
587   getPresentations().Bind(presentation,this);
588 }
589
590 //=======================================================================
591 //function : FindFromPresentation
592 //purpose  : 
593 //=======================================================================
594
595 Handle(CDM_Document) CDM_Document::FindFromPresentation
596                                 (const TCollection_ExtendedString& aPresentation)
597 {
598   TCollection_ExtendedString x(aPresentation);
599   if(!getPresentations().IsBound(x)) {
600     Standard_SStream aMsg;
601     aMsg <<"No document having this presentation: " << x << " does exist."
602          << std::endl << (char)0;
603     throw Standard_NoSuchObject(aMsg.str().c_str());
604   }
605   return getPresentations()(x);
606 }
607
608 //=======================================================================
609 //function : FindPresentation
610 //purpose  : 
611 //=======================================================================
612
613 Standard_Boolean CDM_Document::FindPresentation
614                                 (const TCollection_ExtendedString& aPresentation)
615 {
616   return getPresentations().IsBound(aPresentation);
617 }
618
619 //=======================================================================
620 //function : IsStored
621 //purpose  : 
622 //=======================================================================
623
624 Standard_Boolean CDM_Document::IsStored() const
625 {
626   return !myMetaData.IsNull();
627 }
628
629 //=======================================================================
630 //function : StorageVersion
631 //purpose  : 
632 //=======================================================================
633
634 Standard_Integer CDM_Document::StorageVersion() const
635 {
636   return myStorageVersion;
637 }
638
639 //=======================================================================
640 //function : SetMetaData
641 //purpose  : 
642 //=======================================================================
643
644 void CDM_Document::SetMetaData(const Handle(CDM_MetaData)& aMetaData)
645 {
646   if(!aMetaData->IsRetrieved() || aMetaData->Document() != This()) {
647
648     aMetaData->SetDocument(this);
649
650 // Update the document refencing this MetaData:
651     CDM_DataMapIteratorOfMetaDataLookUpTable it(CDM_MetaData::LookUpTable());
652     for(;it.More();it.Next()) {
653       const Handle(CDM_MetaData)& theMetaData=it.Value();
654       if(theMetaData != aMetaData && theMetaData->IsRetrieved()) {
655         CDM_ListIteratorOfListOfReferences rit(theMetaData->Document()->myToReferences);
656         for(;rit.More();rit.Next()) {
657           rit.Value()->Update(aMetaData);
658         }
659       }
660     }
661     if(!myMetaData.IsNull()) {
662       if(myMetaData->Name() != aMetaData->Name()) UnvalidPresentation();
663       myMetaData->UnsetDocument();
664     }
665     else
666       UnvalidPresentation();
667   }
668
669   myStorageVersion = Modifications();
670   
671   myMetaData = aMetaData;
672   
673   SetRequestedFolder(aMetaData->Folder());
674   if(aMetaData->HasVersion()) SetRequestedPreviousVersion(aMetaData->Version());
675 }
676
677 //=======================================================================
678 //function : UnsetIsStored
679 //purpose  : 
680 //=======================================================================
681
682 void CDM_Document::UnsetIsStored()
683 {
684   if(!myMetaData.IsNull()) { 
685     myMetaData->UnsetDocument();
686 //    myMetaData.Nullify();
687   }
688 }
689
690 //=======================================================================
691 //function : MetaData
692 //purpose  : 
693 //=======================================================================
694
695 Handle(CDM_MetaData) CDM_Document::MetaData() const
696 {
697   if(myMetaData.IsNull())
698     throw Standard_NoSuchObject("cannot furnish the MetaData of an object "
699                                  "which is not stored");
700   return myMetaData;
701 }
702
703 //=======================================================================
704 //function : SetRequestedComment
705 //purpose  : 
706 //=======================================================================
707
708 void CDM_Document::SetRequestedComment(const TCollection_ExtendedString& aComment)
709 {
710   myRequestedComment=aComment;
711 }
712
713 //=======================================================================
714 //function : RequestedComment
715 //purpose  : 
716 //=======================================================================
717
718 TCollection_ExtendedString CDM_Document::RequestedComment() const
719 {
720   return myRequestedComment.ToExtString();
721 }
722
723 //=======================================================================
724 //function : Folder
725 //purpose  : 
726 //=======================================================================
727
728 TCollection_ExtendedString CDM_Document::Folder() const {
729   if(myMetaData.IsNull())
730     throw Standard_NoSuchObject("cannot furnish the folder of an object "
731                                  "which is not stored");
732   return myMetaData->Folder();
733 }
734
735 //=======================================================================
736 //function : SetRequestedFolder
737 //purpose  : 
738 //=======================================================================
739
740 void CDM_Document::SetRequestedFolder(const TCollection_ExtendedString& aFolder)
741 {
742   TCollection_ExtendedString f(aFolder);
743   if(f.Length() != 0) {
744     myRequestedFolderIsDefined=Standard_True;
745     myRequestedFolder=aFolder;
746   }
747 }
748
749 //=======================================================================
750 //function : RequestedFolder
751 //purpose  : 
752 //=======================================================================
753
754 TCollection_ExtendedString CDM_Document::RequestedFolder() const
755 {
756   Standard_NoSuchObject_Raise_if (!myRequestedFolderIsDefined,
757                                   "storage folder is undefined for this document");
758   return myRequestedFolder;
759 }
760
761 //=======================================================================
762 //function : HasRequestedFolder
763 //purpose  : 
764 //=======================================================================
765
766 Standard_Boolean CDM_Document::HasRequestedFolder() const
767 {
768   return myRequestedFolderIsDefined;
769 }
770
771 //=======================================================================
772 //function : SetRequestedName
773 //purpose  : 
774 //=======================================================================
775
776 void CDM_Document::SetRequestedName(const TCollection_ExtendedString& aName)
777 {
778   myRequestedName=aName;
779   myRequestedNameIsDefined=Standard_True;
780 }
781
782 //=======================================================================
783 //function : RequestedName
784 //purpose  : 
785 //=======================================================================
786
787 TCollection_ExtendedString CDM_Document::RequestedName()
788 {
789   if(!myRequestedNameIsDefined) {
790     if(!myMetaData.IsNull())
791       myRequestedName=myMetaData->Name();
792     else
793       myRequestedName=Presentation();
794   }
795   myRequestedNameIsDefined=Standard_True;
796   return myRequestedName;
797 }
798
799 //=======================================================================
800 //function : SetRequestedPreviousVersion
801 //purpose  : 
802 //=======================================================================
803
804 void CDM_Document::SetRequestedPreviousVersion
805                              (const TCollection_ExtendedString& aPreviousVersion)
806 {
807   myRequestedPreviousVersionIsDefined=Standard_True;
808   myRequestedPreviousVersion=aPreviousVersion;
809 }
810
811 //=======================================================================
812 //function : RequestedPreviousVersion
813 //purpose  : 
814 //=======================================================================
815
816 TCollection_ExtendedString CDM_Document::RequestedPreviousVersion() const
817 {
818   Standard_NoSuchObject_Raise_if (!myRequestedPreviousVersionIsDefined,
819                                   "PreviousVersion is undefined fro this document");
820   return myRequestedPreviousVersion;
821 }
822
823 //=======================================================================
824 //function : HasRequestedPreviousVersion
825 //purpose  : 
826 //=======================================================================
827
828 Standard_Boolean CDM_Document::HasRequestedPreviousVersion() const
829 {
830   return myRequestedPreviousVersionIsDefined;
831 }
832
833 //=======================================================================
834 //function : UnsetRequestedPreviousVersion
835 //purpose  : 
836 //=======================================================================
837
838 void CDM_Document::UnsetRequestedPreviousVersion()
839 {
840   myRequestedPreviousVersionIsDefined=Standard_False;
841 }
842
843 //=======================================================================
844 //function : IsOpened
845 //purpose  : 
846 //=======================================================================
847
848 Standard_Boolean CDM_Document::IsOpened() const
849 {
850   return !myApplication.IsNull();
851 }
852
853 //=======================================================================
854 //function : IsOpened
855 //purpose  : 
856 //=======================================================================
857
858 Standard_Boolean CDM_Document::IsOpened
859                                 (const Standard_Integer aReferenceIdentifier) const
860 {
861   CDM_ListIteratorOfListOfReferences it(myToReferences);
862   
863   for (; it.More(); it.Next()) {
864     if (aReferenceIdentifier == it.Value()->ReferenceIdentifier())
865       return it.Value()->IsOpened();
866   }
867   return Standard_False;
868 }
869
870 //=======================================================================
871 //function : Open
872 //purpose  : 
873 //=======================================================================
874
875 void CDM_Document::Open(const Handle(CDM_Application)& anApplication)
876 {
877   myApplication=anApplication;
878 }
879
880 //=======================================================================
881 //function : Close
882 //purpose  : 
883 //=======================================================================
884
885 void CDM_Document::Close()
886 {
887   switch (CanClose()) {
888   case CDM_CCS_NotOpen: 
889     throw Standard_Failure("cannot close a document that has not been opened");
890     break;
891   case CDM_CCS_UnstoredReferenced:
892      throw Standard_Failure("cannot close an unstored document which is referenced");
893     break;
894   case CDM_CCS_ModifiedReferenced:
895     throw Standard_Failure("cannot close a document which is referenced when "
896                             "the document has been modified since it was stored.");
897     break;
898   case CDM_CCS_ReferenceRejection:
899     throw Standard_Failure("cannot close this document because a document "
900                             "referencing it refuses");
901     break;
902   default:
903     break;
904   }
905   if(FromReferencesNumber() != 0) {
906     CDM_ListIteratorOfListOfReferences it(myFromReferences);
907     for(; it.More(); it.Next()) {
908       it.Value()->UnsetToDocument(MetaData(),myApplication);
909     }
910   }
911   RemoveAllReferences();
912   UnsetIsStored();
913   myApplication.Nullify();
914   UnvalidPresentation();
915
916 }
917
918 //=======================================================================
919 //function : CanClose
920 //purpose  : 
921 //=======================================================================
922
923 CDM_CanCloseStatus CDM_Document::CanClose() const
924 {
925   if(!IsOpened()) return CDM_CCS_NotOpen;
926
927   if(FromReferencesNumber() != 0) {
928     if(!IsStored()) return CDM_CCS_UnstoredReferenced;
929     if(IsModified()) return CDM_CCS_ModifiedReferenced;
930
931
932     CDM_ListIteratorOfListOfReferences it(myFromReferences);
933     for(; it.More(); it.Next()) {
934       if(!it.Value()->FromDocument()->CanCloseReference(this, it.Value()->ReferenceIdentifier()))
935         return CDM_CCS_ReferenceRejection;
936     }
937   } 
938   return CDM_CCS_OK;
939 }
940
941 //=======================================================================
942 //function : CanCloseReference
943 //purpose  : 
944 //=======================================================================
945
946 Standard_Boolean CDM_Document::CanCloseReference
947                                 (const Handle(CDM_Document)& /*aDocument*/,
948                                  const Standard_Integer /*(aReferenceIdent*/) const
949 {
950   return Standard_True;
951 }
952
953 //=======================================================================
954 //function : CloseReference
955 //purpose  : 
956 //=======================================================================
957
958 void CDM_Document::CloseReference (const Handle(CDM_Document)& /*aDocument*/,
959                                    const Standard_Integer /*aReferenceIdentifier*/)
960 {
961 }
962
963 //=======================================================================
964 //function : Application
965 //purpose  : 
966 //=======================================================================
967
968 const Handle(CDM_Application)& CDM_Document::Application() const
969 {
970   if(!IsOpened())
971     throw Standard_Failure("this document has not yet been opened "
972                             "by any application");
973   return myApplication;
974 }
975
976 //=======================================================================
977 //function : IsModified
978 //purpose  : 
979 //=======================================================================
980
981 Standard_Boolean CDM_Document::IsModified() const
982 {
983   return Modifications() > StorageVersion();
984 }
985
986 //=======================================================================
987 //function : Print
988 //purpose  : 
989 //=======================================================================
990
991 Standard_OStream& CDM_Document::Print(Standard_OStream& anOStream) const
992 {
993   return anOStream;
994 }
995
996 //=======================================================================
997 //function : CreateReference
998 //purpose  : 
999 //=======================================================================
1000
1001 void CDM_Document::CreateReference(const Handle(CDM_MetaData)& aMetaData,
1002                                    const Standard_Integer aReferenceIdentifier,
1003                                    const Handle(CDM_Application)& anApplication,
1004                                    const Standard_Integer aToDocumentVersion,
1005                                    const Standard_Boolean UseStorageConfiguration)
1006 {
1007   myActualReferenceIdentifier=Max(myActualReferenceIdentifier,aReferenceIdentifier);
1008
1009   if(aMetaData->IsRetrieved()) {
1010     Handle(CDM_Reference) r = new CDM_Reference (this,
1011                                                  aMetaData->Document(),
1012                                                  aReferenceIdentifier,
1013                                                  aToDocumentVersion);
1014     AddToReference(r);
1015     aMetaData->Document()->AddFromReference(r);
1016     
1017   }
1018   else  {
1019       Handle(CDM_Reference) r = new CDM_Reference (this,
1020                                                    aMetaData,
1021                                                    aReferenceIdentifier,
1022                                                    anApplication,
1023                                                    aToDocumentVersion,
1024                                                    UseStorageConfiguration);
1025       AddToReference(r);
1026     }
1027 }
1028
1029 //=======================================================================
1030 //function : CreateReference
1031 //purpose  : 
1032 //=======================================================================
1033
1034 Standard_Integer CDM_Document::CreateReference
1035                                 (const Handle(CDM_MetaData)& aMetaData,
1036                                  const Handle(CDM_Application)& anApplication,
1037                                  const Standard_Integer aDocumentVersion,
1038                                  const Standard_Boolean UseStorageConfiguration)
1039 {
1040   CDM_ListIteratorOfListOfReferences it(myToReferences);
1041
1042   for(; it.More(); it.Next()) {
1043     if(aMetaData == it.Value()->MetaData())
1044       return it.Value()->ReferenceIdentifier();
1045   }
1046   Handle(CDM_Reference) r = new CDM_Reference (this,
1047                                                aMetaData,
1048                                                ++myActualReferenceIdentifier,
1049                                                anApplication,
1050                                                aDocumentVersion,
1051                                                UseStorageConfiguration);
1052   AddToReference(r);
1053   return  r->ReferenceIdentifier();
1054 }
1055
1056 //=======================================================================
1057 //function : AddToReference
1058 //purpose  : 
1059 //=======================================================================
1060
1061 void CDM_Document::AddToReference(const Handle(CDM_Reference)& aReference)
1062 {
1063   myToReferences.Append(aReference);
1064 }
1065
1066 //=======================================================================
1067 //function : AddFromReference
1068 //purpose  : 
1069 //=======================================================================
1070
1071 void CDM_Document::AddFromReference(const Handle(CDM_Reference)& aReference)
1072 {
1073   myFromReferences.Append(aReference);
1074 }
1075
1076 //=======================================================================
1077 //function : RemoveFromReference
1078 //purpose  : 
1079 //=======================================================================
1080
1081 void CDM_Document::RemoveFromReference(const Standard_Integer aReferenceIdentifier)
1082 {
1083   CDM_ListIteratorOfListOfReferences it(myFromReferences);
1084   
1085   for(; it.More(); it.Next()) {
1086     if(aReferenceIdentifier == it.Value()->ReferenceIdentifier()) {
1087       myFromReferences.Remove(it);
1088       return;
1089     }
1090   }
1091 }
1092
1093 //=======================================================================
1094 //function : GetResource
1095 //purpose  : 
1096 //=======================================================================
1097
1098 TCollection_ExtendedString GetResource (const TCollection_ExtendedString aFormat,
1099                                         const TCollection_ExtendedString anItem)
1100 {
1101   TCollection_ExtendedString theResource;
1102   theResource+= aFormat;
1103   theResource+= ".";
1104   theResource+= anItem;
1105   return theResource;
1106 }
1107
1108 static void FIND (const Handle(Resource_Manager)& theDocumentResource,
1109                   const TCollection_ExtendedString& theResourceName,
1110                   Standard_Boolean& IsDef,
1111                   TCollection_ExtendedString& theValue)
1112 {
1113   IsDef=UTL::Find(theDocumentResource,theResourceName);
1114   if(IsDef) theValue=UTL::Value(theDocumentResource,theResourceName);
1115   
1116 }
1117
1118 //=======================================================================
1119 //function : StorageResource
1120 //purpose  : 
1121 //=======================================================================
1122
1123 Handle(Resource_Manager) CDM_Document::StorageResource()
1124 {
1125   if(myApplication.IsNull()) {
1126     Standard_SStream aMsg;
1127     aMsg << "this document of format "<< StorageFormat()
1128          << " has not yet been opened by any application. "<< std::endl;
1129     throw Standard_Failure(aMsg.str().c_str());
1130   }
1131   return myApplication->Resources();
1132 }  
1133
1134 //=======================================================================
1135 //function : LoadResources
1136 //purpose  : 
1137 //=======================================================================
1138
1139 void CDM_Document::LoadResources()
1140 {
1141   if(!myResourcesAreLoaded) {
1142     Handle(Resource_Manager) theDocumentResource = StorageResource();
1143  
1144     TCollection_ExtendedString theFormat=StorageFormat(); theFormat+=".";
1145     TCollection_ExtendedString theResourceName;
1146     
1147     theResourceName=theFormat;
1148     theResourceName+="FileExtension";
1149     FIND(theDocumentResource,
1150          theResourceName,myFileExtensionWasFound,myFileExtension);
1151     
1152     theResourceName=theFormat;
1153     theResourceName+="Description";
1154     FIND(theDocumentResource,theResourceName,myDescriptionWasFound,myDescription);
1155     
1156     myResourcesAreLoaded=Standard_True;
1157     
1158 //    std::cout << "resource Loaded: Format: " << theFormat << ", FileExtension:" << myFileExtension << ", Description:" << myDescription << std::endl;
1159   }
1160   return;
1161 }
1162
1163 //=======================================================================
1164 //function : FindFileExtension
1165 //purpose  : 
1166 //=======================================================================
1167
1168 Standard_Boolean CDM_Document::FindFileExtension ()
1169 {
1170   LoadResources();
1171   return myFileExtensionWasFound;
1172 }
1173
1174 //=======================================================================
1175 //function : FileExtension
1176 //purpose  : 
1177 //=======================================================================
1178
1179 TCollection_ExtendedString CDM_Document::FileExtension()
1180 {
1181   LoadResources();
1182   return  myFileExtension;
1183 }
1184
1185 //=======================================================================
1186 //function : FindDescription
1187 //purpose  : 
1188 //=======================================================================
1189
1190 Standard_Boolean CDM_Document::FindDescription ()
1191 {
1192   LoadResources();
1193   return myDescriptionWasFound;
1194 }
1195
1196 //=======================================================================
1197 //function : Description
1198 //purpose  : 
1199 //=======================================================================
1200
1201 TCollection_ExtendedString CDM_Document::Description()
1202 {
1203   LoadResources();
1204   return myDescription;
1205 }
1206
1207 //=======================================================================
1208 //function : IsReadOnly
1209 //purpose  : 
1210 //=======================================================================
1211
1212 Standard_Boolean CDM_Document::IsReadOnly() const
1213 {
1214   if(IsStored()) return myMetaData->IsReadOnly();
1215   return Standard_False;
1216 }
1217
1218 //=======================================================================
1219 //function : IsReadOnly
1220 //purpose  : 
1221 //=======================================================================
1222
1223 Standard_Boolean CDM_Document::IsReadOnly
1224                                 (const Standard_Integer aReferenceIdentifier) const
1225 {
1226   return Reference(aReferenceIdentifier)->IsReadOnly();
1227 }
1228
1229 //=======================================================================
1230 //function : SetIsReadOnly
1231 //purpose  : 
1232 //=======================================================================
1233
1234 void CDM_Document::SetIsReadOnly()
1235 {
1236   if(IsStored()) myMetaData->SetIsReadOnly();
1237 }
1238     
1239 //=======================================================================
1240 //function : UnsetIsReadOnly
1241 //purpose  : 
1242 //=======================================================================
1243
1244 void CDM_Document::UnsetIsReadOnly()
1245 {
1246   if(IsStored()) myMetaData->UnsetIsReadOnly();
1247 }
1248
1249 //=======================================================================
1250 //function : ReferenceCounter
1251 //purpose  : 
1252 //=======================================================================
1253
1254 Standard_Integer CDM_Document::ReferenceCounter() const
1255 {
1256   return myActualReferenceIdentifier;
1257 }
1258
1259 //=======================================================================
1260 //function : SetReferenceCounter
1261 //purpose  : 
1262 //=======================================================================
1263
1264 void CDM_Document::SetReferenceCounter (const Standard_Integer aReferenceCounter)
1265 {
1266   myActualReferenceIdentifier=aReferenceCounter;
1267 }
1268
1269 //=======================================================================
1270 //function : StorageFormatVersion
1271 //purpose  : 
1272 //=======================================================================
1273 Standard_Integer CDM_Document::StorageFormatVersion() const
1274 {
1275   return myStorageFormatVersion;
1276 }
1277
1278 //! 
1279 //=======================================================================
1280 //function : ChangeStorageFormatVersion
1281 //purpose  : Sets <theVersion> of the format to be used to store the document
1282 //=======================================================================
1283 void CDM_Document::ChangeStorageFormatVersion(const Standard_Integer theVersion)
1284 {
1285   myStorageFormatVersion = theVersion;
1286 }