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