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