
com.adobe.epubcheck.overlay.OverlayHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of epubcheck Show documentation
Show all versions of epubcheck Show documentation
EPUBCheck is a tool to validate the conformance of EPUB publications against
the EPUB specifications. EPUBCheck can be run as a standalone command-line tool or used
as a Java library.
The newest version!
package com.adobe.epubcheck.overlay;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.w3c.epubcheck.core.references.Reference;
import org.w3c.epubcheck.util.url.URLUtils;
import com.adobe.epubcheck.api.EPUBLocation;
import com.adobe.epubcheck.messages.MessageId;
import com.adobe.epubcheck.opf.OPFChecker30;
import com.adobe.epubcheck.opf.ValidationContext;
import com.adobe.epubcheck.util.EpubConstants;
import com.adobe.epubcheck.vocab.AggregateVocab;
import com.adobe.epubcheck.vocab.PackageVocabs;
import com.adobe.epubcheck.vocab.PackageVocabs.ITEM_PROPERTIES;
import com.adobe.epubcheck.vocab.Property;
import com.adobe.epubcheck.vocab.StructureVocab;
import com.adobe.epubcheck.vocab.Vocab;
import com.adobe.epubcheck.vocab.VocabUtil;
import com.adobe.epubcheck.xml.handlers.XMLHandler;
import com.adobe.epubcheck.xml.model.XMLElement;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import io.mola.galimatias.URL;
public class OverlayHandler extends XMLHandler
{
private static Map RESERVED_VOCABS = ImmutableMap. of("",
AggregateVocab.of(StructureVocab.VOCAB, StructureVocab.UNCHECKED_VOCAB));
private static Map KNOWN_VOCAB_URIS = ImmutableMap.of();
private static Set DEFAULT_VOCAB_URIS = ImmutableSet.of(StructureVocab.URI);
private Map vocabs = RESERVED_VOCABS;
private Set resourceRefs = new HashSet();
private final Set requiredProperties = EnumSet.noneOf(ITEM_PROPERTIES.class);
public OverlayHandler(ValidationContext context)
{
super(context);
}
@Override
public void startElement()
{
XMLElement e = currentElement();
String name = e.getName();
processGlobalAttrs();
switch (name)
{
case "smil":
vocabs = VocabUtil.parsePrefixDeclaration(
e.getAttributeNS(EpubConstants.EpubTypeNamespaceUri, "prefix"), RESERVED_VOCABS,
KNOWN_VOCAB_URIS, DEFAULT_VOCAB_URIS, report, location());
break;
case "body":
case "seq":
processTextRef();
break;
case "text":
processTextSrc();
break;
case "audio":
processAudioSrc();
checkTime(e.getAttribute("clipBegin"), e.getAttribute("clipEnd"));
break;
}
}
private void checkTime(String clipBegin, String clipEnd)
{
if (clipEnd == null)
{
// missing clipEnd attribute means clip plays to end so no comparisons
// possible
return;
}
if (clipBegin == null)
{
// set clipBegin to 0 if the attribute isn't set to allow comparisons
clipBegin = "0";
}
SmilClock start;
SmilClock end;
try
{
start = new SmilClock(clipBegin);
end = new SmilClock(clipEnd);
} catch (Exception ex)
{
// invalid clock time will be reported by the schema
return;
}
if (start.compareTo(end) == 1)
{
// clipEnd is chronologically before clipBegin
report.message(MessageId.MED_008, location());
}
else if (start.equals(end))
{
// clipBegin and clipEnd are equal
report.message(MessageId.MED_009, location());
}
}
private void checkType(String type)
{
Set propList = VocabUtil.parsePropertyList(type, vocabs, context, location());
// Check unrecognized properties from the structure vocab
for (Property property : propList)
{
if (StructureVocab.URI.equals(property.getVocabURI())) try
{
property.toEnum();
} catch (UnsupportedOperationException ex)
{
report.message(MessageId.OPF_088, location(), property.getName());
}
}
}
private void processTextSrc()
{
URL url = checkURL(currentElement().getAttribute("src"));
processContentDocumentLink(url);
}
private void processTextRef()
{
URL url = checkURL(
currentElement().getAttributeNS(EpubConstants.EpubTypeNamespaceUri, "textref"));
processContentDocumentLink(url);
}
private void processAudioSrc()
{
URL url = checkURL(currentElement().getAttribute("src"));
// check that the URL has no fragment
if (url.fragment() != null)
{
report.message(MessageId.MED_014, location(), url.fragment());
url = URLUtils.docURL(url);
}
if (url != null && context.container.isPresent())
{
// check that the audio type is a core media type resource
String mimeType = context.resourceRegistry.get().getMimeType(url);
if (mimeType != null && !OPFChecker30.isBlessedAudioType(mimeType))
{
report.message(MessageId.MED_005, location(), context.relativize(url), mimeType);
}
// register the URL for cross-reference checking
registerReference(url, Reference.Type.AUDIO, true);
// if needed, register we found a remote resource
if (context.isRemote(url))
{
requiredProperties.add(ITEM_PROPERTIES.REMOTE_RESOURCES);
}
}
}
private void processContentDocumentLink(URL url)
{
if (url != null && context.container.isPresent())
{
assert context.overlayTextChecker.isPresent();
URL documentURL = URLUtils.docURL(url);
if (!context.overlayTextChecker.get().registerOverlay(documentURL,
context.opfItem.get().getId()))
{
report.message(MessageId.MED_011, location(), context.relativize(url));
}
registerReference(url, Reference.Type.OVERLAY_TEXT_LINK);
}
}
private void processGlobalAttrs()
{
XMLElement e = currentElement();
checkType(e.getAttributeNS(EpubConstants.EpubTypeNamespaceUri, "type"));
}
@Override
public void endElement()
{
XMLElement e = currentElement();
String name = e.getName();
if (name.equals("smil"))
{
checkItemReferences();
checkProperties();
}
}
private void checkItemReferences()
{
if (this.resourceRefs.isEmpty())
{
return;
}
}
protected void checkProperties()
{
if (!context.container.isPresent()) // single file validation
{
return;
}
Set itemProps = Property.filter(context.properties, ITEM_PROPERTIES.class);
for (ITEM_PROPERTIES requiredProperty : Sets.difference(requiredProperties, itemProps))
{
report.message(MessageId.OPF_014, EPUBLocation.of(context),
PackageVocabs.ITEM_VOCAB.getName(requiredProperty));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy