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_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>
31 #include <Standard_ErrorHandler.hxx>
32 #include <Standard_GUID.hxx>
33 #include <Standard_NoSuchObject.hxx>
34 #include <Standard_ProgramError.hxx>
37 IMPLEMENT_STANDARD_RTTIEXT(CDF_Application,CDM_Application)
39 #define theMetaDataDriver CDF_Session::CurrentSession()->MetaDataDriver()
42 //=======================================================================
45 //=======================================================================
46 CDF_Application::CDF_Application():myRetrievableStatus(PCDM_RS_OK) {}
48 //=======================================================================
51 //=======================================================================
52 Handle(CDF_Application) CDF_Application::Load(const Standard_GUID& aGUID) {
53 return Handle(CDF_Application)::DownCast(Plugin::Load(aGUID));
56 //=======================================================================
59 //=======================================================================
60 void CDF_Application::Open(const Handle(CDM_Document)& aDocument) {
61 CDF_Session::CurrentSession()->Directory()->Add(aDocument);
62 aDocument->Open(this);
63 Activate(aDocument,CDF_TOA_New);
66 //=======================================================================
69 //=======================================================================
70 CDM_CanCloseStatus CDF_Application::CanClose(const Handle(CDM_Document)& aDocument) {
71 return aDocument->CanClose();
74 //=======================================================================
77 //=======================================================================
78 void CDF_Application::Close(const Handle(CDM_Document)& aDocument) {
79 CDF_Session::CurrentSession()->Directory()->Remove(aDocument);
83 //=======================================================================
86 //=======================================================================
87 Handle(CDM_Document) CDF_Application::Retrieve(const TCollection_ExtendedString& aFolder,
88 const TCollection_ExtendedString& aName,
89 const Standard_Boolean UseStorageConfiguration) {
90 TCollection_ExtendedString nullVersion;
91 return Retrieve(aFolder,aName,nullVersion,UseStorageConfiguration);
94 //=======================================================================
97 //=======================================================================
98 Handle(CDM_Document) CDF_Application::Retrieve(const TCollection_ExtendedString& aFolder,
99 const TCollection_ExtendedString& aName,
100 const TCollection_ExtendedString& aVersion,
101 const Standard_Boolean UseStorageConfiguration)
103 Handle(CDM_MetaData) theMetaData;
105 if(aVersion.Length() == 0)
106 theMetaData=theMetaDataDriver->MetaData(aFolder,aName);
108 theMetaData=theMetaDataDriver->MetaData(aFolder,aName,aVersion);
110 CDF_TypeOfActivation theTypeOfActivation=TypeOfActivation(theMetaData);
111 Handle(CDM_Document) theDocument=Retrieve(theMetaData,UseStorageConfiguration,Standard_False);
113 CDF_Session::CurrentSession()->Directory()->Add(theDocument);
114 Activate(theDocument,theTypeOfActivation);
116 theDocument->Open(this);
120 //=======================================================================
121 //function : CanRetrieve
123 //=======================================================================
124 PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& aFolder, const TCollection_ExtendedString& aName) {
125 TCollection_ExtendedString aVersion;
126 return CanRetrieve(aFolder,aName,aVersion);
129 //=======================================================================
130 //function : CanRetrieve
132 //=======================================================================
133 PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& aFolder, const TCollection_ExtendedString& aName, const TCollection_ExtendedString& aVersion) {
135 if (!theMetaDataDriver->Find(aFolder,aName,aVersion))
136 return PCDM_RS_UnknownDocument;
137 else if (!theMetaDataDriver->HasReadPermission(aFolder,aName,aVersion))
138 return PCDM_RS_PermissionDenied;
140 Handle(CDM_MetaData) theMetaData = theMetaDataDriver->MetaData(aFolder,aName,aVersion);
142 if(theMetaData->IsRetrieved()) {
143 return theMetaData->Document()->IsModified()
144 ? PCDM_RS_AlreadyRetrievedAndModified : PCDM_RS_AlreadyRetrieved;
147 TCollection_ExtendedString theFileName=theMetaData->FileName();
148 TCollection_ExtendedString theFormat=PCDM_ReadWriter::FileFormat(theFileName);
149 if(theFormat.Length()==0) {
150 TCollection_ExtendedString ResourceName=UTL::Extension(theFileName);
151 ResourceName+=".FileFormat";
152 if(UTL::Find(Resources(),ResourceName)) {
153 theFormat=UTL::Value(Resources(),ResourceName);
156 return PCDM_RS_UnrecognizedFileFormat;
159 // check actual availability of the driver
161 Handle(PCDM_Reader) aReader = ReaderFromFormat(theFormat);
162 if (aReader.IsNull())
163 return PCDM_RS_NoDriver;
165 catch (Standard_Failure)
167 // no need to report error, this was just check for availability
174 //=======================================================================
175 //function : Activate
177 //=======================================================================
178 //void CDF_Application::Activate(const Handle(CDM_Document)& aDocument,const CDF_TypeOfActivation aTypeOfActivation) {
179 void CDF_Application::Activate(const Handle(CDM_Document)& ,const CDF_TypeOfActivation ) {
182 //=======================================================================
183 //function : DefaultFolder
185 //=======================================================================
186 Standard_ExtString CDF_Application::DefaultFolder(){
187 if(myDefaultFolder.Length() == 0) {
188 myDefaultFolder=CDF_Session::CurrentSession()->MetaDataDriver()->DefaultFolder();
190 return myDefaultFolder.ToExtString();
193 //=======================================================================
194 //function : SetDefaultFolder
196 //=======================================================================
197 Standard_Boolean CDF_Application::SetDefaultFolder(const Standard_ExtString aFolder) {
198 Standard_Boolean found = CDF_Session::CurrentSession()->MetaDataDriver()->FindFolder(aFolder);
199 if(found) myDefaultFolder=aFolder;
203 //=======================================================================
204 //function : Retrieve
206 //=======================================================================
207 Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMetaData,const Standard_Boolean UseStorageConfiguration) {
208 return Retrieve(aMetaData,UseStorageConfiguration,Standard_True);
211 //=======================================================================
212 //function : Retrieve
214 //=======================================================================
215 Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMetaData,const Standard_Boolean UseStorageConfiguration, const Standard_Boolean IsComponent) {
217 Handle(CDM_Document) theDocumentToReturn;
218 myRetrievableStatus = PCDM_RS_DriverFailure;
220 Standard_SStream aMsg;
221 switch (CanRetrieve(aMetaData)) {
222 case PCDM_RS_UnknownDocument:
223 aMsg << "could not find the referenced document: " << aMetaData->Path() << "; not found." <<(char)0 << endl;
224 myRetrievableStatus = PCDM_RS_UnknownDocument;
225 throw Standard_Failure(aMsg.str().c_str());
227 case PCDM_RS_PermissionDenied:
228 aMsg << "Could not find the referenced document: " << aMetaData->Path() << "; permission denied. " <<(char)0 << endl;
229 myRetrievableStatus = PCDM_RS_PermissionDenied;
230 throw Standard_Failure(aMsg.str().c_str());
237 Standard_Boolean AlreadyRetrieved=aMetaData->IsRetrieved();
238 if(AlreadyRetrieved) myRetrievableStatus = PCDM_RS_AlreadyRetrieved;
239 Standard_Boolean Modified=AlreadyRetrieved && aMetaData->Document()->IsModified();
240 if(Modified) myRetrievableStatus = PCDM_RS_AlreadyRetrievedAndModified;
241 if(!AlreadyRetrieved || Modified)
243 TCollection_ExtendedString aFormat;
244 if (!Format(aMetaData->FileName(), aFormat))
246 Standard_SStream aMsg;
247 aMsg << "Could not determine format for the file " << aMetaData->FileName() << (char)0;
248 throw Standard_NoSuchObject(aMsg.str().c_str());
250 Handle(PCDM_Reader) theReader = ReaderFromFormat (aFormat);
252 Handle(CDM_Document) theDocument;
255 theDocument=aMetaData->Document();
256 theDocument->RemoveAllReferences();
259 theDocument=theReader->CreateDocument();
261 SetReferenceCounter(theDocument,PCDM_RetrievalDriver::ReferenceCounter(aMetaData->FileName(), MessageDriver()));
263 SetDocumentVersion(theDocument,aMetaData);
264 theMetaDataDriver->ReferenceIterator()->LoadReferences(theDocument,aMetaData,this,UseStorageConfiguration);
268 theReader->Read(aMetaData->FileName(),theDocument,this);
270 catch (Standard_Failure const& anException) {
271 myRetrievableStatus = theReader->GetStatus();
272 if(myRetrievableStatus > PCDM_RS_AlreadyRetrieved){
273 Standard_SStream aMsg;
274 aMsg << anException << endl;
275 throw Standard_Failure(aMsg.str().c_str());
278 myRetrievableStatus = theReader->GetStatus();
279 theDocument->SetMetaData(aMetaData);
281 theDocumentToReturn=theDocument;
284 theDocumentToReturn=aMetaData->Document();
286 return theDocumentToReturn;
289 //=======================================================================
290 //function : DocumentVersion
292 //=======================================================================
293 Standard_Integer CDF_Application::DocumentVersion(const Handle(CDM_MetaData)& theMetaData) {
294 // const Handle(CDM_MessageDriver)& aMsgDriver = MessageDriver();
295 return PCDM_RetrievalDriver::DocumentVersion(theMetaData->FileName(), MessageDriver());
298 //=======================================================================
299 //function : TypeOfActivation
301 //=======================================================================
302 CDF_TypeOfActivation CDF_Application::TypeOfActivation(const Handle(CDM_MetaData)& aMetaData) {
304 if(aMetaData->IsRetrieved()) {
305 Handle(CDM_Document) theDocument=aMetaData->Document();
306 if(theDocument->IsOpened()) {
307 if(theDocument->IsModified())
308 return CDF_TOA_Modified;
310 return CDF_TOA_Unchanged;
319 //=======================================================================
322 //=======================================================================
323 Handle(CDM_Document) CDF_Application::Read (Standard_IStream& theIStream)
325 Handle(CDM_Document) aDoc;
326 Handle(Storage_Data) dData;
328 TCollection_ExtendedString aFormat;
334 aFormat = PCDM_ReadWriter::FileFormat (theIStream, dData);
336 catch (Standard_Failure const& anException)
338 myRetrievableStatus = PCDM_RS_FormatFailure;
340 Standard_SStream aMsg;
341 aMsg << anException << endl;
342 throw Standard_Failure(aMsg.str().c_str());
345 if (aFormat.IsEmpty())
347 myRetrievableStatus = PCDM_RS_FormatFailure;
351 // 1. use a format name to detect plugin corresponding to the format to continue reading
352 Handle(PCDM_Reader) aReader = ReaderFromFormat (aFormat);
354 // 2. create document with the detected reader
355 aDoc = aReader->CreateDocument();
357 // 3. read the content of theIStream to aDoc
362 aReader->Read (theIStream, dData, aDoc, this);
364 catch (Standard_Failure const& anException)
366 myRetrievableStatus = aReader->GetStatus();
367 if (myRetrievableStatus > PCDM_RS_AlreadyRetrieved)
369 Standard_SStream aMsg;
370 aMsg << anException << endl;
371 throw Standard_Failure(aMsg.str().c_str());
375 myRetrievableStatus = aReader->GetStatus();
380 //=======================================================================
381 //function : ReaderFromFormat
383 //=======================================================================
384 Handle(PCDM_Reader) CDF_Application::ReaderFromFormat(const TCollection_ExtendedString& theFormat)
386 // check map of readers
387 Handle(PCDM_RetrievalDriver) aReader;
388 if (myReaders.FindFromKey (theFormat, aReader))
391 // support of legacy method of loading reader as plugin
392 TCollection_ExtendedString aResourceName = theFormat;
393 aResourceName += ".RetrievalPlugin";
394 if (!UTL::Find(Resources(), aResourceName))
396 myReaders.Add(theFormat, aReader);
397 Standard_SStream aMsg;
398 aMsg << "Could not found the item:" << aResourceName <<(char)0;
399 myRetrievableStatus = PCDM_RS_WrongResource;
400 throw Standard_NoSuchObject(aMsg.str().c_str());
403 // Get GUID as a string.
404 TCollection_ExtendedString strPluginId = UTL::Value(Resources(), aResourceName);
406 // If the GUID (as a string) contains blanks, remove them.
407 if (strPluginId.Search(' ') != -1)
408 strPluginId.RemoveAll(' ');
411 Standard_GUID aPluginId = UTL::GUID(strPluginId);
415 aReader = Handle(PCDM_RetrievalDriver)::DownCast(Plugin::Load(aPluginId));
417 catch (Standard_Failure const& anException)
419 myReaders.Add(theFormat, aReader);
420 myRetrievableStatus = PCDM_RS_WrongResource;
423 if (!aReader.IsNull()) {
424 aReader->SetFormat(theFormat);
428 myRetrievableStatus = PCDM_RS_WrongResource;
432 myReaders.Add(theFormat, aReader);
436 //=======================================================================
437 //function : WriterFromFormat
439 //=======================================================================
440 Handle(PCDM_StorageDriver) CDF_Application::WriterFromFormat(const TCollection_ExtendedString& theFormat)
442 // check map of writers
443 Handle(PCDM_StorageDriver) aDriver;
444 if (myWriters.FindFromKey(theFormat, aDriver))
447 // support of legacy method of loading reader as plugin
448 TCollection_ExtendedString aResourceName = theFormat;
449 aResourceName += ".StoragePlugin";
450 if(!UTL::Find(Resources(), aResourceName))
452 myWriters.Add(theFormat, aDriver);
453 Standard_SStream aMsg;
454 aMsg << "Could not found the resource definition:" << aResourceName <<(char)0;
455 throw Standard_NoSuchObject(aMsg.str().c_str());
458 // Get GUID as a string.
459 TCollection_ExtendedString strPluginId = UTL::Value(Resources(), aResourceName);
461 // If the GUID (as a string) contains blanks, remove them.
462 if (strPluginId.Search(' ') != -1)
463 strPluginId.RemoveAll(' ');
466 Standard_GUID aPluginId = UTL::GUID(strPluginId);
470 aDriver = Handle(PCDM_StorageDriver)::DownCast(Plugin::Load(aPluginId));
472 catch (Standard_Failure const& anException)
474 myWriters.Add(theFormat, aDriver);
475 myRetrievableStatus = PCDM_RS_WrongResource;
478 if (aDriver.IsNull())
480 myRetrievableStatus = PCDM_RS_WrongResource;
484 aDriver->SetFormat(theFormat);
488 myWriters.Add(theFormat, aDriver);
492 //=======================================================================
495 //=======================================================================
496 Standard_Boolean CDF_Application::Format(const TCollection_ExtendedString& aFileName,
497 TCollection_ExtendedString& theFormat)
500 theFormat = PCDM_ReadWriter::FileFormat(aFileName);
501 // It is good if the format is in the file. Otherwise base on the extension.
502 if(theFormat.Length()==0) {
503 TCollection_ExtendedString ResourceName;
504 ResourceName=UTL::Extension(aFileName);
505 ResourceName+=".FileFormat";
507 if(UTL::Find(Resources(),ResourceName)) {
508 theFormat = UTL::Value(Resources(),ResourceName);
510 else return Standard_False;
512 return Standard_True;
515 //=======================================================================
516 //function : CanRetrieve
518 //=======================================================================
519 PCDM_ReaderStatus CDF_Application::CanRetrieve(const Handle(CDM_MetaData)& aMetaData) {
520 if(aMetaData->HasVersion())
521 return CanRetrieve(aMetaData->Folder(),aMetaData->Name(),aMetaData->Version());
523 return CanRetrieve(aMetaData->Folder(),aMetaData->Name());