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