0031353: TDocStd_Application does not have api to set progress indicator
[occt.git] / src / CDF / CDF_Application.cxx
1 // Created on: 1997-08-08
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, Wed Jan 14 08:17:35 1998
18
19 #include <CDF_Application.hxx>
20 #include <CDF_Directory.hxx>
21 #include <CDF_MetaDataDriver.hxx>
22 #include <CDF_Session.hxx>
23 #include <CDM_CanCloseStatus.hxx>
24 #include <CDM_Document.hxx>
25 #include <CDM_MetaData.hxx>
26 #include <PCDM_Reader.hxx>
27 #include <PCDM_ReadWriter.hxx>
28 #include <PCDM_RetrievalDriver.hxx>
29 #include <PCDM_StorageDriver.hxx>
30 #include <Plugin.hxx>
31 #include <Standard_ErrorHandler.hxx>
32 #include <Standard_GUID.hxx>
33 #include <Standard_NoSuchObject.hxx>
34 #include <Standard_ProgramError.hxx>
35 #include <UTL.hxx>
36 #include <Message_ProgressSentry.hxx>
37
38 IMPLEMENT_STANDARD_RTTIEXT(CDF_Application,CDM_Application)
39
40 #define theMetaDataDriver CDF_Session::CurrentSession()->MetaDataDriver()
41
42
43 //=======================================================================
44 //function : 
45 //purpose  : 
46 //=======================================================================
47 CDF_Application::CDF_Application():myRetrievableStatus(PCDM_RS_OK) {}
48
49 //=======================================================================
50 //function : Load
51 //purpose  : 
52 //=======================================================================
53 Handle(CDF_Application) CDF_Application::Load(const Standard_GUID& aGUID) {
54   return Handle(CDF_Application)::DownCast(Plugin::Load(aGUID));
55 }
56
57 //=======================================================================
58 //function : Open
59 //purpose  : 
60 //=======================================================================
61 void CDF_Application::Open(const Handle(CDM_Document)& aDocument) {
62   CDF_Session::CurrentSession()->Directory()->Add(aDocument);
63   aDocument->Open(this);
64   Activate(aDocument,CDF_TOA_New);
65 }
66
67 //=======================================================================
68 //function : CanClose
69 //purpose  : 
70 //=======================================================================
71 CDM_CanCloseStatus CDF_Application::CanClose(const Handle(CDM_Document)& aDocument) {
72   return aDocument->CanClose();
73 }
74
75 //=======================================================================
76 //function : Close
77 //purpose  : 
78 //=======================================================================
79 void CDF_Application::Close(const Handle(CDM_Document)& aDocument) {
80   CDF_Session::CurrentSession()->Directory()->Remove(aDocument);
81   aDocument->Close();
82 }
83
84 //=======================================================================
85 //function : Retrieve
86 //purpose  : 
87 //=======================================================================
88 Handle(CDM_Document) CDF_Application::Retrieve (const TCollection_ExtendedString& aFolder, 
89                                                 const TCollection_ExtendedString& aName,
90                                                 const Standard_Boolean UseStorageConfiguration,
91                                                 const Handle(Message_ProgressIndicator)& theProgress)
92 {
93   TCollection_ExtendedString nullVersion;
94   return Retrieve(aFolder, aName, nullVersion, UseStorageConfiguration, theProgress);
95 }
96
97 //=======================================================================
98 //function : Retrieve
99 //purpose  : 
100 //=======================================================================
101 Handle(CDM_Document)  CDF_Application::Retrieve (const TCollection_ExtendedString& aFolder, 
102                                                 const TCollection_ExtendedString& aName,
103                                                 const TCollection_ExtendedString& aVersion,
104                                                 const Standard_Boolean UseStorageConfiguration,
105                                                 const Handle(Message_ProgressIndicator)& theProgress)
106 {
107   Handle(CDM_MetaData) theMetaData; 
108   
109   if(aVersion.Length() == 0) 
110     theMetaData=theMetaDataDriver->MetaData(aFolder,aName);
111   else 
112     theMetaData=theMetaDataDriver->MetaData(aFolder,aName,aVersion);
113
114   CDF_TypeOfActivation theTypeOfActivation=TypeOfActivation(theMetaData);
115   Handle(CDM_Document) theDocument = Retrieve(theMetaData, UseStorageConfiguration,
116                                               Standard_False, theProgress);
117
118   CDF_Session::CurrentSession()->Directory()->Add(theDocument);
119   Activate(theDocument,theTypeOfActivation);
120
121   theDocument->Open(this);
122   return theDocument;
123 }
124
125 //=======================================================================
126 //function : CanRetrieve
127 //purpose  : 
128 //=======================================================================
129 PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& aFolder, const TCollection_ExtendedString&  aName) {
130  TCollection_ExtendedString aVersion;
131  return CanRetrieve(aFolder,aName,aVersion);
132 }
133
134 //=======================================================================
135 //function : CanRetrieve
136 //purpose  : 
137 //=======================================================================
138 PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString&  aFolder, const TCollection_ExtendedString&  aName, const TCollection_ExtendedString&  aVersion) {
139   
140   if (!theMetaDataDriver->Find(aFolder,aName,aVersion))
141     return PCDM_RS_UnknownDocument;
142   else if (!theMetaDataDriver->HasReadPermission(aFolder,aName,aVersion))
143     return PCDM_RS_PermissionDenied;
144   else {
145     Handle(CDM_MetaData) theMetaData = theMetaDataDriver->MetaData(aFolder,aName,aVersion);
146
147     if(theMetaData->IsRetrieved()) {
148       return theMetaData->Document()->IsModified()
149         ? PCDM_RS_AlreadyRetrievedAndModified : PCDM_RS_AlreadyRetrieved;
150     }
151     else {
152       TCollection_ExtendedString theFileName=theMetaData->FileName();
153       TCollection_ExtendedString theFormat=PCDM_ReadWriter::FileFormat(theFileName);
154       if(theFormat.Length()==0) {
155         TCollection_ExtendedString ResourceName=UTL::Extension(theFileName);
156         ResourceName+=".FileFormat";
157         if(UTL::Find(Resources(),ResourceName))  {
158           theFormat=UTL::Value(Resources(),ResourceName);
159         }
160         else
161           return PCDM_RS_UnrecognizedFileFormat;
162       }
163
164       // check actual availability of the driver
165       try {
166         Handle(PCDM_Reader) aReader = ReaderFromFormat(theFormat);
167         if (aReader.IsNull())
168           return PCDM_RS_NoDriver;
169       }
170       catch (Standard_Failure const&)
171       {
172         // no need to report error, this was just check for availability
173       }
174     }
175   }
176   return PCDM_RS_OK;
177 }
178
179 //=======================================================================
180 //function : Activate
181 //purpose  : 
182 //=======================================================================
183 //void CDF_Application::Activate(const Handle(CDM_Document)& aDocument,const CDF_TypeOfActivation aTypeOfActivation) {
184 void CDF_Application::Activate(const Handle(CDM_Document)& ,const CDF_TypeOfActivation ) {
185 }
186
187 //=======================================================================
188 //function : DefaultFolder
189 //purpose  : 
190 //=======================================================================
191 Standard_ExtString CDF_Application::DefaultFolder(){
192   if(myDefaultFolder.Length() == 0) {
193     myDefaultFolder=CDF_Session::CurrentSession()->MetaDataDriver()->DefaultFolder();
194   }
195   return myDefaultFolder.ToExtString();
196 }
197
198 //=======================================================================
199 //function : SetDefaultFolder
200 //purpose  : 
201 //=======================================================================
202 Standard_Boolean CDF_Application::SetDefaultFolder(const Standard_ExtString aFolder) {
203   Standard_Boolean found = CDF_Session::CurrentSession()->MetaDataDriver()->FindFolder(aFolder);
204   if(found) myDefaultFolder=aFolder;
205   return found;
206 }
207
208 //=======================================================================
209 //function : Retrieve
210 //purpose  : 
211 //=======================================================================
212 Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMetaData,
213                                                const Standard_Boolean UseStorageConfiguration, 
214                                                const Handle(Message_ProgressIndicator)& theProgress) {
215   return Retrieve(aMetaData, UseStorageConfiguration, Standard_True, theProgress);
216
217
218 //=======================================================================
219 //function : Retrieve
220 //purpose  : 
221 //=======================================================================
222 Handle(CDM_Document) CDF_Application::Retrieve (const Handle(CDM_MetaData)& aMetaData, 
223                                                 const Standard_Boolean UseStorageConfiguration, 
224                                                 const Standard_Boolean IsComponent, 
225                                                 const Handle(Message_ProgressIndicator)& theProgress) {
226   
227   Handle(CDM_Document) theDocumentToReturn;
228   myRetrievableStatus = PCDM_RS_DriverFailure;
229   if(IsComponent) {
230     Standard_SStream aMsg;
231     switch (CanRetrieve(aMetaData)) {
232     case PCDM_RS_UnknownDocument: 
233       aMsg << "could not find the referenced document: " << aMetaData->Path() << "; not found."  <<(char)0 << std::endl;
234       myRetrievableStatus = PCDM_RS_UnknownDocument;
235       throw Standard_Failure(aMsg.str().c_str());
236       break;
237     case PCDM_RS_PermissionDenied:      
238       aMsg << "Could not find the referenced document: " << aMetaData->Path() << "; permission denied. " <<(char)0 << std::endl;
239       myRetrievableStatus = PCDM_RS_PermissionDenied;
240       throw Standard_Failure(aMsg.str().c_str());
241       break;
242     default:
243       break;
244     }
245     
246   }
247   Standard_Boolean AlreadyRetrieved=aMetaData->IsRetrieved();
248   if(AlreadyRetrieved) myRetrievableStatus = PCDM_RS_AlreadyRetrieved;
249   Standard_Boolean Modified=AlreadyRetrieved && aMetaData->Document()->IsModified();
250   if(Modified) myRetrievableStatus = PCDM_RS_AlreadyRetrievedAndModified;
251   if(!AlreadyRetrieved || Modified)
252   {
253     TCollection_ExtendedString aFormat;
254     if (!Format(aMetaData->FileName(), aFormat))
255     {
256       Standard_SStream aMsg;
257       aMsg << "Could not determine format for the file " << aMetaData->FileName() << (char)0;
258       throw Standard_NoSuchObject(aMsg.str().c_str());
259     }
260     Handle(PCDM_Reader) theReader = ReaderFromFormat (aFormat);
261         
262     Handle(CDM_Document) theDocument;
263
264     if(Modified)  {
265       theDocument=aMetaData->Document();
266       theDocument->RemoveAllReferences();
267     }
268     else
269       theDocument=theReader->CreateDocument();
270     
271     SetReferenceCounter(theDocument,PCDM_RetrievalDriver::ReferenceCounter(aMetaData->FileName(), MessageDriver()));
272     
273     SetDocumentVersion(theDocument,aMetaData);
274     theMetaDataDriver->ReferenceIterator()->LoadReferences(theDocument,aMetaData,this,UseStorageConfiguration);
275
276     try {    
277       OCC_CATCH_SIGNALS
278       theReader->Read (aMetaData->FileName(), theDocument, this, theProgress);
279     } 
280     catch (Standard_Failure const& anException) {
281       myRetrievableStatus = theReader->GetStatus();
282       if(myRetrievableStatus  > PCDM_RS_AlreadyRetrieved){
283         Standard_SStream aMsg;
284         aMsg << anException << std::endl;
285         throw Standard_Failure(aMsg.str().c_str());
286       } 
287     }
288     myRetrievableStatus = theReader->GetStatus();    
289     theDocument->SetMetaData(aMetaData);
290
291     theDocumentToReturn=theDocument;
292   }
293   else
294     theDocumentToReturn=aMetaData->Document();
295   
296   return theDocumentToReturn;
297 }
298
299 //=======================================================================
300 //function : DocumentVersion
301 //purpose  : 
302 //=======================================================================
303 Standard_Integer CDF_Application::DocumentVersion(const Handle(CDM_MetaData)& theMetaData) {
304 //  const Handle(CDM_MessageDriver)& aMsgDriver = MessageDriver();
305   return PCDM_RetrievalDriver::DocumentVersion(theMetaData->FileName(), MessageDriver());
306 }
307
308 //=======================================================================
309 //function : TypeOfActivation
310 //purpose  : 
311 //=======================================================================
312 CDF_TypeOfActivation CDF_Application::TypeOfActivation(const Handle(CDM_MetaData)& aMetaData) {
313
314   if(aMetaData->IsRetrieved()) {
315     Handle(CDM_Document) theDocument=aMetaData->Document();
316     if(theDocument->IsOpened()) {
317       if(theDocument->IsModified())
318         return CDF_TOA_Modified;
319       else
320         return CDF_TOA_Unchanged;
321     }
322     
323     else
324       return CDF_TOA_New;
325   }
326   return CDF_TOA_New;
327 }
328
329 //=======================================================================
330 //function : Read
331 //purpose  : 
332 //=======================================================================
333 Handle(CDM_Document) CDF_Application::Read (Standard_IStream& theIStream,
334                                             const Handle(Message_ProgressIndicator)& theProgress)
335 {
336   Handle(CDM_Document) aDoc;
337   Handle(Storage_Data) dData;
338   
339   TCollection_ExtendedString aFormat;
340
341   try
342   {
343     OCC_CATCH_SIGNALS
344     
345     aFormat = PCDM_ReadWriter::FileFormat (theIStream, dData);
346   }
347   catch (Standard_Failure const& anException)
348   {
349     myRetrievableStatus = PCDM_RS_FormatFailure;
350     
351     Standard_SStream aMsg;
352     aMsg << anException << std::endl;
353     throw Standard_Failure(aMsg.str().c_str());
354   }
355
356   if (aFormat.IsEmpty())
357   {
358     myRetrievableStatus = PCDM_RS_FormatFailure;
359     return aDoc;
360   }
361  
362   // 1. use a format name to detect plugin corresponding to the format to continue reading
363   Handle(PCDM_Reader) aReader = ReaderFromFormat (aFormat);
364
365   // 2. create document with the detected reader
366   aDoc = aReader->CreateDocument();
367
368   // 3. read the content of theIStream to aDoc
369   try
370   {
371     OCC_CATCH_SIGNALS
372     aReader->Read (theIStream, dData, aDoc, this, theProgress);
373   }
374   catch (Standard_Failure const& anException)
375   {
376     myRetrievableStatus = aReader->GetStatus();
377     if (myRetrievableStatus  > PCDM_RS_AlreadyRetrieved)
378     {
379       Standard_SStream aMsg;
380       aMsg << anException << std::endl;
381       throw Standard_Failure(aMsg.str().c_str());
382     }   
383   }
384
385   myRetrievableStatus = aReader->GetStatus();
386
387   return aDoc;
388 }
389
390 //=======================================================================
391 //function : ReaderFromFormat
392 //purpose  : 
393 //=======================================================================
394 Handle(PCDM_Reader) CDF_Application::ReaderFromFormat(const TCollection_ExtendedString& theFormat)
395 {
396   // check map of readers
397   Handle(PCDM_RetrievalDriver) aReader;
398   if (myReaders.FindFromKey (theFormat, aReader))
399     return aReader;
400
401   // support of legacy method of loading reader as plugin
402   TCollection_ExtendedString aResourceName = theFormat;
403   aResourceName += ".RetrievalPlugin";
404   if (!UTL::Find(Resources(), aResourceName))
405   {
406     Standard_SStream aMsg; 
407     aMsg << "Could not found the item:" << aResourceName <<(char)0;
408     myRetrievableStatus = PCDM_RS_WrongResource;
409     throw Standard_NoSuchObject(aMsg.str().c_str());
410   }
411
412   // Get GUID as a string.
413   TCollection_ExtendedString strPluginId = UTL::Value(Resources(), aResourceName);
414     
415   // If the GUID (as a string) contains blanks, remove them.
416   if (strPluginId.Search(' ') != -1)
417     strPluginId.RemoveAll(' ');
418     
419   // Convert to GUID.
420   Standard_GUID aPluginId = UTL::GUID(strPluginId);
421
422   try {
423     OCC_CATCH_SIGNALS
424     aReader = Handle(PCDM_RetrievalDriver)::DownCast(Plugin::Load(aPluginId));  
425   } 
426   catch (Standard_Failure const& anException)
427   {
428     myRetrievableStatus = PCDM_RS_WrongResource;
429     throw anException;
430   }     
431   if (!aReader.IsNull()) {
432     aReader->SetFormat(theFormat);
433   }
434   else
435   {
436     myRetrievableStatus = PCDM_RS_WrongResource;
437   }
438
439   // record in map
440   myReaders.Add(theFormat, aReader);
441   return aReader;
442 }
443
444 //=======================================================================
445 //function : WriterFromFormat
446 //purpose  : 
447 //=======================================================================
448 Handle(PCDM_StorageDriver) CDF_Application::WriterFromFormat(const TCollection_ExtendedString& theFormat)
449 {  
450   // check map of writers
451   Handle(PCDM_StorageDriver) aDriver;
452   if (myWriters.FindFromKey(theFormat, aDriver))
453     return aDriver;
454
455   // support of legacy method of loading reader as plugin
456   TCollection_ExtendedString aResourceName = theFormat;
457   aResourceName += ".StoragePlugin";  
458   if(!UTL::Find(Resources(), aResourceName))
459   {
460     myWriters.Add(theFormat, aDriver);
461     Standard_SStream aMsg; 
462     aMsg << "Could not found the resource definition:" << aResourceName <<(char)0;
463     throw Standard_NoSuchObject(aMsg.str().c_str());
464   }
465
466   // Get GUID as a string.
467   TCollection_ExtendedString strPluginId = UTL::Value(Resources(), aResourceName);
468     
469   // If the GUID (as a string) contains blanks, remove them.
470   if (strPluginId.Search(' ') != -1)
471     strPluginId.RemoveAll(' ');
472     
473   // Convert to GUID.
474   Standard_GUID aPluginId = UTL::GUID(strPluginId);
475
476   try {
477     OCC_CATCH_SIGNALS
478     aDriver = Handle(PCDM_StorageDriver)::DownCast(Plugin::Load(aPluginId));
479   } 
480   catch (Standard_Failure const& anException)
481   {
482     myWriters.Add(theFormat, aDriver);
483     myRetrievableStatus = PCDM_RS_WrongResource;
484     throw anException;
485   }     
486   if (aDriver.IsNull()) 
487   {
488     myRetrievableStatus = PCDM_RS_WrongResource;
489   }
490   else
491   {
492     aDriver->SetFormat(theFormat);
493   }
494
495   // record in map
496   myWriters.Add(theFormat, aDriver);
497   return aDriver;
498 }
499
500 //=======================================================================
501 //function : Format
502 //purpose  : dp 
503 //=======================================================================
504 Standard_Boolean CDF_Application::Format(const TCollection_ExtendedString& aFileName, 
505                                          TCollection_ExtendedString& theFormat)
506 {
507   
508   theFormat = PCDM_ReadWriter::FileFormat(aFileName);
509 // It is good if the format is in the file. Otherwise base on the extension.
510   if(theFormat.Length()==0) {
511     TCollection_ExtendedString ResourceName;
512     ResourceName=UTL::Extension(aFileName);
513     ResourceName+=".FileFormat";
514     
515     if(UTL::Find(Resources(),ResourceName))  {
516       theFormat = UTL::Value(Resources(),ResourceName);
517     }
518     else return Standard_False;
519   }
520   return Standard_True;
521 }
522
523 //=======================================================================
524 //function : CanRetrieve
525 //purpose  : 
526 //=======================================================================
527 PCDM_ReaderStatus CDF_Application::CanRetrieve(const Handle(CDM_MetaData)& aMetaData) {
528   if(aMetaData->HasVersion())
529     return CanRetrieve(aMetaData->Folder(),aMetaData->Name(),aMetaData->Version());
530   else
531     return CanRetrieve(aMetaData->Folder(),aMetaData->Name());
532 }