Skip to content

Commit 16de364

Browse files
committed
new InvocationBuilderListener SPI
Signed-off-by: Jan Supol <jan.supol@oracle.com>
1 parent 4c10f29 commit 16de364

File tree

3 files changed

+400
-0
lines changed

3 files changed

+400
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright (c) 2011, 2019 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.client;
18+
19+
import org.glassfish.jersey.client.spi.InvocationBuilderListener;
20+
import org.glassfish.jersey.internal.inject.InjectionManager;
21+
import org.glassfish.jersey.internal.inject.Providers;
22+
import org.glassfish.jersey.model.internal.RankedComparator;
23+
24+
import javax.ws.rs.client.Invocation;
25+
import javax.ws.rs.core.CacheControl;
26+
import javax.ws.rs.core.Cookie;
27+
import javax.ws.rs.core.MediaType;
28+
import javax.ws.rs.core.MultivaluedMap;
29+
import java.util.Iterator;
30+
import java.util.Locale;
31+
32+
/**
33+
* Client request processing stage. During a request creation, when the {@link Invocation.Builder}
34+
* would be created, this class is utilized.
35+
*/
36+
/* package */ class InvocationBuilderListenerStage {
37+
final Iterator<InvocationBuilderListener> invocationBuilderListenerIterator;
38+
39+
/* package */ InvocationBuilderListenerStage(InjectionManager injectionManager) {
40+
final RankedComparator<InvocationBuilderListener> comparator =
41+
new RankedComparator<>(RankedComparator.Order.ASCENDING);
42+
invocationBuilderListenerIterator = Providers
43+
.getAllProviders(injectionManager, InvocationBuilderListener.class, comparator).iterator();
44+
}
45+
46+
/* package */ void invokeListener(Invocation.Builder builder) {
47+
while (invocationBuilderListenerIterator.hasNext()) {
48+
invocationBuilderListenerIterator.next().onNewBuilder(new InvocationBuilderContextImpl(builder));
49+
}
50+
}
51+
52+
private static class InvocationBuilderContextImpl implements InvocationBuilderListener.InvocationBuilderContext {
53+
private final Invocation.Builder builder;
54+
55+
private InvocationBuilderContextImpl(Invocation.Builder builder) {
56+
this.builder = builder;
57+
}
58+
59+
@Override
60+
public InvocationBuilderListener.InvocationBuilderContext accept(String... mediaTypes) {
61+
builder.accept(mediaTypes);
62+
return this;
63+
}
64+
65+
@Override
66+
public InvocationBuilderListener.InvocationBuilderContext accept(MediaType... mediaTypes) {
67+
builder.accept(mediaTypes);
68+
return this;
69+
}
70+
71+
@Override
72+
public InvocationBuilderListener.InvocationBuilderContext acceptLanguage(Locale... locales) {
73+
builder.acceptLanguage(locales);
74+
return this;
75+
}
76+
77+
@Override
78+
public InvocationBuilderListener.InvocationBuilderContext acceptLanguage(String... locales) {
79+
builder.acceptLanguage(locales);
80+
return this;
81+
}
82+
83+
@Override
84+
public InvocationBuilderListener.InvocationBuilderContext acceptEncoding(String... encodings) {
85+
builder.acceptEncoding(encodings);
86+
return this;
87+
}
88+
89+
@Override
90+
public InvocationBuilderListener.InvocationBuilderContext cookie(Cookie cookie) {
91+
builder.cookie(cookie);
92+
return this;
93+
}
94+
95+
@Override
96+
public InvocationBuilderListener.InvocationBuilderContext cookie(String name, String value) {
97+
builder.cookie(name, value);
98+
return this;
99+
}
100+
101+
@Override
102+
public InvocationBuilderListener.InvocationBuilderContext cacheControl(CacheControl cacheControl) {
103+
builder.cacheControl(cacheControl);
104+
return this;
105+
}
106+
107+
@Override
108+
public InvocationBuilderListener.InvocationBuilderContext header(String name, Object value) {
109+
builder.header(name, value);
110+
return this;
111+
}
112+
113+
@Override
114+
public InvocationBuilderListener.InvocationBuilderContext headers(MultivaluedMap<String, Object> headers) {
115+
builder.headers(headers);
116+
return this;
117+
}
118+
119+
@Override
120+
public InvocationBuilderListener.InvocationBuilderContext property(String name, Object value) {
121+
builder.property(name, value);
122+
return this;
123+
}
124+
}
125+
}
126+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*
2+
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.client.spi;
18+
19+
import org.glassfish.jersey.Beta;
20+
import org.glassfish.jersey.spi.Contract;
21+
22+
import javax.ws.rs.ConstrainedTo;
23+
import javax.ws.rs.RuntimeType;
24+
import javax.ws.rs.client.ClientRequestContext;
25+
import javax.ws.rs.client.Invocation;
26+
import javax.ws.rs.core.CacheControl;
27+
import javax.ws.rs.core.Cookie;
28+
import javax.ws.rs.core.MediaType;
29+
import javax.ws.rs.core.MultivaluedMap;
30+
import java.util.Locale;
31+
32+
/**
33+
* Implementations of this interface will be notified when a new Invocation.Builder
34+
* is created. This will allow implementations to access the invocation builders,
35+
* and is intended for global providers. For example, the Invocation.Builder properties can be
36+
* accessed to set properties that are available on the {@link javax.ws.rs.client.ClientRequestContext}.
37+
*
38+
* In order for the InvocationBuilderListener to be called, the implementation of the interface needs
39+
* to be registered on the {@code Client} the same way the {@code ClientRequestFilter} is registered, for instance.
40+
*
41+
* @since 2.30
42+
*/
43+
@Beta
44+
@Contract
45+
@ConstrainedTo(RuntimeType.CLIENT)
46+
public interface InvocationBuilderListener {
47+
48+
/**
49+
* An {@link javax.ws.rs.client.Invocation.Builder} subset of setter methods.
50+
*/
51+
public interface InvocationBuilderContext {
52+
/**
53+
* Add the accepted response media types.
54+
*
55+
* @param mediaTypes accepted response media types.
56+
* @return the updated context.
57+
*/
58+
InvocationBuilderContext accept(String... mediaTypes);
59+
60+
/**
61+
* Add the accepted response media types.
62+
*
63+
* @param mediaTypes accepted response media types.
64+
* @return the updated context.
65+
*/
66+
InvocationBuilderContext accept(MediaType... mediaTypes);
67+
68+
/**
69+
* Add acceptable languages.
70+
*
71+
* @param locales an array of the acceptable languages.
72+
* @return the updated context.
73+
*/
74+
InvocationBuilderContext acceptLanguage(Locale... locales);
75+
76+
/**
77+
* Add acceptable languages.
78+
*
79+
* @param locales an array of the acceptable languages.
80+
* @return the updated context.
81+
*/
82+
InvocationBuilderContext acceptLanguage(String... locales);
83+
84+
/**
85+
* Add acceptable encodings.
86+
*
87+
* @param encodings an array of the acceptable encodings.
88+
* @return the updated context.
89+
*/
90+
InvocationBuilderContext acceptEncoding(String... encodings);
91+
92+
/**
93+
* Add a cookie to be set.
94+
*
95+
* @param cookie to be set.
96+
* @return the updated context.
97+
*/
98+
InvocationBuilderContext cookie(Cookie cookie);
99+
100+
/**
101+
* Add a cookie to be set.
102+
*
103+
* @param name the name of the cookie.
104+
* @param value the value of the cookie.
105+
* @return the updated context.
106+
*/
107+
InvocationBuilderContext cookie(String name, String value);
108+
109+
/**
110+
* Set the cache control data of the message.
111+
*
112+
* @param cacheControl the cache control directives, if {@code null}
113+
* any existing cache control directives will be removed.
114+
* @return the updated context.
115+
*/
116+
InvocationBuilderContext cacheControl(CacheControl cacheControl);
117+
118+
/**
119+
* Add an arbitrary header.
120+
*
121+
* @param name the name of the header
122+
* @param value the value of the header, the header will be serialized
123+
* using a {@link javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate} if
124+
* one is available via {@link javax.ws.rs.ext.RuntimeDelegate#createHeaderDelegate(java.lang.Class)}
125+
* for the class of {@code value} or using its {@code toString} method
126+
* if a header delegate is not available. If {@code value} is {@code null}
127+
* then all current headers of the same name will be removed.
128+
* @return the updated context.
129+
*/
130+
InvocationBuilderContext header(String name, Object value);
131+
132+
/**
133+
* Replaces all existing headers with the newly supplied headers.
134+
*
135+
* @param headers new headers to be set, if {@code null} all existing
136+
* headers will be removed.
137+
* @return the updated context.
138+
*/
139+
InvocationBuilderContext headers(MultivaluedMap<String, Object> headers);
140+
141+
/**
142+
* Set a new property in the context of a request represented by this invocation builder.
143+
* <p>
144+
* The property is available for a later retrieval via {@link ClientRequestContext#getProperty(String)}
145+
* or {@link javax.ws.rs.ext.InterceptorContext#getProperty(String)}.
146+
* If a property with a given name is already set in the request context,
147+
* the existing value of the property will be updated.
148+
* Setting a {@code null} value into a property effectively removes the property
149+
* from the request property bag.
150+
* </p>
151+
*
152+
* @param name property name.
153+
* @param value (new) property value. {@code null} value removes the property
154+
* with the given name.
155+
* @return the updated context.
156+
* @see Invocation#property(String, Object)
157+
*/
158+
InvocationBuilderContext property(String name, Object value);
159+
}
160+
161+
/**
162+
* Whenever a method on {@link Invocation.Builder} that does not return the {@link Invocation.Builder}
163+
* is called, (i.e. methods that are not part of the {@link InvocationBuilderContext}, for instance
164+
* {@link Invocation.Builder#async()}, {@link Invocation.Builder#build(String)},
165+
* {@link Invocation.Builder#invoke()}, {@link Invocation.Builder#rx()}, or
166+
* {@link Invocation.Builder#submit()}), this method would be called.
167+
* @param context the updated {@link InvocationBuilderContext}.
168+
*/
169+
void onNewBuilder(InvocationBuilderContext context);
170+
171+
}

0 commit comments

Comments
 (0)