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)
|
||||
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
|
||||
* {@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.config.RestClientModule;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.jclouds.xml.XMLParser;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
|
@ -2511,7 +2512,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
Function<HttpResponse, TestJAXBDomain> parser = (Function<HttpResponse, TestJAXBDomain>) RestAnnotationProcessor
|
||||
.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>");
|
||||
TestJAXBDomain domain = parser.apply(new HttpResponse(200, "ok", newStringPayload(payload.toString())));
|
||||
assertEquals(domain.getElem(), "Hello World");
|
||||
|
@ -2529,7 +2530,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
|||
Function<HttpResponse, TestJAXBDomain> parser = (Function<HttpResponse, TestJAXBDomain>) RestAnnotationProcessor
|
||||
.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>");
|
||||
TestJAXBDomain domain = parser.apply(new HttpResponse(200, "ok", newStringPayload(payload.toString())));
|
||||
assertEquals(domain.getElem(), "Hello World");
|
||||
|
|
Loading…
Reference in New Issue