package org.atomhopper.abdera.response; import org.apache.abdera.model.Feed; import org.apache.abdera.model.Link; import org.apache.abdera.protocol.server.ProviderHelper; import org.apache.abdera.protocol.server.RequestContext; import org.apache.abdera.protocol.server.ResponseContext; import org.apache.abdera.util.EntityTag; import org.atomhopper.abdera.filter.AdapterResponseInterceptor; import org.atomhopper.adapter.FeedSource; import org.atomhopper.response.AdapterResponse; import java.util.Arrays; import java.util.Date; import java.util.List; public class FeedResponseHandler extends AbstractResponseHandler<Feed> { private static final String XML = "application/xml"; private static final String LINK_HEADER_NAME = "Link"; private static final String LT = "<"; private static final String GT = ">"; private static final String LINK_SEPARATOR = ", "; public FeedResponseHandler(String[] allowedMethods, AdapterResponseInterceptor<Feed>... interceptors) { super(allowedMethods, interceptors); } public FeedResponseHandler(String[] allowedMethods, List<AdapterResponseInterceptor<Feed>> adapterResponseInterceptorList) { super(allowedMethods, adapterResponseInterceptorList); } @Override protected ResponseContext handleAdapterResponse(RequestContext rc, AdapterResponse <Feed> adapterResponse) { final Date lastUpdated = adapterResponse.getBody() != null ? adapterResponse.getBody().getUpdated() : null; switch (adapterResponse.getResponseStatus()) { case OK: ResponseContext responseContext; if (entityTagMatches(rc.getIfNoneMatch(), adapterResponse.getEntityTag())) { responseContext = ProviderHelper.notmodified(rc); }else{ responseContext = ProviderHelper.returnBase(adapterResponse.getBody(), adapterResponse.getResponseStatus().value(), lastUpdated); } responseContext.setEntityTag(adapterResponse.getEntityTag()); buildLinkHeader(responseContext, adapterResponse); return responseContext; case NOT_FOUND: return ProviderHelper.notfound(rc, adapterResponse.getMessage()).setContentType(XML); case INTERNAL_SERVER_ERROR: return ProviderHelper.servererror(rc, adapterResponse.getMessage(), new InternalServerException()).setContentType(XML); case METHOD_NOT_ALLOWED: return ProviderHelper.notallowed(rc, adapterResponse.getMessage(), getAllowedHttpMethods()).setContentType(XML); case BAD_REQUEST: return ProviderHelper.badrequest(rc, adapterResponse.getMessage()).setContentType(XML); case CONFLICT: return ProviderHelper.conflict(rc, adapterResponse.getMessage()).setContentType(XML); default: return ProviderHelper.notfound(rc).setContentType(XML); } } protected ResponseContext buildLinkHeader(ResponseContext responseContext, AdapterResponse<Feed> adapterResponse) { if ( adapterResponse != null && adapterResponse.getBody() != null ) { String nextLink = null; if ( adapterResponse.getBody().getLink(Link.REL_NEXT) != null ) { nextLink = buildLinkHeaderForType(adapterResponse, Link.REL_NEXT); } else if ( adapterResponse.getBody().getLink( FeedSource.REL_ARCHIVE_NEXT ) != null ) { nextLink = buildLinkHeaderForType(adapterResponse, FeedSource.REL_ARCHIVE_NEXT ); } String prevLink = null; if ( adapterResponse.getBody().getLink(Link.REL_PREVIOUS) != null ) { prevLink = buildLinkHeaderForType(adapterResponse, Link.REL_PREVIOUS); } else if ( adapterResponse.getBody().getLink( FeedSource.REL_ARCHIVE_PREV ) != null ) { prevLink = buildLinkHeaderForType(adapterResponse, FeedSource.REL_ARCHIVE_PREV ); } if ( nextLink != null && prevLink != null ) { responseContext.addHeader(LINK_HEADER_NAME, nextLink + LINK_SEPARATOR + prevLink); } else if ( nextLink != null ) { responseContext.addHeader(LINK_HEADER_NAME, nextLink); } else if ( prevLink != null ) { responseContext.addHeader(LINK_HEADER_NAME, prevLink); } } return responseContext; } protected String buildLinkHeaderForType(AdapterResponse<Feed> adapterResponse, String linkType) { StringBuilder sb = new StringBuilder(); sb.append(LT); sb.append(adapterResponse.getBody().getLink(linkType).getHref()); sb.append(GT); sb.append("; rel=\""); sb.append(linkType); sb.append("\""); return sb.toString(); } private boolean entityTagMatches(EntityTag[] ifNoneMatch, EntityTag entityTag) { if (ifNoneMatch == null || entityTag == null) { return false; } List<EntityTag> ifNoneMatchList = Arrays.asList(ifNoneMatch); return ifNoneMatchList.size() == 1 && ifNoneMatchList.get(0).getTag().equals(entityTag.getTag()); } }