package org.odata4j.format; import java.util.List; import java.util.Map; import javax.ws.rs.core.MediaType; import org.odata4j.edm.EdmDataServices; import org.odata4j.exceptions.NotImplementedException; import org.odata4j.format.json.JsonCollectionFormatWriter; import org.odata4j.format.json.JsonComplexObjectFormatWriter; import org.odata4j.format.json.JsonEntryFormatWriter; import org.odata4j.format.json.JsonErrorFormatWriter; import org.odata4j.format.json.JsonFeedFormatWriter; import org.odata4j.format.json.JsonParametersFormatWriter; import org.odata4j.format.json.JsonPropertyFormatWriter; import org.odata4j.format.json.JsonRequestEntryFormatWriter; import org.odata4j.format.json.JsonServiceDocumentFormatWriter; import org.odata4j.format.json.JsonSimpleFormatWriter; import org.odata4j.format.json.JsonSingleLinkFormatWriter; import org.odata4j.format.json.JsonSingleLinksFormatWriter; import org.odata4j.format.jsonlite.JsonLiteCollectionFormatWriter; import org.odata4j.format.jsonlite.JsonLiteComplexObjectFormatWriter; import org.odata4j.format.jsonlite.JsonLiteEntryFormatWriter; import org.odata4j.format.jsonlite.JsonLiteErrorFormatWriter; import org.odata4j.format.jsonlite.JsonLiteFeedFormatWriter; import org.odata4j.format.jsonlite.JsonLiteParametersFormatWriter; import org.odata4j.format.jsonlite.JsonLitePropertyFormatWriter; import org.odata4j.format.jsonlite.JsonLiteRequestEntryFormatWriter; import org.odata4j.format.jsonlite.JsonLiteServiceDocumentFormatWriter; import org.odata4j.format.jsonlite.JsonLiteSimpleFormatWriter; import org.odata4j.format.jsonlite.JsonLiteSingleLinkFormatWriter; import org.odata4j.format.jsonlite.JsonLiteSingleLinksFormatWriter; import org.odata4j.format.jsonlite.OdataJsonLiteConstant; import org.odata4j.format.xml.AtomCollectionFormatWriter; import org.odata4j.format.xml.AtomComplexFormatWriter; import org.odata4j.format.xml.AtomEntryFormatWriter; import org.odata4j.format.xml.AtomErrorFormatWriter; import org.odata4j.format.xml.AtomFeedFormatWriter; import org.odata4j.format.xml.AtomRequestEntryFormatWriter; import org.odata4j.format.xml.AtomServiceDocumentFormatWriter; import org.odata4j.format.xml.AtomSimpleFormatWriter; import org.odata4j.format.xml.AtomSingleLinkFormatWriter; import org.odata4j.format.xml.AtomSingleLinksFormatWriter; import org.odata4j.format.xml.XmlPropertyFormatWriter; import org.odata4j.producer.CollectionResponse; import org.odata4j.producer.ComplexObjectResponse; import org.odata4j.producer.EntitiesResponse; import org.odata4j.producer.EntityResponse; import org.odata4j.producer.ErrorResponse; import org.odata4j.producer.PropertyResponse; import org.odata4j.producer.SimpleResponse; public class FormatWriterFactory { private static interface FormatWriters { FormatWriter<EdmDataServices> getServiceDocumentFormatWriter(); FormatWriter<EntitiesResponse> getFeedFormatWriter(); FormatWriter<EntityResponse> getEntryFormatWriter(); FormatWriter<PropertyResponse> getPropertyFormatWriter(); FormatWriter<SimpleResponse> getSimpleFormatWriter(); FormatWriter<Entry> getRequestEntryFormatWriter(); FormatWriter<Parameters> getRequestParametersFormatWriter(); FormatWriter<SingleLink> getSingleLinkFormatWriter(); FormatWriter<SingleLinks> getSingleLinksFormatWriter(); FormatWriter<ComplexObjectResponse> getComplexObjectFormatWriter(); FormatWriter<CollectionResponse<?>> getCollectionFormatWriter(); FormatWriter<ErrorResponse> getErrorFormatWriter(); } @SuppressWarnings("unchecked") public static <T> FormatWriter<T> getFormatWriter(Class<T> targetType, List<MediaType> acceptTypes, String format, String callback) { FormatType type = null; // if format is explicitly specified, use that if (format != null) type = FormatType.parse(format); // if header accepts json, use that if (type == null && acceptTypes != null) { for (MediaType acceptType : acceptTypes) { if (acceptType.getType().equals(MediaType.APPLICATION_JSON_TYPE.getType()) && acceptType.getSubtype().equals(MediaType.APPLICATION_JSON_TYPE.getSubtype())) { Map<String, String> parameters = acceptType.getParameters(); if (parameters.containsValue(OdataJsonLiteConstant.VERBOSE_VALUE)) { type = FormatType.JSONVERBOSE; break; } else if (parameters.containsValue(OdataJsonLiteConstant.METADATA_TYPE_FULLMETADATA)) { type = FormatType.JSONLITEFULLMETADATA; break; } else if (parameters.containsValue(OdataJsonLiteConstant.METADATA_TYPE_NOMETADATA)) { type = FormatType.JSONLITENOMETADATA; break; } else { type = FormatType.JSON; break; } } } } // else default to atom if (type == null) type = FormatType.ATOM; // Function calls must use JSON verbose for atom if (targetType.equals(Parameters.class)) { if (type.equals(FormatType.ATOM)) type = FormatType.JSONVERBOSE; } // We will be treating json-lite as default format type which will return minimal metadata, $format=json or jsonlite // Also we are supporting json-verbose format which can be accessed using $format=jsonverbose or verbosejson FormatWriters formatWriters; if (type.equals(FormatType.JSON)) { formatWriters = new JsonLiteWriters(callback, OdataJsonLiteConstant.METADATA_TYPE_MINIMALMETADATA); } else if (type.equals(FormatType.JSONLITEFULLMETADATA)) { formatWriters = new JsonLiteWriters(callback, OdataJsonLiteConstant.METADATA_TYPE_FULLMETADATA); } else if (type.equals(FormatType.JSONLITENOMETADATA)) { formatWriters = new JsonLiteWriters(callback, OdataJsonLiteConstant.METADATA_TYPE_NOMETADATA); } else if (type.equals(FormatType.JSONVERBOSE)) { formatWriters = new JsonVerboseWriters(callback); } else { formatWriters = new AtomWriters(); } if (targetType.equals(EdmDataServices.class)) return (FormatWriter<T>) formatWriters.getServiceDocumentFormatWriter(); if (targetType.equals(EntitiesResponse.class)) return (FormatWriter<T>) formatWriters.getFeedFormatWriter(); if (targetType.equals(EntityResponse.class)) return (FormatWriter<T>) formatWriters.getEntryFormatWriter(); if (targetType.equals(PropertyResponse.class)) return (FormatWriter<T>) formatWriters.getPropertyFormatWriter(); if (targetType.equals(SimpleResponse.class)) return (FormatWriter<T>) formatWriters.getSimpleFormatWriter(); if (Entry.class.isAssignableFrom(targetType)) return (FormatWriter<T>) formatWriters.getRequestEntryFormatWriter(); if (SingleLink.class.isAssignableFrom(targetType)) return (FormatWriter<T>) formatWriters.getSingleLinkFormatWriter(); if (SingleLinks.class.isAssignableFrom(targetType)) return (FormatWriter<T>) formatWriters.getSingleLinksFormatWriter(); if (targetType.equals(ComplexObjectResponse.class)) return (FormatWriter<T>) formatWriters.getComplexObjectFormatWriter(); if (targetType.equals(CollectionResponse.class)) return (FormatWriter<T>) formatWriters.getCollectionFormatWriter(); if (targetType.equals(ErrorResponse.class)) return (FormatWriter<T>) formatWriters.getErrorFormatWriter(); if (targetType.equals(Parameters.class)) return (FormatWriter<T>) formatWriters.getRequestParametersFormatWriter(); throw new IllegalArgumentException("Unable to locate format writer for " + targetType.getName() + " and format " + type); } public static class JsonVerboseWriters implements FormatWriters { private final String callback; public JsonVerboseWriters(String callback) { this.callback = callback; } //TODO: check the metadata type and then provide appropriate writter @Override public FormatWriter<EdmDataServices> getServiceDocumentFormatWriter() { return new JsonServiceDocumentFormatWriter(callback); } @Override public FormatWriter<EntitiesResponse> getFeedFormatWriter() { return new JsonFeedFormatWriter(callback); } @Override public FormatWriter<EntityResponse> getEntryFormatWriter() { return new JsonEntryFormatWriter(callback); } @Override public FormatWriter<PropertyResponse> getPropertyFormatWriter() { return new JsonPropertyFormatWriter(callback); } @Override public FormatWriter<SimpleResponse> getSimpleFormatWriter() { return new JsonSimpleFormatWriter(callback); } @Override public FormatWriter<Entry> getRequestEntryFormatWriter() { return new JsonRequestEntryFormatWriter(callback); } @Override public FormatWriter<SingleLink> getSingleLinkFormatWriter() { return new JsonSingleLinkFormatWriter(callback); } @Override public FormatWriter<SingleLinks> getSingleLinksFormatWriter() { return new JsonSingleLinksFormatWriter(callback); } @Override public FormatWriter<ComplexObjectResponse> getComplexObjectFormatWriter() { return new JsonComplexObjectFormatWriter(callback); } @Override public FormatWriter<CollectionResponse<?>> getCollectionFormatWriter() { return new JsonCollectionFormatWriter(callback); } @Override public FormatWriter<ErrorResponse> getErrorFormatWriter() { return new JsonErrorFormatWriter(callback); } @Override public FormatWriter<Parameters> getRequestParametersFormatWriter() { return new JsonParametersFormatWriter(callback); } } public static class AtomWriters implements FormatWriters { @Override public FormatWriter<EdmDataServices> getServiceDocumentFormatWriter() { return new AtomServiceDocumentFormatWriter(); } @Override public FormatWriter<EntitiesResponse> getFeedFormatWriter() { return new AtomFeedFormatWriter(); } @Override public FormatWriter<EntityResponse> getEntryFormatWriter() { return new AtomEntryFormatWriter(); } @Override public FormatWriter<PropertyResponse> getPropertyFormatWriter() { return new XmlPropertyFormatWriter(); } @Override public FormatWriter<Entry> getRequestEntryFormatWriter() { return new AtomRequestEntryFormatWriter(); } @Override public FormatWriter<SingleLink> getSingleLinkFormatWriter() { return new AtomSingleLinkFormatWriter(); } @Override public FormatWriter<SingleLinks> getSingleLinksFormatWriter() { return new AtomSingleLinksFormatWriter(); } @Override public FormatWriter<ComplexObjectResponse> getComplexObjectFormatWriter() { return new AtomComplexFormatWriter(); } @Override public FormatWriter<CollectionResponse<?>> getCollectionFormatWriter() { return new AtomCollectionFormatWriter(); } @Override public FormatWriter<SimpleResponse> getSimpleFormatWriter() { return new AtomSimpleFormatWriter(); } @Override public FormatWriter<ErrorResponse> getErrorFormatWriter() { return new AtomErrorFormatWriter(); } @Override public FormatWriter<Parameters> getRequestParametersFormatWriter() { throw new NotImplementedException("The ATOM format for function payload is not implemented"); } } public static class JsonLiteWriters implements FormatWriters { private final String callback; private String metadataType; public JsonLiteWriters(String callback) { this.callback = callback; } public JsonLiteWriters(String callback, String metadataType) { this.callback = callback; this.metadataType = metadataType; } @Override public FormatWriter<EdmDataServices> getServiceDocumentFormatWriter() { return new JsonLiteServiceDocumentFormatWriter(callback, metadataType); } @Override public FormatWriter<EntitiesResponse> getFeedFormatWriter() { return new JsonLiteFeedFormatWriter(callback, metadataType); } @Override public FormatWriter<EntityResponse> getEntryFormatWriter() { return new JsonLiteEntryFormatWriter(callback, metadataType); } @Override public FormatWriter<PropertyResponse> getPropertyFormatWriter() { return new JsonLitePropertyFormatWriter(callback, metadataType); } @Override public FormatWriter<SimpleResponse> getSimpleFormatWriter() { return new JsonLiteSimpleFormatWriter(callback, metadataType); } @Override public FormatWriter<Entry> getRequestEntryFormatWriter() { return new JsonLiteRequestEntryFormatWriter(callback, metadataType); } @Override public FormatWriter<SingleLink> getSingleLinkFormatWriter() { return new JsonLiteSingleLinkFormatWriter(callback, metadataType); } @Override public FormatWriter<SingleLinks> getSingleLinksFormatWriter() { return new JsonLiteSingleLinksFormatWriter(callback, metadataType); } @Override public FormatWriter<ComplexObjectResponse> getComplexObjectFormatWriter() { return new JsonLiteComplexObjectFormatWriter(callback, metadataType); } @Override public FormatWriter<CollectionResponse<?>> getCollectionFormatWriter() { return new JsonLiteCollectionFormatWriter(callback, metadataType); } @Override public FormatWriter<ErrorResponse> getErrorFormatWriter() { return new JsonLiteErrorFormatWriter(callback, metadataType); } @Override public FormatWriter<Parameters> getRequestParametersFormatWriter() { return new JsonLiteParametersFormatWriter(callback, metadataType); } } }