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 <CDF_Timer.hxx>
24 #include <CDM_CanCloseStatus.hxx>
25 #include <CDM_Document.hxx>
26 #include <CDM_MetaData.hxx>
27 #include <PCDM_Reader.hxx>
28 #include <PCDM_ReaderStatus.hxx>
29 #include <PCDM_ReadWriter.hxx>
30 #include <PCDM_RetrievalDriver.hxx>
31 #include <PCDM_StorageDriver.hxx>
33 #include <Standard_ErrorHandler.hxx>
34 #include <Standard_GUID.hxx>
35 #include <Standard_NoSuchObject.hxx>
36 #include <Standard_ProgramError.hxx>
37 #include <Standard_Type.hxx>
38 #include <TCollection_ExtendedString.hxx>
41 IMPLEMENT_STANDARD_RTTIEXT(CDF_Application,CDM_Application)
43 #define theMetaDataDriver CDF_Session::CurrentSession()->MetaDataDriver()
46 //=======================================================================
49 //=======================================================================
50 CDF_Application::CDF_Application():myRetrievableStatus(PCDM_RS_OK) {}
52 //=======================================================================
55 //=======================================================================
56 Handle(CDF_Application) CDF_Application::Load(const Standard_GUID& aGUID) {
57 return Handle(CDF_Application)::DownCast(Plugin::Load(aGUID));
60 //=======================================================================
63 //=======================================================================
64 void CDF_Application::Open(const Handle(CDM_Document)& aDocument) {
65 CDF_Session::CurrentSession()->Directory()->Add(aDocument);
66 aDocument->Open(this);
67 Activate(aDocument,CDF_TOA_New);
70 //=======================================================================
73 //=======================================================================
74 CDM_CanCloseStatus CDF_Application::CanClose(const Handle(CDM_Document)& aDocument) {
75 return aDocument->CanClose();
78 //=======================================================================
81 //=======================================================================
82 void CDF_Application::Close(const Handle(CDM_Document)& aDocument) {
83 CDF_Session::CurrentSession()->Directory()->Remove(aDocument);
87 //=======================================================================
90 //=======================================================================
91 Handle(CDM_Document) CDF_Application::Retrieve(const TCollection_ExtendedString& aFolder,
92 const TCollection_ExtendedString& aName,
93 const Standard_Boolean UseStorageConfiguration) {
94 TCollection_ExtendedString nullVersion;
95 return Retrieve(aFolder,aName,nullVersion,UseStorageConfiguration);
98 //=======================================================================
101 //=======================================================================
102 Handle(CDM_Document) CDF_Application::Retrieve(const TCollection_ExtendedString& aFolder,
103 const TCollection_ExtendedString& aName,
104 const TCollection_ExtendedString& aVersion,
105 const Standard_Boolean UseStorageConfiguration) {
110 Handle(CDM_MetaData) theMetaData;
112 if(aVersion.Length() == 0)
113 theMetaData=theMetaDataDriver->MetaData(aFolder,aName);
115 theMetaData=theMetaDataDriver->MetaData(aFolder,aName,aVersion);
118 theTimer.ShowAndRestart("Getting MetaData: ");
121 CDF_TypeOfActivation theTypeOfActivation=TypeOfActivation(theMetaData);
122 Handle(CDM_Document) theDocument=Retrieve(theMetaData,UseStorageConfiguration,Standard_False);
125 theTimer.ShowAndRestart("Creating Transient: ");
128 CDF_Session::CurrentSession()->Directory()->Add(theDocument);
129 Activate(theDocument,theTypeOfActivation);
132 theTimer.ShowAndStop("Activate: ");
135 theDocument->Open(this);
141 //=======================================================================
142 //function : CanRetrieve
144 //=======================================================================
145 PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& aFolder, const TCollection_ExtendedString& aName) {
146 TCollection_ExtendedString aVersion;
147 return CanRetrieve(aFolder,aName,aVersion);
150 //=======================================================================
151 //function : CanRetrieve
153 //=======================================================================
154 PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& aFolder, const TCollection_ExtendedString& aName, const TCollection_ExtendedString& aVersion) {
160 if (!theMetaDataDriver->Find(aFolder,aName,aVersion))
161 return PCDM_RS_UnknownDocument;
162 else if (!theMetaDataDriver->HasReadPermission(aFolder,aName,aVersion))
163 return PCDM_RS_PermissionDenied;
166 theTimer.ShowAndRestart("theMetaDataDriver->Find: ");
169 Handle(CDM_MetaData) theMetaData = theMetaDataDriver->MetaData(aFolder,aName,aVersion);
172 theTimer.ShowAndStop("Getting MetaData: ");
175 if(theMetaData->IsRetrieved()) {
176 return theMetaData->Document()->IsModified()
177 ? PCDM_RS_AlreadyRetrievedAndModified : PCDM_RS_AlreadyRetrieved;
180 TCollection_ExtendedString theFileName=theMetaData->FileName();
181 TCollection_ExtendedString theFormat=PCDM_ReadWriter::FileFormat(theFileName);
182 if(theFormat.Length()==0) {
183 TCollection_ExtendedString ResourceName=UTL::Extension(theFileName);
184 ResourceName+=".FileFormat";
185 if(UTL::Find(Resources(),ResourceName)) {
186 theFormat=UTL::Value(Resources(),ResourceName);
189 return PCDM_RS_UnrecognizedFileFormat;
191 if(!FindReaderFromFormat(theFormat)) return PCDM_RS_NoDriver;
200 //=======================================================================
201 //function : Activate
203 //=======================================================================
204 //void CDF_Application::Activate(const Handle(CDM_Document)& aDocument,const CDF_TypeOfActivation aTypeOfActivation) {
205 void CDF_Application::Activate(const Handle(CDM_Document)& ,const CDF_TypeOfActivation ) {
208 //=======================================================================
209 //function : DefaultFolder
211 //=======================================================================
212 Standard_ExtString CDF_Application::DefaultFolder(){
213 if(myDefaultFolder.Length() == 0) {
214 myDefaultFolder=CDF_Session::CurrentSession()->MetaDataDriver()->DefaultFolder();
216 return myDefaultFolder.ToExtString();
219 //=======================================================================
220 //function : SetDefaultFolder
222 //=======================================================================
223 Standard_Boolean CDF_Application::SetDefaultFolder(const Standard_ExtString aFolder) {
224 Standard_Boolean found = CDF_Session::CurrentSession()->MetaDataDriver()->FindFolder(aFolder);
225 if(found) myDefaultFolder=aFolder;
229 //=======================================================================
230 //function : DefaultExtension
232 //=======================================================================
233 Standard_ExtString CDF_Application::DefaultExtension() {
234 static TCollection_ExtendedString theDefaultExtension;
235 theDefaultExtension="*";
236 TColStd_SequenceOfExtendedString theFormats;
239 for (Standard_Integer i=1; i<= theFormats.Length(); i++) {
240 TCollection_ExtendedString theResource(theFormats(i));
241 theResource+=".FileExtension";
242 if(UTL::Find(Resources(),theResource)) {
243 theDefaultExtension=UTL::Value(Resources(),theResource);
244 return theDefaultExtension.ToExtString();
247 return theDefaultExtension.ToExtString();
250 //=======================================================================
251 //function : Retrieve
253 //=======================================================================
254 Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMetaData,const Standard_Boolean UseStorageConfiguration) {
255 return Retrieve(aMetaData,UseStorageConfiguration,Standard_True);
258 //=======================================================================
259 //function : Retrieve
261 //=======================================================================
262 Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMetaData,const Standard_Boolean UseStorageConfiguration, const Standard_Boolean IsComponent) {
264 Handle(CDM_Document) theDocumentToReturn;
265 myRetrievableStatus = PCDM_RS_DriverFailure;
267 Standard_SStream aMsg;
268 switch (CanRetrieve(aMetaData)) {
269 case PCDM_RS_UnknownDocument:
270 aMsg << "could not find the referenced document: " << aMetaData->Path() << "; not found." <<(char)0 << endl;
271 myRetrievableStatus = PCDM_RS_UnknownDocument;
272 Standard_Failure::Raise(aMsg);
274 case PCDM_RS_PermissionDenied:
275 aMsg << "Could not find the referenced document: " << aMetaData->Path() << "; permission denied. " <<(char)0 << endl;
276 myRetrievableStatus = PCDM_RS_PermissionDenied;
277 Standard_Failure::Raise(aMsg);
284 Standard_Boolean AlreadyRetrieved=aMetaData->IsRetrieved();
285 if(AlreadyRetrieved) myRetrievableStatus = PCDM_RS_AlreadyRetrieved;
286 Standard_Boolean Modified=AlreadyRetrieved && aMetaData->Document()->IsModified();
287 if(Modified) myRetrievableStatus = PCDM_RS_AlreadyRetrievedAndModified;
288 if(!AlreadyRetrieved || Modified) {
290 Handle(PCDM_Reader) theReader=Reader(aMetaData->FileName());
293 Handle(CDM_Document) theDocument;
296 theDocument=aMetaData->Document();
297 theDocument->RemoveAllReferences();
300 theDocument=theReader->CreateDocument();
302 SetReferenceCounter(theDocument,PCDM_RetrievalDriver::ReferenceCounter(aMetaData->FileName(), MessageDriver()));
304 SetDocumentVersion(theDocument,aMetaData);
305 theMetaDataDriver->ReferenceIterator()->LoadReferences(theDocument,aMetaData,this,UseStorageConfiguration);
309 theReader->Read(aMetaData->FileName(),theDocument,this);
311 catch (Standard_Failure) {
312 myRetrievableStatus = theReader->GetStatus();
313 if(myRetrievableStatus > PCDM_RS_AlreadyRetrieved){
314 Standard_SStream aMsg;
315 aMsg << Standard_Failure::Caught() << endl;
316 Standard_Failure::Raise(aMsg);
319 myRetrievableStatus = theReader->GetStatus();
320 theDocument->SetMetaData(aMetaData);
322 theDocumentToReturn=theDocument;
325 theDocumentToReturn=aMetaData->Document();
327 return theDocumentToReturn;
330 //=======================================================================
331 //function : DocumentVersion
333 //=======================================================================
334 Standard_Integer CDF_Application::DocumentVersion(const Handle(CDM_MetaData)& theMetaData) {
335 // const Handle(CDM_MessageDriver)& aMsgDriver = MessageDriver();
336 return PCDM_RetrievalDriver::DocumentVersion(theMetaData->FileName(), MessageDriver());
339 //=======================================================================
340 //function : TypeOfActivation
342 //=======================================================================
343 CDF_TypeOfActivation CDF_Application::TypeOfActivation(const Handle(CDM_MetaData)& aMetaData) {
345 if(aMetaData->IsRetrieved()) {
346 Handle(CDM_Document) theDocument=aMetaData->Document();
347 if(theDocument->IsOpened()) {
348 if(theDocument->IsModified())
349 return CDF_TOA_Modified;
351 return CDF_TOA_Unchanged;
361 //=======================================================================
362 //function : FindReader
364 //=======================================================================
365 Standard_Boolean CDF_Application::FindReader(const TCollection_ExtendedString& aFileName) {
366 Standard_GUID voidGUID;
367 TCollection_ExtendedString voidResourceName;
368 return FindReader(aFileName,voidGUID,voidResourceName);
371 //=======================================================================
374 //=======================================================================
375 Handle(PCDM_Reader) CDF_Application::Reader (const TCollection_ExtendedString& aFileName) {
376 TCollection_ExtendedString theFormat;
377 if (!Format(aFileName,theFormat)) {
378 Standard_SStream aMsg;
379 aMsg << "Could not found the format" <<(char)0;
380 Standard_NoSuchObject::Raise(aMsg);
383 return ReaderFromFormat (theFormat);
386 //=======================================================================
389 //=======================================================================
390 Handle(CDM_Document) CDF_Application::Read (Standard_IStream& theIStream)
392 Handle(CDM_Document) aDoc;
393 Handle(Storage_Data) dData;
395 TCollection_ExtendedString aFormat;
401 aFormat = PCDM_ReadWriter::FileFormat (theIStream, dData);
403 catch (Standard_Failure)
405 myRetrievableStatus = PCDM_RS_FormatFailure;
407 Standard_SStream aMsg;
408 aMsg << Standard_Failure::Caught() << endl;
409 Standard_Failure::Raise(aMsg);
412 if (aFormat.IsEmpty())
414 myRetrievableStatus = PCDM_RS_FormatFailure;
418 // 1. use a format name to detect plugin corresponding to the format to continue reading
419 Handle(PCDM_Reader) aReader = ReaderFromFormat (aFormat);
421 // 2. create document with the detected reader
422 aDoc = aReader->CreateDocument();
424 // 3. read the content of theIStream to aDoc
429 aReader->Read (theIStream, dData, aDoc, this);
431 catch (Standard_Failure)
433 myRetrievableStatus = aReader->GetStatus();
434 if (myRetrievableStatus > PCDM_RS_AlreadyRetrieved)
436 Standard_SStream aMsg;
437 aMsg << Standard_Failure::Caught() << endl;
438 Standard_Failure::Raise(aMsg);
442 myRetrievableStatus = aReader->GetStatus();
447 //=======================================================================
448 //function : FindReaderFromFormat
450 //=======================================================================
451 Standard_Boolean CDF_Application::FindReaderFromFormat(const TCollection_ExtendedString& aFormat) {
452 Standard_GUID voidGUID;
453 TCollection_ExtendedString voidResourceName;
454 return FindReaderFromFormat(aFormat,voidGUID,voidResourceName);
458 //=======================================================================
459 //function : ReaderFromFormat
461 //=======================================================================
462 Handle(PCDM_Reader) CDF_Application::ReaderFromFormat(const TCollection_ExtendedString& aFormat) {
463 TCollection_ExtendedString UnfoundResourceName;
464 Standard_GUID thePluginId;
465 if(!FindReaderFromFormat(aFormat,thePluginId,UnfoundResourceName)) {
466 Standard_SStream aMsg;
467 aMsg << "Could not found the item:" << UnfoundResourceName <<(char)0;
468 myRetrievableStatus = PCDM_RS_WrongResource;
469 Standard_NoSuchObject::Raise(aMsg);
471 Handle(PCDM_Reader) R;
474 R = Handle(PCDM_Reader)::DownCast(Plugin::Load(thePluginId));
476 catch (Standard_Failure) {
477 myRetrievableStatus = PCDM_RS_WrongResource;
478 Standard_SStream aMsg;
479 aMsg << Standard_Failure::Caught() << endl;
480 Standard_Failure::Raise(aMsg);
482 Handle(PCDM_RetrievalDriver) RD = Handle(PCDM_RetrievalDriver)::DownCast(R);
484 RD->SetFormat(aFormat);
487 myRetrievableStatus = PCDM_RS_WrongResource;
491 //=======================================================================
492 //function : FindReader
494 //=======================================================================
495 Standard_Boolean CDF_Application::FindReader(const TCollection_ExtendedString& aFileName, Standard_GUID& thePluginId, TCollection_ExtendedString& ResourceName) {
497 TCollection_ExtendedString theFormat=PCDM_ReadWriter::FileFormat(aFileName);
499 // It is good if the format is in the file. Otherwise base on the extension.
501 if(theFormat.Length()==0) {
502 ResourceName=UTL::Extension(aFileName);
503 ResourceName+=".FileFormat";
505 if(UTL::Find(Resources(),ResourceName)) {
506 theFormat=UTL::Value(Resources(),ResourceName);
509 return Standard_False;
511 return FindReaderFromFormat(theFormat,thePluginId,ResourceName);
514 //=======================================================================
517 //=======================================================================
518 Standard_Boolean CDF_Application::Format(const TCollection_ExtendedString& aFileName,
519 TCollection_ExtendedString& theFormat)
522 theFormat = PCDM_ReadWriter::FileFormat(aFileName);
523 // It is good if the format is in the file. Otherwise base on the extension.
524 if(theFormat.Length()==0) {
525 TCollection_ExtendedString ResourceName;
526 ResourceName=UTL::Extension(aFileName);
527 ResourceName+=".FileFormat";
529 if(UTL::Find(Resources(),ResourceName)) {
530 theFormat = UTL::Value(Resources(),ResourceName);
532 else return Standard_False;
534 return Standard_True;
537 //=======================================================================
538 //function : FindReaderFromFormat
540 //=======================================================================
541 Standard_Boolean CDF_Application::FindReaderFromFormat(const TCollection_ExtendedString& aFormat, Standard_GUID& thePluginId, TCollection_ExtendedString& ResourceName) {
543 ResourceName=aFormat;
544 ResourceName+=".RetrievalPlugin";
546 if(UTL::Find(Resources(),ResourceName)) {
547 // Get GUID as a string.
548 TCollection_ExtendedString strPluginId = UTL::Value(Resources(),ResourceName);
550 // If the GUID (as a string) contains blanks, remove them.
551 if (strPluginId.Search(' ') != -1)
552 strPluginId.RemoveAll(' ');
555 thePluginId=UTL::GUID(strPluginId);
556 return Standard_True;
558 return Standard_False;
561 //=======================================================================
562 //function : CanRetrieve
564 //=======================================================================
565 PCDM_ReaderStatus CDF_Application::CanRetrieve(const Handle(CDM_MetaData)& aMetaData) {
566 if(aMetaData->HasVersion())
567 return CanRetrieve(aMetaData->Folder(),aMetaData->Name(),aMetaData->Version());
569 return CanRetrieve(aMetaData->Folder(),aMetaData->Name());