summaryrefslogtreecommitdiff
path: root/samples/source/CustomSchema.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'samples/source/CustomSchema.cpp')
-rw-r--r--samples/source/CustomSchema.cpp237
1 files changed, 237 insertions, 0 deletions
diff --git a/samples/source/CustomSchema.cpp b/samples/source/CustomSchema.cpp
new file mode 100644
index 0000000..7e159b4
--- /dev/null
+++ b/samples/source/CustomSchema.cpp
@@ -0,0 +1,237 @@
+// =================================================================================================
+// Copyright 2002-2008 Adobe Systems Incorporated
+// All Rights Reserved.
+//
+// NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
+// of the Adobe license agreement accompanying it.
+// =================================================================================================
+
+/**
+* Tutorial solution for the Walkthrough 3 in the XMP Programmers Guide, Working with custom schema.
+*
+* Demonstrates how to work with a custom schema that has complex properties. It shows how to access
+* and modify properties with complex paths using the path composition utilities from the XMP API
+*/
+
+#include <string>
+
+// Must be defined to instantiate template classes
+#define TXMP_STRING_TYPE std::string
+
+// Ensure XMP templates are instantiated
+#include "XMP.incl_cpp"
+
+// Provide access to the API
+#include "XMP.hpp"
+
+#include <iostream>
+#include <fstream>
+
+// Made up namespace URI. Prefix will be xsdkEdit and xsdkUser
+const XMP_StringPtr kXMP_NS_SDK_EDIT = "http://ns.adobe/meta/sdk/Edit/";
+const XMP_StringPtr kXMP_NS_SDK_USERS = "http://ns.adobe/meta/sdk/User/";
+
+using namespace std;
+
+/**
+* Client defined callback function to dump XMP to a file. In this case an output file stream is used
+* to write a buffer, of length bufferSize, to a text file. This callback is called multiple
+* times during the DumpObject() operation. See the XMP API reference for details of
+* XMP_TextOutputProc() callbacks.
+*/
+XMP_Status XMPFileDump(void * refCon, XMP_StringPtr buffer, XMP_StringLen bufferSize)
+{
+ XMP_Status status = 0;
+ try
+ {
+ ofstream * outFile = static_cast<ofstream*>(refCon);
+ (*outFile).write(buffer, bufferSize);
+ }
+ catch(XMP_Error & e)
+ {
+ cout << e.GetErrMsg() << endl;
+ return -1;
+ }
+ return status;
+}
+
+/**
+* Client defined callback function to dump the registered namespaces to a file. In this case
+* an output file stream is used to write a buffer, of length bufferSize, to a text file. This
+* callback is called multiple times during the DumpObject() operation. See the XMP API
+* reference for details of XMP_TextOutputProc() callbacks.
+*/
+XMP_Status DumpNS(void * refCon, XMP_StringPtr buffer, XMP_StringLen bufferSize)
+{
+ XMP_Status status = 0;
+
+ try
+ {
+ ofstream *outFile= static_cast<ofstream*>(refCon);
+ (*outFile).write(buffer, bufferSize);
+ }
+ catch(XMP_Error & e)
+ {
+ cout << e.GetErrMsg() << endl;
+ return -1;
+ }
+ return status;
+}
+
+/**
+* Writes an XMP packet in XML format to a text file
+*
+* rdf - a pointer to the serialized XMP
+* filename - the name of the file to write to
+*/
+void writeRDFToFile(string * rdf, string filename)
+{
+ ofstream outFile;
+ outFile.open(filename.c_str(), ios::out);
+ outFile << *rdf;
+ outFile.close();
+}
+
+/**
+* Registers the namespaces that will be used with the custom schema. Then adds several new
+* properties to that schema. The properties are complex, containing nested arrays and structures.
+*
+* XMPFiles is not used in this sample, hence no external resource is updated with the metadata. The
+* created XMP object is serialized and written as RDF to a text file, the XMP object is dumped to
+* a text file and the registered namespaces are also dumped to a text file.*
+*
+*/
+int main()
+{
+ if(!SXMPMeta::Initialize())
+ {
+ cout << "Could not initialize Toolkit!";
+ }
+ else
+ {
+ try
+ {
+ // Register the namespaces
+ string actualPrefix;
+ SXMPMeta::RegisterNamespace(kXMP_NS_SDK_EDIT, "xsdkEdit", &actualPrefix);
+ SXMPMeta::RegisterNamespace(kXMP_NS_SDK_USERS, "xsdkUser",&actualPrefix);
+
+ SXMPMeta meta;
+
+ // Adds a user of the document
+ // 1. Add a new item onto the DocumentUsers array -
+ // 2. Compose a path to the last element of DocumentUsers array
+ // 3. Add a value for the User field of the UserDetails structure
+ // 4. Add a qualifier to the User field. Compose the path and set the value
+ // 5. Add a value for the DUID field of the UserDetails structure
+ // 6. Add a Contact property for the ContactDetails field of the UserDetails structure
+ // 7. Compose a path to the ContactDetails field of the UserDetails structure.
+ // 8. Create the fields of the ContactDetails structure and provide values
+
+ // Create/Append the top level DocumentUsers array. If the array exists a new item will be added
+ meta.AppendArrayItem(kXMP_NS_SDK_EDIT, "DocumentUsers", kXMP_PropValueIsArray, 0, kXMP_PropValueIsStruct);
+
+ // Compose a path to the last item in the DocumentUsers array, this will point to a UserDetails structure
+ string userItemPath;
+ SXMPUtils::ComposeArrayItemPath(kXMP_NS_SDK_EDIT, "DocumentUsers", kXMP_ArrayLastItem, &userItemPath);
+
+ // We now have a path to the structure, so we can set the field values
+ meta.SetStructField(kXMP_NS_SDK_EDIT, userItemPath.c_str(), kXMP_NS_SDK_USERS, "User", "John Smith", 0);
+
+ // Add a qualifier to the User field, first compose the path to the field and then add the qualifier
+ string userFieldPath;
+ SXMPUtils::ComposeStructFieldPath(kXMP_NS_SDK_EDIT, userItemPath.c_str(), kXMP_NS_SDK_USERS, "User", &userFieldPath);
+ meta.SetQualifier(kXMP_NS_SDK_EDIT, userFieldPath.c_str(), kXMP_NS_SDK_USERS, "Role", "Dev Engineer");
+
+ // Compose a path to the DUID and set field value
+ string duidPath;
+ SXMPUtils::ComposeStructFieldPath(kXMP_NS_SDK_EDIT, userItemPath.c_str(), kXMP_NS_SDK_USERS, "DUID", &duidPath);
+ meta.SetProperty_Int(kXMP_NS_SDK_EDIT, duidPath.c_str(), 2, 0);
+
+ // Add the ContactDetails field, this field is a Contact structure
+ meta.SetStructField(kXMP_NS_SDK_EDIT, userItemPath.c_str(), kXMP_NS_SDK_USERS, "ContactDetails", 0, kXMP_PropValueIsStruct);
+
+ // Compose a path to the field that has the ContactDetails structure
+ string contactStructPath;
+ SXMPUtils::ComposeStructFieldPath(kXMP_NS_SDK_EDIT, userItemPath.c_str(), kXMP_NS_SDK_USERS, "ContactDetails", &contactStructPath);
+
+ // Now add the fields - all empty initially
+ meta.SetStructField(kXMP_NS_SDK_EDIT, contactStructPath.c_str(), kXMP_NS_SDK_USERS, "Email", 0, kXMP_PropArrayIsAlternate);
+ meta.SetStructField(kXMP_NS_SDK_EDIT, contactStructPath.c_str(), kXMP_NS_SDK_USERS, "Telephone", 0, kXMP_PropValueIsArray);
+ meta.SetStructField(kXMP_NS_SDK_EDIT, contactStructPath.c_str(), kXMP_NS_SDK_USERS, "BaseLocation", "", 0);
+
+ // Add some values for the fields
+ // Email: Get the path to the field named 'Email' in the ContactDetails structure and use it to append items
+ string path;
+ SXMPUtils::ComposeStructFieldPath(kXMP_NS_SDK_EDIT, contactStructPath.c_str(), kXMP_NS_SDK_USERS, "Email", &path);
+ meta.AppendArrayItem(kXMP_NS_SDK_EDIT, path.c_str(), 0, "js@adobe.meta.com", 0);
+ meta.AppendArrayItem(kXMP_NS_SDK_EDIT, path.c_str(), 0, "js@adobe.home.com", 0);
+
+ // Telephone
+ SXMPUtils::ComposeStructFieldPath(kXMP_NS_SDK_EDIT, contactStructPath.c_str(), kXMP_NS_SDK_USERS, "Telephone", &path);
+ meta.AppendArrayItem(kXMP_NS_SDK_EDIT, path.c_str(), 0, "89112", 0);
+ meta.AppendArrayItem(kXMP_NS_SDK_EDIT, path.c_str(), 0, "84432", 0);
+
+ // BaseLocation
+ SXMPUtils::ComposeStructFieldPath(kXMP_NS_SDK_EDIT, contactStructPath.c_str(), kXMP_NS_SDK_USERS, "BaseLocation", &path);
+ meta.SetProperty(kXMP_NS_SDK_EDIT, path.c_str(), "London", 0);
+
+ // Add a user edit
+ // 1. Add an item (a structure) to the DocumentEdit array
+ // 2. Compose a path to the last item in the DocumentEdit array
+ // 3. Add fields and values to the EditDetails structure
+
+ // Create the array
+ meta.AppendArrayItem(kXMP_NS_SDK_EDIT, "DocumentEdit", kXMP_PropArrayIsOrdered, 0, kXMP_PropValueIsStruct);
+
+ // Compose a path to the last item of the DocumentEdit array, this gives the path to the structure
+ string lastItemPath;
+ SXMPUtils::ComposeArrayItemPath(kXMP_NS_SDK_EDIT, "DocumentEdit", kXMP_ArrayLastItem, &lastItemPath);
+
+ // Add the Date field
+ SXMPUtils::ComposeStructFieldPath(kXMP_NS_SDK_EDIT, lastItemPath.c_str(), kXMP_NS_SDK_EDIT, "EditDate", &path);
+ XMP_DateTime dt;
+ SXMPUtils::CurrentDateTime(&dt);
+ meta.SetProperty_Date(kXMP_NS_SDK_EDIT, path.c_str(), dt, 0);
+
+ // Add the DUID field
+ SXMPUtils::ComposeStructFieldPath(kXMP_NS_SDK_EDIT, lastItemPath.c_str(), kXMP_NS_SDK_EDIT, "DUID", &path);
+ meta.SetProperty_Int(kXMP_NS_SDK_EDIT, path.c_str(), 2, 0);
+
+ // Add the EditComments field
+ SXMPUtils::ComposeStructFieldPath(kXMP_NS_SDK_EDIT, lastItemPath.c_str(), kXMP_NS_SDK_EDIT, "EditComments", &path);
+ meta.SetLocalizedText(kXMP_NS_SDK_EDIT, path.c_str(), "en", "en-US", "Document created.", 0);
+
+ // Add the EditTool field
+ meta.SetStructField(kXMP_NS_SDK_EDIT, lastItemPath.c_str(), kXMP_NS_SDK_EDIT, "EditTool", "FrameXML", 0);
+
+ // Write the RDF to a file
+ cout << "writing RDF to file CS_RDF.txt" << endl;
+ string metaBuffer;
+ meta.SerializeToBuffer(&metaBuffer);
+ writeRDFToFile(&metaBuffer, "CS_RDF.txt");
+
+ // Dump the XMP object
+ cout << "dumping XMP object to file XMPDump.txt" << endl;
+ ofstream dumpFile;
+ dumpFile.open("XMPDump.txt", ios::out);
+ meta.DumpObject(XMPFileDump, &dumpFile);
+ dumpFile.close();
+
+ // Dump the namespaces to a file
+ cout << "dumping namespaces to file NameDump.txt" << endl;
+ dumpFile.open("NameDump.txt", ios::out);
+ meta.DumpNamespaces(XMPFileDump, &dumpFile);
+ dumpFile.close();
+
+ }
+ catch(XMP_Error & e)
+ {
+ cout << "ERROR: " << e.GetErrMsg();
+ }
+
+ SXMPMeta::Terminate();
+ }
+
+ return 0;
+}