Skip to content

Commit 3199b81

Browse files
committed
feat: new requirements of package link 'media-type' attribute
This commit implements the new requirements of the `media-type` attribute of the package document `link` element. - new `OPF-093` error is reported when the `media-type` attribute is missing on linked resources located inside the EPUB container - new `OPF-094` error is reported when the `media-type` attribute is missing on a link where the `rel` keyword requires it (this was previously checked with Schematron) - new `OPF-095` error is reported when the media type of a "voicing" linked resource is not an audio type (this was previously checked with Schematron) These new checks are implemented in Java, and the old schematron logic is removed. Fixes #1307
1 parent 035effa commit 3199b81

File tree

23 files changed

+150
-48
lines changed

23 files changed

+150
-48
lines changed

src/main/java/com/adobe/epubcheck/messages/DefaultSeverities.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,9 @@ private void initialize()
283283
severities.put(MessageId.OPF_090, Severity.USAGE);
284284
severities.put(MessageId.OPF_091, Severity.ERROR);
285285
severities.put(MessageId.OPF_092, Severity.ERROR);
286+
severities.put(MessageId.OPF_093, Severity.ERROR);
287+
severities.put(MessageId.OPF_094, Severity.ERROR);
288+
severities.put(MessageId.OPF_095, Severity.ERROR);
286289

287290
// PKG
288291
severities.put(MessageId.PKG_001, Severity.WARNING);

src/main/java/com/adobe/epubcheck/messages/MessageId.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ public enum MessageId implements Comparable<MessageId>
277277
OPF_090("OPF-090"),
278278
OPF_091("OPF-091"),
279279
OPF_092("OPF-092"),
280+
OPF_093("OPF-093"),
281+
OPF_094("OPF-094"),
282+
OPF_095("OPF-095"),
280283

281284
// Messages relating to the entire package
282285
PKG_001("PKG-001"),

src/main/java/com/adobe/epubcheck/opf/OPFHandler30.java

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ else if (EpubConstants.DCElements.equals(e.getNamespace()))
336336
* Document. Must be called after the parsing.
337337
*
338338
* @return the metadata for the Rendition represented by the current Package
339-
* Document
339+
* Document
340340
*/
341341
public MetadataSet getMetadata()
342342
{
@@ -350,7 +350,7 @@ public MetadataSet getMetadata()
350350
* called after the parsing.
351351
*
352352
* @return the linked resources for the Rendition represented by the current
353-
* Package Document
353+
* Package Document
354354
*/
355355
public LinkedResources getLinkedResources()
356356
{
@@ -363,7 +363,7 @@ public LinkedResources getLinkedResources()
363363
* the parsing.
364364
*
365365
* @return the linked resources for the Rendition represented by the current
366-
* Package Document
366+
* Package Document
367367
*/
368368
public ResourceCollections getCollections()
369369
{
@@ -446,28 +446,67 @@ private void processLink()
446446

447447
String href = e.getAttribute("href");
448448
if (href != null)
449-
{ // check by schema
449+
{ // href presence is checked by schema
450450

451+
// check the 'href' URL
451452
URL url = checkURL(href);
452-
if (context.isRemote(url)) {
453+
if (context.isRemote(url))
454+
{
453455
report.info(path, FeatureEnum.REFERENCE, href);
454456
}
455-
456457
if (context.xrefChecker.isPresent())
457458
{
458459
context.xrefChecker.get().registerReference(url, Type.LINK, location());
459460
}
460461

462+
// check the 'rel' attribute
463+
String rel = e.getAttribute("rel");
464+
Set<Property> relSet = processLinkRel(rel);
465+
Set<LINKREL_PROPERTIES> relEnum = Property.filter(relSet, LINKREL_PROPERTIES.class);
466+
467+
// check the 'media-type' attribute
468+
String mediatype = e.getAttribute("media-type");
469+
if (mediatype == null)
470+
{
471+
// media-type is required for in-container URLs
472+
// NOTE: as legacy EPUB 3.2 collections made heavy use
473+
// of local links with no media type, we only check this
474+
// for metadata links, which may be a violation of EPUB.
475+
if (!context.isRemote(url) && !metadataBuilders.isEmpty())
476+
{
477+
if (linkedResourcesBuilders.size() == 1)
478+
report.message(MessageId.OPF_093, location());
479+
}
480+
// media-type is required by some keywords
481+
else if (relEnum.stream().anyMatch(
482+
keyword -> keyword == LINKREL_PROPERTIES.RECORD
483+
|| keyword == LINKREL_PROPERTIES.VOICING))
484+
{
485+
report.message(MessageId.OPF_094, location(), rel);
486+
}
487+
}
488+
else
489+
{
490+
// 'voicing' links require an audio media type
491+
if (relEnum.contains(LINKREL_PROPERTIES.VOICING) && !OPFChecker30.isAudioType(mediatype))
492+
{
493+
report.message(MessageId.OPF_095, location(), mediatype);
494+
}
495+
}
496+
497+
// check the 'properties' attribute
498+
processLinkProperties(e.getAttribute("properties"));
499+
500+
// build the data model
461501
if (!linkedResourcesBuilders.isEmpty())
462502
{
463-
processLinkProperties(e.getAttribute("properties"));
464503
LinkedResource resource = new LinkedResource.Builder(url).id(e.getAttribute("id"))
465-
.rel(processLinkRel(e.getAttribute("rel"))).mimetype(e.getAttribute("media-type"))
466-
.refines(e.getAttribute("refines")).build();
504+
.rel(relSet).mimetype(mediatype).refines(e.getAttribute("refines")).build();
467505
linkedResourcesBuilders.peekFirst().add(resource);
468506
}
469507
}
470508

509+
// check hreflang attribute
471510
String hreflang = e.getAttribute("hreflang");
472511
if (hreflang != null && !hreflang.isEmpty())
473512
{

src/main/resources/com/adobe/epubcheck/messages/MessageBundle.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ OPF_089=The "alternate" link rel keyword cannot be paired with other keywords.
289289
OPF_090=It is encouraged to use MIME media type "%1$s" instead of "%2$s".
290290
OPF_091=The item href URL must not have a fragment identifier.
291291
OPF_092=Language tag "%1$s" is not well-formed: %2$s
292+
OPF_093=The "media-type" attribute is required for linked resources located in the EPUB container
293+
OPF_094=The "media-type" attribute is required for "%1$s" links.
294+
OPF_095=The "media-type" attribute of "voicing" links must be an audio MIME type, but found "%1$s".
292295

293296
#Package
294297
PKG_001=Validating the EPUB against version %1$s but detected version %2$s.

src/main/resources/com/adobe/epubcheck/schema/30/package-30.sch

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,15 @@
3434

3535
<pattern id="opf.link.record">
3636
<rule context="opf:link[tokenize(@rel,'\s+')='record']">
37-
<assert test="exists(@media-type)">The type of "record" references must be identifiable
38-
from the link element’s "media-type" attribute.</assert>
37+
<!--<assert test="exists(@media-type)">**checked in java**</assert>-->
3938
<assert test="empty(@refines)">"record" links only applies to the Publication (must not
4039
have a "refines" attribute).</assert>
4140
</rule>
4241
</pattern>
4342

4443
<pattern id="opf.link.voicing">
4544
<rule context="opf:link[tokenize(@rel,'\s+')='voicing']">
46-
<assert test="starts-with(normalize-space(@media-type),'audio/')">"voicing" links must have a "media-type" attribute identifying an audio MIME type.</assert>
45+
<!--<assert test="starts-with(normalize-space(@media-type),'audio/')">**checked in java**</assert>-->
4746
<assert test="exists(@refines)">"voicing" links must have a "refines" attribute.</assert>
4847
</rule>
4948
</pattern>

src/test/resources/epub3/03-resources/files/file-url-in-package-document-error.opf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<dc:language>en</dc:language>
66
<dc:identifier id="q">NOID</dc:identifier>
77
<meta property="dcterms:modified">2017-06-14T00:00:01Z</meta>
8-
<link href="file:example" rel="acquire"/>
8+
<link href="file:example" rel="acquire" media-type="text/html"/>
99
</metadata>
1010
<manifest>
1111
<item id="content_001" href="content_001.xhtml" media-type="application/xhtml+xml"/>

src/test/resources/epub3/05-package-document/files/link-to-publication-resource-error.opf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<dc:identifier id="uid">NOID</dc:identifier>
99
<meta property="dcterms:modified">2019-01-01T12:00:00Z</meta>
1010
<!--Linked resources MUST NOT be listed in the manifest.-->
11-
<link rel="example:property" href="contents.xhtml#ch1"/>
11+
<link rel="example:property" href="contents.xhtml#ch1" media-type="application/xhtml+xml"/>
1212
</metadata>
1313
<manifest>
1414
<item id="t001" href="contents.xhtml" properties="nav" media-type="application/xhtml+xml"/>

0 commit comments

Comments
 (0)