9554798b5bf8e23ca4d74431c587ee513cac9dc4
[occt.git] / src / CDF / CDF_Application.cxx
1 // File:        CDF_Application.cxx
2 // Created:     Fri Aug  8 07:49:46 1997
3 // Author:      Jean-Louis Frenkel
4 //              <rmi@frilox.paris1.matra-dtv.fr>
5 // Modified by rmi, Wed Jan 14 08:17:35 1998
6
7
8 #include <CDF_Application.ixx>
9 #include <Standard_ErrorHandler.hxx>
10 #include <TCollection_ExtendedString.hxx>
11 #include <Standard_ProgramError.hxx>
12 #include <Standard_GUID.hxx>
13 #include <CDM_MetaData.hxx>
14 #include <CDM_CanCloseStatus.hxx>
15 #include <CDF_Session.hxx>
16 #include <CDF_Directory.hxx>
17 #include <CDF_MetaDataDriver.hxx>
18 #include <CDF_RetrievableStatus.hxx>
19 #include <PCDM_ReadWriter.hxx>
20 #include <PCDM_RetrievalDriver.hxx>
21 #include <PCDM_StorageDriver.hxx>
22 #include <PCDM_ReaderStatus.hxx>
23
24 #include <Plugin.hxx>
25 #include <UTL.hxx>
26
27 #include <CDF_Timer.hxx>
28
29 #define theMetaDataDriver CDF_Session::CurrentSession()->MetaDataDriver()
30
31
32 //=======================================================================
33 //function : 
34 //purpose  : 
35 //=======================================================================
36 CDF_Application::CDF_Application():myRetrievableStatus(CDF_RS_OK) {}
37
38 //=======================================================================
39 //function : Load
40 //purpose  : 
41 //=======================================================================
42 Handle(CDF_Application) CDF_Application::Load(const Standard_GUID& aGUID) {
43   return Handle(CDF_Application)::DownCast(Plugin::Load(aGUID));
44 }
45
46 //=======================================================================
47 //function : Open
48 //purpose  : 
49 //=======================================================================
50 void CDF_Application::Open(const Handle(CDM_Document)& aDocument) {
51   CDF_Session::CurrentSession()->Directory()->Add(aDocument);
52   aDocument->Open(this);
53   Activate(aDocument,CDF_TOA_New);
54 }
55
56 //=======================================================================
57 //function : CanClose
58 //purpose  : 
59 //=======================================================================
60 CDM_CanCloseStatus CDF_Application::CanClose(const Handle(CDM_Document)& aDocument) {
61   return aDocument->CanClose();
62 }
63
64 //=======================================================================
65 //function : Close
66 //purpose  : 
67 //=======================================================================
68 void CDF_Application::Close(const Handle(CDM_Document)& aDocument) {
69   CDF_Session::CurrentSession()->Directory()->Remove(aDocument);
70   aDocument->Close();
71 }
72
73 //=======================================================================
74 //function : Retrieve
75 //purpose  : 
76 //=======================================================================
77 Handle(CDM_Document) CDF_Application::Retrieve(const TCollection_ExtendedString& aFolder, 
78                                      const TCollection_ExtendedString& aName, 
79                                      const Standard_Boolean UseStorageConfiguration) {
80   TCollection_ExtendedString nullVersion;
81   return Retrieve(aFolder,aName,nullVersion,UseStorageConfiguration);
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 TCollection_ExtendedString& aVersion,
91                                      const Standard_Boolean UseStorageConfiguration) {
92 #ifdef DEB
93   CDF_Timer theTimer;
94 #endif
95
96   Handle(CDM_MetaData) theMetaData; 
97   
98   if(aVersion.Length() == 0) 
99     theMetaData=theMetaDataDriver->MetaData(aFolder,aName);
100   else 
101     theMetaData=theMetaDataDriver->MetaData(aFolder,aName,aVersion);
102
103 #ifdef DEB  
104   theTimer.ShowAndRestart("Getting MetaData: ");
105 #endif
106
107   CDF_TypeOfActivation theTypeOfActivation=TypeOfActivation(theMetaData);
108   Handle(CDM_Document) theDocument=Retrieve(theMetaData,UseStorageConfiguration,Standard_False);
109
110 #ifdef DEB
111   theTimer.ShowAndRestart("Creating Transient: ");
112 #endif
113
114   CDF_Session::CurrentSession()->Directory()->Add(theDocument);
115   Activate(theDocument,theTypeOfActivation);
116
117 #ifdef DEB
118   theTimer.ShowAndStop("Activate: ");
119 #endif
120
121   theDocument->Open(this);
122   return theDocument;
123
124
125 }
126
127 //=======================================================================
128 //function : CanRetrieve
129 //purpose  : 
130 //=======================================================================
131 CDF_RetrievableStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& aFolder, const TCollection_ExtendedString&  aName) {
132  TCollection_ExtendedString aVersion;
133  return CanRetrieve(aFolder,aName,aVersion);
134 }
135
136 //=======================================================================
137 //function : CanRetrieve
138 //purpose  : 
139 //=======================================================================
140 CDF_RetrievableStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString&  aFolder, const TCollection_ExtendedString&  aName, const TCollection_ExtendedString&  aVersion) {
141   
142 #ifdef DEB
143   CDF_Timer theTimer;
144 #endif
145
146   if (!theMetaDataDriver->Find(aFolder,aName,aVersion))
147     return CDF_RS_UnknownDocument;
148   else if (!theMetaDataDriver->HasReadPermission(aFolder,aName,aVersion))
149     return CDF_RS_PermissionDenied;
150   else {
151 #ifdef DEB
152     theTimer.ShowAndRestart("theMetaDataDriver->Find: ");
153 #endif
154
155     Handle(CDM_MetaData) theMetaData = theMetaDataDriver->MetaData(aFolder,aName,aVersion);
156
157 #ifdef DEB
158     theTimer.ShowAndStop("Getting MetaData: ");
159 #endif
160
161     if(theMetaData->IsRetrieved()) {
162       return theMetaData->Document()->IsModified()
163         ? CDF_RS_AlreadyRetrievedAndModified : CDF_RS_AlreadyRetrieved;
164     }
165     else {
166       TCollection_ExtendedString theFileName=theMetaData->FileName();
167       TCollection_ExtendedString theFormat=PCDM_ReadWriter::FileFormat(theFileName);
168       if(theFormat.Length()==0) {
169         TCollection_ExtendedString ResourceName=UTL::Extension(theFileName);
170         ResourceName+=".FileFormat";
171         if(UTL::Find(Resources(),ResourceName))  {
172           theFormat=UTL::Value(Resources(),ResourceName);
173         }
174         else
175           return CDF_RS_UnrecognizedFileFormat;
176       }
177       if(!FindReaderFromFormat(theFormat)) return CDF_RS_NoDriver;
178     }
179   }
180   return CDF_RS_OK;
181   
182 }
183
184
185
186 //=======================================================================
187 //function : Activate
188 //purpose  : 
189 //=======================================================================
190 //void CDF_Application::Activate(const Handle(CDM_Document)& aDocument,const CDF_TypeOfActivation aTypeOfActivation) {
191 void CDF_Application::Activate(const Handle(CDM_Document)& ,const CDF_TypeOfActivation ) {
192 }
193
194 //=======================================================================
195 //function : DefaultFolder
196 //purpose  : 
197 //=======================================================================
198 Standard_ExtString CDF_Application::DefaultFolder(){
199   if(myDefaultFolder.Length() == 0) {
200     myDefaultFolder=CDF_Session::CurrentSession()->MetaDataDriver()->DefaultFolder();
201   }
202   return myDefaultFolder.ToExtString();
203 }
204
205 //=======================================================================
206 //function : SetDefaultFolder
207 //purpose  : 
208 //=======================================================================
209 Standard_Boolean CDF_Application::SetDefaultFolder(const Standard_ExtString aFolder) {
210   Standard_Boolean found = CDF_Session::CurrentSession()->MetaDataDriver()->FindFolder(aFolder);
211   if(found) myDefaultFolder=aFolder;
212   return found;
213 }
214
215 //=======================================================================
216 //function : DefaultExtension
217 //purpose  : 
218 //=======================================================================
219 Standard_ExtString CDF_Application::DefaultExtension() {
220   static TCollection_ExtendedString theDefaultExtension;
221   theDefaultExtension="*";
222   TColStd_SequenceOfExtendedString theFormats;
223   Formats(theFormats);
224   
225   for (Standard_Integer i=1; i<= theFormats.Length(); i++) {
226     TCollection_ExtendedString theResource(theFormats(i));
227     theResource+=".FileExtension";
228     if(UTL::Find(Resources(),theResource)) {
229       theDefaultExtension=UTL::Value(Resources(),theResource);
230       return theDefaultExtension.ToExtString();
231     }
232   }
233   return theDefaultExtension.ToExtString();
234 }
235
236 //=======================================================================
237 //function : Retrieve
238 //purpose  : 
239 //=======================================================================
240 Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMetaData,const Standard_Boolean UseStorageConfiguration) {
241   return Retrieve(aMetaData,UseStorageConfiguration,Standard_True);
242
243
244 //=======================================================================
245 //function : ConvertStatus
246 //purpose  : 
247 //=======================================================================
248 static CDF_RetrievableStatus ConvertStatus(const PCDM_ReaderStatus theStatus) {
249   CDF_RetrievableStatus aStatus;
250   switch(theStatus) {
251   case PCDM_RS_OK:
252     aStatus=CDF_RS_OK;
253     break;
254   case PCDM_RS_NoDriver:
255     aStatus=CDF_RS_NoDriver;
256     break;
257   case PCDM_RS_UnknownFileDriver:
258     aStatus=CDF_RS_UnknownFileDriver;
259     break;
260   case PCDM_RS_OpenError:
261     aStatus=CDF_RS_OpenError;
262     break;
263   case PCDM_RS_NoVersion:
264     aStatus=CDF_RS_NoVersion;
265     break;
266   case PCDM_RS_NoSchema:
267     aStatus=CDF_RS_NoSchema;
268     break;
269   case PCDM_RS_NoDocument:
270     aStatus=CDF_RS_NoDocument;
271     break;
272   case PCDM_RS_ExtensionFailure:
273     aStatus=CDF_RS_ExtensionFailure;
274     break;
275   case PCDM_RS_WrongStreamMode:
276     aStatus=CDF_RS_WrongStreamMode;
277     break;
278   case PCDM_RS_FormatFailure:
279     aStatus=CDF_RS_FormatFailure;
280     break;
281   case PCDM_RS_TypeFailure:
282     aStatus=CDF_RS_TypeFailure;
283     break;
284   case PCDM_RS_TypeNotFoundInSchema:
285     aStatus=CDF_RS_TypeNotFoundInSchema;
286     break;
287   case PCDM_RS_UnrecognizedFileFormat:
288     aStatus=CDF_RS_UnrecognizedFileFormat;
289     break;
290   case PCDM_RS_MakeFailure:
291     aStatus=CDF_RS_MakeFailure;
292     break;
293   case PCDM_RS_PermissionDenied:
294     aStatus=CDF_RS_PermissionDenied;
295     break;
296   default:
297     aStatus=CDF_RS_DriverFailure;    
298   }
299   return aStatus;
300 }
301
302 //=======================================================================
303 //function : Retrieve
304 //purpose  : 
305 //=======================================================================
306 Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMetaData,const Standard_Boolean UseStorageConfiguration, const Standard_Boolean IsComponent) {
307   
308   Handle(CDM_Document) theDocumentToReturn;
309   myRetrievableStatus = CDF_RS_DriverFailure;
310   if(IsComponent) {
311     Standard_SStream aMsg;
312     switch (CanRetrieve(aMetaData)) {
313     case CDF_RS_UnknownDocument: 
314       aMsg << "could not find the referenced document: " << aMetaData->Path() << "; not found."  <<(char)0 << endl;
315       myRetrievableStatus = CDF_RS_UnknownDocument;
316       Standard_Failure::Raise(aMsg);
317       break;
318     case CDF_RS_PermissionDenied:      
319       aMsg << "Could not find the referenced document: " << aMetaData->Path() << "; permission denied. " <<(char)0 << endl;
320       myRetrievableStatus = CDF_RS_PermissionDenied;
321       Standard_Failure::Raise(aMsg);
322       break;
323     default:
324       break;
325     }
326     
327   }
328   Standard_Boolean AlreadyRetrieved=aMetaData->IsRetrieved();
329   if(AlreadyRetrieved) myRetrievableStatus = CDF_RS_AlreadyRetrieved;
330   Standard_Boolean Modified=AlreadyRetrieved && aMetaData->Document()->IsModified();
331   if(Modified) myRetrievableStatus = CDF_RS_AlreadyRetrievedAndModified;
332   if(!AlreadyRetrieved || Modified) {
333
334     Handle(PCDM_Reader) theReader=Reader(aMetaData->FileName());
335     
336     
337     Handle(CDM_Document) theDocument;
338
339     if(Modified)  {
340       theDocument=aMetaData->Document();
341       theDocument->RemoveAllReferences();
342     }
343     else
344       theDocument=theReader->CreateDocument();
345     
346     SetReferenceCounter(theDocument,PCDM_RetrievalDriver::ReferenceCounter(aMetaData->FileName(), MessageDriver()));
347     
348     SetDocumentVersion(theDocument,aMetaData);
349     theMetaDataDriver->ReferenceIterator()->LoadReferences(theDocument,aMetaData,this,UseStorageConfiguration);
350
351     try {    
352       OCC_CATCH_SIGNALS
353       theReader->Read(aMetaData->FileName(),theDocument,this);
354     } 
355     catch (Standard_Failure) {
356       PCDM_ReaderStatus aStatus = theReader->GetStatus();
357       myRetrievableStatus = ConvertStatus(aStatus);
358       if(myRetrievableStatus  > CDF_RS_AlreadyRetrieved){
359         Standard_SStream aMsg;
360         aMsg << Standard_Failure::Caught() << endl;
361         Standard_Failure::Raise(aMsg);
362       } 
363     }
364     PCDM_ReaderStatus aStatus = theReader->GetStatus();
365     myRetrievableStatus = ConvertStatus(aStatus);
366     
367     theDocument->SetMetaData(aMetaData);
368
369     theDocumentToReturn=theDocument;
370   }
371   else
372     theDocumentToReturn=aMetaData->Document();
373   
374   return theDocumentToReturn;
375 }
376
377 //=======================================================================
378 //function : DocumentVersion
379 //purpose  : 
380 //=======================================================================
381 Standard_Integer CDF_Application::DocumentVersion(const Handle(CDM_MetaData)& theMetaData) {
382 //  const Handle(CDM_MessageDriver)& aMsgDriver = MessageDriver();
383   return PCDM_RetrievalDriver::DocumentVersion(theMetaData->FileName(), MessageDriver());
384 }
385
386 //=======================================================================
387 //function : TypeOfActivation
388 //purpose  : 
389 //=======================================================================
390 CDF_TypeOfActivation CDF_Application::TypeOfActivation(const Handle(CDM_MetaData)& aMetaData) {
391
392   if(aMetaData->IsRetrieved()) {
393     Handle(CDM_Document) theDocument=aMetaData->Document();
394     if(theDocument->IsOpened()) {
395       if(theDocument->IsModified())
396         return CDF_TOA_Modified;
397       else
398         return CDF_TOA_Unchanged;
399     }
400     
401     else
402       return CDF_TOA_New;
403   }
404   return CDF_TOA_New;
405 }
406
407
408 //=======================================================================
409 //function : FindReader
410 //purpose  : 
411 //=======================================================================
412 Standard_Boolean CDF_Application::FindReader(const TCollection_ExtendedString& aFileName) {
413   Standard_GUID voidGUID;
414   TCollection_ExtendedString voidResourceName;
415   return FindReader(aFileName,voidGUID,voidResourceName);
416 }
417
418 //=======================================================================
419 //function : Reader
420 //purpose  : code dp
421 //=======================================================================
422 Handle(PCDM_Reader) CDF_Application::Reader (const TCollection_ExtendedString& aFileName) {
423   TCollection_ExtendedString theFormat;
424   if (!Format(aFileName,theFormat)) {
425     Standard_SStream aMsg; 
426     aMsg << "Could not found the format" <<(char)0;
427     Standard_NoSuchObject::Raise(aMsg);
428
429   }
430   return ReaderFromFormat (theFormat);
431 }
432
433 //=======================================================================
434 //function : FindReaderFromFormat
435 //purpose  : 
436 //=======================================================================
437 Standard_Boolean CDF_Application::FindReaderFromFormat(const TCollection_ExtendedString& aFormat) {
438   Standard_GUID voidGUID;
439   TCollection_ExtendedString voidResourceName;
440   return FindReaderFromFormat(aFormat,voidGUID,voidResourceName);
441 }
442
443
444 //=======================================================================
445 //function : ReaderFromFormat
446 //purpose  : 
447 //=======================================================================
448 Handle(PCDM_Reader) CDF_Application::ReaderFromFormat(const TCollection_ExtendedString& aFormat) {
449   TCollection_ExtendedString UnfoundResourceName;
450   Standard_GUID thePluginId;
451   if(!FindReaderFromFormat(aFormat,thePluginId,UnfoundResourceName)) {
452     Standard_SStream aMsg; 
453     aMsg << "Could not found the item:" << UnfoundResourceName <<(char)0;
454     myRetrievableStatus = CDF_RS_WrongResource;
455     Standard_NoSuchObject::Raise(aMsg);
456   } 
457   Handle(PCDM_Reader) R;
458   try {
459     OCC_CATCH_SIGNALS
460     R = Handle(PCDM_Reader)::DownCast(Plugin::Load(thePluginId));  
461   } 
462   catch (Standard_Failure) {
463     myRetrievableStatus = CDF_RS_WrongResource;
464     Standard_SStream aMsg;
465     aMsg << Standard_Failure::Caught() << endl;
466     Standard_Failure::Raise(aMsg);
467   }     
468   Handle(PCDM_RetrievalDriver) RD = Handle(PCDM_RetrievalDriver)::DownCast(R);
469   if (!RD.IsNull()) {
470     RD->SetFormat(aFormat);
471     return RD;
472   } else 
473     myRetrievableStatus = CDF_RS_WrongResource;
474   return R;
475 }
476
477 //=======================================================================
478 //function : FindReader
479 //purpose  : 
480 //=======================================================================
481 Standard_Boolean CDF_Application::FindReader(const TCollection_ExtendedString& aFileName, Standard_GUID& thePluginId, TCollection_ExtendedString& ResourceName) {
482   
483   TCollection_ExtendedString theFormat=PCDM_ReadWriter::FileFormat(aFileName);
484
485 // Si le format est dans le fichier, tant mieux. Sinon on se base sur l'extension.
486   
487   if(theFormat.Length()==0) {
488     ResourceName=UTL::Extension(aFileName);
489     ResourceName+=".FileFormat";
490     
491     if(UTL::Find(Resources(),ResourceName))  {
492       theFormat=UTL::Value(Resources(),ResourceName);
493     }
494     else 
495       return Standard_False;
496   }
497   return FindReaderFromFormat(theFormat,thePluginId,ResourceName);
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   // Si le format est dans le fichier, tant mieux. Sinon on se base sur l'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 : FindReaderFromFormat
525 //purpose  : 
526 //=======================================================================
527 Standard_Boolean CDF_Application::FindReaderFromFormat(const TCollection_ExtendedString& aFormat, Standard_GUID& thePluginId, TCollection_ExtendedString& ResourceName) {
528   
529   ResourceName=aFormat;
530   ResourceName+=".RetrievalPlugin";
531   
532   if(UTL::Find(Resources(),ResourceName))  {
533     thePluginId=UTL::GUID(UTL::Value(Resources(),ResourceName));
534     return Standard_True;
535   }
536   return Standard_False;
537 }
538
539 //=======================================================================
540 //function : CanRetrieve
541 //purpose  : 
542 //=======================================================================
543 CDF_RetrievableStatus CDF_Application::CanRetrieve(const Handle(CDM_MetaData)& aMetaData) {
544   if(aMetaData->HasVersion())
545     return CanRetrieve(aMetaData->Folder(),aMetaData->Name(),aMetaData->Version());
546   else
547     return CanRetrieve(aMetaData->Folder(),aMetaData->Name());
548 }