public void write(
      UriInfo uriInfo,
      Writer w,
      String entityName,
      Entity entity,
      Collection<Link> links,
      Map<Transition, RESTResource> embeddedResources) {
    String baseUri = AtomXMLProvider.getBaseUri(serviceDocument, uriInfo);

    String absoluteId = getAbsoluteId(uriInfo, links);

    DateTime utc = new DateTime().withZone(DateTimeZone.UTC);
    String updated = InternalUtil.toString(utc);

    Abdera abdera = new Abdera();
    StreamWriter writer = abdera.newStreamWriter();
    writer.setOutputStream(new WriterOutputStream(w));
    writer.setAutoflush(false);
    writer.setAutoIndent(true);
    writer.startDocument();

    writer.startEntry();
    writer.writeNamespace("d", d);
    writer.writeNamespace("m", m);
    writer.writeAttribute("xml:base", baseUri);
    writeEntry(writer, entityName, entity, links, embeddedResources, baseUri, absoluteId, updated);
    writer.endEntry();
    writer.endDocument();
    writer.flush();
  }
Example #2
0
  protected String writeEntry(
      XMLWriter2 writer,
      OEntity oe,
      List<OProperty<?>> entityProperties,
      List<OLink> entityLinks,
      String baseUri,
      String updated,
      EdmEntitySet ees,
      boolean isResponse) {

    String relid = null;
    String absid = null;
    if (isResponse) {
      relid = InternalUtil.getEntityRelId(oe);
      absid = baseUri + relid;
      writeElement(writer, "id", absid);
    }

    OAtomEntity oae = getAtomInfo(oe);

    writeElement(writer, "title", oae.getAtomEntityTitle(), "type", "text");
    String summary = oae.getAtomEntitySummary();
    if (summary != null) {
      writeElement(writer, "summary", summary, "type", "text");
    }

    LocalDateTime updatedTime = oae.getAtomEntityUpdated();
    if (updatedTime != null) {
      updated = InternalUtil.toString(updatedTime.toDateTime(DateTimeZone.UTC));
    }
    writeElement(writer, "updated", updated);

    writer.startElement("author");
    writeElement(writer, "name", oae.getAtomEntityAuthor());
    writer.endElement("author");

    if (isResponse) {
      writeElement(
          writer, "link", null, "rel", "edit", "title", ees.getType().getName(), "href", relid);
    }

    if (entityLinks != null) {
      if (isResponse) {
        // the producer has populated the link collection, we just what he gave us.
        for (OLink link : entityLinks) {
          String rel = related + link.getTitle();
          String type = (link.isCollection()) ? atom_feed_content_type : atom_entry_content_type;
          String href = relid + "/" + link.getTitle();
          if (link.isInline()) {
            writer.startElement("link");
            writer.writeAttribute("rel", rel);
            writer.writeAttribute("type", type);
            writer.writeAttribute("title", link.getTitle());
            writer.writeAttribute("href", href);
            // write the inlined entities inside the link element
            writeLinkInline(writer, link, href, baseUri, updated, isResponse);
            writer.endElement("link");
          } else {
            // deferred link.
            writeElement(
                writer,
                "link",
                null,
                "rel",
                rel,
                "type",
                type,
                "title",
                link.getTitle(),
                "href",
                href);
          }
        }
      } else {
        // for requests we include only the provided links
        // Note: It seems that OLinks for responses are only built using the
        // title and OLinks for requests have the additional info in them
        // alread.  I'm leaving that inconsistency in place for now but this
        // else and its preceding if could probably be unified.
        for (OLink olink : entityLinks) {
          String type = olink.isCollection() ? atom_feed_content_type : atom_entry_content_type;

          writer.startElement("link");
          writer.writeAttribute("rel", olink.getRelation());
          writer.writeAttribute("type", type);
          writer.writeAttribute("title", olink.getTitle());
          writer.writeAttribute("href", olink.getHref());
          if (olink.isInline()) {
            // write the inlined entities inside the link element
            writeLinkInline(writer, olink, olink.getHref(), baseUri, updated, isResponse);
          }
          writer.endElement("link");
        }
      }
    } // else entityLinks null

    writeElement(
        writer,
        "category",
        null,
        // oe is null for creates
        "term",
        oe == null
            ? ees.getType().getFullyQualifiedTypeName()
            : oe.getEntityType().getFullyQualifiedTypeName(),
        "scheme",
        scheme);

    boolean hasStream = false;
    if (oe != null) {
      OAtomStreamEntity stream = oe.findExtension(OAtomStreamEntity.class);
      if (stream != null) {
        hasStream = true;
        writer.startElement("content");
        writer.writeAttribute("type", stream.getAtomEntityType());
        writer.writeAttribute("src", baseUri + stream.getAtomEntitySource());
        writer.endElement("content");
      }
    }

    if (!hasStream) {
      writer.startElement("content");
      writer.writeAttribute("type", MediaType.APPLICATION_XML);
    }

    writer.startElement(new QName2(m, "properties", "m"));
    writeProperties(writer, entityProperties);
    writer.endElement("properties");

    if (!hasStream) {
      writer.endElement("content");
    }
    return absid;
  }
  protected void writeEntry(
      StreamWriter writer,
      String entityName,
      Entity entity,
      Collection<Link> entityLinks,
      Map<Transition, RESTResource> embeddedResources,
      String baseUri,
      String absoluteId,
      String updated) {
    assert (entityName != null);

    // entity name could be different between entity resource and underlying entity
    // e.g., for Errors entity, entity resource would have the request entity name
    String entityMetadataName = entity != null ? entity.getName() : entityName;

    EntityMetadata entityMetadata = metadata.getEntityMetadata(entityMetadataName);
    String modelName = metadata.getModelName();
    writer.writeId(absoluteId);
    OAtomEntity oae = getAtomInfo(entity);

    writer.writeTitle(oae.getAtomEntityTitle());
    String summary = oae.getAtomEntitySummary();
    if (!summary.isEmpty()) {
      writer.writeSummary(summary);
    }

    LocalDateTime updatedTime = oae.getAtomEntityUpdated();
    if (updatedTime != null) {
      updated = InternalUtil.toString(updatedTime.toDateTime(DateTimeZone.UTC));
    }

    writer.writeUpdated(updated);
    writer.writeAuthor(oae.getAtomEntityAuthor());

    if (entityLinks != null) {
      for (Link link : entityLinks) {
        String type =
            (link.getTransition().getTarget() instanceof CollectionResourceState)
                ? atom_feed_content_type
                : atom_entry_content_type;
        String href = link.getRelativeHref(baseUri);
        String rel = link.getRel();
        writer.startLink(href, rel);

        if ("self".equals(link.getRel())) {
          ResourceState target = link.getTransition().getTarget();
          writer.writeAttribute("profile", target.getRel());
        }

        if (!"self".equals(link.getRel()) && !"edit".equals(link.getRel())) {
          writer.writeAttribute("type", type);
        }
        writer.writeAttribute("title", link.getTitle());
        if (embeddedResources != null && embeddedResources.get(link.getTransition()) != null) {
          String embeddedAbsoluteId = link.getHref();
          writeLinkInline(
              writer,
              metadata,
              link,
              embeddedResources.get(link.getTransition()),
              link.getHref(),
              baseUri,
              embeddedAbsoluteId,
              updated);
        }
        String linkId = link.getLinkId();
        if (linkId != null && linkId.length() > 0) {
          writer.writeAttribute("id", linkId);
        }
        writer.endLink();
      }
    }

    writer.writeCategory(modelName + Metadata.MODEL_SUFFIX + "." + entityName, scheme);
    writer.flush();

    writer.startContent(MediaType.APPLICATION_XML);

    writer.startElement(new QName(m, "properties", "m"));
    if (entity != null) {
      writeProperties(writer, entityMetadata, entity.getProperties(), modelName);
    }
    writer.endElement();

    writer.endContent();
  }
  @SuppressWarnings("unchecked")
  protected void writeProperty(XMLWriter2 writer, OProperty<?> prop, boolean isDocumentElement) {

    String name = prop.getName();
    EdmType type = prop.getType();
    Object value = prop.getValue();

    if (isDocumentElement) writer.startElement(new QName2(name), d);
    else writer.startElement(new QName2(d, name, "d"));

    String sValue = null;

    if (!type.isSimple()) {
      writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
      // complex
      List<OProperty<?>> complexProperties = (List<OProperty<?>>) value;
      if (complexProperties != null) {
        writeProperties(writer, complexProperties);
      }
    } else {
      // simple
      if (type == EdmType.INT32) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = value.toString();
        }
      } else if (type == EdmType.INT16) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = value.toString();
        }
      } else if (type == EdmType.INT64) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = value.toString();
        }
      } else if (type == EdmType.BOOLEAN) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = value.toString();
        }
      } else if (type == EdmType.BYTE) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = Hex.encodeHexString(new byte[] {(Byte) value});
        }
      } else if (type == EdmType.DECIMAL) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = value.toString();
        }
      } else if (type == EdmType.SINGLE) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = value.toString();
        }
      } else if (type == EdmType.DOUBLE) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = value.toString();
        }
      } else if (type == EdmType.STRING) {
        if (value != null) {
          sValue = value.toString();
        }
      } else if (type == EdmType.DATETIME) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) sValue = InternalUtil.formatDateTime((LocalDateTime) value);
      } else if (type == EdmType.BINARY) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        byte[] bValue = (byte[]) value;
        if (value != null) {
          sValue = Base64.encodeBase64String(bValue);
        }
      } else if (type == EdmType.GUID) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = value.toString();
        }
      } else if (type == EdmType.TIME) {
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = InternalUtil.toString((LocalTime) value);
        }
      } else if (type == EdmType.DATETIMEOFFSET) {
        // Edm.DateTimeOffset '-'? yyyy '-' mm '-' dd 'T' hh ':' mm
        // ':' ss ('.' s+)? (zzzzzz)?
        writer.writeAttribute(new QName2(m, "type", "m"), type.toTypeString());
        if (value != null) {
          sValue = InternalUtil.toString((DateTime) value);
        }
      } else {
        throw new UnsupportedOperationException("Implement " + type);
      }
    }

    if (value == null) {
      writer.writeAttribute(new QName2(m, "null", "m"), "true");
    } else {
      writer.writeText(sValue);
    }
    writer.endElement(name);
  }