All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
Public Types | Public Member Functions | Static Public Member Functions
Qtilities::Core::Interfaces::IExportable Class Reference

Objects can implement this interface if they are able to export and reconstruct themselves. More...

#include <IExportable.h>

Inheritance diagram for Qtilities::Core::Interfaces::IExportable:
Inheritance graph
[legend]

List of all members.

Public Types

enum  ExportMode { None = 0, Binary = 1, XML = 2 }
 Possible export modes that an implementation of IExportable can support. More...
enum  Result {
  Complete = 0, Incomplete = 1, Failed = 2, FailedContinue = 4,
  VersionTooNew = 8, VersionTooOld = 16, VersionSupported = 32, SuccessResult = Complete | Incomplete | VersionSupported,
  FailedResult = Failed | FailedContinue | VersionTooNew | VersionTooOld
}
 The possible results of an export/import operation. More...

Public Member Functions

quint32 applicationExportVersion () const
 Returns the application export version currently used by all your application's classes.
virtual void clearExportTask ()
 Clears the export task.
IExportableduplicate (QString *error_msg=0, int properties_to_copy=0, ExportResultFlags *result_flags=0) const
 Function which will create a duplicate (copy) of this object.
virtual ExportResultFlags exportBinary (QDataStream &stream) const
 Allows exporting to a QDataStream.
virtual ITaskexportTask () const
 Gets the task which must be used to log import/export information to.
Qtilities::ExportVersion exportVersion () const
 Returns the export version currently used by all Qtilities classes.
virtual ExportResultFlags exportXml (QDomDocument *doc, QDomElement *object_node) const
 Allows exporting to an XML document. A reference to the QDomElement to which the object's information must be added is provided, along with a reference to the QDomDocument.
virtual ExportResultFlags importBinary (QDataStream &stream, QList< QPointer< QObject > > &import_list)
 Allows importing and reconstruction of the object state from information provided in a QDataStream.
virtual ExportResultFlags importXml (QDomDocument *doc, QDomElement *object_node, QList< QPointer< QObject > > &import_list)
 Allows importing and reconstruction of data from information provided in a XML document. A reference to the QDomElement which contains the object's information is provided, along with a reference to the QDomDocument.
virtual InstanceFactoryInfo instanceFactoryInfo () const
 The instance factory information which must be used when the exported object is reconstructed during an import.
bool isExportable () const
 Gets if this object must be part of it's parents' exports.
virtual void setApplicationExportVersion (quint32 version)
 Sets the application export version currently used by all your application's classes.
virtual void setExportTask (ITask *task)
 Sets the task which must be used to log import/export information to.
virtual void setExportVersion (Qtilities::ExportVersion version)
 Returns the export version currently used by all Qtilities classes.
virtual void setIsExportable (bool new_is_exportable)
 Sets if this object must be part of it's parents' exports.
virtual ExportModeFlags supportedFormats () const
 Provides information about the export format(s) supported by your implementation of IExportable.
- Public Member Functions inherited from Qtilities::Core::Interfaces::IObjectBase
virtual QObject * objectBase ()=0
 Returns the QObject* base of the interface.
virtual const QObject * objectBase () const =0
 Returns a const QObject* base of the interface.
QString objectOriginID () const
 Allows interfaces to provide some sort of source identification.
void setObjectOriginID (const QString &object_origin_id)
 Allows setting of the object source ID of this interface implementation.

Static Public Member Functions

template<typename T >
static T * duplicateInstance (IExportable *obj, QString *error_msg=0, int properties_to_copy=0, ExportResultFlags *result_flags=0)
 Provides an easy to use template based implementation of IExportable::duplicate().
static QString exportModeToString (ExportMode export_mode)
 Function which returns a string associated with a specific ExportMode.
static ExportMode stringToExportMode (const QString &export_mode_string)
 Function which returns the ExportMode associated with a string.
static Result validateQtilitiesExportVersion (Qtilities::ExportVersion export_version, ITask *task=0)
 Checks the exportVersion() against the supported Qtilities export versions for the current Qtilities version.
static Result validateQtilitiesImportVersion (Qtilities::ExportVersion import_version, ITask *task=0)
 Checks the exportVersion() against the supported Qtilities import versions for the current Qtilities version.

Detailed Description

Objects can implement this interface if they are able to export and reconstruct themselves.

IExportable is an interface used throughout Qtilities by classes in order to stream their data. At present two export options are supported:

Any object that implements this interface can specify which of the above export formats it supports through the supportedFormats() function. The interface also allows you to provide the needed information about reconstructing your object through the instanceFactoryInfo() function. In short, this allows your object to specify the factory that should be used to reconstruct it as well as the factory tag to use in that factory. For a detailed overview of the factory architecture used in Qtilities, please refer to Factories.

In your own applications you can easily implement this interface in order to make your objects reconstructable and exportable throughout Qtilities. For example if you implement this interface in an object and attach that object to an Qtilities::Core::Observer, the observer's export function will automatically make your object part of their exports. All export and import functions returns the result of their operation in the form of Qtilities::Core::Interfaces::IExportable::ExportResultFlags.

Lets look at the two export formats in detail.

Binary Exporting

Binary exports are done through the exportBinary() and importBinary() functions. This works exactly in the same way as normal << and >> stream operator, you get a QDataStream object to which your data is streamed. On the import side, there is an additional parameter which acts as a cleanup list. This is used in cases where you construct objects which are not parented through QObject::parent() and you have a long list of objects that is streamed. If an object close to then end of the list indicates that it failed, the import operation must be stopped and all unparented objects must be deleted in order to prevent memory leaks. In this case the list of objects which must be deleted will be available in this list.

See the Binary vs. XML Exports section of this page for a comparison between Binary and XML exports.

XML Exporting

XML exports allow you to build up an XML QDomDocument with information about a set of objects and is performed through the exportXml() and importXml() functions. These both provides you with a reference to the QDomDocument which allows you to create a new QDomElements. A QDomElement which represents your object is also provided. This allows you to easily construct new QDomElements and attach them to your objects node.

See the Binary vs. XML Exports section of this page for a comparison between Binary and XML exports.

Binary vs. XML Exports

Both binary and XML imports have their advantages and disadvantages and when using Qtilities projects, observers or export functions on the object manager, additional advantages and disadvantages applies.

Lets provide an overview of the advantages and disadvantages of both approaches:

Binary Exports
Advantages:

Disadvantages:

XML Exports
Advantages:

Disadvantages:

Clearly there are advantages in both export methods, and if more usefull standards arive in the future the interface can be expanded and your objects can easily adopt to new standards (JSON for example).

Versioning

Proper versioning of the format used during import and export operations is important if you want to support files that was exported using previous versions of your applications, and previous version of Qtilities. Much like the way QDataStream::version() functionality allows easy management of the format that internal Qt classes use during data streaming operations, the interface provides the exportVersion() and setExportVersion() functions in order to determine the formats used during export and import operations on Qtilities classes. In addition to that, the interface offers applicationExportVersion() and setApplicationExportVersion() which allows you keep track of what formatting to use for your own classes.

You can specify your application's export version as follows:

int main(int argc, char *argv[])
{
QtilitiesApplication a(argc, argv);
QtilitiesApplication::setOrganizationName("YourOrganization");
QtilitiesApplication::setOrganizationDomain("YourDomain");
QtilitiesApplication::setApplicationName("My Application");
QtilitiesApplication::setApplicationVersion("1.0");
// Set the application export version:
// lots of application code...
}

The same can be done in non-GUI applications through Qtilities::Core::QtilitiesCoreApplication. When using the approach above, all your classes which implement IExportable will automatically return the application export version you set, and you can specify a different version to use explicitly if you want to using the setter function. The exportVersion() function will automatically return the latest version of Qtilities, specified through Qtilities::Qtilities_Latest.

An important note is that in tree type hierarchical structure, the export and application export version must be traversed down the tree. This is automatically done by Qtilities::Core::Observer, thus if you attach your objects to an Observer and use it to do your exports, you don't need to worry about it. Also when using for example Qtilities::ProjectManagement::Project you don't need to care about this as it is automatically done for you. Or if you use Qtilities::CoreGui::TreeNode::saveToFile(), the same will apply, you don't need to worry about it.

For an overview of the data formats used by different versions of Qtilities, see Serializing Qtilities Data Types Overview.

Example Implementation

This section provides an example implementation of IExportable and shows some output results. We will only implement the XML import and export functions here for simplicity, but the same principles applies to Binary exports.

The example class is called VersionInformation and it basically stores information about a version number. It implements IExportable and implements itself as a FactoryItem so that it can be reconstructed during imports. The complete class along with its source code is part of the ExportingExample example in the QtilitiesExamples project and documented under Qtilities::Examples::ExportingExample::VersionDetails.

Here only the export and import functions will be shown. First, the export function which shows how the function handles different application versions.

IExportable::ExportResultFlags VersionDetails::exportXml(QDomDocument* doc, QDomElement* object_node) const {
// Create a simple node and add our information to it:
QDomElement revision_data = doc->createElement("RevisionInfo");
object_node->appendChild(revision_data);
// Information in both version 0 and version 1 of our class:
revision_data.setAttribute("DescriptionBrief",d->description_brief);
revision_data.setAttribute("DescriptionDetailed",d->description_detailed);
revision_data.setAttribute("Minor",d->version_minor);
revision_data.setAttribute("Major",d->version_major);
// Lets say we add a new parameter in the next version of the class:
revision_data.setAttribute("NewAttribute",d->new_attribute_storage);
}

And next the import function which checks the application export version again. In this case the version will be set to the version of the file that is parsed.

IExportable::ExportResultFlags VersionDetails::importXml(QDomDocument* doc, QDomElement* object_node, QList<QPointer<QObject> >& import_list) {
Q_UNUSED(doc)
Q_UNUSED(import_list)
return IExportable::VersionTooOld;
return IExportable::VersionTooNew;
// If we want to log messages here, we do it using the LOG_TASK macros since
// the exportTask() might have been set on IExportable. For example:
LOG_TASK_INFO("Importing VersionDetails...",exportTask());
// Find our RevisionInfo element:
IExportable::ExportResultFlags result = IExportable::Complete;
QDomNodeList childNodes = object_node->childNodes();
for(int i = 0; i < childNodes.count(); i++) {
QDomNode childNode = childNodes.item(i);
QDomElement child = childNode.toElement();
if (child.isNull())
continue;
if (child.tagName() == "RevisionInfo") {
if (child.hasAttribute("DescriptionBrief"))
d->description_brief = child.attribute("DescriptionBrief");
if (child.hasAttribute("DescriptionDetailed"))
d->description_detailed = child.attribute("DescriptionDetailed");
if (child.hasAttribute("Minor"))
d->version_minor = child.attribute("Minor").toInt();
if (child.hasAttribute("Major"))
d->version_major = child.attribute("Major").toInt();
if (child.hasAttribute("NewAttribute") && applicationExportVersion() == 1)
d->new_attribute_storage = child.attribute("NewAttribute");
continue;
}
}
return result;
}

The ExportingExample basically creates a couple of classes, attaches them to an Qtilities::CoreGui::TreeNode and exports them for us to see the effect of the applicationExportVersion().

int main(int argc, char *argv[])
{
QtilitiesApplication a(argc, argv);
QtilitiesApplication::setOrganizationName("YourOrganization");
QtilitiesApplication::setOrganizationDomain("YourDomain");
QtilitiesApplication::setApplicationName("My Application");
QtilitiesApplication::setApplicationVersion("1.0");
// Set the application export version:
// Register our VersionDetails class in the Qtilities factory:
FactoryItemID version_info_id("Version Details");
OBJECT_MANAGER->registerFactoryInterface(&VersionDetails::factory,version_info_id);
// Next create a TreeNode with a couple of our classes attached to it:
TreeNode* node = new TreeNode("TestNode");
VersionDetails* ver1 = new VersionDetails;
ver1->setDescriptionBrief("Version 1 Brief");
ver1->setDescriptionDetailed("Version 1 Brief");
ver1->setVersionMajor(0);
ver1->setVersionMinor(0);
VersionDetails* ver2 = new VersionDetails;
ver2->setDescriptionBrief("Version 2 Brief");
ver2->setDescriptionDetailed("Version 2 Brief");
ver2->setVersionMajor(1);
ver2->setVersionMinor(2);
node->attachSubject(ver1);
node->attachSubject(ver2);
node->addNode("NewNode");
// Next export the node to a file:
node->saveToFile("Output_Version_0.xml");
node->setApplicationExportVersion(1);
node->saveToFile("Output_Version_1.xml");
ObserverWidget* view = new ObserverWidget(node);
view->show();
return a.exec();
}

Finally we look at the section of the two output files for this example where the VersionDetails class was exported. First the contents of Output_Version_0.xml is shown:

<TreeItem Ownership="ManualOwnership" InstanceFactoryInfo="Version Details" Name="Version 1 Brief">
<RevisionInfo Minor="0" Major="0" DescriptionDetailed="Version 1 Brief" DescriptionBrief="Version 1 Brief"/>
</TreeItem>
<TreeItem Ownership="ManualOwnership" InstanceFactoryInfo="Version Details" Name="Version 2 Brief">
<RevisionInfo Minor="2" Major="1" DescriptionDetailed="Version 2 Brief" DescriptionBrief="Version 2 Brief"/>

Next the contents of Output_Version_1.xml is shown, note the added NewAttribute parameter:

<TreeItem Ownership="ManualOwnership" InstanceFactoryInfo="Version Details" Name="Version 1 Brief">
<RevisionInfo Minor="0" Major="0" DescriptionDetailed="Version 1 Brief" DescriptionBrief="Version 1 Brief" NewAttribute=""/>
</TreeItem>
<TreeItem Ownership="ManualOwnership" InstanceFactoryInfo="Version Details" Name="Version 2 Brief">
<RevisionInfo Minor="2" Major="1" DescriptionDetailed="Version 2 Brief" DescriptionBrief="Version 2 Brief" NewAttribute=""/>

If the above is not clear enough, running and playing around with the example should clear any confusion.


Member Enumeration Documentation

Possible export modes that an implementation of IExportable can support.

See also:
supportedFormats()
Enumerator:
None 

Does not support any export modes.

Binary 

Binary exporting using QDataStream.

See also:
exportBinary(), importBinary()
XML 

XML exporting using QDomDocument.

See also:
exportXml(), importXml()

The possible results of an export/import operation.

Enumerator:
Complete 

Complete when all the information was successfully exported/imported.

Incomplete 

Incomplete when some information could not be exported/imported. An example of this is when an Observer exports itself. When only a subset of the subjets observed by the observer implements the IExportable interface the Observer will return Partial because it was only exported partially.

Failed 

Failed when an error occured. The import/export must be aborted in this case.

FailedContinue 

Failed when an error occured. The import/export can continue in this case.

VersionTooNew 

Failed because the import format is too new. The import/export can continue in this case.

VersionTooOld 

Failed because the import format is too old. The import/export can continue in this case.

VersionSupported 

Flag indicating that an export version is supported by the current version of the application.

SuccessResult 

Successfull operation.

FailedResult 

Failed operation.


Member Function Documentation

quint32 Qtilities::Core::Interfaces::IExportable::applicationExportVersion ( ) const

Returns the application export version currently used by all your application's classes.

The default is version 0.

See also:
setApplicationExportVersion()
void Qtilities::Core::Interfaces::IExportable::clearExportTask ( )
virtual
Qtilities::Core::Interfaces::IExportable * Qtilities::Core::Interfaces::IExportable::duplicate ( QString *  error_msg = 0,
int  properties_to_copy = 0,
ExportResultFlags *  result_flags = 0 
) const

Function which will create a duplicate (copy) of this object.

This function will create a duplicate of this object. This operation is perfomed as follows:

This function allows powerfull duplication of any object implementing IExportable. For example, you can duplicate a complete tree by calling duplicate() on Qtilities::CoreGui::TreeNode.

Note:
In order for duplication to be complete, all items must be properly registered in a factory (or factories) known to the object manager. See the Factories article for more information.

This function is used by duplicateInstance() which is a template based wrapper around duplicate(). The example below demonstrates how to duplicate an object. The example duplicates a complete tree.

TreeNode node;
QStringList items;
items << "A" << "B" << "C";
node.addItems(items);
TreeNode* duplicated_node = IExportable::duplicateInstance<TreeNode>(&node);
Parameters:
properties_to_copyIndicates which dynamic QObject properties (if any) must be duplicated on the new object. By default no properties will be duplicated. This value is a Qtilities::Core::ObjectManager::PropertyTypeFlags flag casted to int.
result_flagsWhen a valid reference is passed, it will be set to the correct export result flags for the operation.
error_msgWhen a valid reference is passed, it will be populated with an error message when the duplication cannot be performed.
Returns:
A newly constructed duplicated object when successfull, null otherwise.
See also:
duplicateInstance()
template<typename T >
static T* Qtilities::Core::Interfaces::IExportable::duplicateInstance ( IExportable obj,
QString *  error_msg = 0,
int  properties_to_copy = 0,
ExportResultFlags *  result_flags = 0 
)
inlinestatic

Provides an easy to use template based implementation of IExportable::duplicate().

This function will create a duplicate of obj using IExportable::duplicate(). See the duplicate() function documentation for more information.

Note:
obj must implement the IExportable interface.
Parameters:
properties_to_copyIndicates which dynamic QObject properties (if any) must be duplicated on the new object. By default no properties will be duplicated. This value is a Qtilities::Core::ObjectManager::PropertyTypeFlags flag casted to int.
result_flagsWhen a valid reference is passed, it will be set to the correct export result flags for the operation.
error_msgWhen a valid reference is passed, it will be populated with an error message when the duplication cannot be performed.
objThe object to duplicate. Note that it must implement IExportable in order for this function to work.
Returns:
A newly constructed duplicated object when successfull, null otherwise.
See also:
duplicate()
Qtilities::Core::Interfaces::IExportable::ExportResultFlags Qtilities::Core::Interfaces::IExportable::exportBinary ( QDataStream &  stream) const
virtual
Qtilities::Core::Interfaces::ITask * Qtilities::Core::Interfaces::IExportable::exportTask ( ) const
virtual

Gets the task which must be used to log import/export information to.

See also:
setExportTask(), clearExportTask()
Qtilities::ExportVersion Qtilities::Core::Interfaces::IExportable::exportVersion ( ) const
inline

Returns the export version currently used by all Qtilities classes.

By default the latest Qtilities version is selected. For an overview of the data formats used by Qtilities, see Serializing Qtilities Data Types Overview.

See also:
setExportVersion()
Qtilities::Core::Interfaces::IExportable::ExportResultFlags Qtilities::Core::Interfaces::IExportable::exportXml ( QDomDocument *  doc,
QDomElement *  object_node 
) const
virtual
Qtilities::Core::Interfaces::IExportable::ExportResultFlags Qtilities::Core::Interfaces::IExportable::importBinary ( QDataStream &  stream,
QList< QPointer< QObject > > &  import_list 
)
virtual

Allows importing and reconstruction of the object state from information provided in a QDataStream.

See Serializing Qtilities Data Types Overview for more information about the expected output format.

Parameters:
streamThe QDataStream which contains the object's information.
import_listAll objects constructed during the import operation must be added to the import list. When the operation fails, all objects in this list will be deleted.

Reimplemented in Qtilities::Core::Observer, Qtilities::Core::ObserverHints, Qtilities::Core::SharedProperty, Qtilities::Core::ObserverRelationalTable, Qtilities::Core::QtilitiesCategory, Qtilities::Core::MultiContextProperty, Qtilities::Core::ActivityPolicyFilter, Qtilities::CoreGui::NamingPolicyFilter, Qtilities::Core::FileSetInfo, Qtilities::Core::QtilitiesProperty, Qtilities::Core::ObserverData, Qtilities::Core::RelationalTableEntry, Qtilities::Core::SubjectTypeFilter, Qtilities::ProjectManagement::Project, Qtilities::Core::CategoryLevel, Qtilities::ProjectManagement::ObserverProjectItemWrapper, Qtilities::ProjectManagement::CodeEditorProjectItemWrapper, and Qtilities::CoreGui::TreeItem.

Qtilities::Core::Interfaces::IExportable::ExportResultFlags Qtilities::Core::Interfaces::IExportable::importXml ( QDomDocument *  doc,
QDomElement *  object_node,
QList< QPointer< QObject > > &  import_list 
)
virtual
virtual InstanceFactoryInfo Qtilities::Core::Interfaces::IExportable::instanceFactoryInfo ( ) const
inlinevirtual
bool Qtilities::Core::Interfaces::IExportable::isExportable ( ) const
inline

Gets if this object must be part of it's parents' exports.

True by default.

void Qtilities::Core::Interfaces::IExportable::setApplicationExportVersion ( quint32  version)
virtual

Sets the application export version currently used by all your application's classes.

See also:
applicationExportVersion()

Reimplemented in Qtilities::Core::Observer.

void Qtilities::Core::Interfaces::IExportable::setExportTask ( ITask task)
virtual

Sets the task which must be used to log import/export information to.

To remove the task, use clearExportTask()

See also:
exportTask(), clearExportTask()

Reimplemented in Qtilities::Core::Observer, and Qtilities::Core::ObserverData.

virtual void Qtilities::Core::Interfaces::IExportable::setExportVersion ( Qtilities::ExportVersion  version)
inlinevirtual

Returns the export version currently used by all Qtilities classes.

By default the latest Qtilities version is selected.

See also:
exportVersion()

Reimplemented in Qtilities::Core::Observer, Qtilities::Core::QtilitiesCategory, Qtilities::Core::ObserverData, and Qtilities::ProjectManagement::ObserverProjectItemWrapper.

Qtilities::Core::Interfaces::IExportable::ExportModeFlags Qtilities::Core::Interfaces::IExportable::supportedFormats ( ) const
virtual
Qtilities::Core::Interfaces::IExportable::Result IExportable::validateQtilitiesExportVersion ( Qtilities::ExportVersion  export_version,
ITask task = 0 
)
static

Checks the exportVersion() against the supported Qtilities export versions for the current Qtilities version.

Parameters:
export_versionThe export version to check.
taskA task to which a compatibility message should be logged if its too new or too old.
Returns:
IExportable::VersionSupported when the version is supported, IExportable::VersionTooOld when the version is too new, IExportable::VersionTooOld when the version is too old.
Qtilities::Core::Interfaces::IExportable::Result IExportable::validateQtilitiesImportVersion ( Qtilities::ExportVersion  import_version,
ITask task = 0 
)
static

Checks the exportVersion() against the supported Qtilities import versions for the current Qtilities version.

Parameters:
import_versionThe import version to check.
taskA task to which a compatibility message should be logged if its too new or too old.
Returns:
IExportable::VersionSupported when the version is supported, IExportable::VersionTooOld when the version is too new, IExportable::VersionTooOld when the version is too old.


Qtilities : Reference Documentation Back to top Copyright © 2009-2013, Jaco Naudé