예제 #1
0
  protected void checkLink(XMLElement e, String attrNS, String attr) {
    String href = e.getAttributeNS(attrNS, attr);
    String rel = e.getAttributeNS(attrNS, "rel");
    if (xrefChecker.isPresent()
        && href != null
        && rel != null
        && rel.toLowerCase().contains("stylesheet")) {
      href = PathUtil.resolveRelativeReference(path, href, base == null ? null : base.toString());
      xrefChecker
          .get()
          .registerReference(
              path,
              parser.getLineNumber(),
              parser.getColumnNumber(),
              href,
              XRefChecker.Type.STYLESHEET);

      // Check the mimetype to record possible non-standard stylesheets
      // with no fallback
      String mimetype = xrefChecker.get().getMimeType(href);
      if (mimetype != null) {
        if (OPFChecker.isBlessedStyleType(mimetype)
            || OPFChecker.isDeprecatedBlessedStyleType(mimetype)) {
          hasCss = true;
        } else {
          nonStandardStylesheetLink =
              Optional.of(
                  EPUBLocation.create(
                      path, parser.getLineNumber(), parser.getColumnNumber(), href));
        }
      }
    }
  }
예제 #2
0
 protected void checkImage(XMLElement e, String attrNS, String attr) {
   String href = e.getAttributeNS(attrNS, attr);
   if (xrefChecker.isPresent() && href != null) {
     href = PathUtil.resolveRelativeReference(path, href, base == null ? null : base.toString());
     xrefChecker
         .get()
         .registerReference(
             path, parser.getLineNumber(), parser.getColumnNumber(), href, XRefChecker.Type.IMAGE);
   }
 }
예제 #3
0
  protected void checkHRef(XMLElement e, String attrNS, String attr) {
    String href = e.getAttributeNS(attrNS, attr);
    if (href == null) {
      return;
    }
    href = href.trim();
    if (href.isEmpty()) {
      // if href="" then selfreference which is valid,
      // but as per issue 225, issue a hint
      report.message(
          MessageId.HTM_045,
          EPUBLocation.create(path, parser.getLineNumber(), parser.getColumnNumber(), href));
      return;
    } else if (href.contains("#epubcfi")) {
      return; // temp until cfi implemented
    } else if (".".equals(href)) {
      // selfreference, no need to check
      return;
    }

    URI uri = checkURI(href);
    if (uri == null) return;

    if ("http".equals(uri.getScheme())) {
      report.info(path, FeatureEnum.REFERENCE, href);
    }

    /*
     * mgy 20120417 adding check for base to initial if clause as part of
     * solution to issue 155
     */
    if (URISchemes.contains(uri.getScheme())
        || (null != base && URISchemes.contains(base.getScheme()))) {
      return;
    }
    // This if statement is needed to make sure XML Fragment identifiers
    // are not reported as non-registered URI scheme types
    else if (uri.getScheme() != null) {
      report.message(
          MessageId.HTM_025,
          EPUBLocation.create(path, parser.getLineNumber(), parser.getColumnNumber(), href));
      return;
    }

    try {
      href = PathUtil.resolveRelativeReference(path, href, base == null ? null : base.toString());
    } catch (IllegalArgumentException err) {
      report.message(
          MessageId.OPF_010,
          EPUBLocation.create(path, parser.getLineNumber(), parser.getColumnNumber(), href),
          err.getMessage());
      return;
    }
    processHyperlink(href);
  }
예제 #4
0
 public void startElement() {
   XMLElement e = parser.getCurrentElement();
   String ns = e.getNamespace();
   String name = e.getName();
   String id = e.getAttribute("id");
   if (ns.equals("http://www.daisy.org/z3986/2005/dtbook/")) {
     // link@href, a@href, img@src
     String uri = null;
     /*
      * This section checks to see if the references used are registered
      * schema-types and whether they point to external resources. The
      * resources are only allowed to be external if the attribute
      * "external" is set to true.
      */
     if (name.equals("a")) {
       uri = e.getAttribute("href");
       String external = e.getAttribute("external");
       if (uri != null && external.equals("true")) {
         if (OPSHandler.isRegisteredSchemeType(uri)) uri = null;
         else if (uri.indexOf(':') > 0) {
           parser
               .getReport()
               .warning(
                   path,
                   parser.getLineNumber(),
                   parser.getColumnNumber(),
                   "use of non-registered URI schema type in href: " + uri);
           uri = null;
         }
       }
     } else if (name.equals("link")) {
       uri = e.getAttribute("href");
     } else if (name.equals("img")) {
       uri = e.getAttribute("src");
     }
     if (uri != null) {
       // TODO check if dtbook uses xml:base of so set third param
       uri = PathUtil.resolveRelativeReference(path, uri, null);
       xrefChecker.registerReference(
           path,
           parser.getLineNumber(),
           parser.getColumnNumber(),
           uri,
           name.equals("img") ? XRefChecker.RT_IMAGE : XRefChecker.RT_HYPERLINK);
       if (uri.startsWith("http")) {
         parser.getReport().info(path, FeatureEnum.REFERENCE, uri);
       }
     }
     if (id != null)
       xrefChecker.registerAnchor(
           path, parser.getLineNumber(), parser.getColumnNumber(), id, XRefChecker.RT_HYPERLINK);
   }
 }
예제 #5
0
 protected void checkPaint(XMLElement e, String attr) {
   String paint = e.getAttribute(attr);
   if (xrefChecker.isPresent()
       && paint != null
       && paint.startsWith("url(")
       && paint.endsWith(")")) {
     String href = paint.substring(4, paint.length() - 1);
     href = PathUtil.resolveRelativeReference(path, href, base == null ? null : base.toString());
     xrefChecker
         .get()
         .registerReference(
             path,
             parser.getLineNumber(),
             parser.getColumnNumber(),
             href,
             XRefChecker.Type.SVG_PAINT);
   }
 }
예제 #6
0
 public void startElement() {
   XMLElement e = parser.getCurrentElement();
   String ns = e.getNamespace();
   String name = e.getName();
   if (ns.equals("http://www.daisy.org/z3986/2005/ncx/")) {
     if (name.equals("content")) {
       String href = e.getAttribute("src");
       if (href != null) {
         href = PathUtil.resolveRelativeReference(path, href, null);
         xrefChecker.registerReference(
             path,
             parser.getLineNumber(),
             parser.getColumnNumber(),
             href,
             XRefChecker.RT_HYPERLINK);
       }
     }
   }
 }
예제 #7
0
 private void processRef(String ref, XRefChecker.Type type) {
   if (ref != null && context.xrefChecker.isPresent()) {
     ref = PathUtil.resolveRelativeReference(path, ref, null);
     if (type == XRefChecker.Type.AUDIO) {
       String mimeType = context.xrefChecker.get().getMimeType(ref);
       if (mimeType != null && !OPFChecker30.isBlessedAudioType(mimeType)) {
         report.message(
             MessageId.MED_005,
             EPUBLocation.create(path, parser.getLineNumber(), parser.getColumnNumber()),
             ref,
             mimeType);
       }
     }
     context
         .xrefChecker
         .get()
         .registerReference(path, parser.getLineNumber(), parser.getColumnNumber(), ref, type);
   }
 }
예제 #8
0
  private void processLink(XMLElement e) {
    processLinkRel(e.getAttribute("rel"));
    // needs refactor: its problematic to register
    // link resources as items
    String id = e.getAttribute("id");
    String href = e.getAttribute("href");
    if (href != null && !href.matches("^[^:/?#]+://.*")) {
      try {
        href = PathUtil.resolveRelativeReference(path, href, null);
      } catch (IllegalArgumentException ex) {
        report.message(
            MessageId.OPF_010,
            new MessageLocation(path, parser.getLineNumber(), parser.getColumnNumber(), href),
            ex.getMessage());
        href = null;
      }
    }
    if (href != null && href.matches("^[^:/?#]+://.*")) {
      report.info(path, FeatureEnum.REFERENCE, href);
    }

    String mimeType = e.getAttribute("media-type");
    OPFItem item =
        new OPFItem(
            id, href, mimeType, "", "", "", null, parser.getLineNumber(), parser.getColumnNumber());

    if (id != null) {
      itemMapById.put(id, item);
    }

    // if (href != null) {
    // mgy: awaiting proper refactor, only add these if local
    if (href != null && !href.matches("^[^:/?#]+://.*")) {
      itemMapByPath.put(href, item);
      items.add(item);
    }
  }
예제 #9
0
  public void startElement() {
    boolean registerEntry = true;
    XMLElement e = parser.getCurrentElement();
    String ns = e.getNamespace();
    if (ns == null
        || ns.equals("")
        || ns.equals("http://openebook.org/namespaces/oeb-package/1.0/")
        || ns.equals("http://www.idpf.org/2007/opf")) {
      String name = e.getName();
      if (name.equals("package")) {
        if (!ns.equals("http://www.idpf.org/2007/opf")) {
          report.warning(
              path,
              parser.getLineNumber(),
              parser.getColumnNumber(),
              "OPF file is using OEBPS 1.2 syntax allowing backwards compatibility");
          opf12PackageFile = true;
        }
        /*
         * This section checks to see the value of the unique-identifier
         * attribute and stores it in the String uniqueIdent or reports
         * an error if the unique-identifier attribute is missing or
         * does not have a value
         */
        String uniqueIdentAttr = e.getAttribute("unique-identifier");
        if (uniqueIdentAttr != null && !uniqueIdentAttr.equals("")) {
          uniqueIdent = uniqueIdentAttr;
        } else {
          report.error(
              path,
              parser.getLineNumber(),
              parser.getColumnNumber(),
              "unique-identifier attribute in package element must be present and have a value");
        }
      } else if (name.equals("item")) {
        String id = e.getAttribute("id");
        String href = e.getAttribute("href");
        if (href != null && !(version == EPUBVersion.VERSION_3 && href.startsWith("http://"))) {
          try {
            href = PathUtil.resolveRelativeReference(path, href, null);
          } catch (IllegalArgumentException ex) {
            report.error(path, parser.getLineNumber(), parser.getColumnNumber(), ex.getMessage());
            href = null;
          }
        }
        String mimeType = e.getAttribute("media-type");
        String fallback = e.getAttribute("fallback");
        String fallbackStyle = e.getAttribute("fallback-style");
        String namespace = e.getAttribute("island-type");
        String properties = e.getAttribute("properties");
        if (properties != null) properties = properties.replaceAll("[\\s]+", " ");

        if (version == EPUBVersion.VERSION_3
            && href.startsWith("http://")
            && !OPFChecker30.isBlessedAudioType(mimeType))
          if (OPFChecker30.isCoreMediaType(mimeType)) {
            report.error(
                path,
                parser.getLineNumber(),
                parser.getColumnNumber(),
                "Only audio and video remote resources are permitted");
          } else {
            // mgy 20120414: this shouldn't even be a warning
            //						report.warning(
            //								path,
            //								parser.getLineNumber(),
            //								parser.getColumnNumber(),
            //								"Remote resource not validated");
          }

        OPFItem item =
            new OPFItem(
                id,
                href,
                mimeType,
                fallback,
                fallbackStyle,
                namespace,
                properties,
                parser.getLineNumber(),
                parser.getColumnNumber());

        if (id != null) itemMapById.put(id, item);
        if (properties != null) {
          String propertyArray[] = properties.split(" ");
          for (int i = 0; i < propertyArray.length; i++) {
            if (propertyArray[i].equals("nav")) item.setNav(true);
            if (propertyArray[i].equals("scripted")) item.setScripted(true);
          }
        }
        if (href != null && registerEntry) {
          itemMapByPath.put(href, item);
          items.add(item);
        }
      } else if (name.equals("reference")) {
        String type = e.getAttribute("type");
        String title = e.getAttribute("title");
        String href = e.getAttribute("href");
        if (href != null && xrefChecker != null) {
          try {
            href = PathUtil.resolveRelativeReference(path, href, null);
            xrefChecker.registerReference(
                path,
                parser.getLineNumber(),
                parser.getColumnNumber(),
                href,
                XRefChecker.RT_GENERIC);
          } catch (IllegalArgumentException ex) {
            report.error(path, parser.getLineNumber(), parser.getColumnNumber(), ex.getMessage());
            href = null;
          }
        }
        OPFReference ref =
            new OPFReference(type, title, href, parser.getLineNumber(), parser.getColumnNumber());
        refs.add(ref);
      } else if (name.equals("spine")) {
        String idref = e.getAttribute("toc");
        if (idref != null) {
          toc = (OPFItem) itemMapById.get(idref);
          if (toc == null)
            report.error(
                path,
                parser.getLineNumber(),
                parser.getColumnNumber(),
                "item with id '" + idref + "' not found");
          else {
            toc.setNcx(true);
            if (toc.getMimeType() != null && !toc.getMimeType().equals("application/x-dtbncx+xml"))
              report.error(
                  path,
                  parser.getLineNumber(),
                  parser.getColumnNumber(),
                  "toc attribute references resource with non-NCX mime type; \"application/x-dtbncx+xml\" is expected");
          }
        }
      } else if (name.equals("itemref")) {
        String idref = e.getAttribute("idref");
        if (idref != null) {
          OPFItem item = getItemById(idref);
          if (item != null) {
            spine.add(item);
            item.setInSpine(true);

            String linear = e.getAttribute("linear");
            if (linear != null && "no".equals(linear.trim())) {
              item.setSpineLinear(false);
            } else {
              item.setSpineLinear(true);
            }

          } else {
            report.error(
                path,
                parser.getLineNumber(),
                parser.getColumnNumber(),
                "item with id '" + idref + "' not found");
          }
        }
      } else if (name.equals("dc-metadata") || name.equals("x-metadata")) {
        if (!opf12PackageFile)
          report.error(
              path,
              parser.getLineNumber(),
              parser.getColumnNumber(),
              "use of deprecated element '" + name + "'");
      }
    } else if (ns.equals("http://purl.org/dc/elements/1.1/")) {
      // in the DC metadata, when the <identifier> element is parsed, if
      // it has a non-null and non-empty id attribute value that is the
      // same as the value of the unique-identifier attribute of the
      // package element, set uniqueIdentExists = true (to make sure that
      // the unique-identifier attribute references an existing
      // <identifier> id attribute
      String name = e.getName();
      if (name.equals("identifier")) {
        String idAttr = e.getAttribute("id");
        if (idAttr != null && !idAttr.equals("") && idAttr.equals(uniqueIdent))
          uniqueIdentExists = true;
      } else if (name.equals("creator")) {
        String role = e.getAttributeNS("http://www.idpf.org/2007/opf", "role");
        if (role != null && !role.equals("")) {
          if (!isValidRole(role))
            report.error(
                path,
                parser.getLineNumber(),
                parser.getColumnNumber(),
                "role value '" + role + "' is not valid");
        }
      }
    }
  }