[OLINGO-362] Now supporting refresh token
This commit is contained in:
parent
df7cba6909
commit
c155238d9c
|
@ -18,16 +18,12 @@
|
|||
*/
|
||||
package org.apache.olingo.fit;
|
||||
|
||||
import org.apache.cxf.interceptor.InInterceptors;
|
||||
import org.apache.olingo.fit.rest.OAuth2InInterceptor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.ws.rs.Path;
|
||||
import java.io.IOException;
|
||||
|
||||
@Service
|
||||
@Path("/V40/OAuth2.svc")
|
||||
@InInterceptors(classes = {OAuth2InInterceptor.class})
|
||||
public class V4OAuth2 extends V4Services {
|
||||
|
||||
public V4OAuth2() throws IOException {
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.fit.rest;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.cxf.interceptor.Fault;
|
||||
import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
|
||||
import org.apache.cxf.jaxrs.client.WebClient;
|
||||
import org.apache.cxf.message.Message;
|
||||
import org.apache.cxf.phase.AbstractPhaseInterceptor;
|
||||
import org.apache.cxf.phase.Phase;
|
||||
import org.apache.cxf.rs.security.oauth2.client.OAuthClientUtils;
|
||||
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
|
||||
import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant;
|
||||
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
|
||||
import org.apache.cxf.transport.http.AbstractHTTPDestination;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OAuth2InInterceptor extends AbstractPhaseInterceptor<Message> {
|
||||
|
||||
private static final OAuthClientUtils.Consumer OAUTH2_CONSUMER =
|
||||
new OAuthClientUtils.Consumer(OAuth2Provider.CLIENT_ID, OAuth2Provider.CLIENT_SECRET);
|
||||
|
||||
public OAuth2InInterceptor() {
|
||||
super(Phase.PRE_INVOKE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(final Message message) throws Fault {
|
||||
final String requestURL = (String) message.get(Message.REQUEST_URL);
|
||||
if (requestURL.contains("V40/OAuth2.svc")) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final Map<String, List<String>> headers = (Map<String, List<String>>) message.get(Message.PROTOCOL_HEADERS);
|
||||
final List<String> oauth2CodeHeader = headers.get(OAuth2Provider.OAUTH2_CODE_HEADER);
|
||||
if (oauth2CodeHeader == null || oauth2CodeHeader.isEmpty()) {
|
||||
message.put(AbstractHTTPDestination.REQUEST_REDIRECTED, Boolean.TRUE);
|
||||
|
||||
final HttpServletResponse response = (HttpServletResponse) message.get(AbstractHTTPDestination.HTTP_RESPONSE);
|
||||
try {
|
||||
final String authorizationServiceURI =
|
||||
StringUtils.substringBefore(requestURL, "V40/OAuth2.svc") + "oauth/authorize";
|
||||
|
||||
final URI authorizationURI = OAuthClientUtils.getAuthorizationURI(
|
||||
authorizationServiceURI,
|
||||
OAuth2Provider.CLIENT_ID,
|
||||
OAuth2Provider.REDIRECT_URI,
|
||||
null,
|
||||
null);
|
||||
response.addHeader("Location", authorizationURI.toASCIIString());
|
||||
response.sendError(303);
|
||||
} catch (Exception e) {
|
||||
throw new Fault(e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
final JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
|
||||
bean.setAddress(StringUtils.substringBefore(requestURL, "V40/OAuth2.svc") + "oauth/token");
|
||||
bean.setUsername("odatajclient");
|
||||
bean.setPassword("odatajclient");
|
||||
final WebClient accessTokenService = bean.createWebClient().
|
||||
type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).
|
||||
accept(MediaType.APPLICATION_JSON_TYPE);
|
||||
|
||||
final AuthorizationCodeGrant codeGrant = new AuthorizationCodeGrant(oauth2CodeHeader.get(0));
|
||||
final ClientAccessToken accessToken =
|
||||
OAuthClientUtils.getAccessToken(accessTokenService, OAUTH2_CONSUMER, codeGrant);
|
||||
if (accessToken == null) {
|
||||
throw new WebApplicationException("No OAuth2 access token");
|
||||
}
|
||||
} catch (OAuthServiceException e) {
|
||||
throw new Fault(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,8 +40,6 @@ public class OAuth2Provider implements AuthorizationCodeDataProvider {
|
|||
|
||||
public static final String REDIRECT_URI = "/stub/StaticService/V40/OAuth2.svc/";
|
||||
|
||||
public static final String OAUTH2_CODE_HEADER = "oauth2.token";
|
||||
|
||||
private Client client;
|
||||
|
||||
private ServerAuthorizationCodeGrant grant;
|
||||
|
|
|
@ -16,38 +16,23 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.client.core.http;
|
||||
package org.apache.olingo.fit.rest;
|
||||
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
public abstract class AbstractOAuth2HttpUriRequestFactory extends DefaultHttpUriRequestFactory {
|
||||
|
||||
protected final URI redirectURI;
|
||||
|
||||
public AbstractOAuth2HttpUriRequestFactory(final URI redirectURI) {
|
||||
this.redirectURI = redirectURI;
|
||||
}
|
||||
|
||||
protected abstract boolean isInited();
|
||||
|
||||
protected abstract void init() throws OAuth2Exception;
|
||||
|
||||
protected abstract void sign(HttpUriRequest request);
|
||||
@Provider
|
||||
public class OAuth2RequestFilter extends OAuthRequestFilter implements ContainerRequestFilter {
|
||||
|
||||
@Override
|
||||
public HttpUriRequest create(final HttpMethod method, final URI uri) {
|
||||
if (!isInited()) {
|
||||
init();
|
||||
public void filter(final ContainerRequestContext context) {
|
||||
final String svcName =
|
||||
StringUtils.substringBefore(StringUtils.substringAfter(context.getUriInfo().getPath(), "/"), "/");
|
||||
if ("OAuth2.svc".equals(svcName)) {
|
||||
super.filter(context);
|
||||
}
|
||||
|
||||
final HttpUriRequest request = super.create(method, uri);
|
||||
|
||||
sign(request);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
|
@ -40,6 +40,9 @@
|
|||
<jaxrs:server id="services" address="/" basePackages="org.apache.olingo.fit">
|
||||
<jaxrs:providers>
|
||||
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"/>
|
||||
<bean class="org.apache.olingo.fit.rest.OAuth2RequestFilter">
|
||||
<property name="dataProvider" ref="oauthProvider"/>
|
||||
</bean>
|
||||
<bean class="org.apache.olingo.fit.rest.ServiceNameResponseFilter"/>
|
||||
</jaxrs:providers>
|
||||
</jaxrs:server>
|
||||
|
@ -52,7 +55,7 @@
|
|||
<property name="dataProvider" ref="oauthProvider"/>
|
||||
</bean>
|
||||
<bean id="oauthSecurityInterceptor" class="org.apache.olingo.fit.rest.StaticSecurityInterceptor"/>
|
||||
<jaxrs:server id="oauthServer" address="/oauth">
|
||||
<jaxrs:server id="oauthServer" address="/oauth2">
|
||||
<jaxrs:serviceBeans>
|
||||
<ref bean="authorizationService"/>
|
||||
<ref bean="accessTokenService"/>
|
||||
|
|
|
@ -20,70 +20,84 @@ package org.apache.olingo.fit;
|
|||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
|
||||
import org.apache.cxf.jaxrs.client.WebClient;
|
||||
import org.apache.cxf.rs.security.oauth2.client.OAuthClientUtils;
|
||||
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
|
||||
import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant;
|
||||
import org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrant;
|
||||
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpRequestInterceptor;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.params.ClientPNames;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.apache.olingo.client.core.http.AbstractOAuth2HttpUriRequestFactory;
|
||||
import org.apache.olingo.client.core.http.AbstractOAuth2HttpClientFactory;
|
||||
import org.apache.olingo.client.core.http.OAuth2Exception;
|
||||
import org.apache.olingo.fit.rest.OAuth2Provider;
|
||||
|
||||
import java.net.URI;
|
||||
public class CXFOAuth2HttpClientFactory extends AbstractOAuth2HttpClientFactory {
|
||||
|
||||
public class CXFOAuth2HttpUriRequestFactory extends AbstractOAuth2HttpUriRequestFactory {
|
||||
private static final OAuthClientUtils.Consumer OAUTH2_CONSUMER =
|
||||
new OAuthClientUtils.Consumer(OAuth2Provider.CLIENT_ID, OAuth2Provider.CLIENT_SECRET);
|
||||
|
||||
private String code;
|
||||
private ClientAccessToken accessToken;
|
||||
|
||||
public CXFOAuth2HttpUriRequestFactory(final URI redirectURI) {
|
||||
super(redirectURI);
|
||||
public CXFOAuth2HttpClientFactory(final URI oauth2GrantServiceURI, final URI oauth2TokenServiceURI) {
|
||||
super(oauth2GrantServiceURI, oauth2TokenServiceURI);
|
||||
}
|
||||
|
||||
private WebClient getAccessTokenService() {
|
||||
final JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
|
||||
bean.setAddress(oauth2TokenServiceURI.toASCIIString());
|
||||
bean.setUsername("odatajclient");
|
||||
bean.setPassword("odatajclient");
|
||||
return bean.createWebClient().
|
||||
type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).accept(MediaType.APPLICATION_JSON_TYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInited() {
|
||||
return code != null;
|
||||
protected boolean isInited() throws OAuth2Exception {
|
||||
return accessToken != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() throws OAuth2Exception {
|
||||
// 1. Disable automatic redirects handling
|
||||
final URI authURI = OAuthClientUtils.getAuthorizationURI(
|
||||
oauth2GrantServiceURI.toASCIIString(),
|
||||
OAuth2Provider.CLIENT_ID,
|
||||
OAuth2Provider.REDIRECT_URI,
|
||||
null,
|
||||
null);
|
||||
|
||||
// Disable automatic redirects handling
|
||||
final HttpParams params = new BasicHttpParams();
|
||||
params.setParameter(ClientPNames.HANDLE_REDIRECTS, false);
|
||||
final DefaultHttpClient httpClient = new DefaultHttpClient(params);
|
||||
|
||||
// 2. Try to access the redirect URI without any special header: get redirected to the OAuth2 service
|
||||
URI location = null;
|
||||
try {
|
||||
final HttpResponse response = httpClient.execute(new HttpGet(redirectURI));
|
||||
|
||||
final Header locationHeader = response.getFirstHeader("Location");
|
||||
if (response.getStatusLine().getStatusCode() != 303 || locationHeader == null) {
|
||||
throw new IllegalStateException("OAuth flow is broken");
|
||||
}
|
||||
|
||||
location = new URI(locationHeader.getValue());
|
||||
|
||||
EntityUtils.consumeQuietly(response.getEntity());
|
||||
} catch (Exception e) {
|
||||
throw new OAuth2Exception(e);
|
||||
}
|
||||
|
||||
JsonNode oAuthAuthorizationData = null;
|
||||
String authenticityCookie = null;
|
||||
try {
|
||||
// 3. Need to (basic) authenticate against the OAuth2 service
|
||||
final HttpGet method = new HttpGet(location);
|
||||
// 1. Need to (basic) authenticate against the OAuth2 service
|
||||
final HttpGet method = new HttpGet(authURI);
|
||||
method.addHeader("Authorization", "Basic " + Base64.encodeBase64String("odatajclient:odatajclient".getBytes()));
|
||||
final HttpResponse response = httpClient.execute(method);
|
||||
|
||||
// 4. Pull out OAuth2 authorization data and "authenticity" cookie (CXF specific)
|
||||
// 2. Pull out OAuth2 authorization data and "authenticity" cookie (CXF specific)
|
||||
oAuthAuthorizationData = new XmlMapper().readTree(EntityUtils.toString(response.getEntity()));
|
||||
|
||||
final Header setCookieHeader = response.getFirstHeader("Set-Cookie");
|
||||
|
@ -95,9 +109,10 @@ public class CXFOAuth2HttpUriRequestFactory extends AbstractOAuth2HttpUriRequest
|
|||
throw new OAuth2Exception(e);
|
||||
}
|
||||
|
||||
String code = null;
|
||||
try {
|
||||
// 5. Submit the HTTP form for allowing access to the application
|
||||
location = new URIBuilder(oAuthAuthorizationData.get("replyTo").asText()).
|
||||
// 3. Submit the HTTP form for allowing access to the application
|
||||
final URI location = new URIBuilder(oAuthAuthorizationData.get("replyTo").asText()).
|
||||
addParameter("session_authenticity_token", oAuthAuthorizationData.get("authenticityToken").asText()).
|
||||
addParameter("client_id", oAuthAuthorizationData.get("clientId").asText()).
|
||||
addParameter("redirect_uri", oAuthAuthorizationData.get("redirectUri").asText()).
|
||||
|
@ -114,18 +129,53 @@ public class CXFOAuth2HttpUriRequestFactory extends AbstractOAuth2HttpUriRequest
|
|||
throw new IllegalStateException("OAuth flow is broken");
|
||||
}
|
||||
|
||||
// 6. Finally get the code value out of this last redirect
|
||||
// 4. Get the authorization code value out of this last redirect
|
||||
code = StringUtils.substringAfterLast(locationHeader.getValue(), "=");
|
||||
|
||||
EntityUtils.consumeQuietly(response.getEntity());
|
||||
} catch (Exception e) {
|
||||
throw new OAuth2Exception(e);
|
||||
}
|
||||
|
||||
// 5. Obtain the access token
|
||||
try {
|
||||
accessToken = OAuthClientUtils.getAccessToken(
|
||||
getAccessTokenService(), OAUTH2_CONSUMER, new AuthorizationCodeGrant(code));
|
||||
} catch (OAuthServiceException e) {
|
||||
throw new OAuth2Exception(e);
|
||||
}
|
||||
|
||||
if (accessToken == null) {
|
||||
throw new OAuth2Exception("No OAuth2 access token");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sign(final HttpUriRequest request) {
|
||||
request.addHeader(OAuth2Provider.OAUTH2_CODE_HEADER, code);
|
||||
protected void accessToken(final DefaultHttpClient client) throws OAuth2Exception {
|
||||
client.addRequestInterceptor(new HttpRequestInterceptor() {
|
||||
|
||||
@Override
|
||||
public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
|
||||
request.removeHeaders(HttpHeaders.AUTHORIZATION);
|
||||
request.addHeader(HttpHeaders.AUTHORIZATION, OAuthClientUtils.createAuthorizationHeader(accessToken));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refreshToken(final DefaultHttpClient client) throws OAuth2Exception {
|
||||
final String refreshToken = accessToken.getRefreshToken();
|
||||
if (refreshToken == null) {
|
||||
throw new OAuth2Exception("No OAuth2 refresh token");
|
||||
}
|
||||
|
||||
// refresh the token
|
||||
try {
|
||||
accessToken = OAuthClientUtils.getAccessToken(
|
||||
getAccessTokenService(), OAUTH2_CONSUMER, new RefreshTokenGrant(refreshToken));
|
||||
} catch (OAuthServiceException e) {
|
||||
throw new OAuth2Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -18,6 +18,9 @@
|
|||
*/
|
||||
package org.apache.olingo.fit.v4;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||
|
@ -25,39 +28,41 @@ import org.apache.olingo.client.api.uri.v4.URIBuilder;
|
|||
import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
|
||||
import org.apache.olingo.client.api.v4.ODataClient;
|
||||
import org.apache.olingo.client.core.ODataClientFactory;
|
||||
import org.apache.olingo.client.core.http.DefaultHttpUriRequestFactory;
|
||||
import org.apache.olingo.commons.api.domain.v4.ODataEntity;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.fit.CXFOAuth2HttpUriRequestFactory;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.apache.olingo.client.core.http.DefaultHttpClientFactory;
|
||||
import org.apache.olingo.fit.CXFOAuth2HttpClientFactory;
|
||||
|
||||
public class OAuth2TestITCase extends AbstractTestITCase {
|
||||
|
||||
private static final URI OAUTH2_GRANT_SERVICE_URI =
|
||||
URI.create("http://localhost:9080/stub/StaticService/oauth2/authorize");
|
||||
|
||||
private static final URI OAUTH2_TOKEN_SERVICE_URI =
|
||||
URI.create("http://localhost:9080/stub/StaticService/oauth2/token");
|
||||
|
||||
private EdmEnabledODataClient _edmClient;
|
||||
|
||||
@BeforeClass
|
||||
public static void enableOAuth2() {
|
||||
client.getConfiguration().setHttpUriRequestFactory(
|
||||
new CXFOAuth2HttpUriRequestFactory(URI.create(testOAuth2ServiceRootURL)));
|
||||
client.getConfiguration().setHttpClientFactory(
|
||||
new CXFOAuth2HttpClientFactory(OAUTH2_GRANT_SERVICE_URI, OAUTH2_TOKEN_SERVICE_URI));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void disableOAuth2() {
|
||||
client.getConfiguration().setHttpUriRequestFactory(new DefaultHttpUriRequestFactory());
|
||||
client.getConfiguration().setHttpClientFactory(new DefaultHttpClientFactory());
|
||||
}
|
||||
|
||||
protected EdmEnabledODataClient getEdmClient() {
|
||||
if (_edmClient == null) {
|
||||
_edmClient = ODataClientFactory.getEdmEnabledV4(testOAuth2ServiceRootURL);
|
||||
_edmClient.getConfiguration().setHttpUriRequestFactory(
|
||||
new CXFOAuth2HttpUriRequestFactory(URI.create(testOAuth2ServiceRootURL)));
|
||||
_edmClient.getConfiguration().setHttpClientFactory(
|
||||
new CXFOAuth2HttpClientFactory(OAUTH2_GRANT_SERVICE_URI, OAUTH2_TOKEN_SERVICE_URI));
|
||||
}
|
||||
|
||||
return _edmClient;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.client.api.http;
|
||||
|
||||
public interface WrappingHttpClientFactory extends HttpClientFactory {
|
||||
|
||||
HttpClientFactory getWrappedHttpClientFactory();
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.client.core.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpRequestInterceptor;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpResponseInterceptor;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.olingo.client.api.http.HttpClientFactory;
|
||||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
import org.apache.olingo.client.api.http.WrappingHttpClientFactory;
|
||||
|
||||
public abstract class AbstractOAuth2HttpClientFactory
|
||||
extends AbstractHttpClientFactory implements WrappingHttpClientFactory {
|
||||
|
||||
protected final DefaultHttpClientFactory wrapped;
|
||||
|
||||
protected final URI oauth2GrantServiceURI;
|
||||
|
||||
protected final URI oauth2TokenServiceURI;
|
||||
|
||||
protected HttpUriRequest currentRequest;
|
||||
|
||||
public AbstractOAuth2HttpClientFactory(final URI oauth2GrantServiceURI, final URI oauth2TokenServiceURI) {
|
||||
this(new DefaultHttpClientFactory(), oauth2GrantServiceURI, oauth2TokenServiceURI);
|
||||
}
|
||||
|
||||
public AbstractOAuth2HttpClientFactory(final DefaultHttpClientFactory wrapped,
|
||||
final URI oauth2GrantServiceURI, final URI oauth2TokenServiceURI) {
|
||||
|
||||
super();
|
||||
this.wrapped = wrapped;
|
||||
this.oauth2GrantServiceURI = oauth2GrantServiceURI;
|
||||
this.oauth2TokenServiceURI = oauth2TokenServiceURI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClientFactory getWrappedHttpClientFactory() {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
protected abstract boolean isInited() throws OAuth2Exception;
|
||||
|
||||
protected abstract void init() throws OAuth2Exception;
|
||||
|
||||
protected abstract void accessToken(DefaultHttpClient client) throws OAuth2Exception;
|
||||
|
||||
protected abstract void refreshToken(DefaultHttpClient client) throws OAuth2Exception;
|
||||
|
||||
@Override
|
||||
public HttpClient create(final HttpMethod method, final URI uri) {
|
||||
if (!isInited()) {
|
||||
init();
|
||||
}
|
||||
|
||||
final DefaultHttpClient httpClient = wrapped.create(method, uri);
|
||||
accessToken(httpClient);
|
||||
|
||||
httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
|
||||
|
||||
@Override
|
||||
public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
|
||||
if (request instanceof HttpUriRequest) {
|
||||
currentRequest = (HttpUriRequest) request;
|
||||
} else {
|
||||
currentRequest = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
|
||||
|
||||
@Override
|
||||
public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException {
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
|
||||
refreshToken(httpClient);
|
||||
|
||||
if (currentRequest != null) {
|
||||
httpClient.execute(currentRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(final HttpClient httpClient) {
|
||||
wrapped.close(httpClient);
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,10 @@ public class OAuth2Exception extends RuntimeException {
|
|||
|
||||
private static final long serialVersionUID = 5695438980473040134L;
|
||||
|
||||
public OAuth2Exception(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public OAuth2Exception(final Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
|
|
@ -28,12 +28,13 @@ import org.apache.olingo.client.api.http.HttpClientFactory;
|
|||
import org.apache.olingo.client.api.http.HttpMethod;
|
||||
|
||||
import java.net.URI;
|
||||
import org.apache.olingo.client.api.http.WrappingHttpClientFactory;
|
||||
|
||||
/**
|
||||
* Implementation for working behind an HTTP proxy (possibly requiring authentication); requires another concrete
|
||||
* {@link HttpClientFactory} implementation acting as real HTTP client factory.
|
||||
*/
|
||||
public class ProxyWrapperHttpClientFactory implements HttpClientFactory {
|
||||
public class ProxyWrappingHttpClientFactory implements WrappingHttpClientFactory {
|
||||
|
||||
private final URI proxy;
|
||||
|
||||
|
@ -43,19 +44,19 @@ public class ProxyWrapperHttpClientFactory implements HttpClientFactory {
|
|||
|
||||
private final DefaultHttpClientFactory wrapped;
|
||||
|
||||
public ProxyWrapperHttpClientFactory(final URI proxy) {
|
||||
public ProxyWrappingHttpClientFactory(final URI proxy) {
|
||||
this(proxy, null, null, new DefaultHttpClientFactory());
|
||||
}
|
||||
|
||||
public ProxyWrapperHttpClientFactory(final URI proxy, final String proxyUsername, final String proxyPassword) {
|
||||
public ProxyWrappingHttpClientFactory(final URI proxy, final String proxyUsername, final String proxyPassword) {
|
||||
this(proxy, proxyUsername, proxyPassword, new DefaultHttpClientFactory());
|
||||
}
|
||||
|
||||
public ProxyWrapperHttpClientFactory(final URI proxy, final DefaultHttpClientFactory wrapped) {
|
||||
public ProxyWrappingHttpClientFactory(final URI proxy, final DefaultHttpClientFactory wrapped) {
|
||||
this(proxy, null, null, wrapped);
|
||||
}
|
||||
|
||||
public ProxyWrapperHttpClientFactory(final URI proxy,
|
||||
public ProxyWrappingHttpClientFactory(final URI proxy,
|
||||
final String proxyUsername, final String proxyPassword, final DefaultHttpClientFactory wrapped) {
|
||||
|
||||
this.proxy = proxy;
|
|
@ -46,10 +46,11 @@ import java.io.InputStream;
|
|||
public abstract class AbstractODataDeserializer {
|
||||
|
||||
protected final ODataServiceVersion version;
|
||||
|
||||
protected final ODataDeserializer deserializer;
|
||||
|
||||
public AbstractODataDeserializer(final ODataServiceVersion version, final boolean serverMode,
|
||||
final ODataFormat format) {
|
||||
final ODataFormat format) {
|
||||
this.version = version;
|
||||
if (format == ODataFormat.XML || format == ODataFormat.ATOM) {
|
||||
deserializer = new AtomDeserializer(version);
|
||||
|
@ -76,18 +77,18 @@ public abstract class AbstractODataDeserializer {
|
|||
|
||||
protected XmlMapper getXmlMapper() {
|
||||
final XmlMapper xmlMapper = new XmlMapper(
|
||||
new XmlFactory(new InputFactoryImpl(), new OutputFactoryImpl()), new JacksonXmlModule());
|
||||
new XmlFactory(new InputFactoryImpl(), new OutputFactoryImpl()), new JacksonXmlModule());
|
||||
|
||||
xmlMapper.setInjectableValues(new InjectableValues.Std().
|
||||
addValue(ODataServiceVersion.class, version).
|
||||
addValue(Boolean.class, Boolean.FALSE));
|
||||
addValue(ODataServiceVersion.class, version).
|
||||
addValue(Boolean.class, Boolean.FALSE));
|
||||
|
||||
xmlMapper.addHandler(new DeserializationProblemHandler() {
|
||||
@Override
|
||||
public boolean handleUnknownProperty(final DeserializationContext ctxt, final JsonParser jp,
|
||||
final com.fasterxml.jackson.databind.JsonDeserializer<?> deserializer,
|
||||
final Object beanOrClass, final String propertyName)
|
||||
throws IOException, JsonProcessingException {
|
||||
final com.fasterxml.jackson.databind.JsonDeserializer<?> deserializer,
|
||||
final Object beanOrClass, final String propertyName)
|
||||
throws IOException, JsonProcessingException {
|
||||
|
||||
// skip any unknown property
|
||||
ctxt.getParser().skipChildren();
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.apache.olingo.client.api.CommonODataClient;
|
|||
import org.apache.olingo.client.api.http.HttpClientFactory;
|
||||
import org.apache.olingo.client.api.uri.SegmentType;
|
||||
import org.apache.olingo.client.core.http.BasicAuthHttpClientFactory;
|
||||
import org.apache.olingo.client.core.http.ProxyWrapperHttpClientFactory;
|
||||
import org.apache.olingo.commons.api.Constants;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
|
@ -65,6 +64,7 @@ import java.util.Iterator;
|
|||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.olingo.client.api.http.WrappingHttpClientFactory;
|
||||
|
||||
/**
|
||||
* URI utilities.
|
||||
|
@ -354,8 +354,8 @@ public final class URIUtils {
|
|||
HttpClientFactory httpclientFactory = client.getConfiguration().getHttpClientFactory();
|
||||
if (httpclientFactory instanceof BasicAuthHttpClientFactory) {
|
||||
return true;
|
||||
} else if (httpclientFactory instanceof ProxyWrapperHttpClientFactory) {
|
||||
ProxyWrapperHttpClientFactory tmp = (ProxyWrapperHttpClientFactory) httpclientFactory;
|
||||
} else if (httpclientFactory instanceof WrappingHttpClientFactory) {
|
||||
WrappingHttpClientFactory tmp = (WrappingHttpClientFactory) httpclientFactory;
|
||||
if (tmp.getWrappedHttpClientFactory() instanceof BasicAuthHttpClientFactory) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.apache.olingo.commons.core.data.LinkImpl;
|
|||
import org.apache.olingo.commons.core.data.LinkedComplexValueImpl;
|
||||
import org.apache.olingo.commons.core.data.PropertyImpl;
|
||||
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
@ -69,23 +68,39 @@ import java.util.regex.Pattern;
|
|||
public class JsonDeserializer implements ODataDeserializer {
|
||||
|
||||
protected final Pattern CUSTOM_ANNOTATION = Pattern.compile("(.+)@(.+)\\.(.+)");
|
||||
|
||||
protected final ODataServiceVersion version;
|
||||
|
||||
protected final boolean serverMode;
|
||||
|
||||
protected String jsonType;
|
||||
|
||||
protected String jsonId;
|
||||
|
||||
protected String jsonETag;
|
||||
|
||||
protected String jsonReadLink;
|
||||
|
||||
protected String jsonEditLink;
|
||||
|
||||
protected String jsonMediaEditLink;
|
||||
|
||||
protected String jsonMediaReadLink;
|
||||
|
||||
protected String jsonMediaContentType;
|
||||
|
||||
protected String jsonMediaETag;
|
||||
|
||||
protected String jsonAssociationLink;
|
||||
|
||||
protected String jsonNavigationLink;
|
||||
|
||||
protected String jsonCount;
|
||||
|
||||
protected String jsonNextLink;
|
||||
|
||||
protected String jsonDeltaLink;
|
||||
|
||||
protected String jsonError;
|
||||
|
||||
private JsonGeoValueDeserializer geoDeserializer;
|
||||
|
@ -129,7 +144,7 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
|
||||
protected String setInline(final String name, final String suffix, final JsonNode tree,
|
||||
final ObjectCodec codec, final LinkImpl link) throws IOException {
|
||||
final ObjectCodec codec, final LinkImpl link) throws IOException {
|
||||
|
||||
final String entityNamePrefix = name.substring(0, name.indexOf(suffix));
|
||||
if (tree.has(entityNamePrefix)) {
|
||||
|
@ -143,11 +158,9 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
} else if (inline instanceof ArrayNode) {
|
||||
link.setType(ODataLinkType.ENTITY_SET_NAVIGATION.toString());
|
||||
|
||||
EntitySet entitySet = new EntitySetImpl();
|
||||
Iterator<JsonNode> entries = inline.elements();
|
||||
while (entries.hasNext()) {
|
||||
entitySet.getEntities().add(
|
||||
entityDeserializer.doDeserialize(entries.next().traverse(codec)).getPayload());
|
||||
final EntitySet entitySet = new EntitySetImpl();
|
||||
for (final Iterator<JsonNode> entries = inline.elements(); entries.hasNext();) {
|
||||
entitySet.getEntities().add(entityDeserializer.doDeserialize(entries.next().traverse(codec)).getPayload());
|
||||
}
|
||||
|
||||
link.setInlineEntitySet(entitySet);
|
||||
|
@ -157,7 +170,7 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
|
||||
protected void links(final Map.Entry<String, JsonNode> field, final Linked linked, final Set<String> toRemove,
|
||||
final JsonNode tree, final ObjectCodec codec) throws IOException {
|
||||
final JsonNode tree, final ObjectCodec codec) throws IOException {
|
||||
if (serverMode) {
|
||||
serverLinks(field, linked, toRemove, tree, codec);
|
||||
} else {
|
||||
|
@ -166,7 +179,7 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
|
||||
private void clientLinks(final Map.Entry<String, JsonNode> field, final Linked linked, final Set<String> toRemove,
|
||||
final JsonNode tree, final ObjectCodec codec) throws IOException {
|
||||
final JsonNode tree, final ObjectCodec codec) throws IOException {
|
||||
|
||||
if (field.getKey().endsWith(jsonNavigationLink)) {
|
||||
final LinkImpl link = new LinkImpl();
|
||||
|
@ -195,10 +208,10 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
|
||||
private void serverLinks(final Map.Entry<String, JsonNode> field, final Linked linked, final Set<String> toRemove,
|
||||
final JsonNode tree, final ObjectCodec codec) throws IOException {
|
||||
final JsonNode tree, final ObjectCodec codec) throws IOException {
|
||||
|
||||
if (field.getKey().endsWith(Constants.JSON_BIND_LINK_SUFFIX)
|
||||
|| field.getKey().endsWith(jsonNavigationLink)) {
|
||||
|| field.getKey().endsWith(jsonNavigationLink)) {
|
||||
|
||||
if (field.getValue().isValueNode()) {
|
||||
final String suffix = field.getKey().replaceAll("^.*@", "@");
|
||||
|
@ -258,7 +271,7 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
if (node.has(Constants.ATTR_TYPE)) {
|
||||
type = ODataPropertyType.PRIMITIVE;
|
||||
typeInfo = new EdmTypeInfo.Builder().
|
||||
setTypeExpression("Edm.Geography" + node.get(Constants.ATTR_TYPE).asText()).build();
|
||||
setTypeExpression("Edm.Geography" + node.get(Constants.ATTR_TYPE).asText()).build();
|
||||
} else {
|
||||
type = ODataPropertyType.COMPLEX;
|
||||
}
|
||||
|
@ -270,8 +283,8 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
|
||||
protected void populate(final Annotatable annotatable, final List<Property> properties,
|
||||
final ObjectNode tree, final ObjectCodec codec)
|
||||
throws IOException, EdmPrimitiveTypeException {
|
||||
final ObjectNode tree, final ObjectCodec codec)
|
||||
throws IOException, EdmPrimitiveTypeException {
|
||||
|
||||
String type = null;
|
||||
Annotation annotation = null;
|
||||
|
@ -297,8 +310,8 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
final PropertyImpl property = new PropertyImpl();
|
||||
property.setName(field.getKey());
|
||||
property.setType(type == null
|
||||
? null
|
||||
: new EdmTypeInfo.Builder().setTypeExpression(type).build().internal());
|
||||
? null
|
||||
: new EdmTypeInfo.Builder().setTypeExpression(type).build().internal());
|
||||
type = null;
|
||||
|
||||
value(property, field.getValue(), codec);
|
||||
|
@ -313,25 +326,25 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
|
||||
private Object fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) throws EdmPrimitiveTypeException {
|
||||
return node.isNull() ? null :
|
||||
typeInfo == null ? node.asText() :
|
||||
typeInfo.getPrimitiveTypeKind().isGeospatial() ?
|
||||
getGeoDeserializer().deserialize(node, typeInfo) :
|
||||
((EdmPrimitiveType) typeInfo.getType())
|
||||
.valueOfString(node.asText(), true, null,
|
||||
Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, true,
|
||||
((EdmPrimitiveType) typeInfo.getType()).getDefaultType());
|
||||
return node.isNull() ? null
|
||||
: typeInfo == null ? node.asText()
|
||||
: typeInfo.getPrimitiveTypeKind().isGeospatial()
|
||||
? getGeoDeserializer().deserialize(node, typeInfo)
|
||||
: ((EdmPrimitiveType) typeInfo.getType())
|
||||
.valueOfString(node.asText(), true, null,
|
||||
Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, true,
|
||||
((EdmPrimitiveType) typeInfo.getType()).getDefaultType());
|
||||
}
|
||||
|
||||
private Object fromComplex(final ObjectNode node, final ObjectCodec codec)
|
||||
throws IOException, EdmPrimitiveTypeException {
|
||||
throws IOException, EdmPrimitiveTypeException {
|
||||
|
||||
if (version.compareTo(ODataServiceVersion.V40) < 0) {
|
||||
List<Property> properties = new ArrayList<Property>();
|
||||
final List<Property> properties = new ArrayList<Property>();
|
||||
populate(null, properties, node, codec);
|
||||
return properties;
|
||||
} else {
|
||||
LinkedComplexValue linkComplexValue = new LinkedComplexValueImpl();
|
||||
final LinkedComplexValue linkComplexValue = new LinkedComplexValueImpl();
|
||||
final Set<String> toRemove = new HashSet<String>();
|
||||
for (final Iterator<Map.Entry<String, JsonNode>> itor = node.fields(); itor.hasNext();) {
|
||||
final Map.Entry<String, JsonNode> field = itor.next();
|
||||
|
@ -346,13 +359,13 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
|
||||
private void fromCollection(final Valuable valuable, final Iterator<JsonNode> nodeItor, final EdmTypeInfo typeInfo,
|
||||
final ObjectCodec codec) throws IOException, EdmPrimitiveTypeException {
|
||||
final ObjectCodec codec) throws IOException, EdmPrimitiveTypeException {
|
||||
|
||||
List<Object> values = new ArrayList<Object>();
|
||||
final List<Object> values = new ArrayList<Object>();
|
||||
ValueType valueType = ValueType.COLLECTION_PRIMITIVE;
|
||||
|
||||
final EdmTypeInfo type = typeInfo == null ? null :
|
||||
new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
|
||||
final EdmTypeInfo type = typeInfo == null ? null
|
||||
: new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
|
||||
|
||||
while (nodeItor.hasNext()) {
|
||||
final JsonNode child = nodeItor.next();
|
||||
|
@ -371,8 +384,8 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
((ObjectNode) child).remove(jsonType);
|
||||
}
|
||||
final Object value = fromComplex((ObjectNode) child, codec);
|
||||
valueType = value instanceof LinkedComplexValue ? ValueType.COLLECTION_LINKED_COMPLEX :
|
||||
ValueType.COLLECTION_COMPLEX;
|
||||
valueType = value instanceof LinkedComplexValue ? ValueType.COLLECTION_LINKED_COMPLEX
|
||||
: ValueType.COLLECTION_COMPLEX;
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
|
@ -380,50 +393,51 @@ public class JsonDeserializer implements ODataDeserializer {
|
|||
}
|
||||
|
||||
protected void value(final Valuable valuable, final JsonNode node, final ObjectCodec codec)
|
||||
throws IOException, EdmPrimitiveTypeException {
|
||||
EdmTypeInfo typeInfo = StringUtils.isBlank(valuable.getType()) ? null :
|
||||
new EdmTypeInfo.Builder().setTypeExpression(valuable.getType()).build();
|
||||
throws IOException, EdmPrimitiveTypeException {
|
||||
|
||||
EdmTypeInfo typeInfo = StringUtils.isBlank(valuable.getType()) ? null
|
||||
: new EdmTypeInfo.Builder().setTypeExpression(valuable.getType()).build();
|
||||
|
||||
final Map.Entry<ODataPropertyType, EdmTypeInfo> guessed = guessPropertyType(node);
|
||||
if (typeInfo == null) {
|
||||
typeInfo = guessed.getValue();
|
||||
}
|
||||
|
||||
final ODataPropertyType propType = typeInfo == null ? guessed.getKey() :
|
||||
typeInfo.isCollection() ? ODataPropertyType.COLLECTION :
|
||||
typeInfo.isPrimitiveType() ? ODataPropertyType.PRIMITIVE :
|
||||
node.isValueNode() ? ODataPropertyType.ENUM : ODataPropertyType.COMPLEX;
|
||||
final ODataPropertyType propType = typeInfo == null ? guessed.getKey()
|
||||
: typeInfo.isCollection() ? ODataPropertyType.COLLECTION
|
||||
: typeInfo.isPrimitiveType() ? ODataPropertyType.PRIMITIVE
|
||||
: node.isValueNode() ? ODataPropertyType.ENUM : ODataPropertyType.COMPLEX;
|
||||
|
||||
switch (propType) {
|
||||
case COLLECTION:
|
||||
fromCollection(valuable, node.elements(), typeInfo, codec);
|
||||
break;
|
||||
case COLLECTION:
|
||||
fromCollection(valuable, node.elements(), typeInfo, codec);
|
||||
break;
|
||||
|
||||
case COMPLEX:
|
||||
if (node.has(jsonType)) {
|
||||
valuable.setType(node.get(jsonType).asText());
|
||||
((ObjectNode) node).remove(jsonType);
|
||||
}
|
||||
final Object value = fromComplex((ObjectNode) node, codec);
|
||||
valuable.setValue(value instanceof LinkedComplexValue ? ValueType.LINKED_COMPLEX : ValueType.COMPLEX, value);
|
||||
break;
|
||||
case COMPLEX:
|
||||
if (node.has(jsonType)) {
|
||||
valuable.setType(node.get(jsonType).asText());
|
||||
((ObjectNode) node).remove(jsonType);
|
||||
}
|
||||
final Object value = fromComplex((ObjectNode) node, codec);
|
||||
valuable.setValue(value instanceof LinkedComplexValue ? ValueType.LINKED_COMPLEX : ValueType.COMPLEX, value);
|
||||
break;
|
||||
|
||||
case ENUM:
|
||||
valuable.setValue(ValueType.ENUM, node.asText());
|
||||
break;
|
||||
case ENUM:
|
||||
valuable.setValue(ValueType.ENUM, node.asText());
|
||||
break;
|
||||
|
||||
case PRIMITIVE:
|
||||
if (valuable.getType() == null && typeInfo != null) {
|
||||
valuable.setType(typeInfo.getFullQualifiedName().toString());
|
||||
}
|
||||
final Object primitiveValue = fromPrimitive(node, typeInfo);
|
||||
valuable.setValue(primitiveValue instanceof Geospatial ? ValueType.GEOSPATIAL : ValueType.PRIMITIVE,
|
||||
primitiveValue);
|
||||
break;
|
||||
case PRIMITIVE:
|
||||
if (valuable.getType() == null && typeInfo != null) {
|
||||
valuable.setType(typeInfo.getFullQualifiedName().toString());
|
||||
}
|
||||
final Object primitiveValue = fromPrimitive(node, typeInfo);
|
||||
valuable.setValue(primitiveValue instanceof Geospatial ? ValueType.GEOSPATIAL : ValueType.PRIMITIVE,
|
||||
primitiveValue);
|
||||
break;
|
||||
|
||||
case EMPTY:
|
||||
default:
|
||||
valuable.setValue(ValueType.PRIMITIVE, StringUtils.EMPTY);
|
||||
case EMPTY:
|
||||
default:
|
||||
valuable.setValue(ValueType.PRIMITIVE, StringUtils.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue