/*
* Copyright 2013-2016 Skynav, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY SKYNAV, INC. AND ITS CONTRIBUTORS “AS IS” AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SKYNAV, INC. OR ITS CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.skynav.ttv.verifier.util;
import java.net.URI;
import javax.xml.namespace.QName;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.Locator;
import com.skynav.ttv.model.ttml.TTML;
import com.skynav.ttv.model.value.Image;
import com.skynav.ttv.model.value.impl.EmbeddedImageImpl;
import com.skynav.ttv.model.value.impl.ExternalImageImpl;
import com.skynav.ttv.util.Location;
import com.skynav.ttv.util.Message;
import com.skynav.ttv.util.Reporter;
import com.skynav.ttv.util.URIs;
import com.skynav.ttv.verifier.ItemVerifier.ItemType;
import com.skynav.ttv.verifier.VerifierContext;
public class Images {
public static boolean isImage(String value, Location location, VerifierContext context, Image[] outputImage) {
return isImage(value, location, context, true, outputImage);
}
public static boolean isImage(String value, Location location, VerifierContext context, boolean verifyContent, Image[] outputImage) {
Image image;
if ((outputImage != null) && (outputImage.length < 1))
throw new IllegalArgumentException();
if (URIs.isLocalFragment(value)) {
String id = URIs.getFragment(value);
assert id != null;
Object content = location.getContent();
Node node = content != null ? context.getXMLNode(content) : null;
if ((node == null) && (content instanceof Element))
node = (Element) content;
if (node != null) {
Document document = node.getOwnerDocument();
if (document != null) {
Element targetElement = document.getElementById(id);
if (targetElement != null) {
Object target = context.getBindingElement(targetElement);
if (target != null) {
QName targetName = context.getBindingElementName(target);
if (!isImageElement(targetName))
return false; // target must be an image element
else {
URI base = location.getSystemIdAsURI();
URI uri = URIs.makeURISafely("#" + id, base);
image = internalImage(uri, target); // good local reference (though not necessarily resolvable)
}
} else
throw new IllegalStateException(); // no binding for target element (illegal state)
} else
return false; // no target element for given fragment identifier
} else
throw new IllegalStateException(); // no owner document (illegal state)
} else
throw new IllegalStateException(); // no node (illegal state)
} else if (value.trim().length() == value.length()) {
URI base = location.getSystemIdAsURI();
URI uri = URIs.makeURISafely(value, base);
if (uri == null)
return false; // bad syntax
else
image = externalImage(uri); // good non-local reference (though not necessarily resolvable)
} else if (value.length() > 0) {
return false; // image reference is all LWSP or has LWSP padding
} else {
return false; // image reference is empty string
}
// record specified type and format
image.setSpecifiedType(null); // [TBD] populate specified type from content
image.setSpecifiedFormat(null); // [TBD] populate speicifed format from content
// verify image content
assert image != null;
if (verifyContent && !context.getModel().getImageVerifier().verify(image, location.getLocator(), context, ItemType.Other))
return false;
// return image instance if requested
if (outputImage != null) {
assert outputImage.length > 0;
outputImage[0] = image;
}
return true;
}
private static Image internalImage(URI uri, Object target) {
return new EmbeddedImageImpl(uri, target);
}
private static Image externalImage(URI uri) {
return new ExternalImageImpl(uri);
}
public static void badImage(String value, Location location, VerifierContext context) {
Reporter reporter = context.getReporter();
Message m = null;
Locator locator = location.getLocator();
if (URIs.isLocalFragment(value)) {
String id = URIs.getFragment(value);
assert id != null;
Object content = location.getContent();
Node node = content != null ? context.getXMLNode(content) : null;
if ((node == null) && (content instanceof Element))
node = (Element) content;
if (node != null) {
Document document = node.getOwnerDocument();
if (document != null) {
Element targetElement = document.getElementById(id);
if (targetElement != null) {
Object target = context.getBindingElement(targetElement);
if (target != null) {
QName targetName = context.getBindingElementName(target);
if (!isImageElement(targetName)) { // target must be an image element
m = reporter.message(locator, "*KEY*",
"Bad <image> expression, got ''{0}'', target must be an image element.", value);
}
}
} else { // no target element for given fragment identifier
m = reporter.message(locator, "*KEY*",
"Bad <image> expression, got ''{0}'', no target element for given fragment identifier.", value);
}
}
}
} else if (value.trim().length() == value.length()) {
URI base = location.getSystemIdAsURI();
URI uri = URIs.makeURISafely(value, base);
if (uri == null) { // bad syntax
m = reporter.message(locator, "*KEY*",
"Bad <image> expression, got ''{0}'', illegal syntax.", value);
}
} else if (value.length() > 0) { // image reference is all LWSP or has LWSP padding
m = reporter.message(locator, "*KEY*",
"Bad <image> expression, got ''{0}'', all LWSP or has LWSP padding.", value);
} else { // image reference is empty string
m = reporter.message(locator, "*KEY*",
"Bad <image> expression, got ''{0}'', empty string.", value);
}
if (m != null)
reporter.logError(m);
}
private static final QName imageElementName = new QName(TTML.Constants.NAMESPACE_TT, "image");
private static boolean isImageElement(QName name) {
return name.equals(imageElementName);
}
}