0031918: Application Framework - New binary format for fast reading part of OCAF...
[occt.git] / src / TDocStd / TDocStd_Application.cxx
1 // Created on: 1999-06-30
2 // Created by: Denis PASCAL
3 // Copyright (c) 1999-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 #include <TDocStd_Application.hxx>
18
19 #include <CDF_Directory.hxx>
20 #include <CDF_DirectoryIterator.hxx>
21 #include <CDF_Store.hxx>
22 #include <PCDM_RetrievalDriver.hxx>
23 #include <PCDM_StorageDriver.hxx>
24 #include <PCDM_ReaderFilter.hxx>
25 #include <Plugin.hxx>
26 #include <Plugin_Failure.hxx>
27 #include <Resource_Manager.hxx>
28 #include <Standard_DomainError.hxx>
29 #include <Standard_Dump.hxx>
30 #include <Standard_ErrorHandler.hxx>
31 #include <Standard_NoSuchObject.hxx>
32 #include <Standard_NotImplemented.hxx>
33 #include <TCollection_ExtendedString.hxx>
34 #include <TDocStd_Document.hxx>
35 #include <TDocStd_Owner.hxx>
36 #include <TDocStd_PathParser.hxx>
37 #include <OSD_Thread.hxx>
38
39 IMPLEMENT_STANDARD_RTTIEXT(TDocStd_Application,CDF_Application)
40
41 // TDocStd_Owner attribute have pointer of closed TDocStd_Document
42 //=======================================================================
43 //function : TDocStd_Application
44 //purpose  :
45 //=======================================================================
46 TDocStd_Application::TDocStd_Application()
47         : myIsDriverLoaded (Standard_True)
48 {
49   if(myMetaDataDriver.IsNull())
50     myIsDriverLoaded = Standard_False;
51 }
52
53 //=======================================================================
54 //function : IsDriverLoaded
55 //purpose  :
56 //=======================================================================
57 Standard_Boolean TDocStd_Application::IsDriverLoaded() const
58 {
59   return myIsDriverLoaded;
60 }
61
62 //=======================================================================
63 //function : Resources
64 //purpose  :
65 //=======================================================================
66
67 Handle(Resource_Manager)  TDocStd_Application::Resources()  {
68   if (myResources.IsNull()) {
69     myResources = new Resource_Manager(ResourcesName());
70   }
71   return myResources;
72 }
73
74 //=======================================================================
75 //function : ResourcesName
76 //purpose  :
77 //=======================================================================
78
79 Standard_CString TDocStd_Application::ResourcesName()
80 {
81   return "";
82 }
83
84 //=======================================================================
85 //function : DefineFormat
86 //purpose  : 
87 //=======================================================================
88 void TDocStd_Application::DefineFormat (const TCollection_AsciiString& theFormat,
89                                         const TCollection_AsciiString& theDescription,
90                                         const TCollection_AsciiString& theExtension,
91                                         const Handle(PCDM_RetrievalDriver)& theReader,
92                                         const Handle(PCDM_StorageDriver)& theWriter)
93 {
94   // register resources for CDM mechanics to work
95   Handle(Resource_Manager) aResources = Resources();
96   aResources->SetResource ((theFormat + ".Description"  ).ToCString(), theDescription.ToCString());
97   aResources->SetResource ((theFormat + ".FileExtension").ToCString(), theExtension.ToCString());
98   aResources->SetResource ((theExtension + ".FileFormat").ToCString(), theFormat.ToCString());
99
100   // set format ID in the drivers to allow them putting it in
101   // the OCAF documents opened by these drivers
102   if (!theReader.IsNull())
103     theReader->SetFormat(theFormat);
104   if (!theWriter.IsNull())
105     theWriter->SetFormat(theFormat);
106
107   // register drivers
108   myReaders.Add(theFormat, theReader);
109   myWriters.Add(theFormat, theWriter);
110 }
111
112 //=======================================================================
113 //function : ReadingFormats
114 //purpose  :
115 //=======================================================================
116
117 void TDocStd_Application::ReadingFormats(TColStd_SequenceOfAsciiString &theFormats)
118 {
119         theFormats.Clear();
120
121   NCollection_IndexedDataMap<TCollection_ExtendedString, Handle(PCDM_RetrievalDriver)>::Iterator
122     anIter(myReaders);
123   for (; anIter.More(); anIter.Next()) {
124     Handle(PCDM_RetrievalDriver) aDriver = anIter.Value();
125     if (aDriver.IsNull() == Standard_False) {
126       theFormats.Append(anIter.Key());
127     }
128   }
129 }
130
131 //=======================================================================
132 //function : WritingFormats
133 //purpose  :
134 //=======================================================================
135
136 void TDocStd_Application::WritingFormats(TColStd_SequenceOfAsciiString &theFormats)
137 {
138   theFormats.Clear();
139
140   NCollection_IndexedDataMap<TCollection_ExtendedString, Handle(PCDM_StorageDriver)>::Iterator
141     anIter(myWriters);
142   for (; anIter.More(); anIter.Next()) {
143     Handle(PCDM_StorageDriver) aDriver = anIter.Value();
144     if (aDriver.IsNull() == Standard_False) {
145       theFormats.Append(anIter.Key());
146     }
147   }
148 }
149
150 //=======================================================================
151 //function : NbDocuments
152 //purpose  :
153 //=======================================================================
154
155 Standard_Integer TDocStd_Application::NbDocuments() const
156 {
157   return myDirectory->Length();
158 }
159
160 //=======================================================================
161 //function : GetDocument
162 //purpose  :
163 //=======================================================================
164
165 void TDocStd_Application::GetDocument(const Standard_Integer index,Handle(TDocStd_Document)& theDoc) const
166 {
167   CDF_DirectoryIterator it (myDirectory);
168   Standard_Integer current = 0;
169   for (;it.MoreDocument();it.NextDocument()) {
170     current++;
171     if (index == current) {
172       Handle(TDocStd_Document) D =
173         Handle(TDocStd_Document)::DownCast(it.Document());
174       theDoc = D;
175       return;
176     }
177   }
178 }
179
180 //=======================================================================
181 //function : NewDocument
182 //purpose  :
183 //=======================================================================
184
185 void TDocStd_Application::NewDocument(const TCollection_ExtendedString& format, Handle(CDM_Document)& theDoc)
186 {
187   Handle(TDocStd_Document) D = new TDocStd_Document(format);
188   InitDocument (D);
189   CDF_Application::Open(D); // add the document in the session
190   theDoc = D;
191 }
192
193 //=======================================================================
194 //function : NewDocument
195 //purpose  : A non-virtual method taking a TDocStd_Documment object as an input.
196 //         : Internally it calls a virtual method NewDocument() with CDM_Document object.
197 //=======================================================================
198
199 void TDocStd_Application::NewDocument (const TCollection_ExtendedString& format, Handle(TDocStd_Document)& theDoc)
200 {
201   Handle(CDM_Document) aCDMDoc;
202   NewDocument (format, aCDMDoc);
203   theDoc = Handle(TDocStd_Document)::DownCast (aCDMDoc);
204 }
205
206 //=======================================================================
207 //function : InitDocument
208 //purpose  : do nothing
209 //=======================================================================
210
211 void TDocStd_Application::InitDocument(const Handle(CDM_Document)& /*aDoc*/) const
212 {
213 }
214
215 //=======================================================================
216 //function : Close
217 //purpose  :
218 //=======================================================================
219
220 void TDocStd_Application::Close(const Handle(TDocStd_Document)& theDoc)
221 {
222   if (theDoc.IsNull())
223   {
224     return;
225   }
226
227   Handle(TDocStd_Owner) Owner;
228   if (theDoc->Main().Root().FindAttribute(TDocStd_Owner::GetID(),Owner)) {
229     Handle(TDocStd_Document) emptyDoc;
230     Owner->SetDocument(emptyDoc);
231   }
232   theDoc->BeforeClose();
233   CDF_Application::Close(theDoc);
234 }
235
236 //=======================================================================
237 //function : IsInSession
238 //purpose  :
239 //=======================================================================
240
241 Standard_Integer TDocStd_Application::IsInSession (const TCollection_ExtendedString& path) const
242 {
243     TCollection_ExtendedString unifiedPath(path);
244     unifiedPath.ChangeAll('/', '|');
245     unifiedPath.ChangeAll('\\', '|');
246
247     Standard_Integer nbdoc = NbDocuments();
248     Handle(TDocStd_Document) D;
249     for (Standard_Integer i = 1; i <= nbdoc; i++) 
250     {
251         GetDocument(i,D);
252         if (D->IsSaved()) 
253         {
254             TCollection_ExtendedString unifiedDocPath(D->GetPath());
255             unifiedDocPath.ChangeAll('/', '|');
256             unifiedDocPath.ChangeAll('\\', '|');
257
258             if (unifiedPath == unifiedDocPath) 
259                 return i;
260         }
261     }
262     return 0;
263 }
264
265 //=======================================================================
266 //function : Open
267 //purpose  :
268 //=======================================================================
269
270 PCDM_ReaderStatus TDocStd_Application::Open (const TCollection_ExtendedString& path, 
271                                              Handle(TDocStd_Document)& theDoc,
272                                              const Handle(PCDM_ReaderFilter)& theFilter,
273                                              const Message_ProgressRange& theRange)
274 {
275   PCDM_ReaderStatus status = PCDM_RS_DriverFailure;
276   TDocStd_PathParser tool (path);
277   TCollection_ExtendedString directory = tool.Trek();
278   TCollection_ExtendedString file = tool.Name();
279   file += ".";
280   file += tool.Extension();
281   status = CanRetrieve(directory, file, !theFilter.IsNull() && theFilter->IsAppendMode());
282
283   if (status != PCDM_RS_OK)
284   {
285     return status;
286   }
287
288   try
289   {
290     OCC_CATCH_SIGNALS
291     Handle(TDocStd_Document) D =
292       Handle(TDocStd_Document)::DownCast(Retrieve(directory, file, Standard_True, theFilter, theRange));
293     if (theFilter.IsNull() || !theFilter->IsAppendMode())
294       CDF_Application::Open(D);
295     theDoc = D;
296   }
297   catch (Standard_Failure const& anException)
298   {
299     //    status = GetRetrieveStatus();
300     if (!MessageDriver().IsNull())
301     {
302       //      Standard_SStream aMsg;
303       //      aMsg << Standard_Failure::Caught() << std::endl;
304       //      std::cout << "TDocStd_Application::Open(): " << aMsg.rdbuf()->str() << std::endl;
305       TCollection_ExtendedString aString (anException.GetMessageString());
306       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
307     }
308   }
309   status = GetRetrieveStatus();
310 #ifdef OCCT_DEBUG
311   std::cout << "TDocStd_Application::Open(): The status = " << status << std::endl;
312 #endif
313   return status;
314 }
315
316 //=======================================================================
317 //function : Open
318 //purpose  :
319 //=======================================================================
320 PCDM_ReaderStatus TDocStd_Application::Open (Standard_IStream& theIStream,
321                                              Handle(TDocStd_Document)& theDoc,
322                                              const Handle(PCDM_ReaderFilter)& theFilter,
323                                              const Message_ProgressRange& theRange)
324
325   try
326   {
327     OCC_CATCH_SIGNALS
328     Handle(CDM_Document) aCDMDoc = theDoc;
329     Read(theIStream, aCDMDoc, theFilter, theRange);
330     // Read calls NewDocument of TDocStd_Application, so, it should the TDocStd_Document in the result anyway
331     theDoc = Handle(TDocStd_Document)::DownCast(aCDMDoc);
332
333     if (!theDoc.IsNull() && (theFilter.IsNull() || !theFilter->IsAppendMode()))
334     {
335       CDF_Application::Open(theDoc);
336     }
337   }
338
339   catch (Standard_Failure const& anException)
340   {
341     if (!MessageDriver().IsNull())
342     {
343       TCollection_ExtendedString aFailureMessage (anException.GetMessageString());
344       MessageDriver()->Send (aFailureMessage.ToExtString(), Message_Fail);
345     }
346   }
347   return GetRetrieveStatus();
348 }
349
350 //=======================================================================
351 //function : SaveAs
352 //purpose  :
353 //=======================================================================
354
355 PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& theDoc,
356                                               const TCollection_ExtendedString& path,
357                                               const Message_ProgressRange& theRange)
358 {
359   TDocStd_PathParser tool (path);
360   TCollection_ExtendedString directory = tool.Trek();
361   TCollection_ExtendedString file = tool.Name();
362   file+=".";
363   file+=tool.Extension();
364   theDoc->Open(this);
365   CDF_Store storer (theDoc);
366   if (!storer.SetFolder(directory))
367   {
368     TCollection_ExtendedString aMsg ("TDocStd_Application::SaveAs() - folder ");
369     aMsg += directory;
370     aMsg += " does not exist";
371     if(!MessageDriver().IsNull())
372       MessageDriver()->Send(aMsg.ToExtString(), Message_Fail);
373     return storer.StoreStatus(); //CDF_SS_Failure;
374   }
375   storer.SetName (file);
376   try {
377     OCC_CATCH_SIGNALS
378     storer.Realize (theRange);
379   }
380   catch (Standard_Failure const& anException) {
381     if (!MessageDriver().IsNull()) {
382       TCollection_ExtendedString aString (anException.GetMessageString());
383       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
384     }
385   }
386   if(storer.StoreStatus() == PCDM_SS_OK)
387     theDoc->SetSaved();
388 #ifdef OCCT_DEBUG
389   std::cout<<"TDocStd_Application::SaveAs(): The status = "<<storer.StoreStatus()<<std::endl;
390 #endif
391   return storer.StoreStatus();
392 }
393
394 //=======================================================================
395 //function : SaveAs
396 //purpose  :
397 //=======================================================================
398 PCDM_StoreStatus TDocStd_Application::SaveAs(const Handle(TDocStd_Document)& theDoc, 
399                                              Standard_OStream& theOStream,
400                                              const Message_ProgressRange& theRange)
401 {
402   try
403   {
404     Handle(PCDM_StorageDriver) aDocStorageDriver = WriterFromFormat(theDoc->StorageFormat());
405
406     if (aDocStorageDriver.IsNull())
407     {
408       return PCDM_SS_DriverFailure;
409     }
410
411     aDocStorageDriver->SetFormat(theDoc->StorageFormat());
412     aDocStorageDriver->Write(theDoc, theOStream, theRange);
413
414     if (aDocStorageDriver->GetStoreStatus() == PCDM_SS_OK)
415     {
416       theDoc->SetSaved();
417     }
418
419     return aDocStorageDriver->GetStoreStatus();
420   }
421   catch (Standard_Failure const& anException)
422   {
423     if (!MessageDriver().IsNull())
424     {
425       TCollection_ExtendedString aString(anException.GetMessageString());
426       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
427     }
428   }
429   return PCDM_SS_Failure;
430 }
431
432 //=======================================================================
433 //function : Save
434 //purpose  :
435 //=======================================================================
436
437 PCDM_StoreStatus TDocStd_Application::Save (const Handle(TDocStd_Document)& D,
438                                             const Message_ProgressRange&    theRange)
439 {
440   PCDM_StoreStatus status = PCDM_SS_OK;
441   if (D->IsSaved()) {
442     CDF_Store storer (D);
443     try{
444       OCC_CATCH_SIGNALS
445       storer.Realize (theRange);
446     }
447     catch (Standard_Failure const& anException) {
448       if (!MessageDriver().IsNull()) {
449         TCollection_ExtendedString aString (anException.GetMessageString());
450         MessageDriver()->Send(aString.ToExtString(), Message_Fail);
451       }
452     }
453     if(storer.StoreStatus() == PCDM_SS_OK)
454       D->SetSaved();
455     status = storer.StoreStatus();
456   } else {
457     if(!MessageDriver().IsNull()) {
458       TCollection_ExtendedString aMsg("Document has not been saved yet");
459       MessageDriver()->Send(aMsg.ToExtString(), Message_Fail);
460     }
461     status = PCDM_SS_Failure;
462   }
463 #ifdef OCCT_DEBUG
464   std::cout<<"TDocStd_Application::Save(): The status = "<<status<<std::endl;
465 #endif
466   return status;
467 }
468
469 //=======================================================================
470 //function : SaveAs
471 //purpose  : 
472 //=======================================================================
473
474 PCDM_StoreStatus TDocStd_Application::SaveAs(const Handle(TDocStd_Document)& D,
475                                              const TCollection_ExtendedString& path,
476                                              TCollection_ExtendedString& theStatusMessage,
477                                              const Message_ProgressRange& theRange)
478
479   TDocStd_PathParser tool (path);
480   PCDM_StoreStatus aStatus = PCDM_SS_Failure;
481   TCollection_ExtendedString directory = tool.Trek();   
482   TCollection_ExtendedString file = tool.Name();   
483   file+=".";   
484   file+=tool.Extension();
485   D->Open(this);
486   CDF_Store storer (D);  
487   if (storer.SetFolder(directory)) {
488     storer.SetName (file);
489     try {
490       OCC_CATCH_SIGNALS
491       storer.Realize (theRange);
492     }
493     catch (Standard_Failure const& anException) {
494       if (!MessageDriver().IsNull()) {
495         TCollection_ExtendedString aString (anException.GetMessageString());
496         MessageDriver()->Send(aString.ToExtString(), Message_Fail);
497       }
498     }
499     if(storer.StoreStatus() == PCDM_SS_OK)
500       D->SetSaved();
501     theStatusMessage = storer.AssociatedStatusText();
502     aStatus = storer.StoreStatus();
503   } else {
504     theStatusMessage =
505       TCollection_ExtendedString("TDocStd_Application::SaveAs"
506                                  ": No such directory ") + directory;
507     aStatus = PCDM_SS_Failure;
508   }
509   return aStatus;
510 }
511
512 //=======================================================================
513 //function : SaveAs
514 //purpose  : 
515 //=======================================================================
516
517 PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& theDoc,
518                                               Standard_OStream&               theOStream,
519                                               TCollection_ExtendedString&     theStatusMessage,
520                                               const Message_ProgressRange&    theRange)
521
522   try
523   {
524     Handle(PCDM_StorageDriver) aDocStorageDriver = WriterFromFormat (theDoc->StorageFormat());
525     if (aDocStorageDriver.IsNull())
526     {
527       theStatusMessage = TCollection_ExtendedString("TDocStd_Application::SaveAs: no storage driver");
528       return PCDM_SS_DriverFailure;
529     }
530
531     aDocStorageDriver->SetFormat(theDoc->StorageFormat());
532     aDocStorageDriver->Write(theDoc, theOStream, theRange);
533         
534     if (aDocStorageDriver->GetStoreStatus() == PCDM_SS_OK)
535     {
536       theDoc->SetSaved();
537     }
538
539     return aDocStorageDriver->GetStoreStatus();
540   }
541   catch (Standard_Failure const& anException)
542   {
543     if (!MessageDriver().IsNull())
544     {
545       TCollection_ExtendedString aString(anException.GetMessageString());
546       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
547     }
548   }
549   return PCDM_SS_Failure;
550 }
551
552 //=======================================================================
553 //function : Save
554 //purpose  : 
555 //=======================================================================
556
557 PCDM_StoreStatus TDocStd_Application::Save (const Handle(TDocStd_Document)& D,
558                                             TCollection_ExtendedString&     theStatusMessage, 
559                                             const Message_ProgressRange&    theRange)
560 {  
561   PCDM_StoreStatus status = PCDM_SS_OK;
562   if (D->IsSaved()) {  
563     CDF_Store storer (D);  
564     try {
565       OCC_CATCH_SIGNALS
566       storer.Realize (theRange);
567     }
568     catch (Standard_Failure const& anException) {
569       if (!MessageDriver().IsNull()) {
570         TCollection_ExtendedString aString (anException.GetMessageString());
571         MessageDriver()->Send(aString.ToExtString(), Message_Fail);
572       }
573     }
574     if(storer.StoreStatus() == PCDM_SS_OK)
575       D->SetSaved();
576     status = storer.StoreStatus();
577     theStatusMessage = storer.AssociatedStatusText();
578   } else {
579     theStatusMessage = "TDocStd_Application::the document has not been saved yet";
580     status = PCDM_SS_Failure;
581   }
582   return status;
583 }
584
585
586 //=======================================================================
587 //function : OnOpenTransaction
588 //purpose  : 
589 //=======================================================================
590
591 void TDocStd_Application::OnOpenTransaction (const Handle(TDocStd_Document)&)
592 {
593   // nothing to do on this level
594 }
595
596 //=======================================================================
597 //function : OnAbortTransaction
598 //purpose  : 
599 //=======================================================================
600
601 void TDocStd_Application::OnAbortTransaction (const Handle(TDocStd_Document)&)
602 {
603   // nothing to do on this level
604 }
605
606 //=======================================================================
607 //function : OnCommitTransaction
608 //purpose  : 
609 //=======================================================================
610
611 void TDocStd_Application::OnCommitTransaction (const Handle(TDocStd_Document)&)
612 {
613   // nothing to do on this level
614 }
615
616 //=======================================================================
617 //function : DumpJson
618 //purpose  : 
619 //=======================================================================
620 void TDocStd_Application::DumpJson (Standard_OStream& theOStream, Standard_Integer) const
621 {
622   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
623
624   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsDriverLoaded)
625 }