@Override public boolean isWriteable( Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { if (mediaType.isCompatible(MediaType.APPLICATION_ATOM_XML_TYPE) // good old Microsoft Excel 2013 has forced us to need to accept this media type (which is // completely wrong) https://github.com/temenostech/IRIS/issues/154 || mediaType.equals(ExtendedMediaTypes.APPLICATION_ATOMSVC_XML_TYPE) || mediaType.equals(MediaType.APPLICATION_XML_TYPE)) { return ResourceTypeHelper.isType(type, genericType, EntityResource.class) || ResourceTypeHelper.isType(type, genericType, CollectionResource.class, OEntity.class) || ResourceTypeHelper.isType(type, genericType, CollectionResource.class, Entity.class); } return false; }
/** * To handle generic case where user do not know the type, here we will be looking for a type and * then generate EntityResource<E> * * @param entity * @return EntityResource<E> */ public static <E> EntityResource<E> createEntityResource(E entity) { GenericEntity<E> ge = new GenericEntity<E>(entity) {}; Type t = com.temenos.interaction.core.command.CommandHelper.getEffectiveGenericType( ge.getType(), entity); if (ResourceTypeHelper.isType(ge.getRawType(), t, OEntity.class, OEntity.class)) { OEntity te = (OEntity) entity; String entityName = te != null && te.getEntityType() != null ? te.getEntityType().getName() : null; return com.temenos.interaction.core.command.CommandHelper.createEntityResource( entityName, entity, OEntity.class); } else if (ResourceTypeHelper.isType(ge.getRawType(), t, Entity.class, Entity.class)) { Entity te = (Entity) entity; String entityName = te != null ? te.getName() : null; return com.temenos.interaction.core.command.CommandHelper.createEntityResource( entityName, entity, Entity.class); } else { // Call the generic and lets see what happens return com.temenos.interaction.core.command.CommandHelper.createEntityResource(entity, null); } }
/** * Reads a Atom (OData) representation of {@link EntityResource} from the input stream. * * @precondition {@link InputStream} contains a valid Atom (OData) Entity enclosed in a * <resource/> document * @postcondition {@link EntityResource} will be constructed and returned. * @invariant valid InputStream */ @Override public EntityResource<OEntity> readFrom( Class<RESTResource> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { // check media type can be handled, isReadable must have been called assert (ResourceTypeHelper.isType(type, genericType, EntityResource.class)); assert (mediaType.isCompatible(MediaType.APPLICATION_ATOM_XML_TYPE)); try { OEntityKey entityKey = null; // work out the entity name using resource path from UriInfo String baseUri = AtomXMLProvider.getBaseUri(serviceDocument, uriInfo); String absoluteUri = AtomXMLProvider.getAbsolutePath(uriInfo); logger.info("Reading atom xml content for [" + absoluteUri + "]"); String resourcePath = null; StringBuffer regex = new StringBuffer("(?<=" + baseUri + ")\\S+"); Pattern p = Pattern.compile(regex.toString()); Matcher m = p.matcher(absoluteUri); while (m.find()) { resourcePath = m.group(); } if (resourcePath == null) throw new IllegalStateException("No resource found"); ResourceState currentState = getCurrentState(serviceDocument, resourcePath); if (currentState == null) throw new IllegalStateException("No state found"); String pathIdParameter = getPathIdParameter(currentState); MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters(); if (pathParameters != null && pathParameters.getFirst(pathIdParameter) != null) { if (STRING_KEY_RESOURCE_PATTERN.matcher(resourcePath).find()) { entityKey = OEntityKey.create(pathParameters.getFirst(pathIdParameter)); } else { entityKey = OEntityKey.parse(pathParameters.getFirst(pathIdParameter)); } } if (currentState.getEntityName() == null) { throw new IllegalStateException("Entity name could not be determined"); } /* * get the entity set name using the metadata */ String entitySetName = getEntitySet(currentState); // Check contents of the stream, if empty or null then return empty resource InputStream verifiedStream = verifyContentReceieved(entityStream); if (verifiedStream == null) { return new EntityResource<OEntity>(); } // Lets parse the request content Reader reader = new InputStreamReader(verifiedStream); assert (entitySetName != null) : "Must have found a resource or thrown exception"; Entry e = new AtomEntryFormatParserExt(metadataOData4j, entitySetName, entityKey, null) .parse(reader); return new EntityResource<OEntity>(e.getEntity()); } catch (IllegalStateException e) { logger.warn("Malformed request from client", e); throw new WebApplicationException(Status.BAD_REQUEST); } }
@Override public boolean isReadable( Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { // this class can only deserialise EntityResource with OEntity return ResourceTypeHelper.isType(type, genericType, EntityResource.class); }
/** * Writes a Atom (OData) representation of {@link EntityResource} to the output stream. * * @precondition supplied {@link EntityResource} is non null * @precondition {@link EntityResource#getEntity()} returns a valid OEntity, this provider only * supports serialising OEntities * @postcondition non null Atom (OData) XML document written to OutputStream * @invariant valid OutputStream */ @SuppressWarnings("unchecked") @Override public void writeTo( RESTResource resource, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { assert (resource != null); assert (uriInfo != null); // Set response headers if (httpHeaders != null) { httpHeaders.putSingle( HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_ATOM_XML); // Workaround for // https://issues.apache.org/jira/browse/WINK-374 } try { RESTResource restResource = processLinks((RESTResource) resource); Collection<Link> processedLinks = restResource.getLinks(); if (ResourceTypeHelper.isType(type, genericType, EntityResource.class, OEntity.class)) { EntityResource<OEntity> entityResource = (EntityResource<OEntity>) resource; OEntity tempEntity = entityResource.getEntity(); EdmEntitySet entitySet = getEdmEntitySet(entityResource.getEntityName()); List<OLink> olinks = formOLinks(entityResource); // Write entry // create OEntity with our EdmEntitySet see issue // https://github.com/aphethean/IRIS/issues/20 OEntity oentity = OEntities.create( entitySet, tempEntity.getEntityKey(), tempEntity.getProperties(), null); entryWriter.write( uriInfo, new OutputStreamWriter(entityStream, UTF_8), Responses.entity(oentity), entitySet, olinks); } else if (ResourceTypeHelper.isType(type, genericType, EntityResource.class, Entity.class)) { EntityResource<Entity> entityResource = (EntityResource<Entity>) resource; // Write entry Entity entity = entityResource.getEntity(); String entityName = entityResource.getEntityName(); // Write Entity object with Abdera implementation entityEntryWriter.write( uriInfo, new OutputStreamWriter(entityStream, UTF_8), entityName, entity, processedLinks, entityResource.getEmbedded()); } else if (ResourceTypeHelper.isType(type, genericType, EntityResource.class)) { EntityResource<Object> entityResource = (EntityResource<Object>) resource; // Links and entity properties Object entity = entityResource.getEntity(); String entityName = entityResource.getEntityName(); EntityProperties props = new EntityProperties(); if (entity != null) { Map<String, Object> objProps = (transformer != null ? transformer : new BeanTransformer()).transform(entity); if (objProps != null) { for (String propName : objProps.keySet()) { props.setProperty(new EntityProperty(propName, objProps.get(propName))); } } } entityEntryWriter.write( uriInfo, new OutputStreamWriter(entityStream, UTF_8), entityName, new Entity(entityName, props), processedLinks, entityResource.getEmbedded()); } else if (ResourceTypeHelper.isType( type, genericType, CollectionResource.class, OEntity.class)) { CollectionResource<OEntity> collectionResource = ((CollectionResource<OEntity>) resource); EdmEntitySet entitySet = getEdmEntitySet(collectionResource.getEntityName()); List<EntityResource<OEntity>> collectionEntities = (List<EntityResource<OEntity>>) collectionResource.getEntities(); List<OEntity> entities = new ArrayList<OEntity>(); Map<OEntity, Collection<Link>> linkId = new HashMap<OEntity, Collection<Link>>(); for (EntityResource<OEntity> collectionEntity : collectionEntities) { // create OEntity with our EdmEntitySet see issue // https://github.com/aphethean/IRIS/issues/20 OEntity tempEntity = collectionEntity.getEntity(); List<OLink> olinks = formOLinks(collectionEntity); Collection<Link> links = collectionEntity.getLinks(); OEntity entity = OEntities.create( entitySet, null, tempEntity.getEntityKey(), tempEntity.getEntityTag(), tempEntity.getProperties(), olinks); entities.add(entity); linkId.put(entity, links); } // TODO implement collection properties and get transient values for inlinecount and // skiptoken Integer inlineCount = null; String skipToken = null; feedWriter.write( uriInfo, new OutputStreamWriter(entityStream, UTF_8), processedLinks, Responses.entities(entities, entitySet, inlineCount, skipToken), metadata.getModelName(), linkId); } else if (ResourceTypeHelper.isType( type, genericType, CollectionResource.class, Entity.class)) { CollectionResource<Entity> collectionResource = ((CollectionResource<Entity>) resource); // TODO implement collection properties and get transient values for inlinecount and // skiptoken Integer inlineCount = null; String skipToken = null; // Write feed AtomEntityFeedFormatWriter entityFeedWriter = new AtomEntityFeedFormatWriter(serviceDocument, metadata); entityFeedWriter.write( uriInfo, new OutputStreamWriter(entityStream, UTF_8), collectionResource, inlineCount, skipToken, metadata.getModelName()); } else { logger.error( "Accepted object for writing in isWriteable, but type not supported in writeTo method"); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } catch (ODataProducerException e) { logger.error("An error occurred while writing " + mediaType + " resource representation", e); } }