private static <T> T getParamXPath(
     final Class<T> pClass, final String pXpath, final CompactFragment pBody) throws XmlException {
   // TODO Avoid JAXB where possible, use XMLDeserializer instead
   final boolean string = CharSequence.class.isAssignableFrom(pClass);
   Node match;
   DocumentFragment fragment =
       DomUtil.childrenToDocumentFragment(XMLFragmentStreamReader.from(pBody));
   for (Node n = fragment.getFirstChild(); n != null; n = n.getNextSibling()) {
     match = xpathMatch(n, pXpath);
     if (match != null) {
       if (!string) {
         XmlDeserializer deserializer = pClass.getAnnotation(XmlDeserializer.class);
         if (deserializer != null) {
           try {
             XmlDeserializerFactory<?> factory = deserializer.value().newInstance();
             factory.deserialize(XmlStreaming.newReader(new DOMSource(n)));
           } catch (InstantiationException | IllegalAccessException e) {
             throw new RuntimeException(e);
           }
         } else {
           return JAXB.unmarshal(new DOMSource(match), pClass);
         }
       } else {
         return pClass.cast(nodeToString(match));
       }
     }
   }
   return null;
 }
Пример #2
0
  @NotNull
  @Override
  public SimpleAdapter marshal(@NotNull final XmlSerializable v) throws Exception {

    final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    final Document document = dbf.newDocumentBuilder().newDocument();
    final DocumentFragment content = document.createDocumentFragment();
    final XMLOutputFactory xof = XMLOutputFactory.newFactory();
    final XMLStreamWriter out = xof.createXMLStreamWriter(new DOMResult(content));

    v.serialize(XmlStreaming.newWriter(new DOMResult(content)));
    final int childCount = content.getChildNodes().getLength();
    if (childCount == 0) {
      return new SimpleAdapter();
    } else if (childCount == 1) {
      final SimpleAdapter result = new SimpleAdapter();
      final Node child = content.getFirstChild();
      if (child instanceof Element) {
        result.setAttributes(child.getAttributes());
        for (Node child2 = child.getFirstChild();
            child2 != null;
            child2 = child2.getNextSibling()) {
          result.children.add(child2);
        }
      } else {
        result.children.add(child);
      }
      return result;
    } else { // More than one child
      final SimpleAdapter result = new SimpleAdapter();
      for (Node child = content.getFirstChild(); child != null; child = child.getNextSibling()) {
        result.children.add(child);
      }
      return result;
    }
  }
 @XContent
 protected void setGuards(DocumentFragment content) {
   Node node = content.getFirstChild();
   while (node != null) {
     if (node.getNodeType() == Node.ELEMENT_NODE) {
       String name = node.getNodeName();
       if ("guard".equals(name)) {
         NamedNodeMap map = node.getAttributes();
         Node aId = map.getNamedItem("id");
         Node aType = map.getNamedItem("type");
         if (aId == null) {
           throw new IllegalArgumentException("id is required");
         }
         String id = aId.getNodeValue();
         if (aType == null) {
           throw new IllegalArgumentException("type is required");
         } else {
           // String value = node.getTextContent().trim();
           // guards.put(id, new ScriptGuard(value));
           // TODO: compound guard
         }
         String type = aType.getNodeValue();
         if ("permission".equals(type)) {
           String value = node.getTextContent().trim();
           guards.put(id, new PermissionGuard(value));
         } else if ("isAdministrator".equals(type)) {
           String value = node.getTextContent().trim();
           guards.put(id, new IsAdministratorGuard(value));
         } else if ("facet".equals(type)) {
           String value = node.getTextContent().trim();
           guards.put(id, new FacetGuard(value));
         } else if ("type".equals(type)) {
           String value = node.getTextContent().trim();
           guards.put(id, new TypeGuard(value));
         } else if ("schema".equals(type)) {
           String value = node.getTextContent().trim();
           guards.put(id, new SchemaGuard(value));
         } else if ("user".equals(type)) {
           String value = node.getTextContent().trim();
           guards.put(id, new UserGuard(value));
         } else if ("group".equals(type)) {
           String value = node.getTextContent().trim();
           guards.put(id, new GroupGuard(value));
         } else if ("script".equals(type)) {
           Node engineNode = map.getNamedItem("engine");
           if (engineNode == null) {
             throw new IllegalArgumentException(
                 "Must specify an engine attribute on script guards");
           }
           String value = node.getTextContent().trim();
           guards.put(id, new ScriptGuard(engineNode.getNodeValue(), value));
         } else if ("expression".equals(type)) {
           String value = node.getTextContent().trim();
           try {
             guards.put(id, PermissionService.getInstance().parse(value, guards));
           } catch (ParseException e) {
             log.error(e, e);
           }
         } else { // the type should be a guard factory
           String value = node.getTextContent().trim();
           try {
             Class<?> factory = Class.forName(type);
             Guard guard = ((GuardFactory) factory.newInstance()).newGuard(value);
             guards.put(id, guard);
           } catch (Exception e) {
             log.error(e, e); // TODO should throw a DeployException
           }
         }
       }
     }
     node = node.getNextSibling();
   }
 }
Пример #4
0
  /**
   * Adjust column widths in an HTML table.
   *
   * <p>The specification of column widths in CALS (a relative width plus an optional absolute
   * width) are incompatible with HTML column widths. This method adjusts CALS column width
   * specifiers in an attempt to produce equivalent HTML specifiers.
   *
   * <p>In order for this method to work, the CALS width specifications should be placed in the
   * "width" attribute of the &lt;col>s within a &lt;colgroup>. Then the colgroup result tree
   * fragment is passed to this method.
   *
   * <p>This method makes use of two parameters from the XSL stylesheet that calls it: <code>
   * nominal.table.width</code> and <code>table.width</code>. The value of <code>nominal.table.width
   * </code> must be an absolute distance. The value of <code>table.width</code> can be either
   * absolute or relative.
   *
   * <p>Presented with a mixture of relative and absolute lengths, the table width is used to
   * calculate appropriate values. If the <code>table.width</code> is relative, the nominal width is
   * used for this calculation.
   *
   * <p>There are three possible combinations of values:
   *
   * <ol>
   *   <li>There are no relative widths; in this case the absolute widths are used in the HTML
   *       table.
   *   <li>There are no absolute widths; in this case the relative widths are used in the HTML
   *       table.
   *   <li>There are a mixture of absolute and relative widths:
   *       <ol>
   *         <li>If the table width is absolute, all widths become absolute.
   *         <li>If the table width is relative, make all the widths absolute relative to the
   *             nominal table width then turn them all back into relative widths.
   *       </ol>
   * </ol>
   *
   * @param context The stylesheet context; supplied automatically by Xalan
   * @param xalanNI
   * @return The result tree fragment containing the adjusted colgroup.
   */
  public DocumentFragment adjustColumnWidths(ExpressionContext context, NodeIterator xalanNI) {

    int nominalWidth = convertLength(Params.getString(context, "nominal.table.width"));
    String tableWidth = Params.getString(context, "table.width");
    String styleType = Params.getString(context, "stylesheet.result.type");
    boolean foStylesheet = styleType.equals("fo");

    DocumentFragment xalanRTF = (DocumentFragment) xalanNI.nextNode();
    Element colgroup = (Element) xalanRTF.getFirstChild();

    // N.B. ...stree.ElementImpl doesn't implement getElementsByTagName()

    Node firstCol = null;
    // If this is an FO tree, there might be no colgroup...
    if (colgroup.getLocalName().equals("colgroup")) {
      firstCol = colgroup.getFirstChild();
    } else {
      firstCol = colgroup;
    }

    // Count the number of columns...
    Node child = firstCol;
    int numColumns = 0;
    while (child != null) {
      if (child.getNodeType() == Node.ELEMENT_NODE
          && (child.getNodeName().equals("col")
              || (child.getNamespaceURI().equals(foURI)
                  && child.getLocalName().equals("table-column")))) {
        numColumns++;
      }

      child = child.getNextSibling();
    }

    String widths[] = new String[numColumns];
    Element columns[] = new Element[numColumns];
    int colnum = 0;

    child = firstCol;
    while (child != null) {
      if (child.getNodeType() == Node.ELEMENT_NODE
          && (child.getNodeName().equals("col")
              || (child.getNamespaceURI().equals(foURI)
                  && child.getLocalName().equals("table-column")))) {
        Element col = (Element) child;

        columns[colnum] = col;

        if (foStylesheet) {
          if ("".equals(col.getAttribute("column-width"))) {
            widths[colnum] = "1*";
          } else {
            widths[colnum] = col.getAttribute("column-width");
          }
        } else {
          if ("".equals(col.getAttribute("width"))) {
            widths[colnum] = "1*";
          } else {
            widths[colnum] = col.getAttribute("width");
          }
        }

        colnum++;
      }
      child = child.getNextSibling();
    }

    float relTotal = 0;
    float relParts[] = new float[numColumns];

    float absTotal = 0;
    float absParts[] = new float[numColumns];

    for (int count = 0; count < numColumns; count++) {
      String width = widths[count];
      int pos = width.indexOf("*");
      if (pos >= 0) {
        String relPart = width.substring(0, pos);
        String absPart = width.substring(pos + 1);

        try {
          float rel = Float.parseFloat(relPart);
          relTotal += rel;
          relParts[count] = rel;
        } catch (NumberFormatException e) {
          System.out.println(relPart + " is not a valid relative unit.");
        }

        int pixels = 0;
        if (absPart != null && !absPart.equals("")) {
          pixels = convertLength(absPart);
        }

        absTotal += pixels;
        absParts[count] = pixels;
      } else {
        relParts[count] = 0;

        int pixels = 0;
        if (width != null && !width.equals("")) {
          pixels = convertLength(width);
        }

        absTotal += pixels;
        absParts[count] = pixels;
      }
    }

    // Ok, now we have the relative widths and absolute widths in
    // two parallel arrays.
    //
    // - If there are no relative widths, output the absolute widths
    // - If there are no absolute widths, output the relative widths
    // - If there are a mixture of relative and absolute widths,
    //   - If the table width is absolute, turn these all into absolute
    //     widths.
    //   - If the table width is relative, turn these all into absolute
    //     widths in the nominalWidth and then turn them back into
    //     percentages.

    if (relTotal == 0) {
      for (int count = 0; count < numColumns; count++) {
        Float f = new Float(absParts[count]);
        if (foStylesheet) {
          int pixels = f.intValue();
          float inches = (float) pixels / pixelsPerInch;
          widths[count] = inches + "in";
        } else {
          widths[count] = Integer.toString(f.intValue());
        }
      }
    } else if (absTotal == 0) {
      for (int count = 0; count < numColumns; count++) {
        float rel = relParts[count] / relTotal * 100;
        Float f = new Float(rel);
        widths[count] = Integer.toString(f.intValue());
      }
      widths = correctRoundingError(widths);
    } else {
      int pixelWidth = nominalWidth;

      if (tableWidth.indexOf("%") <= 0) {
        pixelWidth = convertLength(tableWidth);
      }

      if (pixelWidth <= absTotal) {
        System.out.println("Table is wider than table width.");
      } else {
        pixelWidth -= absTotal;
      }

      absTotal = 0;
      for (int count = 0; count < numColumns; count++) {
        float rel = relParts[count] / relTotal * pixelWidth;
        relParts[count] = rel + absParts[count];
        absTotal += rel + absParts[count];
      }

      if (tableWidth.indexOf("%") <= 0) {
        for (int count = 0; count < numColumns; count++) {
          Float f = new Float(relParts[count]);
          if (foStylesheet) {
            int pixels = f.intValue();
            float inches = (float) pixels / pixelsPerInch;
            widths[count] = inches + "in";
          } else {
            widths[count] = Integer.toString(f.intValue());
          }
        }
      } else {
        for (int count = 0; count < numColumns; count++) {
          float rel = relParts[count] / absTotal * 100;
          Float f = new Float(rel);
          widths[count] = Integer.toString(f.intValue());
        }
        widths = correctRoundingError(widths);
      }
    }

    // Now rebuild the colgroup with the right widths

    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = null;

    try {
      docBuilder = docFactory.newDocumentBuilder();
    } catch (ParserConfigurationException e) {
      System.out.println("PCE!");
      return xalanRTF;
    }
    Document doc = docBuilder.newDocument();
    DocumentFragment df = doc.createDocumentFragment();
    DOMBuilder rtf = new DOMBuilder(doc, df);

    try {
      String ns = colgroup.getNamespaceURI();
      String localName = colgroup.getLocalName();
      String name = colgroup.getTagName();

      if (colgroup.getLocalName().equals("colgroup")) {
        rtf.startElement(ns, localName, name, copyAttributes(colgroup));
      }

      for (colnum = 0; colnum < numColumns; colnum++) {
        Element col = columns[colnum];

        NamedNodeMap domAttr = col.getAttributes();

        AttributesImpl attr = new AttributesImpl();
        for (int acount = 0; acount < domAttr.getLength(); acount++) {
          Node a = domAttr.item(acount);
          String a_ns = a.getNamespaceURI();
          String a_localName = a.getLocalName();

          if ((foStylesheet && !a_localName.equals("column-width"))
              || !a_localName.equalsIgnoreCase("width")) {
            attr.addAttribute(
                a.getNamespaceURI(), a.getLocalName(), a.getNodeName(), "CDATA", a.getNodeValue());
          }
        }

        if (foStylesheet) {
          attr.addAttribute("", "column-width", "column-width", "CDATA", widths[colnum]);
        } else {
          attr.addAttribute("", "width", "width", "CDATA", widths[colnum]);
        }

        rtf.startElement(col.getNamespaceURI(), col.getLocalName(), col.getTagName(), attr);
        rtf.endElement(col.getNamespaceURI(), col.getLocalName(), col.getTagName());
      }

      if (colgroup.getLocalName().equals("colgroup")) {
        rtf.endElement(ns, localName, name);
      }
    } catch (SAXException se) {
      System.out.println("SE!");
      return xalanRTF;
    }

    return df;
  }