29. Erzeugung einer METS-XML-Datei
Kapitel hinzufügen

JavaScript zur Erzeugung einer METS-XML-Datei für einen Job unter Nutzung der KeyMap des Workflows. Das Script ist Bestandteil von BCS-2 V6 Professional. Sie finden es unter dem Dateinamen tt_create_mets_xml.js im folgenden Verzeichnis: C:\ProgramData\ImageWareComponents\BCS2_V6_64\js.

// -----------------------------------------------------------------------------------------------------------------
// WF-specific Variables
// -----------------------------------------------------------------------------------------------------------------
//
// Name                                Description                                              Default or Example
// ----                                -----------                                              ------------------
// BASE_URL                            Base URL for the whole Structure
// DOCUMENT_TYPE                       Type of Document (Monograph, Article, Periodical)
// DV_OWNER                            Rights-Owner                                             unknown
// DV_OWNER_CONTACT                    Contact (EMail) of Owner                                 bcs2@imageware.de
// DV_OWNER_LOGO                       URL of Logo-File                                         http://rlosw.de/dfg/bcs2.jpg
// DV_OWNER_SITE_URL                   Web-Site of Owner                                        http://www.imageware.de
// FOLDER_NAME                         Template for the Name of the Folder with images          $job.name$
//                                     and METS-XML File (relative to UPLOAD_MASTER_FOLDER
//                                     and BASE_URL
// GENERATE_ORIGINALS                  true or 1: turn on Originals Generation                  true
// GENERATE_PREVIEWS                   true or 1: turn on Preview Generation                    true
// GENERATE_THUMBNAILS                 true or 1: turn on Thumbnail Generation                  true
// INDEX_NAME                          Name of Structure Index which holds the
//                                     node-name (Structure or Pagenode...)
// METS_ROOT_ELEMENT                   Root-Element of generated METS-XML.
//                                     Adjust here to use the correct Versions...
// OMIT_FOLDER_AND_BASE_URL            true: just plain filenames in FLocat Elements            false
// ORIGINAL_FILE_NAME                  Template for Original Files                              orig_
// PREVIEW_FILE_NAME                   Template for Preview Files                               prev_
// THUMBNAIL_FILE_NAME                 Template for Thumbnail Files                             th_
// UPLOAD_HOST_MASTER_FOLDER           Master-Folder for Upload                                 /var/www/dfg
// UPLOAD_HOST_NAME                    Hostname for FTP/SFTP-Upload of Images and METS-File
// UPLOAD_HOST_PASSWORD                Password for FTP/SFTP Upload
// UPLOAD_HOST_USERNAME                Username for FTP/SFTP Upload
//
// -----------------------------------------------------------------------------------------------------------------

// -----------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------

function addFileGroup(tt_number, omit_folder_and_base_url, use, base_url, folder_name, file_name, mime_type)

{
   var mime_list = job.getKeyValue('TT_Result_List');

   if (tt_number >= mime_list.length) {
      ut.alertUser('Error during addFileGroup for target ' + tt_number + ':', 'internal Result-List is missing, aborting...');
      return;
   }

   var map       = mime_list[tt_number];
   var mime_list = map['Last_TT_MimeTypes'];
   var ext_list  = map['Last_TT_FileExtensions'];

   if (mime_list.length != ext_list.length) {
      ut.alertUser('Error during addFileGroup for target ' + tt_number + ':',
      'mime-type list length: ' + mime_list.length + ', ext list length: ' + ext_list.length + '. Error');
      return;
   }

   xr.xmlPush ("mets:fileGrp");
   xr.xmlAddAttribute ("USE", use);

// for (i = 1; i <= job.pages.length; i++) {
   for (i = 0; i < mime_list.length; i++) {

      mime_type  = mime_list[i];
      file_ext   = ext_list[i];
      log_number =  i + 1;

      id        = "FID" + log_number + "_" + file_name;

      xr.xmlPush ("mets:file");
      xr.xmlAddAttribute ("ID", id);
      xr.xmlAddAttribute ("MIMETYPE", mime_type);

      xr.xmlAddChild("mets:FLocat");

      if (omit_folder_and_base_url)
         url = file_name + "_" + log_number + "." + file_ext;
      else
         url = base_url + "/" + folder_name + "/" + file_name + "_" + log_number + "." + file_ext;

      xr.xmlAddAttribute ("xlink:href", url);
      xr.xmlAddAttribute ("LOCTYPE", "URL");

      xr.xmlPop(); // mets:file

   } // for i...

   xr.xmlPop(); // mets:fileGrp

} // fuction addFileGroup

// -----------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------

//
// Tranfer-Target-Numbers: zero-based Index !!!
// set the CORRECT transfer-target-numbers right here
// normally the three image-generating targets have indexes 0, 1 and 2
// but this may change, when you edit your WorkFlow...
//
var tt_number_thumbnails = 0;
var tt_number_previews   = 1;
var tt_number_originals  = 2;

//
// collect the items to generate...
//
var create_thumbnails        = ('true' == job.getWfKeyValue('GENERATE_THUMBNAILS'));
var create_previews          = ('true' == job.getWfKeyValue('GENERATE_PREVIEWS'));
var create_originals         = ('true' == job.getWfKeyValue('GENERATE_ORIGINALS'));
var omit_folder_and_base_url = ('true' == job.getWfKeyValue('OMIT_FOLDER_AND_BASE_URL'));

/*
ut.notifyUser('th', create_thumbnails);
ut.notifyUser('pr', create_previews);
ut.notifyUser('or', create_originals);
*/

var dv_owner            = job.getWfKeyValue('DV_OWNER');
var dv_owner_contact    = job.getWfKeyValue('DV_OWNER_CONTACT');
var dv_owner_logo       = job.getWfKeyValue('DV_OWNER_LOGO');
var dv_owner_site_url   = job.getWfKeyValue('DV_OWNER_SITE_URL');

var thumbnail_file_name = job.getWfKeyValue('THUMBNAIL_FILE_NAME');
var preview_file_name   = job.getWfKeyValue('PREVIEW_FILE_NAME');
var original_file_name  = job.getWfKeyValue('ORIGINAL_FILE_NAME');
var base_url            = job.getWfKeyValue('BASE_URL');
var folder_name         = eval(job.getWfKeyValue('FOLDER_NAME'));
var document_type       = job.getWfKeyValue('DOCUMENT_TYPE');

var job_name            = job.name;
var num_pages           = job.numPages;

var logmap_ID           = "logMD_" + job_name;
var admMD_ID            = "admMD_" + job_name;
var dmdMD_ID            = "dmdID_" + job_name;
var logmap;
var log2page_map;
var page_list;
var page_item;

//
// Initialize the XML-Document with the METS-Root-Element
//
xr.initGenericDocWithSubTree(job.getWfKeyValue('METS_ROOT_ELEMENT'));

xr.xmlAddAttribute ("OBJID", job_name);
xr.xmlAddAttribute ("TYPE",  "still image");
xr.xmlAddAttribute ("LABEL", "IWC");

//
// METS Header
//
xr.xmlPush ("mets:metsHdr");
xr.xmlAddAttribute ("CREATEDATE",  ut.dateTime("yyyy-MM-ddTHH:mm:ss"));
xr.xmlAddAttribute ("LASTMODDATE", ut.dateTime("yyyy-MM-ddTHH:mm:ss"));

xr.xmlPush ("mets:metsAgent");
xr.xmlAddAttribute ("ROLE", "CREATOR");
xr.xmlAddAttribute ("TYPE", "ORGANIZATION");

xr.xmlAddChild("mets:name");
xr.xmlAddText("N.N.");

xr.xmlPop(); // mets:metsAgent

xr.xmlPop(); // mets:metsHdr
//
// END METS Header
//

//
// DMD Section
//
xr.xmlPush ("mets:dmdSec");
xr.xmlAddAttribute ("ID", dmdMD_ID);

xr.xmlPush ("mets:mdWrap");
xr.xmlAddAttribute ("MDTYPE", "MODS");

xr.xmlPush ("mets:xmlData");

xr.xmlAddSubTree(job.getKeyValue("Mods_Xml_String"));

xr.xmlPop(); // mets:xmlData

xr.xmlPop(); // mets:mdWrap

xr.xmlPop(); // mets:dmdSec

//
// END DMD Section
//

//
// AMD Section
//
xr.xmlPush ("mets:amdSec");
xr.xmlAddAttribute ("ID", admMD_ID);

xr.xmlPush ("mets:rightsMD");
xr.xmlAddAttribute ("ID", "amd_dvrights_" + job_name);

xr.xmlPush ("mets:mdWrap");
xr.xmlAddAttribute ("MDTYPE",      "OTHER");
xr.xmlAddAttribute ("OTHERMDTYPE", "DVRIGHTS");
xr.xmlPush ("mets:xmlData");

xr.xmlPush ("dv:rights");

   xr.xmlAddChild("dv:owner",         dv_owner);
   xr.xmlAddChild("dv:ownerLogo",     dv_owner_logo);
   xr.xmlAddChild("dv:ownerSiteURL",  dv_owner_site_url);
   xr.xmlAddChild("dv:ownerContact",  dv_owner_contact);

xr.xmlPop(); // dv:rights
xr.xmlPop(); // mets:xmlData
xr.xmlPop(); // mets:mdWrap
xr.xmlPop(); // mets:rightsMD
xr.xmlPop(); // mets:amdSec

//
// END AMD Section
//

if (create_thumbnails || create_previews || create_originals) {

   //
   // File Section
   //
   xr.xmlPush ("mets:fileSec");

   if (create_thumbnails) {
      mime_type = "image/jpeg";
      addFileGroup(tt_number_thumbnails, omit_folder_and_base_url, "THUMBS", base_url, folder_name, thumbnail_file_name, mime_type)
   } // if create_thumbnails...

   if (create_previews) {
      mime_type = "image/jpeg";
      addFileGroup(tt_number_previews, omit_folder_and_base_url, "DEFAULT", base_url, folder_name, preview_file_name, mime_type)
   } // if create_previews...

   if (create_originals) {
      mime_type = "image/jpeg";
      addFileGroup(tt_number_originals, omit_folder_and_base_url, "MAX", base_url, folder_name, original_file_name, mime_type)
   } // if create_originals...

   xr.xmlPop(); // mets:fileSec

   //
   // Compute relevant Objects from the Job's internal structure Tree:
   // logmap: result of Function job.treeAsMetsStructure();
   // yields the following sub-objects:
   //
   // xml_string:   contains the XML-SubTree with the logical structure map
   // log2page_map: is a map: foreach Logical Item (by its ID) the corresponding page-number is given
   // page_list:    is a list of maps foreach physical page: given page-number, page-name, and optionally level and type
   //
   logmap       = job.treeAsMetsStructure();
   log2page_map = logmap['log2page_map'];
   page_list    = logmap['page_list'];


   //
   // Structure Map (Physical)
   //
   xr.xmlPush ("mets:structMap");
   xr.xmlAddAttribute ("TYPE", "PHYSICAL");

   //
   // top-level Div of Structure-Map
   //
   xr.xmlPush ("mets:div"); // toplevel div
   xr.xmlAddAttribute ("ID", "physMd_" + job_name);
   xr.xmlAddAttribute ("TYPE", "physSequence");

   //
   // Iterate over pages
   //
   for (i = 1; i <= job.pages.length; i++) {

      id        = "phys_" + i;

      if (i <= page_list.length)
         page_item = page_list[i-1];

      xr.xmlPush ("mets:div");
      xr.xmlAddAttribute ("ID", id);
      xr.xmlAddAttribute ("ORDER", page_item['number']);
      xr.xmlAddAttribute ("ORDERLABEL", page_item['name']);
      xr.xmlAddAttribute ("TYPE", "page");

      if (create_thumbnails) {
         id = "FID" + i + "_" + thumbnail_file_name;
         xr.xmlAddChild("mets:fptr");
         xr.xmlAddAttribute ("FILEID", id);
      } // if create_thumbs...

      if (create_previews) {
         id = "FID" + i + "_" + preview_file_name;
         xr.xmlAddChild("mets:fptr");
         xr.xmlAddAttribute ("FILEID", id);
      } // if create_thumbs...

      if (create_originals) {
         id = "FID" + i + "_" + original_file_name;
         xr.xmlAddChild("mets:fptr");
         xr.xmlAddAttribute ("FILEID", id);
      } // if create_thumbs...

      xr.xmlPop(); // mets:div

   } // for i...

   xr.xmlPop(); // mets:div toplevel


   xr.xmlPop(); // mets:structMap

   //
   // END Structure-Map (Physical)
   //

   //
   // Structure Map (Logical)
   //
   xr.xmlPush ("mets:structMap");
   xr.xmlAddAttribute ("TYPE", "LOGICAL");

   //
   // top-level Div of Structure-Map
   //
   xr.xmlPush ("mets:div"); // toplevel div
   xr.xmlAddAttribute ("ID", logmap_ID);
   xr.xmlAddAttribute ("DMDID", dmdMD_ID);
   xr.xmlAddAttribute ("AMDID", admMD_ID);
   xr.xmlAddAttribute ("TYPE", "monograph");


   xr.xmlAddSubTree(logmap['xml_string']);

   xr.xmlPop(); // mets:div toplevel


   xr.xmlPop(); // mets:structMap
   //
   // END Structure-Map (Physical)
   //

   //
   // structLink
   //
   xr.xmlPush ("mets:structLink");

   //
   // Connect top level Item of Structure to each
   // physical page
   //
   for (i = 1; i <= job.pages.length; i++) {

      phys_id = "phys_" + i;

      xr.xmlAddChild("mets:smLink");
      xr.xmlAddAttribute("xlink:to",   phys_id);
      xr.xmlAddAttribute("xlink:from", logmap_ID);

   } // for i

   //
   // now iterate over log2page_map: each entry corresponds an logical
   // structure element, and the value in the map ist the number of the
   // physical item...
   //
   for (log_item in log2page_map) {

      phys_id = "phys_" + log2page_map[log_item];

      xr.xmlAddChild("mets:smLink");
      xr.xmlAddAttribute("xlink:to",   phys_id);
      xr.xmlAddAttribute("xlink:from", log_item);

   } // for log_item in ...

   xr.xmlPop(); // mets:structLink
   //
   // END structLink
   //


} // if create_thumbnails...

//
// Also create a Link ready for the dfg-viewer...
//

dfg_viewer_link = 'http://dfg-viewer.de/show/?tx_dlf[id]=';
dfg_viewer_link += base_url;
dfg_viewer_link += '/' + folder_name + '/';
dfg_viewer_link += 'METS_' + job.name + '.xml';

//
// Insert into Job's KeyMap...
//
job.setKeyValue('dfg_viewer_url', dfg_viewer_link);


//
// This returns the generated XML and leads to writing the XML-File...
//
xr.genericXmlString();