/** * Same as super-class, but additionally provides support for using a * dynamic callback-method name for JSONP, as might be provided * through a URI query-string parameter. */ @Provider @Getter @Setter public class JSONPObjectProviderForDynamicCallbacks extends JSONPObjectProvider { /** */ private static final Logger log = Logger.getLogger( JSONPObjectProviderForDynamicCallbacks.class ); /** */ public static final String DEFAULT_CALLBACK_PARAMETER_NAME = "callback"; /** */ private String callbackParamName = DEFAULT_CALLBACK_PARAMETER_NAME; /** */ private boolean checkForValidCallbackName = true; /** */ @Context private UriInfo uriInfo; /** * */ @Override protected String getActualCallbackName() { final MultivaluedMap params = uriInfo.getQueryParameters(); // try to determine the desired callback-name dynamically from query-parameters if( getCallbackParamName() != null && params.containsKey( getCallbackParamName() ) ) { final String dynamicCallbackName = params.getFirst( getCallbackParamName() ); if( ! StringUtils.isBlank( dynamicCallbackName ) ) { // if that feature is configured, check that the dynamically determined callback name is a valid JS identifier if ( isCheckForValidCallbackName() && ! JavaScriptUtils.isValidJsIdentifier( dynamicCallbackName ) ) { if ( log.isEnabledFor( Level.WARN ) ) { log.warn( "A JSONP client requested invalid callback-name \"" + dynamicCallbackName + "\" through query-string-parameter \"" + getCallbackParamName() + "\". " + "Ignoring it and using pre-configured callback-name \"" + getCallbackName() + "\" instead." ); } return getCallbackName(); } // return dynamically determined callback name return dynamicCallbackName; } } // if determining the actual callback name dynamically failed, fall back to pre-configured callback name return getCallbackName(); } }