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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified by rmi, Wed Jan 14 08:17:35 1998
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_Reader.hxx>
26 #include <PCDM_ReadWriter.hxx>
27 #include <PCDM_RetrievalDriver.hxx>
28 #include <PCDM_StorageDriver.hxx>
30 #include <Standard_ErrorHandler.hxx>
31 #include <Standard_GUID.hxx>
32 #include <Standard_NoSuchObject.hxx>
33 #include <Standard_ProgramError.hxx>
36 IMPLEMENT_STANDARD_RTTIEXT(CDF_Application,CDM_Application)
37 //=======================================================================
40 //=======================================================================
41 CDF_Application::CDF_Application():myRetrievableStatus(PCDM_RS_OK)
43 myDirectory = new CDF_Directory();
44 myMetaDataDriver = new CDF_FWOSDriver (MetaDataLookUpTable());
47 //=======================================================================
50 //=======================================================================
51 Handle(CDF_Application) CDF_Application::Load(const Standard_GUID& aGUID) {
52 return Handle(CDF_Application)::DownCast(Plugin::Load(aGUID));
55 //=======================================================================
58 //=======================================================================
59 void CDF_Application::Open(const Handle(CDM_Document)& aDocument) {
60 myDirectory->Add(aDocument);
61 aDocument->Open(this);
62 Activate(aDocument,CDF_TOA_New);
65 //=======================================================================
68 //=======================================================================
69 CDM_CanCloseStatus CDF_Application::CanClose(const Handle(CDM_Document)& aDocument) {
70 return aDocument->CanClose();
73 //=======================================================================
76 //=======================================================================
77 void CDF_Application::Close(const Handle(CDM_Document)& aDocument) {
78 myDirectory->Remove(aDocument);
82 //=======================================================================
85 //=======================================================================
86 Handle(CDM_Document) CDF_Application::Retrieve (const TCollection_ExtendedString& aFolder,
87 const TCollection_ExtendedString& aName,
88 const Standard_Boolean UseStorageConfiguration,
89 const Message_ProgressRange& theRange)
91 TCollection_ExtendedString nullVersion;
92 return Retrieve(aFolder, aName, nullVersion, UseStorageConfiguration, theRange);
95 //=======================================================================
98 //=======================================================================
99 Handle(CDM_Document) CDF_Application::Retrieve (const TCollection_ExtendedString& aFolder,
100 const TCollection_ExtendedString& aName,
101 const TCollection_ExtendedString& aVersion,
102 const Standard_Boolean UseStorageConfiguration,
103 const Message_ProgressRange& theRange)
105 Handle(CDM_MetaData) theMetaData;
107 if(aVersion.Length() == 0)
108 theMetaData=myMetaDataDriver->MetaData(aFolder,aName);
110 theMetaData=myMetaDataDriver->MetaData(aFolder,aName,aVersion);
112 CDF_TypeOfActivation theTypeOfActivation=TypeOfActivation(theMetaData);
113 Handle(CDM_Document) theDocument = Retrieve(theMetaData, UseStorageConfiguration,
114 Standard_False, theRange);
116 myDirectory->Add(theDocument);
117 Activate(theDocument,theTypeOfActivation);
119 theDocument->Open(this);
123 //=======================================================================
124 //function : CanRetrieve
126 //=======================================================================
127 PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& aFolder, const TCollection_ExtendedString& aName) {
128 TCollection_ExtendedString aVersion;
129 return CanRetrieve(aFolder,aName,aVersion);
132 //=======================================================================
133 //function : CanRetrieve
135 //=======================================================================
136 PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& aFolder, const TCollection_ExtendedString& aName, const TCollection_ExtendedString& aVersion) {
138 if (!myMetaDataDriver->Find(aFolder,aName,aVersion))
139 return PCDM_RS_UnknownDocument;
140 else if (!myMetaDataDriver->HasReadPermission(aFolder,aName,aVersion))
141 return PCDM_RS_PermissionDenied;
143 Handle(CDM_MetaData) theMetaData = myMetaDataDriver->MetaData(aFolder,aName,aVersion);
145 if(theMetaData->IsRetrieved()) {
146 return theMetaData->Document()->IsModified()
147 ? PCDM_RS_AlreadyRetrievedAndModified : PCDM_RS_AlreadyRetrieved;
150 TCollection_ExtendedString theFileName=theMetaData->FileName();
151 TCollection_ExtendedString theFormat=PCDM_ReadWriter::FileFormat(theFileName);
152 if(theFormat.Length()==0) {
153 TCollection_ExtendedString ResourceName=UTL::Extension(theFileName);
154 ResourceName+=".FileFormat";
155 if(UTL::Find(Resources(),ResourceName)) {
156 theFormat=UTL::Value(Resources(),ResourceName);
159 return PCDM_RS_UnrecognizedFileFormat;
162 // check actual availability of the driver
164 Handle(PCDM_Reader) aReader = ReaderFromFormat(theFormat);
165 if (aReader.IsNull())
166 return PCDM_RS_NoDriver;
168 catch (Standard_Failure const&)
170 // no need to report error, this was just check for availability
177 //=======================================================================
178 //function : Activate
180 //=======================================================================
181 //void CDF_Application::Activate(const Handle(CDM_Document)& aDocument,const CDF_TypeOfActivation aTypeOfActivation) {
182 void CDF_Application::Activate(const Handle(CDM_Document)& ,const CDF_TypeOfActivation ) {
185 //=======================================================================
186 //function : DefaultFolder
188 //=======================================================================
189 Standard_ExtString CDF_Application::DefaultFolder(){
190 if(myDefaultFolder.Length() == 0) {
191 myDefaultFolder=myMetaDataDriver->DefaultFolder();
193 return myDefaultFolder.ToExtString();
196 //=======================================================================
197 //function : SetDefaultFolder
199 //=======================================================================
200 Standard_Boolean CDF_Application::SetDefaultFolder(const Standard_ExtString aFolder) {
201 Standard_Boolean found = myMetaDataDriver->FindFolder(aFolder);
202 if(found) myDefaultFolder=aFolder;
206 //=======================================================================
207 //function : Retrieve
209 //=======================================================================
210 Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMetaData,
211 const Standard_Boolean UseStorageConfiguration,
212 const Message_ProgressRange& theRange) {
213 return Retrieve(aMetaData, UseStorageConfiguration, Standard_True, theRange);
216 //=======================================================================
217 //function : Retrieve
219 //=======================================================================
220 Handle(CDM_Document) CDF_Application::Retrieve (const Handle(CDM_MetaData)& aMetaData,
221 const Standard_Boolean UseStorageConfiguration,
222 const Standard_Boolean IsComponent,
223 const Message_ProgressRange& theRange) {
225 Handle(CDM_Document) theDocumentToReturn;
226 myRetrievableStatus = PCDM_RS_DriverFailure;
228 Standard_SStream aMsg;
229 switch (CanRetrieve(aMetaData)) {
230 case PCDM_RS_UnknownDocument:
231 aMsg << "could not find the referenced document: " << aMetaData->Path() << "; not found." <<(char)0 << std::endl;
232 myRetrievableStatus = PCDM_RS_UnknownDocument;
233 throw Standard_Failure(aMsg.str().c_str());
235 case PCDM_RS_PermissionDenied:
236 aMsg << "Could not find the referenced document: " << aMetaData->Path() << "; permission denied. " <<(char)0 << std::endl;
237 myRetrievableStatus = PCDM_RS_PermissionDenied;
238 throw Standard_Failure(aMsg.str().c_str());
245 Standard_Boolean AlreadyRetrieved=aMetaData->IsRetrieved();
246 if(AlreadyRetrieved) myRetrievableStatus = PCDM_RS_AlreadyRetrieved;
247 Standard_Boolean Modified=AlreadyRetrieved && aMetaData->Document()->IsModified();
248 if(Modified) myRetrievableStatus = PCDM_RS_AlreadyRetrievedAndModified;
249 if(!AlreadyRetrieved || Modified)
251 TCollection_ExtendedString aFormat;
252 if (!Format(aMetaData->FileName(), aFormat))
254 Standard_SStream aMsg;
255 aMsg << "Could not determine format for the file " << aMetaData->FileName() << (char)0;
256 throw Standard_NoSuchObject(aMsg.str().c_str());
258 Handle(PCDM_Reader) theReader = ReaderFromFormat (aFormat);
260 Handle(CDM_Document) theDocument;
263 theDocument=aMetaData->Document();
264 theDocument->RemoveAllReferences();
267 theDocument=theReader->CreateDocument();
269 SetReferenceCounter(theDocument,PCDM_RetrievalDriver::ReferenceCounter(aMetaData->FileName(), MessageDriver()));
271 SetDocumentVersion(theDocument,aMetaData);
272 myMetaDataDriver->ReferenceIterator(MessageDriver())->LoadReferences(theDocument,aMetaData,this,UseStorageConfiguration);
276 theReader->Read (aMetaData->FileName(), theDocument, this, theRange);
278 catch (Standard_Failure const& anException) {
279 myRetrievableStatus = theReader->GetStatus();
280 if(myRetrievableStatus > PCDM_RS_AlreadyRetrieved){
281 Standard_SStream aMsg;
282 aMsg << anException << std::endl;
283 throw Standard_Failure(aMsg.str().c_str());
286 myRetrievableStatus = theReader->GetStatus();
287 theDocument->Open (this); // must be done before SetMetaData
288 theDocument->SetMetaData(aMetaData);
290 theDocumentToReturn=theDocument;
293 theDocumentToReturn=aMetaData->Document();
295 return theDocumentToReturn;
298 //=======================================================================
299 //function : DocumentVersion
301 //=======================================================================
302 Standard_Integer CDF_Application::DocumentVersion(const Handle(CDM_MetaData)& theMetaData) {
303 // const Handle(CDM_MessageDriver)& aMsgDriver = MessageDriver();
304 return PCDM_RetrievalDriver::DocumentVersion(theMetaData->FileName(), MessageDriver());
307 //=======================================================================
308 //function : TypeOfActivation
310 //=======================================================================
311 CDF_TypeOfActivation CDF_Application::TypeOfActivation(const Handle(CDM_MetaData)& aMetaData) {
313 if(aMetaData->IsRetrieved()) {
314 Handle(CDM_Document) theDocument=aMetaData->Document();
315 if(theDocument->IsOpened()) {
316 if(theDocument->IsModified())
317 return CDF_TOA_Modified;
319 return CDF_TOA_Unchanged;
328 //=======================================================================
331 //=======================================================================
332 Handle(CDM_Document) CDF_Application::Read (Standard_IStream& theIStream,
333 const Message_ProgressRange& theRange)
335 Handle(CDM_Document) aDoc;
336 Handle(Storage_Data) dData;
338 TCollection_ExtendedString aFormat;
344 aFormat = PCDM_ReadWriter::FileFormat (theIStream, dData);
346 catch (Standard_Failure const& anException)
348 myRetrievableStatus = PCDM_RS_FormatFailure;
350 Standard_SStream aMsg;
351 aMsg << anException << std::endl;
352 throw Standard_Failure(aMsg.str().c_str());
355 if (aFormat.IsEmpty())
357 myRetrievableStatus = PCDM_RS_FormatFailure;
361 // 1. use a format name to detect plugin corresponding to the format to continue reading
362 Handle(PCDM_Reader) aReader = ReaderFromFormat (aFormat);
364 // 2. create document with the detected reader
365 aDoc = aReader->CreateDocument();
367 // 3. read the content of theIStream to aDoc
371 aReader->Read (theIStream, dData, aDoc, this, theRange);
373 catch (Standard_Failure const& anException)
375 myRetrievableStatus = aReader->GetStatus();
376 if (myRetrievableStatus > PCDM_RS_AlreadyRetrieved)
378 Standard_SStream aMsg;
379 aMsg << anException << std::endl;
380 throw Standard_Failure(aMsg.str().c_str());
384 myRetrievableStatus = aReader->GetStatus();
389 //=======================================================================
390 //function : ReaderFromFormat
392 //=======================================================================
393 Handle(PCDM_Reader) CDF_Application::ReaderFromFormat(const TCollection_ExtendedString& theFormat)
395 // check map of readers
396 Handle(PCDM_RetrievalDriver) aReader;
397 if (myReaders.FindFromKey (theFormat, aReader))
400 // support of legacy method of loading reader as plugin
401 TCollection_ExtendedString aResourceName = theFormat;
402 aResourceName += ".RetrievalPlugin";
403 if (!UTL::Find(Resources(), aResourceName))
405 Standard_SStream aMsg;
406 aMsg << "Could not found the item:" << aResourceName <<(char)0;
407 myRetrievableStatus = PCDM_RS_WrongResource;
408 throw Standard_NoSuchObject(aMsg.str().c_str());
411 // Get GUID as a string.
412 TCollection_ExtendedString strPluginId = UTL::Value(Resources(), aResourceName);
414 // If the GUID (as a string) contains blanks, remove them.
415 if (strPluginId.Search(' ') != -1)
416 strPluginId.RemoveAll(' ');
419 Standard_GUID aPluginId = UTL::GUID(strPluginId);
423 aReader = Handle(PCDM_RetrievalDriver)::DownCast(Plugin::Load(aPluginId));
425 catch (Standard_Failure const& anException)
427 myRetrievableStatus = PCDM_RS_WrongResource;
430 if (!aReader.IsNull()) {
431 aReader->SetFormat(theFormat);
435 myRetrievableStatus = PCDM_RS_WrongResource;
439 myReaders.Add(theFormat, aReader);
443 //=======================================================================
444 //function : WriterFromFormat
446 //=======================================================================
447 Handle(PCDM_StorageDriver) CDF_Application::WriterFromFormat(const TCollection_ExtendedString& theFormat)
449 // check map of writers
450 Handle(PCDM_StorageDriver) aDriver;
451 if (myWriters.FindFromKey(theFormat, aDriver))
454 // support of legacy method of loading reader as plugin
455 TCollection_ExtendedString aResourceName = theFormat;
456 aResourceName += ".StoragePlugin";
457 if(!UTL::Find(Resources(), aResourceName))
459 myWriters.Add(theFormat, aDriver);
460 Standard_SStream aMsg;
461 aMsg << "Could not found the resource definition:" << aResourceName <<(char)0;
462 throw Standard_NoSuchObject(aMsg.str().c_str());
465 // Get GUID as a string.
466 TCollection_ExtendedString strPluginId = UTL::Value(Resources(), aResourceName);
468 // If the GUID (as a string) contains blanks, remove them.
469 if (strPluginId.Search(' ') != -1)
470 strPluginId.RemoveAll(' ');
473 Standard_GUID aPluginId = UTL::GUID(strPluginId);
477 aDriver = Handle(PCDM_StorageDriver)::DownCast(Plugin::Load(aPluginId));
479 catch (Standard_Failure const& anException)
481 myWriters.Add(theFormat, aDriver);
482 myRetrievableStatus = PCDM_RS_WrongResource;
485 if (aDriver.IsNull())
487 myRetrievableStatus = PCDM_RS_WrongResource;
491 aDriver->SetFormat(theFormat);
495 myWriters.Add(theFormat, aDriver);
499 //=======================================================================
502 //=======================================================================
503 Standard_Boolean CDF_Application::Format(const TCollection_ExtendedString& aFileName,
504 TCollection_ExtendedString& theFormat)
507 theFormat = PCDM_ReadWriter::FileFormat(aFileName);
508 // It is good if the format is in the file. Otherwise base on the extension.
509 if(theFormat.Length()==0) {
510 TCollection_ExtendedString ResourceName;
511 ResourceName=UTL::Extension(aFileName);
512 ResourceName+=".FileFormat";
514 if(UTL::Find(Resources(),ResourceName)) {
515 theFormat = UTL::Value(Resources(),ResourceName);
517 else return Standard_False;
519 return Standard_True;
522 //=======================================================================
523 //function : CanRetrieve
525 //=======================================================================
526 PCDM_ReaderStatus CDF_Application::CanRetrieve(const Handle(CDM_MetaData)& aMetaData) {
527 if(aMetaData->HasVersion())
528 return CanRetrieve(aMetaData->Folder(),aMetaData->Name(),aMetaData->Version());
530 return CanRetrieve(aMetaData->Folder(),aMetaData->Name());
533 //=======================================================================
534 //function : MetaDataDriver
536 //=======================================================================
537 Handle(CDF_MetaDataDriver) CDF_Application::MetaDataDriver() const {
538 Standard_NoSuchObject_Raise_if(myMetaDataDriver.IsNull(), "no metadatadriver has been provided; this application is not able to store or retrieve files.");
539 return myMetaDataDriver;