All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.movielabs.mddflib.avails.xml.RowToXmlHelperV1_7_3 Maven / Gradle / Ivy

/**
 * Copyright (c) 2018 MovieLabs

 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.movielabs.mddflib.avails.xml;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.jdom2.Attribute;
import org.jdom2.Element;
import org.jdom2.Namespace;

import com.movielabs.mddflib.logging.LogMgmt;

/**
 * Create XML document from a v1.7.3 Excel spreadsheet. The XML generated will
 * be based on v2.3 of the Avails XSD and reflects a "best effort" in that there
 * is no guarantee that it is valid.
 * 
 * @author L. Levin, Critical Architectures LLC
 *
 */
public class RowToXmlHelperV1_7_3 extends RowToXmlHelperV1_7_2 {

	static final String MISSING = "--FUBAR (missing)";

	/**
	 * @param logger
	 * @param fields
	 */
	RowToXmlHelperV1_7_3(AvailsSheet sheet, Row row, LogMgmt logger) {
		super(sheet, row, logger);
	}

	protected void processTransactionBody(Element transactionEl) {
		String prefix = "AvailTrans/";
		addLicensee(transactionEl); // added v1.7.3

		process(transactionEl, "LicenseType", xb.getAvailsNSpace(), prefix + "LicenseType");
		process(transactionEl, "Description", xb.getAvailsNSpace(), prefix + "Description");
		/*
		 * for v1.7.3, Territory allows CSV list of multiple regions for SVOD
		 */
		addRegion(transactionEl, "Territory", xb.getAvailsNSpace(), prefix + "Territory", ",");
		/* TerritoryExclusion add in v1.7.3 */
		addRegion(transactionEl, "TerritoryExcluded", xb.getAvailsNSpace(), prefix + "TerritoryExclusion", ",");

		// Start or StartCondition
		processCondition(transactionEl, "Start", xb.getAvailsNSpace(), prefix + "Start");
		// End or EndCondition
		processCondition(transactionEl, "End", xb.getAvailsNSpace(), prefix + "End");

		/* WindowDuration is new for v1.7.3 */
		process(transactionEl, "WindowDuration", xb.getAvailsNSpace(), "AvailTrans/WindowDuration");

		processLanguage(transactionEl, "AllowedLanguage", xb.getAvailsNSpace(), prefix + "AllowedLanguages", ",", true);
		processLanguage(transactionEl, "HoldbackLanguage", xb.getAvailsNSpace(), prefix + "HoldbackLanguage", ",",
				true);
		Element[] assetLangEls = processLanguage(transactionEl, "AssetLanguage", xb.getAvailsNSpace(),
				prefix + "AssetLanguage", ",", true);
		processReqLanguages(assetLangEls);

		process(transactionEl, "LicenseRightsDescription", xb.getAvailsNSpace(), prefix + "LicenseRightsDescription");
		process(transactionEl, "FormatProfile", xb.getAvailsNSpace(), prefix + "FormatProfile");
		process(transactionEl, "ContractID", xb.getAvailsNSpace(), prefix + "ContractID");
		process(transactionEl, "ReportingID", xb.getAvailsNSpace(), prefix + "ReportingID");

		addAllTerms(transactionEl);

		process(transactionEl, "OtherInstructions", xb.getAvailsNSpace(), prefix + "OtherInstructions");

	}

	/**
	 * Handles the special case of the RequiredFulfillmentLanguages. If
	 * an AssetLanguage is also listed as a RequiredFulfillmentLanguage then
	 * AssetLanguage@assetProvided is set to true.
	 * 
	 * @param assetLangEls
	 */
	private void processReqLanguages(Element[] assetLangEls) {
		// 1st get the list of required fulfillment language:
		Pedigree pg = getPedigreedData("AvailTrans/RequiredFulfillmentLanguages");
		if (pg == null) {
			return;
		}
		String value = pg.getRawValue();
		String[] valueArray;
		String separator = ",";
		// remove white space
		value = value.replaceAll(" ", "");
		valueArray = value.split(separator);
		Collection reqLanguages = new HashSet(Arrays.asList(valueArray));
		Collection providedLanguages = new HashSet();
		if (assetLangEls != null) {
			for (int i = 0; i < assetLangEls.length; i++) {
				Element aEl = assetLangEls[i];
				String langCode = aEl.getValue();
				Attribute aa = aEl.getAttribute("asset");
				if (aa != null) {
					langCode = langCode + ":" + aa.getValue();
				}
				if (reqLanguages.contains(langCode)) {
					aEl.setAttribute("assetProvided", "true");
				}
				providedLanguages.add(langCode);
			}
		}
		// Now check for a REQUIRED language that IS NOT included in the set of
		// Asset Languages
		reqLanguages.removeAll(providedLanguages);
		reqLanguages.remove(""); // not the same as null
		// Anything left is probably an error
		if (!reqLanguages.isEmpty()) {
			Cell sourceCell = (Cell) pg.getSource();
			String details = "A RequiredFulfillmentLanguage should also be identified as an AssetLanguage that the content owner intends to provide. ";
			for (String reqLangCode : reqLanguages) {
				String errMsg = "Required fulfillment language '" + reqLangCode + "' is not an AssetLanguage";
				logger.logIssue(LogMgmt.TAG_XLATE, LogMgmt.LEV_ERR, sourceCell, errMsg, details, null,
						DefaultXmlBuilder.moduleId);
			}
		}
	}

	/**
	 * Process language related values that may or may not have an optional
	 * 'asset' suffix.
	 * 
	 * @param transactionEl
	 * @param childName
	 * @param ns
	 * @param cellKey
	 * @param listSep
	 * @param allowAssetSuffix
	 */
	protected Element[] processLanguage(Element transactionEl, String childName, Namespace ns, String cellKey,
			String listSep, boolean allowAssetSuffix) {
		// start with basic processing...
		Element[] elementList = process(transactionEl, childName, ns, cellKey, listSep);
		if (elementList == null) {
			return elementList;
		}
		/*
		 * if adding a suffix to the language code is allowed, we need to do
		 * some extra work. Otherwise return what we already have.
		 */
		if (!allowAssetSuffix) {
			return elementList;
		}
		/*
		 * specific assets can be specified for a given language by adding one
		 * of the following suffixes: "sub" for subtitle only, "dub" for dub
		 * only, and "subdub" for both subs and dubs. All of the following are
		 * therefore valid: "en", "fr-ca:subdub", "es-419:dub". If the colon
		 * delimiter is present, the suffix needs to be removed from the element
		 * value and converted to an attribute.
		 * 
		 */
		for (Element next : elementList) {
			String curValue = next.getText();
			String[] parts = curValue.split(":");
			if (parts.length == 2) {
				next.setText(parts[0]);
				next.setAttribute("asset", parts[1]);
			}
		}
		return elementList;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.movielabs.mddflib.avails.xml.RowToXmlHelperV1_7#processCondition(org.
	 * jdom2.Element, java.lang.String, org.jdom2.Namespace, java.lang.String)
	 */
	protected Element processCondition(Element parentEl, String childName, Namespace ns, String cellKey) {
		Element condEl = super.processCondition(parentEl, childName, ns, cellKey);
		/*
		 * New for v1.7.3 is "lag". Need to see if a start or end lag was
		 * specified and, if so is it allowed.
		 */
		String lagKey = childName + "Lag";
		String lagCell = "AvailTrans/" + lagKey;
		Pedigree lagData = getPedigreedData(lagCell);
		if (!isSpecified(lagData)) {
			/* nothing specified so just return what we already have */
			return condEl;
		}
		/*
		 * Now we need to verify we have either a valid StartCondition or
		 * EndCondition as 'Lag' is not compatible with the plain vanilla Start
		 * or End.
		 */
		String anchorKey = childName + " Condition";
		if (condEl == null) {
			Cell sourceCell = (Cell) lagData.getSource();
			String errMsg = "Invalid use of '" + lagKey + "'; Missing " + anchorKey;
			String details = lagKey + " is an offest from a " + anchorKey + ". The " + anchorKey
					+ " value, however, was not specified";
			logger.logIssue(LogMgmt.TAG_XLSX, LogMgmt.LEV_ERR, sourceCell, errMsg, details, null, DefaultXmlBuilder.moduleId);
			return condEl;
		}
		// Have a base value but is it the right type?
		if (!condEl.getName().endsWith("Condition")) {
			Cell sourceCell = (Cell) lagData.getSource();
			String errMsg = "Invalid use of '" + lagKey + "'; Base value must be conditional ";
			String details = lagKey + " is an offest from a " + anchorKey + ". The " + childName
					+ " value, however, was specified as an absolute date/time";
			logger.logIssue(LogMgmt.TAG_XLSX, LogMgmt.LEV_ERR, sourceCell, errMsg, details, null, DefaultXmlBuilder.moduleId);
			return condEl;
		}
		// All checks passed so we can add the attribute
		condEl.setAttribute("lag", lagData.getRawValue());
		xb.addToPedigree(condEl.getAttribute("lag"), lagData);
		return condEl;
	}

	/**
	 * @param transactionEl
	 */
	private void addLicensee(Element transactionEl) {
		Pedigree pg = getPedigreedData("Avail/Licensee");
		if (isSpecified(pg)) {
			Element licenseeEl = new Element("Licensee", xb.getAvailsNSpace());
			Element nameEl = process(licenseeEl, "DisplayName", xb.getMdNSpace(), "Avail/Licensee");
			transactionEl.addContent(licenseeEl);
		}

	}

	protected void addAllTerms(Element transactionEl) {
		super.addAllTerms(transactionEl);

		/* Now add Terms that are new for v1.7.3 */
		String prefix = "AvailTrans/";
		addTerm(transactionEl, prefix + "Download", "Download", "Text");
		addTerm(transactionEl, prefix + "Exclusive", "Exclusive", "Boolean");
		addTerm(transactionEl, prefix + "ExclusiveAttributes", "ExclusiveAttributes", "Text");
		addTerm(transactionEl, prefix + "BrandingRights", "BrandingRights", "Boolean");
		addTerm(transactionEl, prefix + "BrandingRightsAttributes", "BrandingRightsAttributes", "Text");
		addTerm(transactionEl, prefix + "TitleStatus", "TitleStatus", "Text");
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy