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(); }
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); }