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#ifndef __DAE_DATABASE__
10#define __DAE_DATABASE__
11
12#include <memory>
13#include <vector>
14#include <dae.h>
15#include <dae/daeTypes.h>
16#include <dae/daeElement.h>
17#include <dae/daeURI.h>
18#include <dae/daeDocument.h>
19
20
21/**
22 * The @c daeDatabase class defines the COLLADA runtime database interface.
23 */
24class DLLSPEC daeDatabase
25{
26public:
27	/**
28	 * Constructor
29	 */
30	daeDatabase(DAE& dae);
31
32	/**
33	 * Destructor
34	 */
35	virtual ~daeDatabase() {}
36
37	/**
38	 * Get the associated DAE object.
39	 * @return The associated DAE object.
40	 */
41	virtual DAE* getDAE();
42
43	/**
44	* Creates a new document, defining its root as the <tt><i>dom</i></tt> object; returns an error if the document name already exists.
45	* @param name Name of the new document, must be a valid URI.
46	* @param dom Existing @c domCOLLADA root element of the document
47	* @param document Pointer to a @c daeDocument pointer that receives the document created
48    * @param zaeRootDocument Indicates if the new document is the root document of a ZAE archive.
49    * @param extractedFileURI URI to extracted dae file.
50	* @return Returns @c DAE_OK if the document was created successfully, otherwise returns a negative value as defined in daeError.h.
51	* @note The @c daeElement passed in as <tt><i>dom</i></tt> should always be a @c domCOLLADA object, the API may enforce this in the future.
52	* @deprecated This function will be removed in future versions. Please use createDocument.
53	*/
54	virtual daeInt insertDocument(daeString name, daeElement* dom, daeDocument** document = NULL, bool zaeRootDocument = false, const std::string& extractedFileURI = "") = 0;
55	/**
56	* Creates a new @c domCOLLADA root element and a new document; returns an error if the document name already exists.
57	* @param name Name of the new document, must be a valid URI.
58	* @param document Pointer to a @c daeDocument pointer that receives the document created
59	* @return Returns DAE_OK if the document was created successfully, otherwise returns a negative value as defined in daeError.h.
60	* @deprecated This function will be removed in future versions. Please use createDocument.
61	*/
62	virtual daeInt insertDocument(daeString name, daeDocument** document = NULL) = 0;
63	/**
64	* Creates a new document, defining its root as the <tt><i>dom</i></tt> object; returns an error if the document name already exists.
65	* @param name Name of the new document, must be a valid URI.
66	* @param dom Existing @c domCOLLADA root element of the document
67	* @param document Pointer to a @c daeDocument pointer that receives the document created
68    * @param zaeRootDocument Indicates if the new document is the root document of a ZAE archive.
69    * @param extractedFileURI URI to extracted dae file.
70	* @return Returns @c DAE_OK if the document was created successfully, otherwise returns a negative value as defined in daeError.h.
71	* @note The @c daeElement passed in as <tt><i>dom</i></tt> should always be a @c domCOLLADA object, the API may enforce this in the future.
72	*/
73	virtual daeInt createDocument(daeString name, daeElement* dom, daeDocument** document = NULL, bool zaeRootDocument = false, const std::string& extractedFileURI = "") = 0;
74	/**
75	* Creates a new @c domCOLLADA root element and a new document; returns an error if the document name already exists.
76	* @param name Name of the new document, must be a valid URI.
77	* @param document Pointer to a @c daeDocument pointer that receives the document created
78	* @return Returns DAE_OK if the document was created successfully, otherwise returns a negative value as defined in daeError.h.
79	*/
80	virtual daeInt createDocument(daeString name, daeDocument** document = NULL) = 0;
81
82	/**
83	 * Inserts an already existing document into the database.
84	 * @param c The document to insert.
85	 * @return Returns DAE_OK if the document was inserted successfully, otherwise returns a negative value as defined in daeError.h.
86	 */
87	virtual daeInt insertDocument( daeDocument *c ) = 0;
88
89	/**
90	* Removes a document from the database.
91	* @param document Document to remove from the database
92	* @return Returns DAE_OK if the document was successfully removed, otherwise returns a negative value as defined in daeError.h.
93	*/
94	virtual daeInt removeDocument(daeDocument* document) = 0;
95	/**
96	* Gets the number of documents.
97	* @return Returns the number of documents.
98	*/
99	virtual daeUInt getDocumentCount() = 0;
100	/**
101	* Gets a document based on the document index.
102	* @param index Index of the document to get.
103	* @return Returns a pointer on the document, or NULL if not found.
104	*/
105	virtual daeDocument* getDocument(daeUInt index) = 0;
106	/**
107	* Gets a document based on the document index.
108	* @param index Index of the document to get.
109	* @return Returns a pointer on the document, or NULL if not found.
110	*/
111	daeDocument* getDoc(daeUInt index);
112	/**
113	* Gets a document based on the document name.
114	* @param name The name of the document as a URI.
115	* @param skipUriNormalization Use the document name as is; don't normalize it first.
116	*   This is mostly for improved performance.
117	* @return Returns a pointer to the document, or NULL if not found.
118	* @note If the URI contains a fragment, the fragment is stripped off.
119	*/
120	virtual daeDocument* getDocument(daeString name, bool skipUriNormalization = false) = 0;
121	/**
122	* Gets a document name.
123	* @param index Index of the document to get.
124	* @return Returns the name of the document at the given index.
125	*/
126	virtual daeString getDocumentName(daeUInt index) = 0;
127	/**
128	* Indicates if a document is loaded or not.
129	* @param name Name of the document  as a URI.
130	* @return Returns true if the document is loaded, false otherwise.
131	* @note If the URI contains a fragment, the fragment is stripped off.
132	*/
133	virtual daeBool isDocumentLoaded(daeString name) = 0;
134
135	/**
136	* Inserts a @c daeElement into the runtime database.
137	* @param document Document in which the @c daeElement lives.
138	* @param element @c daeElement to insert in the database
139	* @return Returns @c DAE_OK if element successfully inserted, otherwise returns a negative value as defined in daeError.h.
140	*/
141	virtual daeInt insertElement(daeDocument* document,
142	                             daeElement* element) = 0;
143	/**
144	* Removes a @c daeElement from the runtime database; not implemented in the reference STL implementation.
145	* @param document Document in which the @c daeElement lives.
146	* @param element Element to remove.
147	* @return Returns @c DAE_OK if element successfully removed, otherwise returns a negative value as defined in daeError.h.
148	*/
149	virtual daeInt removeElement(daeDocument* document,
150	                             daeElement* element) = 0;
151	/**
152	 * Updates the database to reflect a change to the ID of a @c daeElement.
153	 * @param element @c daeElement whose ID is going to change.
154	 * @param newID The ID that will be assigned to the element.
155	 * @return Returns @c DAE_OK if the database was successfully updated, otherwise returns a negative value as defined in daeError.h.
156	 * @note The database doesn't actually change the ID of the element, it
157	 * merely updates its internal structures to reflect the change. It's
158	 * expected that the ID will be assigned to the element by someone else.
159	 */
160	virtual daeInt changeElementID(daeElement* element,
161	                               daeString newID) = 0;
162
163	/**
164	 * Updates the database to reflect a change to the sid of a @c daeElement.
165	 * @param element @c daeElement whose sid is going to change.
166	 * @param newSID The sid that will be assigned to the element.
167	 * @return Returns @c DAE_OK if the database was successfully updated, otherwise returns a negative value as defined in daeError.h.
168	 * @note The database doesn't actually change the sid of the element, it
169	 * merely updates its internal structures to reflect the change. It's
170	 * expected that the sid will be assigned to the element by someone else.
171 	 * Note - This function currently isn't implemented in the default database.
172	 */
173	virtual daeInt changeElementSID(daeElement* element,
174	                                daeString newSID) = 0;
175
176	/**
177	* Unloads all of the documents of the runtime database.
178	* This function frees all the @c dom* objects created so far,
179	* except any objects on which you still have a smart pointer reference (@c daeSmartRef).
180	* @return Returns @c DAE_OK if all documents successfully unloaded, otherwise returns a negative value as defined in daeError.h.
181	*/
182	virtual daeInt clear() = 0;
183
184	/**
185	 * Lookup elements by ID, searching through all documents.
186	 * @param id The ID to match on.
187	 * @return The array of matching elements.
188	 */
189	virtual std::vector<daeElement*> idLookup(const std::string& id) = 0;
190
191	/**
192	 * Find an element with the given ID in a specific document.
193	 * @param id The ID to match on.
194	 * @param doc The document to search in.
195	 * @return The matching element if one is found, NULL otherwise.
196	 */
197	daeElement* idLookup(const std::string& id, daeDocument* doc);
198
199	/**
200	 * Lookup elements by type ID.
201	 * @param typeID The type to match on, e.g. domNode::ID().
202	 * @param doc The document to search in, or NULL to search in all documents.
203	 * @return The array of matching elements.
204	 */
205	std::vector<daeElement*> typeLookup(daeInt typeID, daeDocument* doc = NULL);
206
207	/**
208	 * Same as the previous method, but returns the array of matching elements via a
209	 * reference parameter for additional efficiency.
210	 * @param typeID The type to match on, e.g. domNode::ID().
211	 * @param matchingElements The array of matching elements.
212	 * @param doc The document to search in, or NULL to search in all documents.
213	 */
214	virtual void typeLookup(daeInt typeID,
215	                        std::vector<daeElement*>& matchingElements,
216	                        daeDocument* doc = NULL) = 0;
217
218	/**
219	 * Lookup elements by type ID.
220	 * @param doc The document to search in, or NULL to search in all documents.
221	 * @return The array of matching elements.
222	 */
223	template<typename T>
224	std::vector<T*> typeLookup(daeDocument* doc = NULL) {
225		std::vector<T*> result;
226		typeLookup(result, doc);
227		return result;
228	}
229
230	/**
231	 * Same as the previous method, but returns the array of matching elements via a
232	 * reference parameter for additional efficiency.
233	 * @param matchingElements The array of matching elements.
234	 * @param doc The document to search in, or NULL to search in all documents.
235	 */
236	template<typename T> void
237	typeLookup(std::vector<T*>& matchingElements, daeDocument* doc = NULL) {
238		std::vector<daeElement*> elts;
239		typeLookup(T::ID(), elts, doc);
240		matchingElements.clear();
241		matchingElements.reserve(elts.size());
242		for (size_t i = 0; i < elts.size(); i++)
243			matchingElements.push_back((T*)elts[i]);
244	}
245
246	/**
247	 * Lookup elements by sid.
248	 * @param sid The sid to match on.
249	 * @param doc The document to search in, or NULL to search in all documents.
250	 * @return The array of matching elements.
251	 * Note - This function currently isn't implemented in the default database.
252	 */
253	std::vector<daeElement*> sidLookup(const std::string& sid, daeDocument* doc = NULL);
254
255	/**
256	 * Same as the previous method, but the results are returned via a parameter instead
257	 * of a return value, for extra efficiency.
258	 * @param sid The sid to match on.
259	 * @param matchingElements The array of matching elements.
260	 * @param doc The document to search in, or NULL to search in all documents.
261	 * Note - This function currently isn't implemented in the default database.
262	 */
263	virtual void sidLookup(const std::string& sid,
264	                       std::vector<daeElement*>& matchingElements,
265	                       daeDocument* doc = NULL) = 0;
266
267	/**
268	* Sets the top meta object.
269	* Called by @c dae::setDatabase() when the database changes. It passes to this function the
270	* top meta object, which is the root of a
271    * hierarchy of @c daeMetaElement objects. This top meta object is capable of creating
272	* any of the root objects in the DOM tree.
273	* @param _topMeta Top meta object to use to create objects to fill the database.
274	* @return Returns DAE_OK if successful, otherwise returns a negative value defined in daeError.h.
275	*/
276	virtual daeInt setMeta(daeMetaElement *_topMeta) = 0;
277
278public:
279	// The following methods are deprecated, and it's recommended that you don't use them.
280	// Where appropriate, alternative methods are specified.
281
282	virtual daeUInt getTypeCount() = 0;
283	virtual daeString getTypeName(daeUInt index) = 0;
284
285	// Instead of the following two methods, use idLookup or typeLookup.
286	virtual daeUInt getElementCount(daeString name = NULL,
287	                                daeString type = NULL,
288	                                daeString file = NULL) = 0;
289	virtual daeInt getElement(daeElement** pElement,
290	                          daeInt index,
291	                          daeString name = NULL,
292	                          daeString type = NULL,
293	                          daeString file = NULL ) = 0;
294
295	inline daeInt insertCollection(daeString name, daeElement* dom, daeDocument** document = NULL) {
296		return insertDocument( name, dom, document );
297	}
298	inline daeInt insertCollection(daeString name, daeDocument** document = NULL) {
299		return insertDocument( name, document );
300	}
301	inline daeInt createCollection(daeString name, daeElement* dom, daeDocument** document = NULL) {
302		return createDocument( name, dom, document );
303	}
304	inline daeInt createCollection(daeString name, daeDocument** document = NULL) {
305		return createDocument( name, document );
306	}
307	inline daeInt insertCollection( daeDocument *c ) {
308		return insertDocument( c );
309	}
310	inline daeInt removeCollection(daeDocument* document) {
311		return removeDocument( document );
312	}
313	inline daeUInt getCollectionCount() {
314		return getDocumentCount();
315	}
316	inline daeDocument* getCollection(daeUInt index) {
317		return getDocument( index );
318	}
319	inline daeDocument* getCollection(daeString name) {
320		return getDocument( name );
321	}
322	inline daeString getCollectionName(daeUInt index) {
323		return getDocumentName( index );
324	}
325	inline daeBool isCollectionLoaded(daeString name) {
326		return isDocumentLoaded( name );
327	}
328
329protected:
330	DAE& dae;
331};
332
333#endif //__DAE_DATABASE__
334
335