mirror of https://github.com/apache/jclouds.git
Added BindToXMLPayload binder to allow seralization of objects to the payload using JAXB
This commit is contained in:
parent
0387b1bb92
commit
e5478cdd84
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.rest.binders;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown during the binding process.
|
||||||
|
*
|
||||||
|
* @author Ignasi Barrera
|
||||||
|
*/
|
||||||
|
public class BindException extends RuntimeException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private HttpRequest request;
|
||||||
|
|
||||||
|
public BindException(final HttpRequest request)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindException(final HttpRequest request, final String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindException(final HttpRequest request, final Throwable cause)
|
||||||
|
{
|
||||||
|
super(cause.getMessage(), cause);
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindException(final HttpRequest request, final String message, final Throwable cause)
|
||||||
|
{
|
||||||
|
super(message, cause);
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage()
|
||||||
|
{
|
||||||
|
String msg = "Could not bind object to request" + request + ": ";
|
||||||
|
return msg + super.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpRequest getRequest()
|
||||||
|
{
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.rest.binders;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.io.MutableContentMetadata;
|
||||||
|
import org.jclouds.rest.Binder;
|
||||||
|
import org.jclouds.xml.XMLParser;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds the request parameters to an XML formatted payload.
|
||||||
|
*
|
||||||
|
* @author Ignasi Barrera
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class BindToXMLPayload implements Binder
|
||||||
|
{
|
||||||
|
protected final XMLParser xmlParser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public BindToXMLPayload(final XMLParser xmlParser)
|
||||||
|
{
|
||||||
|
this.xmlParser = checkNotNull(xmlParser, "xmlParser");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R extends HttpRequest> R bindToRequest(final R request, final Object input)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String xml = xmlParser.toXML(checkNotNull(input, "input"));
|
||||||
|
request.setPayload(xml);
|
||||||
|
MutableContentMetadata metadata = request.getPayload().getContentMetadata();
|
||||||
|
if (contentTypeMustBeAdded(metadata))
|
||||||
|
{
|
||||||
|
metadata.setContentType(MediaType.APPLICATION_XML);
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
throw new BindException(request, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean contentTypeMustBeAdded(final MutableContentMetadata metadata)
|
||||||
|
{
|
||||||
|
return Strings.isNullOrEmpty(metadata.getContentType())
|
||||||
|
|| metadata.getContentType().equals("application/unknown");
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,6 +33,9 @@ import com.google.inject.ImplementedBy;
|
||||||
@ImplementedBy(JAXBParser.class)
|
@ImplementedBy(JAXBParser.class)
|
||||||
public interface XMLParser
|
public interface XMLParser
|
||||||
{
|
{
|
||||||
|
/** The default xml header. */
|
||||||
|
public static final String DEFAULT_XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize the object into xml. If the object is a generic type, use
|
* Serialize the object into xml. If the object is a generic type, use
|
||||||
* {@link #toXML(Object, Type)}
|
* {@link #toXML(Object, Type)}
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.rest.binders;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.rest.internal.RestAnnotationProcessorTest.TestJAXBDomain;
|
||||||
|
import org.jclouds.xml.XMLParser;
|
||||||
|
import org.jclouds.xml.internal.JAXBParser;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code BindToXMLPayload}.
|
||||||
|
*
|
||||||
|
* @author Ignasi Barrera
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "BindToXMLPayloadTest")
|
||||||
|
public class BindToXMLPayloadTest
|
||||||
|
{
|
||||||
|
XMLParser xml = new JAXBParser();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBindJAXBObject() throws SecurityException, NoSuchMethodException
|
||||||
|
{
|
||||||
|
BindToXMLPayload binder = new BindToXMLPayload(xml);
|
||||||
|
|
||||||
|
// Build the object to bind
|
||||||
|
TestJAXBDomain obj = new TestJAXBDomain();
|
||||||
|
obj.setElem("Hello World");
|
||||||
|
|
||||||
|
HttpRequest request = HttpRequest.builder().method("GET").endpoint(URI.create("http://momma")).build();
|
||||||
|
request = binder.bindToRequest(request, obj);
|
||||||
|
assertEquals(request.getPayload().getRawContent(), XMLParser.DEFAULT_XML_HEADER + "<test><elem>Hello World</elem></test>");
|
||||||
|
assertEquals(request.getPayload().getContentMetadata().getContentType(), MediaType.APPLICATION_XML);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHeaderIsChangedIfNeeded() throws SecurityException, NoSuchMethodException
|
||||||
|
{
|
||||||
|
BindToXMLPayload binder = new BindToXMLPayload(xml);
|
||||||
|
|
||||||
|
// Build the object to bind
|
||||||
|
TestJAXBDomain obj = new TestJAXBDomain();
|
||||||
|
obj.setElem("Hello World");
|
||||||
|
|
||||||
|
// Add teh unknown content-type header to verify it is changed by the binder
|
||||||
|
Multimap<String, String> headers = ImmutableMultimap.<String, String> of("Content-type", "application/unknown");
|
||||||
|
HttpRequest request = HttpRequest.builder().method("GET").endpoint(URI.create("http://momma")).headers(headers).build();
|
||||||
|
|
||||||
|
request = binder.bindToRequest(request, obj);
|
||||||
|
assertEquals(request.getPayload().getRawContent(), XMLParser.DEFAULT_XML_HEADER + "<test><elem>Hello World</elem></test>");
|
||||||
|
assertEquals(request.getPayload().getContentMetadata().getContentType(), MediaType.APPLICATION_XML);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
|
public void testNullIsBad()
|
||||||
|
{
|
||||||
|
BindToXMLPayload binder = new BindToXMLPayload(xml);
|
||||||
|
binder.bindToRequest(HttpRequest.builder().method("GET").endpoint(URI.create("http://momma")).build(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = BindException.class)
|
||||||
|
public void testInvalidObjectBinding()
|
||||||
|
{
|
||||||
|
BindToXMLPayload binder = new BindToXMLPayload(xml);
|
||||||
|
HttpRequest request = HttpRequest.builder().method("GET").endpoint(URI.create("http://momma")).build();
|
||||||
|
request = binder.bindToRequest(request, new Object());
|
||||||
|
}
|
||||||
|
}
|
|
@ -145,6 +145,7 @@ import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
import org.jclouds.rest.binders.BindToStringPayload;
|
import org.jclouds.rest.binders.BindToStringPayload;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
|
import org.jclouds.xml.XMLParser;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
|
@ -2511,7 +2512,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
||||||
Function<HttpResponse, TestJAXBDomain> parser = (Function<HttpResponse, TestJAXBDomain>) RestAnnotationProcessor
|
Function<HttpResponse, TestJAXBDomain> parser = (Function<HttpResponse, TestJAXBDomain>) RestAnnotationProcessor
|
||||||
.createResponseParser(parserFactory, injector, method, request);
|
.createResponseParser(parserFactory, injector, method, request);
|
||||||
|
|
||||||
StringBuffer payload = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
StringBuffer payload = new StringBuffer(XMLParser.DEFAULT_XML_HEADER);
|
||||||
payload.append("<test><elem>Hello World</elem></test>");
|
payload.append("<test><elem>Hello World</elem></test>");
|
||||||
TestJAXBDomain domain = parser.apply(new HttpResponse(200, "ok", newStringPayload(payload.toString())));
|
TestJAXBDomain domain = parser.apply(new HttpResponse(200, "ok", newStringPayload(payload.toString())));
|
||||||
assertEquals(domain.getElem(), "Hello World");
|
assertEquals(domain.getElem(), "Hello World");
|
||||||
|
@ -2529,7 +2530,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
||||||
Function<HttpResponse, TestJAXBDomain> parser = (Function<HttpResponse, TestJAXBDomain>) RestAnnotationProcessor
|
Function<HttpResponse, TestJAXBDomain> parser = (Function<HttpResponse, TestJAXBDomain>) RestAnnotationProcessor
|
||||||
.createResponseParser(parserFactory, injector, method, request);
|
.createResponseParser(parserFactory, injector, method, request);
|
||||||
|
|
||||||
StringBuffer payload = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
StringBuffer payload = new StringBuffer(XMLParser.DEFAULT_XML_HEADER);
|
||||||
payload.append("<test><elem>Hello World</elem></test>");
|
payload.append("<test><elem>Hello World</elem></test>");
|
||||||
TestJAXBDomain domain = parser.apply(new HttpResponse(200, "ok", newStringPayload(payload.toString())));
|
TestJAXBDomain domain = parser.apply(new HttpResponse(200, "ok", newStringPayload(payload.toString())));
|
||||||
assertEquals(domain.getElem(), "Hello World");
|
assertEquals(domain.getElem(), "Hello World");
|
||||||
|
|
Loading…
Reference in New Issue