001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2016 ForgeRock AS. 015 */ 016package org.forgerock.opendj.rest2ldap; 017 018import org.forgerock.api.models.ApiDescription; 019import org.forgerock.http.ApiProducer; 020import org.forgerock.json.resource.ActionRequest; 021import org.forgerock.json.resource.ActionResponse; 022import org.forgerock.json.resource.CreateRequest; 023import org.forgerock.json.resource.DeleteRequest; 024import org.forgerock.json.resource.PatchRequest; 025import org.forgerock.json.resource.QueryRequest; 026import org.forgerock.json.resource.QueryResourceHandler; 027import org.forgerock.json.resource.QueryResponse; 028import org.forgerock.json.resource.ReadRequest; 029import org.forgerock.json.resource.Request; 030import org.forgerock.json.resource.RequestHandler; 031import org.forgerock.json.resource.ResourceException; 032import org.forgerock.json.resource.ResourceResponse; 033import org.forgerock.json.resource.UpdateRequest; 034import org.forgerock.services.context.Context; 035import org.forgerock.services.descriptor.Describable; 036import org.forgerock.util.Reject; 037import org.forgerock.util.promise.Promise; 038 039/** Decorator for a request handler that can return an api descriptor of the underlying handler. */ 040public class DescribableRequestHandler implements RequestHandler, Describable<ApiDescription, Request> { 041 private final RequestHandler delegate; 042 private final Describable<ApiDescription, Request> describableDelegate; 043 private ApiDescription api; 044 045 /** 046 * Builds an object decorating the provided handler. 047 * 048 * @param handler 049 * the handler to decorate. 050 */ 051 @SuppressWarnings("unchecked") 052 public DescribableRequestHandler(final RequestHandler handler) { 053 this.delegate = Reject.checkNotNull(handler); 054 this.describableDelegate = delegate instanceof Describable 055 ? (Describable<ApiDescription, Request>) delegate 056 : null; 057 } 058 059 @Override 060 public Promise<ActionResponse, ResourceException> handleAction(Context context, ActionRequest request) { 061 return delegate.handleAction(wrap(context), request); 062 } 063 064 @Override 065 public Promise<ResourceResponse, ResourceException> handleCreate(Context context, CreateRequest request) { 066 return delegate.handleCreate(wrap(context), request); 067 } 068 069 @Override 070 public Promise<ResourceResponse, ResourceException> handleDelete(Context context, DeleteRequest request) { 071 return delegate.handleDelete(wrap(context), request); 072 } 073 074 @Override 075 public Promise<ResourceResponse, ResourceException> handlePatch(Context context, PatchRequest request) { 076 return delegate.handlePatch(wrap(context), request); 077 } 078 079 @Override 080 public Promise<QueryResponse, ResourceException> handleQuery( 081 Context context, QueryRequest request, QueryResourceHandler handler) { 082 return delegate.handleQuery(wrap(context), request, handler); 083 } 084 085 @Override 086 public Promise<ResourceResponse, ResourceException> handleRead(Context context, ReadRequest request) { 087 return delegate.handleRead(wrap(context), request); 088 } 089 090 @Override 091 public Promise<ResourceResponse, ResourceException> handleUpdate(Context context, UpdateRequest request) { 092 return delegate.handleUpdate(wrap(context), request); 093 } 094 095 /** 096 * Allows sub classes to wrap the provided context and return the wrapping context. 097 * 098 * @param context 099 * the context to wrap 100 * @return the wrapping context that should be used 101 */ 102 protected Context wrap(final Context context) { 103 return context; 104 } 105 106 @Override 107 public ApiDescription api(ApiProducer<ApiDescription> producer) { 108 if (describableDelegate != null) { 109 api = describableDelegate.api(producer); 110 } 111 return api; 112 } 113 114 @Override 115 public ApiDescription handleApiRequest(Context context, Request request) { 116 return api; 117 } 118 119 @Override 120 public void addDescriptorListener(Describable.Listener listener) { 121 if (describableDelegate != null) { 122 describableDelegate.addDescriptorListener(listener); 123 } 124 } 125 126 @Override 127 public void removeDescriptorListener(Describable.Listener listener) { 128 if (describableDelegate != null) { 129 describableDelegate.removeDescriptorListener(listener); 130 } 131 } 132}