1 /*
2 * Copyright 2006 Sony Computer Entertainment Inc.
3 *
4 * Licensed under the MIT Open Source License, for details please see license.txt or the website
5 * http://www.opensource.org/licenses/mit-license.php
6 *
7 */
8
9 #include <sstream>
10 #include <dae.h>
11 #include <dom.h>
12 #include <dae/daeDatabase.h>
13 #include <dae/daeIOPluginCommon.h>
14 #include <dae/daeMetaElement.h>
15 #include <dae/daeErrorHandler.h>
16 #include <dae/daeMetaElementAttribute.h>
17 #ifndef NO_ZAE
18 #include <dae/daeZAEUncompressHandler.h>
19 #endif
20
21 using namespace std;
22
daeIOPluginCommon()23 daeIOPluginCommon::daeIOPluginCommon()
24 : database(NULL),
25 topMeta(NULL)
26 {
27 }
28
~daeIOPluginCommon()29 daeIOPluginCommon::~daeIOPluginCommon()
30 {
31 }
32
setMeta(daeMetaElement * _topMeta)33 daeInt daeIOPluginCommon::setMeta(daeMetaElement *_topMeta)
34 {
35 topMeta = _topMeta;
36 return DAE_OK;
37 }
38
setDatabase(daeDatabase * _database)39 void daeIOPluginCommon::setDatabase(daeDatabase* _database)
40 {
41 database = _database;
42 }
43
44 // This function needs to be re-entrant, it can be called recursively from inside of resolveAll
45 // to load files that the first file depends on.
read(const daeURI & uri,daeString docBuffer)46 daeInt daeIOPluginCommon::read(const daeURI& uri, daeString docBuffer)
47 {
48 // Make sure topMeta has been set before proceeding
49 if (topMeta == NULL)
50 {
51 return DAE_ERR_BACKEND_IO;
52 }
53
54 // Generate a version of the URI with the fragment removed
55 daeURI fileURI(*uri.getDAE(), uri.str(), true);
56
57 //check if document already exists
58 if ( database->isDocumentLoaded( fileURI.getURI() ) )
59 {
60 return DAE_ERR_COLLECTION_ALREADY_EXISTS;
61 }
62
63 daeElementRef domObject = docBuffer ?
64 readFromMemory(docBuffer, fileURI) :
65 readFromFile(fileURI); // Load from URI
66
67 #ifdef NO_ZAE
68
69 if (!domObject) {
70 string msg = docBuffer ?
71 "Failed to load XML document from memory\n" :
72 string("Failed to load ") + fileURI.str() + "\n";
73 daeErrorHandler::get()->handleError(msg.c_str());
74 return DAE_ERR_BACKEND_IO;
75 }
76
77 // Insert the document into the database, the Database will keep a ref on the main dom, so it won't get deleted
78 // until we clear the database
79
80 daeDocument *document = NULL;
81
82 int res = database->insertDocument(fileURI.getURI(),domObject,&document);
83 if (res!= DAE_OK)
84 return res;
85
86 #else
87
88 bool zaeRoot = false;
89 string extractedURI = "";
90 if (!domObject) {
91 daeZAEUncompressHandler zaeHandler(fileURI);
92 if (zaeHandler.isZipFile())
93 {
94 string rootFilePath = zaeHandler.obtainRootFilePath();
95 daeURI rootFileURI(*fileURI.getDAE(), rootFilePath);
96 domObject = readFromFile(rootFileURI);
97 if (!domObject)
98 {
99 string msg = string("Failed to load ") + fileURI.str() + "\n";
100 daeErrorHandler::get()->handleError(msg.c_str());
101 return DAE_ERR_BACKEND_IO;
102 }
103 zaeRoot = true;
104 extractedURI = rootFileURI.str();
105 }
106 else
107 {
108 string msg = docBuffer ?
109 "Failed to load XML document from memory\n" :
110 string("Failed to load ") + fileURI.str() + "\n";
111 daeErrorHandler::get()->handleError(msg.c_str());
112 return DAE_ERR_BACKEND_IO;
113 }
114 }
115
116 // Insert the document into the database, the Database will keep a ref on the main dom, so it won't get deleted
117 // until we clear the database
118
119 daeDocument *document = NULL;
120
121 int res = database->insertDocument(fileURI.getURI(),domObject,&document, zaeRoot, extractedURI);
122 if (res!= DAE_OK)
123 return res;
124
125 #endif
126
127 return DAE_OK;
128 }
129
130
131
132
133
134
135
136
137
138
beginReadElement(daeElement * parentElement,daeString elementName,const vector<attrPair> & attributes,daeInt lineNumber)139 daeElementRef daeIOPluginCommon::beginReadElement(daeElement* parentElement,
140 daeString elementName,
141 const vector<attrPair>& attributes,
142 daeInt lineNumber) {
143 daeMetaElement* parentMeta = parentElement ? parentElement->getMeta() : topMeta;
144 daeElementRef element = parentMeta->create(elementName);
145
146 if(!element)
147 {
148 ostringstream msg;
149 msg << "The DOM was unable to create an element named " << elementName << " at line "
150 << lineNumber << ". Probably a schema violation.\n";
151 daeErrorHandler::get()->handleWarning( msg.str().c_str() );
152 return NULL;
153 }
154
155 // Process the attributes
156 for (size_t i = 0; i < attributes.size(); i++) {
157 daeString name = attributes[i].first,
158 value = attributes[i].second;
159 if (!element->setAttribute(name, value)) {
160 ostringstream msg;
161 msg << "The DOM was unable to create an attribute " << name << " = " << value
162 << " at line " << lineNumber << ".\nProbably a schema violation.\n";
163 daeErrorHandler::get()->handleWarning(msg.str().c_str());
164 }
165 }
166
167 if (parentElement == NULL) {
168 // This is the root element. Check the COLLADA version.
169 daeURI *xmlns = (daeURI*)(element->getMeta()->getMetaAttribute( "xmlns" )->getWritableMemory( element ));
170 if ( strcmp( xmlns->getURI(), COLLADA_NAMESPACE ) != 0 ) {
171 // Invalid COLLADA version
172 daeErrorHandler::get()->handleError("Trying to load an invalid COLLADA version for this DOM build!");
173 return NULL;
174 }
175 }
176
177 return element;
178 }
179
readElementText(daeElement * element,daeString text,daeInt elementLineNumber)180 bool daeIOPluginCommon::readElementText(daeElement* element, daeString text, daeInt elementLineNumber) {
181 if (element->setCharData(text))
182 return true;
183
184 ostringstream msg;
185 msg << "The DOM was unable to set a value for element of type " << element->getTypeName()
186 << " at line " << elementLineNumber << ".\nProbably a schema violation.\n";
187 daeErrorHandler::get()->handleWarning(msg.str().c_str());
188 return false;
189 }
190