You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/12/23 21:28:59 UTC
[1/2] juneau git commit: (JUNEAU-76) Improvements to Context/Builder
APIs
Repository: juneau
Updated Branches:
refs/heads/master 803910f74 -> 776647695
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java
index 869c914..e2e1a70 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStoreBuilder.java
@@ -80,6 +80,8 @@ public class PropertyStoreBuilder {
* @return This object (for method chaining).
*/
public synchronized PropertyStoreBuilder apply(PropertyStore copyFrom) {
+ propertyStore = null;
+
if (copyFrom != null)
for (Map.Entry<String,PropertyGroup> e : copyFrom.groups.entrySet()) {
String gName = e.getKey();
@@ -163,6 +165,7 @@ public class PropertyStoreBuilder {
* @return This object (for method chaining).
*/
public synchronized PropertyStoreBuilder remove(String key) {
+ propertyStore = null;
return set(key, null);
}
@@ -176,6 +179,7 @@ public class PropertyStoreBuilder {
* @return This object (for method chaining).
*/
public synchronized PropertyStoreBuilder set(Map<String,Object> newProperties) {
+ propertyStore = null;
clear();
add(newProperties);
return this;
@@ -191,6 +195,7 @@ public class PropertyStoreBuilder {
* @return This object (for method chaining).
*/
public synchronized PropertyStoreBuilder add(Map<String,Object> newProperties) {
+ propertyStore = null;
if (newProperties != null)
for (Map.Entry<String,Object> e : newProperties.entrySet())
@@ -220,9 +225,9 @@ public class PropertyStoreBuilder {
* @throws ConfigException If property is not a SET/LIST/MAP property, or the argument is invalid.
*/
public synchronized PropertyStoreBuilder addTo(String key, String arg, Object value) {
+ propertyStore = null;
String g = group(key);
String n = g.isEmpty() ? key : key.substring(g.length()+1);
- propertyStore = null;
PropertyGroupBuilder gb = groups.get(g);
if (gb == null) {
@@ -254,6 +259,7 @@ public class PropertyStoreBuilder {
* @throws ConfigException If property is not a SET/LIST/MAP property, or the argument is invalid.
*/
public synchronized PropertyStoreBuilder addTo(String key, Object value) {
+ propertyStore = null;
return addTo(key, null, value);
}
@@ -266,9 +272,9 @@ public class PropertyStoreBuilder {
* @throws ConfigException If property is not a SET or LIST property.
*/
public synchronized PropertyStoreBuilder removeFrom(String key, Object value) {
+ propertyStore = null;
String g = group(key);
String n = g.isEmpty() ? key : key.substring(g.length()+1);
- propertyStore = null;
PropertyGroupBuilder gb = groups.get(g);
@@ -285,6 +291,32 @@ public class PropertyStoreBuilder {
}
/**
+ * Peeks at a property value.
+ *
+ * <p>
+ * Used for debugging purposes.
+ *
+ * @param key The property key.
+ * @return The property value, or <jk>null</jk> if it doesn't exist.
+ */
+ public Object peek(String key) {
+ String g = group(key);
+ String n = g.isEmpty() ? key : key.substring(g.length()+1);
+
+ PropertyGroupBuilder gb = groups.get(g);
+
+ // Create property group anyway to generate a good error message.
+ if (gb == null)
+ return null;
+
+ MutableProperty bp = gb.properties.get(n);
+ if (bp == null)
+ return null;
+
+ return bp.peek();
+ }
+
+ /**
* Clears all entries in this property store.
*/
public synchronized void clear() {
@@ -424,6 +456,8 @@ public class PropertyStoreBuilder {
abstract void set(Object value);
abstract void apply(Object value);
+
+ abstract Object peek();
void add(String arg, Object value) {
throw new ConfigException("Cannot add value {0} ({1}) to property ''{2}'' ({3}).",
@@ -471,6 +505,11 @@ public class PropertyStoreBuilder {
synchronized boolean isEmpty() {
return this.value == null;
}
+
+ @Override /* MutableProperty */
+ synchronized Object peek() {
+ return value;
+ }
}
//-------------------------------------------------------------------------------------------------------------------
@@ -560,6 +599,11 @@ public class PropertyStoreBuilder {
synchronized boolean isEmpty() {
return this.value.isEmpty();
}
+
+ @Override /* MutableProperty */
+ synchronized Object peek() {
+ return value;
+ }
}
//-------------------------------------------------------------------------------------------------------------------
@@ -673,6 +717,11 @@ public class PropertyStoreBuilder {
synchronized boolean isEmpty() {
return this.value.isEmpty();
}
+
+ @Override /* MutableProperty */
+ synchronized Object peek() {
+ return value;
+ }
}
//-------------------------------------------------------------------------------------------------------------------
@@ -743,6 +792,11 @@ public class PropertyStoreBuilder {
synchronized boolean isEmpty() {
return this.value.isEmpty();
}
+
+ @Override /* MutableProperty */
+ synchronized Object peek() {
+ return value;
+ }
}
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index 62ca444..4ccb585 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -63,11 +63,220 @@ import org.apache.juneau.urlencoding.*;
@SuppressWarnings("rawtypes")
public class RestClient extends BeanContext {
- private static final ConcurrentHashMap<Class,PartSerializer> partSerializerCache = new ConcurrentHashMap<>();
+ //-------------------------------------------------------------------------------------------------------------------
+ // Configurable properties
+ //-------------------------------------------------------------------------------------------------------------------
+
+ private static final String PREFIX = "RestClient.";
+
+ /**
+ * <b>Configuration property:</b> Keep HttpClient open.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.keepHttpClientOpen.b"</js>
+ * <li><b>Data type:</b> <code>Boolean</code>
+ * <li><b>Default:</b> <jk>false</jk>
+ * </ul>
+ *
+ * <p>
+ * Don't close this client when the {@link RestClient#close()} method is called.
+ */
+ public static final String RESTCLIENT_keepHttpClientOpen = PREFIX + "keepHttpClientOpen.b";
+
+ /**
+ * <b>Configuration property: Shut down executor service on close.</b>
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.executorServiceShutdownOnClose.b"</js>
+ * <li><b>Data type:</b> <code>Boolean</code>
+ * <li><b>Default:</b> <jk>false</jk>
+ * </ul>
+ *
+ * <p>
+ * Call {@link ExecutorService#shutdown()} when {@link RestClient#close()} is called.
+ */
+ public static final String RESTCLIENT_executorServiceShutdownOnClose = PREFIX + "executorServiceShutdownOnClose.b";
+
+ /**
+ * <b>Configuration property:</b> Number of retries to attempt.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.retries.i"</js>
+ * <li><b>Data type:</b> <code>Integer</code>
+ * <li><b>Default:</b> <code>1</code>
+ * </ul>
+ *
+ * <p>
+ * The number of retries to attempt when the connection cannot be made or a <code>>400</code> response is received.
+ */
+ public static final String RESTCLIENT_retries = PREFIX + "retries.i";
+
+ /**
+ * <b>Configuration property:</b> The time in milliseconds between retry attempts.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.retryInterval.i"</js>
+ * <li><b>Data type:</b> <code>Integer</code>
+ * <li><b>Default:</b> <code>-1</code>
+ * </ul>
+ *
+ * <p>
+ * The time in milliseconds between retry attempts.
+ * <code>-1</code> means retry immediately.
+ */
+ public static final String RESTCLIENT_retryInterval = PREFIX + "retryInterval.i";
+
+ /**
+ * <b>Configuration property:</b> Retry-on determination object.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.retryOn.o"</js>
+ * <li><b>Data type:</b> <code>Class<? extends {@link RetryOn}</code> or {@link RetryOn}
+ * <li><b>Default:</b> {@link RetryOn#DEFAULT}
+ * </ul>
+ *
+ * <p>
+ * Object used for determining whether a retry should be attempted.
+ */
+ public static final String RESTCLIENT_retryOn = PREFIX + "retryOn.o";
+
+ /**
+ * <b>Configuration property:</b> Root URI.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.rootUri.s"</js>
+ * <li><b>Data type:</b> <code>String</code>
+ * <li><b>Default:</b> <jk>false</jk>
+ * </ul>
+ *
+ * <p>
+ * When set, relative URL strings passed in through the various rest call methods (e.g. {@link RestClient#doGet(Object)}
+ * will be prefixed with the specified root.
+ * This root URL is ignored on those methods if you pass in a {@link URL}, {@link URI}, or an absolute URL string.
+ * Trailing slashes are trimmed.
+ */
+ public static final String RESTCLIENT_rootUri = PREFIX + "rootUri.s";
+
+ /**
+ * <b>Configuration property:</b> Request headers.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.requestHeader.ms"</js>
+ * <li><b>Data type:</b> <code>Map<String,String></code>
+ * <li><b>Default:</b> empty map
+ * </ul>
+ *
+ * <p>
+ * Don't close this client when the {@link RestClient#close()} method is called.
+ */
+ public static final String RESTCLIENT_headers = PREFIX + "headers.ms";
+
+ /**
+ * <b>Configuration property:</b> Serializer.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.serializer.o"</js>
+ * <li><b>Data type:</b> <code>Class<? <jk>extends</jk> Serializer></code> or {@link Serializer}.
+ * <li><b>Default:</b> {@link JsonSerializer};
+ * </ul>
+ *
+ * <p>
+ * The serializer to use for serializing POJOs in request bodies.
+ */
+ public static final String RESTCLIENT_serializer = PREFIX + "serializer.o";
+ /**
+ * <b>Configuration property:</b> Parser.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.parser.o"</js>
+ * <li><b>Data type:</b> <code>Class<? <jk>extends</jk> Parser></code> or {@link Parser}.
+ * <li><b>Default:</b> {@link JsonParser};
+ * </ul>
+ *
+ * <p>
+ * The parser to use for parsing POJOs in response bodies.
+ */
+ public static final String RESTCLIENT_parser = PREFIX + "parser.o";
+
+ /**
+ * <b>Configuration property:</b> Part serializer.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.urlEncodingSerializer.o"</js>
+ * <li><b>Data type:</b> <code>Class<? <jk>implements</jk> PartSerializer></code> or {@link PartSerializer}.
+ * <li><b>Default:</b> {@link UrlEncodingSerializer};
+ * </ul>
+ *
+ * <p>
+ * The serializer to use for serializing POJOs in form data, query parameters, headers, and path variables.
+ */
+ public static final String RESTCLIENT_partSerializer = PREFIX + "partSerializer.o";
+
+ /**
+ * <b>Configuration property:</b> Executor service.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.executorService.o"</js>
+ * <li><b>Data type:</b> <code>Class<? <jk>implements</jk> ExecutorService></code> or {@link ExecutorService}.
+ * <li><b>Default:</b> <jk>null</jk>.
+ * </ul>
+ *
+ * Defines the executor service to use when calling future methods on the {@link RestCall} class.
+ *
+ * <p>
+ * This executor service is used to create {@link Future} objects on the following methods:
+ * <ul>
+ * <li>{@link RestCall#runFuture()}
+ * <li>{@link RestCall#getResponseFuture(Class)}
+ * <li>{@link RestCall#getResponseFuture(Type,Type...)}
+ * <li>{@link RestCall#getResponseAsString()}
+ * </ul>
+ *
+ * <p>
+ * The default executor service is a single-threaded {@link ThreadPoolExecutor} with a 30 second timeout
+ * and a queue size of 10.
+ */
+ public static final String RESTCLIENT_executorService = PREFIX + "executorService.o";
+
+ /**
+ * <b>Configuration property:</b> Call interceptors.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.interceptors.lo"</js>
+ * <li><b>Data type:</b> <code>List<Class<? <jk>implements</jk> RestCallInterceptor | RestCallInterceptor</code>>.</code>
+ * <li><b>Default:</b> empty list.
+ * </ul>
+ *
+ * Interceptors that get called immediately after a connection is made.
+ */
+ public static final String RESTCLIENT_interceptors = PREFIX + "interceptors.lo";
+
+ /**
+ * Add to the Call interceptors property.
+ */
+ public static final String RESTCLIENT_interceptors_add = PREFIX + "interceptors.lo/add";
+
+ /**
+ * <b>Configuration property:</b> Debug.
+ *
+ * <ul>
+ * <li><b>Name:</b> <js>"RestClient.debug.b"</js>
+ * <li><b>Data type:</b> <code>Boolean</code>
+ * <li><b>Default:</b> <jk>false</jk>
+ * </ul>
+ *
+ * <p>
+ * Enable debug mode.
+ */
+ public static final String RESTCLIENT_debug = PREFIX + "debug.b";
+
+
+ private static final ConcurrentHashMap<Class,PartSerializer> partSerializerCache = new ConcurrentHashMap<>();
+
private final Map<String,String> headers;
private final CloseableHttpClient httpClient;
- private final boolean keepHttpClientOpen;
+ private final boolean keepHttpClientOpen, debug;
private final UrlEncodingSerializer urlEncodingSerializer; // Used for form posts only.
private final PartSerializer partSerializer;
private final String rootUrl;
@@ -81,12 +290,11 @@ public class RestClient extends BeanContext {
final RetryOn retryOn;
final int retries;
final long retryInterval;
- final boolean debug;
final RestCallInterceptor[] intercepters;
// This is lazy-created.
private volatile ExecutorService executorService;
- boolean executorServiceShutdownOnClose = true;
+ private final boolean executorServiceShutdownOnClose;
/**
* Instantiates a new clean-slate {@link RestClientBuilder} object.
@@ -105,53 +313,52 @@ public class RestClient extends BeanContext {
return new RestClientBuilder(getPropertyStore());
}
+ @SuppressWarnings("unchecked")
RestClient(
PropertyStore ps,
- CloseableHttpClient httpClient,
- boolean keepHttpClientOpen,
- Serializer serializer,
- Parser parser,
- UrlEncodingSerializer urlEncodingSerializer,
- PartSerializer partSerializer,
- Map<String,String> headers,
- List<RestCallInterceptor> intercepters,
- String rootUri,
- RetryOn retryOn,
- int retries,
- long retryInterval,
- boolean debug,
- ExecutorService executorService,
- boolean executorServiceShutdownOnClose) {
+ CloseableHttpClient httpClient) {
super(ps);
this.httpClient = httpClient;
- this.keepHttpClientOpen = keepHttpClientOpen;
- this.serializer = serializer;
- this.parser = parser;
- this.urlEncodingSerializer = urlEncodingSerializer;
- this.partSerializer = partSerializer;
-
- Map<String,String> h2 = new ConcurrentHashMap<>(headers);
-
- this.headers = Collections.unmodifiableMap(h2);
- this.rootUrl = rootUri;
- this.retryOn = retryOn;
- this.retries = retries;
- this.retryInterval = retryInterval;
- this.debug = debug;
-
- List<RestCallInterceptor> l = new ArrayList<>(intercepters);
- if (debug)
- l.add(RestCallLogger.DEFAULT);
+ this.keepHttpClientOpen = getProperty(RESTCLIENT_keepHttpClientOpen, boolean.class, false);
+ this.headers = getMapProperty(RESTCLIENT_headers, String.class);
+ this.retries = getProperty(RESTCLIENT_retries, int.class, 1);
+ this.retryInterval = getProperty(RESTCLIENT_retryInterval, int.class, -1);
+ this.retryOn = getInstanceProperty(RESTCLIENT_retryOn, RetryOn.class, RetryOn.DEFAULT);
+ this.debug = getProperty(RESTCLIENT_debug, boolean.class, false);
+ this.executorServiceShutdownOnClose = getProperty(RESTCLIENT_executorServiceShutdownOnClose, boolean.class, false);
+ this.rootUrl = StringUtils.nullIfEmpty(getProperty(RESTCLIENT_rootUri, String.class, "").replaceAll("\\/$", ""));
+
+ Object o = getProperty(RESTCLIENT_serializer, Object.class, JsonSerializer.class);
+ if (o instanceof Serializer) {
+ this.serializer = ((Serializer)o).builder().apply(ps).build();
+ } else if (o instanceof Class) {
+ this.serializer = ContextCache.INSTANCE.create((Class<? extends Serializer>)o, ps);
+ } else {
+ throw new ContextRuntimeException("Invalid object type found for property ''{0}'': ''{1}''", RESTCLIENT_serializer, o.getClass());
+ }
+
+ o = getProperty(RESTCLIENT_parser, Object.class, JsonParser.class);
+ if (o instanceof Parser) {
+ this.parser = ((Parser)o).builder().apply(ps).build();
+ } else if (o instanceof Class) {
+ this.parser = ContextCache.INSTANCE.create((Class<? extends Parser>)o, ps);
+ } else {
+ throw new ContextRuntimeException("Invalid object type found for property ''{0}'': ''{1}''", RESTCLIENT_parser, o.getClass());
+ }
- this.intercepters = l.toArray(new RestCallInterceptor[l.size()]);
+ this.urlEncodingSerializer = new SerializerBuilder(ps).build(UrlEncodingSerializer.class);
+ this.partSerializer = getInstanceProperty(RESTCLIENT_partSerializer, PartSerializer.class, urlEncodingSerializer);
+ this.executorService = getInstanceProperty(RESTCLIENT_executorService, ExecutorService.class, null);
+
+ RestCallInterceptor[] rci = getInstanceArrayProperty(RESTCLIENT_interceptors, RestCallInterceptor.class, new RestCallInterceptor[0]);
+ if (debug)
+ rci = ArrayUtils.append(rci, RestCallLogger.DEFAULT);
+ this.intercepters = rci;
if (Boolean.getBoolean("org.apache.juneau.rest.client.RestClient.trackLifecycle"))
creationStack = Thread.currentThread().getStackTrace();
else
creationStack = null;
-
- this.executorService = executorService;
- this.executorServiceShutdownOnClose = executorServiceShutdownOnClose;
}
/**
@@ -168,7 +375,7 @@ public class RestClient extends BeanContext {
httpClient.close();
if (executorService != null && executorServiceShutdownOnClose)
executorService.shutdown();
- if (Boolean.getBoolean("org.apache.juneau.rest.client.RestClient.trackLifecycle"))
+ if (creationStack != null)
closedStack = Thread.currentThread().getStackTrace();
}
@@ -183,7 +390,7 @@ public class RestClient extends BeanContext {
if (executorService != null && executorServiceShutdownOnClose)
executorService.shutdown();
} catch (Throwable t) {}
- if (Boolean.getBoolean("org.apache.juneau.rest.client.RestClient.trackLifecycle"))
+ if (creationStack != null)
closedStack = Thread.currentThread().getStackTrace();
}
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
index c8bddb3..b9c18b0 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
@@ -13,9 +13,10 @@
package org.apache.juneau.rest.client;
import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.json.JsonSerializer.*;
import static org.apache.juneau.parser.Parser.*;
-import static org.apache.juneau.serializer.Serializer.*;
import static org.apache.juneau.uon.UonSerializer.*;
+import static org.apache.juneau.rest.client.RestClient.*;
import java.lang.reflect.*;
import java.net.*;
@@ -44,11 +45,9 @@ import org.apache.http.impl.conn.*;
import org.apache.http.protocol.*;
import org.apache.juneau.*;
import org.apache.juneau.http.*;
-import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.uon.*;
-import org.apache.juneau.urlencoding.*;
/**
* Builder class for the {@link RestClient} class.
@@ -58,29 +57,9 @@ public class RestClientBuilder extends BeanContextBuilder {
private HttpClientConnectionManager httpClientConnectionManager;
private HttpClientBuilder httpClientBuilder = createHttpClientBuilder();
private CloseableHttpClient httpClient;
- private boolean keepHttpClientOpen;
-
- private Class<? extends Serializer> serializerClass = JsonSerializer.class;
- private Class<? extends Parser> parserClass = JsonParser.class;
- private Class<? extends PartSerializer> partSerializerClass = UrlEncodingSerializer.class;
- private Serializer serializer;
- private Parser parser;
- private PartSerializer partSerializer;
-
- private Map<String,String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-
- private List<RestCallInterceptor> intercepters = new ArrayList<>();
-
- private String rootUrl;
private SSLOpts sslOpts;
private boolean pooled;
- private int retries = 1;
- private long retryInterval = -1;
- private RetryOn retryOn = RetryOn.DEFAULT;
- private boolean debug, executorServiceShutdownOnClose;
- private ExecutorService executorService;
-
/**
* Constructor, default settings.
*/
@@ -137,29 +116,7 @@ public class RestClientBuilder extends BeanContextBuilder {
PropertyStore ps = psb.build();
- Serializer s =
- this.serializer != null
- ? this.serializer.builder().apply(ps).build()
- : new SerializerBuilder(ps).build(this.serializerClass);
-
- Parser p =
- this.parser != null
- ? this.parser.builder().apply(ps).build()
- : new ParserBuilder(ps).build(this.parserClass);
-
- UrlEncodingSerializer us = new SerializerBuilder(ps).build(UrlEncodingSerializer.class);
-
- PartSerializer pf = null;
- if (partSerializer != null)
- pf = partSerializer;
- else if (partSerializerClass != null) {
- if (partSerializerClass == UrlEncodingSerializer.class)
- pf = us;
- else
- pf = partSerializerClass.newInstance();
- }
-
- return new RestClient(ps, httpClient, keepHttpClientOpen, s, p, us, pf, headers, intercepters, rootUrl, retryOn, retries, retryInterval, debug, executorService, executorServiceShutdownOnClose);
+ return new RestClient(ps, httpClient);
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -271,10 +228,7 @@ public class RestClientBuilder extends BeanContextBuilder {
* @return This object (for method chaining).
*/
public RestClientBuilder rootUrl(Object rootUrl) {
- String s = rootUrl.toString();
- if (s.endsWith("/"))
- s = s.replaceAll("\\/$", "");
- this.rootUrl = s;
+ set(RESTCLIENT_rootUri, rootUrl);
return this;
}
@@ -321,12 +275,11 @@ public class RestClientBuilder extends BeanContextBuilder {
/**
* Adds an intercepter that gets called immediately after a connection is made.
*
- * @param intercepter The intercepter.
+ * @param interceptor The intercepter.
* @return This object (for method chaining).
*/
- public RestClientBuilder intercepter(RestCallInterceptor intercepter) {
- intercepters.add(intercepter);
- return this;
+ public RestClientBuilder interceptor(RestCallInterceptor interceptor) {
+ return addTo(RESTCLIENT_interceptors, interceptor);
}
/**
@@ -337,8 +290,7 @@ public class RestClientBuilder extends BeanContextBuilder {
* @return This object (for method chaining).
*/
public RestClientBuilder logTo(Level level, Logger log) {
- intercepter(new RestCallLogger(level, log));
- return this;
+ return interceptor(new RestCallLogger(level, log));
}
/**
@@ -351,10 +303,10 @@ public class RestClientBuilder extends BeanContextBuilder {
* If <jk>null</jk>, uses {@link RetryOn#DEFAULT}.
* @return This object (for method chaining).
*/
- public RestClientBuilder retryable(int retries, long interval, RetryOn retryOn) {
- this.retries = retries;
- this.retryInterval = interval;
- this.retryOn = retryOn;
+ public RestClientBuilder retryable(int retries, int interval, RetryOn retryOn) {
+ set(RESTCLIENT_retries, retries);
+ set(RESTCLIENT_retryInterval, interval);
+ set(RESTCLIENT_retryOn, retryOn);
return this;
}
@@ -376,8 +328,7 @@ public class RestClientBuilder extends BeanContextBuilder {
* @return This object (for method chaining).
*/
public RestClientBuilder serializer(Serializer serializer) {
- this.serializer = serializer;
- return this;
+ return set(RESTCLIENT_serializer, serializer);
}
/**
@@ -388,8 +339,7 @@ public class RestClientBuilder extends BeanContextBuilder {
* @return This object (for method chaining).
*/
public RestClientBuilder serializer(Class<? extends Serializer> serializerClass) {
- this.serializerClass = serializerClass;
- return this;
+ return set(RESTCLIENT_serializer, serializerClass);
}
/**
@@ -398,8 +348,8 @@ public class RestClientBuilder extends BeanContextBuilder {
* @param parser The parser.
* @return This object (for method chaining).
*/
- public RestClientBuilder parser(Parser parser) {
- this.parser = parser;
+ public RestClientBuilder parser(Parser parser) {
+ set(RESTCLIENT_parser, parser);
return this;
}
@@ -411,8 +361,7 @@ public class RestClientBuilder extends BeanContextBuilder {
* @return This object (for method chaining).
*/
public RestClientBuilder parser(Class<? extends Parser> parserClass) {
- this.parserClass = parserClass;
- return this;
+ return set(RESTCLIENT_parser, parserClass);
}
/**
@@ -423,8 +372,7 @@ public class RestClientBuilder extends BeanContextBuilder {
* @return This object (for method chaining).
*/
public RestClientBuilder partSerializer(PartSerializer partSerializer) {
- this.partSerializer = partSerializer;
- return this;
+ return set(RESTCLIENT_partSerializer, partSerializer);
}
/**
@@ -437,8 +385,7 @@ public class RestClientBuilder extends BeanContextBuilder {
* @return This object (for method chaining).
*/
public RestClientBuilder partSerializer(Class<? extends PartSerializer> partSerializerClass) {
- this.partSerializerClass = partSerializerClass;
- return this;
+ return set(RESTCLIENT_partSerializer, partSerializerClass);
}
/**
@@ -468,7 +415,7 @@ public class RestClientBuilder extends BeanContextBuilder {
*/
public RestClientBuilder httpClient(CloseableHttpClient httpClient, boolean keepHttpClientOpen) {
this.httpClient = httpClient;
- this.keepHttpClientOpen = keepHttpClientOpen;
+ set(RESTCLIENT_keepHttpClientOpen, keepHttpClientOpen);
return this;
}
@@ -493,8 +440,8 @@ public class RestClientBuilder extends BeanContextBuilder {
* @return This object (for method chaining).
*/
public RestClientBuilder executorService(ExecutorService executorService, boolean shutdownOnClose) {
- this.executorService = executorService;
- this.executorServiceShutdownOnClose = shutdownOnClose;
+ set(RESTCLIENT_executorService, executorService);
+ set(RESTCLIENT_executorServiceShutdownOnClose, shutdownOnClose);
return this;
}
@@ -504,18 +451,6 @@ public class RestClientBuilder extends BeanContextBuilder {
//--------------------------------------------------------------------------------
/**
- * Specifies a request header property to add to all requests created by this client.
- *
- * @param name The HTTP header name.
- * @param value The HTTP header value.
- * @return This object (for method chaining).
- */
- public RestClientBuilder header(String name, Object value) {
- this.headers.put(name, value == null ? null : value.toString());
- return this;
- }
-
- /**
* Sets the value for the <code>Accept</code> request header.
*
* <p>
@@ -909,10 +844,41 @@ public class RestClientBuilder extends BeanContextBuilder {
//--------------------------------------------------------------------------------
- // Context properties
+ // Properties
//--------------------------------------------------------------------------------
/**
+ * <b>Configuration property:</b> Keep HttpClient open.
+ *
+ * <p>
+ * Don't close this client when the {@link RestClient#close()} method is called.
+ *
+ * <h5 class='section'>Notes:</h5>
+ * <ul>
+ * <li>This is equivalent to calling <code>set(<jsf>RESTCLIENT_keepHttpClientOpen</jsf>, value)</code>.
+ * </ul>
+ *
+ * @param value The new value for this property.
+ * @return This object (for method chaining).
+ * @see RestClient#RESTCLIENT_keepHttpClientOpen
+ */
+ public RestClientBuilder keepHttpClientOpen(boolean value) {
+ return set(RESTCLIENT_keepHttpClientOpen, value);
+ }
+
+ /**
+ * <b>Configuration property:</b> Request headers.
+ *
+ * @param key The header name.
+ * @param value The header value.
+ * @return This object (for method chaining).
+ * @see RestClient#RESTCLIENT_headers
+ */
+ public RestClientBuilder header(String key, Object value) {
+ return addTo(RESTCLIENT_headers, key, value);
+ }
+
+ /**
* Sets the {@link Serializer#SERIALIZER_maxDepth} property on all serializers in this group.
*
* @param value The new value for this property.
@@ -1589,7 +1555,7 @@ public class RestClientBuilder extends BeanContextBuilder {
@Override /* ContextBuilder */
public RestClientBuilder debug() {
super.debug();
- this.debug = true;
+ set(RESTCLIENT_debug, true);
header("Debug", true);
return this;
}
[2/2] juneau git commit: (JUNEAU-76) Improvements to Context/Builder
APIs
Posted by ja...@apache.org.
(JUNEAU-76) Improvements to Context/Builder APIs
Project: http://git-wip-us.apache.org/repos/asf/juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/juneau/commit/77664769
Tree: http://git-wip-us.apache.org/repos/asf/juneau/tree/77664769
Diff: http://git-wip-us.apache.org/repos/asf/juneau/diff/77664769
Branch: refs/heads/master
Commit: 7766476956c1fa895702e511cd15cfb349f6e693
Parents: 803910f
Author: JamesBognar <ja...@apache.org>
Authored: Sat Dec 23 16:28:55 2017 -0500
Committer: JamesBognar <ja...@apache.org>
Committed: Sat Dec 23 16:28:55 2017 -0500
----------------------------------------------------------------------
.../org/apache/juneau/PropertyStore2Test.java | 35 +-
.../apache/juneau/dto/html5/Html5BasicTest.java | 37 +
.../juneau/dto/html5/Html5BasicTests.java | 37 -
.../juneau/xml/XmlIgnoreCommentsTest.java | 1251 ++++++++++++++++++
.../juneau/xml/XmlTestIgnoreComments.java | 1251 ------------------
juneau-core/juneau-marshall/TODO.txt | 2 -
.../java/org/apache/juneau/BeanContext.java | 24 +-
.../main/java/org/apache/juneau/Context.java | 19 +
.../org/apache/juneau/PropertyConverter.java | 8 +-
.../org/apache/juneau/PropertyStoreBuilder.java | 58 +-
.../apache/juneau/rest/client/RestClient.java | 293 +++-
.../juneau/rest/client/RestClientBuilder.java | 144 +-
12 files changed, 1689 insertions(+), 1470 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java
index a62fa1b..e524471 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStore2Test.java
@@ -197,11 +197,11 @@ public class PropertyStore2Test {
b.set("A.f4.o", StringBuilder.class);
b.set("A.f5.o", null);
ps = b.build();
- assertObjectEquals("{A:{'f1.o':123,'f2.o':true,'f3.o':'123','f4.o':''}}", ps);
+ assertObjectEquals("{A:{'f1.o':123,'f2.o':true,'f3.o':'123','f4.o':'java.lang.StringBuilder'}}", ps);
assertType(Integer.class, ps.getProperty("A.f1.o"));
assertType(Boolean.class, ps.getProperty("A.f2.o"));
assertType(StringBuilder.class, ps.getProperty("A.f3.o"));
- assertType(StringBuilder.class, ps.getProperty("A.f4.o"));
+ assertType(Class.class, ps.getProperty("A.f4.o"));
// Test nulls
b.set("A.f2.o", null);
@@ -213,13 +213,8 @@ public class PropertyStore2Test {
testError(b, "A.f1.o/add", "foo", "Cannot add value 'foo' (String) to property 'f1.o' (Object).");
testError(b, "A.f1.o/add.123", "foo", "Cannot add value 'foo' (String) to property 'f1.o' (Object).");
testError(b, "A.f1.o/remove", "foo", "Cannot remove value 'foo' (String) from property 'f1.o' (Object).");
- testError(b, "A.f1.o", ObjectWithNoNoArgConstructor.class, "Value 'org.apache.juneau.PropertyStore2Test$ObjectWithNoNoArgConstructor' (Class) cannot be converted to an Object on property 'f1.o' (Object).");
}
- public static class ObjectWithNoNoArgConstructor {
- private ObjectWithNoNoArgConstructor() {}
- }
-
@Test
public void testSetString() throws Exception {
PropertyStoreBuilder b = PropertyStore.create();
@@ -703,14 +698,14 @@ public class PropertyStore2Test {
b.set("A.f2.lo", new AList<Object>().appendAll(123, true, new StringBuilder(123), StringBuilder.class, null));
b.set("A.f3.lo", null);
ps = b.build();
- assertObjectEquals("{A:{'f1.lo':[''],'f2.lo':[123,true,'','']}}", ps);
+ assertObjectEquals("{A:{'f1.lo':['java.lang.StringBuilder'],'f2.lo':[123,true,'','java.lang.StringBuilder']}}", ps);
assertType(List.class, ps.getProperty("A.f1.lo"));
assertType(List.class, ps.getProperty("A.f2.lo"));
- assertType(StringBuilder.class, ((List<?>)ps.getProperty("A.f1.lo")).get(0));
+ assertType(Class.class, ((List<?>)ps.getProperty("A.f1.lo")).get(0));
assertType(Integer.class, ((List<?>)ps.getProperty("A.f2.lo")).get(0));
assertType(Boolean.class, ((List<?>)ps.getProperty("A.f2.lo")).get(1));
assertType(StringBuilder.class, ((List<?>)ps.getProperty("A.f2.lo")).get(2));
- assertType(StringBuilder.class, ((List<?>)ps.getProperty("A.f2.lo")).get(3));
+ assertType(Class.class, ((List<?>)ps.getProperty("A.f2.lo")).get(3));
b.clear();
b.set("A.f1.lo/add", 1);
@@ -723,31 +718,31 @@ public class PropertyStore2Test {
b.set("A.f1.lo/add", new AList<Class<?>>().appendAll(StringBuilder.class));
b.set("A.f1.lo/add", new AList<Class<?>>().appendAll(HashMap.class));
b.addTo("A.f1.lo", new AList<Class<?>>().appendAll(LinkedList.class));
- assertObjectEquals("{A:{'f1.lo':[[],{},'']}}", b.build());
+ assertObjectEquals("{A:{'f1.lo':['java.util.LinkedList','java.util.HashMap','java.lang.StringBuilder']}}", b.build());
b.set("A.f1.lo/remove", new AList<Class<?>>().appendAll(HashMap.class));
b.removeFrom("A.f1.lo", new AList<Class<?>>().appendAll());
b.removeFrom("A.f1.lo", new AList<Class<?>>().appendAll(LinkedList.class));
- assertObjectEquals("{A:{'f1.lo':['']}}", b.build());
+ assertObjectEquals("{A:{'f1.lo':['java.lang.StringBuilder']}}", b.build());
b.clear();
b.set("A.f1.lo/add", new AList<Object>().appendAll(StringBuilder.class));
b.set("A.f1.lo/add", new AList<Object>().appendAll(HashMap.class));
b.addTo("A.f1.lo", new AList<Object>().appendAll(LinkedList.class));
- assertObjectEquals("{A:{'f1.lo':[[],{},'']}}", b.build());
+ assertObjectEquals("{A:{'f1.lo':['java.util.LinkedList','java.util.HashMap','java.lang.StringBuilder']}}", b.build());
b.set("A.f1.lo/remove", new AList<Object>().appendAll(HashMap.class));
b.set("A.f1.lo/remove", new AList<Object>().appendAll());
b.removeFrom("A.f1.lo", new AList<Object>().appendAll(LinkedList.class));
- assertObjectEquals("{A:{'f1.lo':['']}}", b.build());
+ assertObjectEquals("{A:{'f1.lo':['java.lang.StringBuilder']}}", b.build());
b.clear();
b.set("A.f1.lo/add", new Class<?>[]{StringBuilder.class});
b.set("A.f1.lo/add", new Class<?>[]{HashMap.class});
b.addTo("A.f1.lo", new Class<?>[]{LinkedList.class});
- assertObjectEquals("{A:{'f1.lo':[[],{},'']}}", b.build());
+ assertObjectEquals("{A:{'f1.lo':['java.util.LinkedList','java.util.HashMap','java.lang.StringBuilder']}}", b.build());
b.set("A.f1.lo/remove", new Class<?>[]{HashMap.class});
b.set("A.f1.lo/remove", new Class<?>[]{});
b.removeFrom("A.f1.lo", new Class<?>[]{LinkedList.class});
- assertObjectEquals("{A:{'f1.lo':['']}}", b.build());
+ assertObjectEquals("{A:{'f1.lo':['java.lang.StringBuilder']}}", b.build());
b.set("A.f1.lo", null);
assertObjectEquals("{}", b.build());
@@ -758,7 +753,7 @@ public class PropertyStore2Test {
b.set("A.f1.lo/add.1", LinkedList.class);
b.set("A.f1.lo/add.0", TestEnum.ONE);
b.set("A.f1.lo/add.-10", TestEnum.TWO);
- assertObjectEquals("{A:{'f1.lo':['TWO','ONE','',[],{}]}}", b.build());
+ assertObjectEquals("{A:{'f1.lo':['TWO','ONE','java.lang.StringBuilder','java.util.LinkedList','java.util.HashMap']}}", b.build());
try {
b.addTo("A.f1.lo", "foo", "bar");
@@ -896,7 +891,7 @@ public class PropertyStore2Test {
b.set("A.f4.mo", "{foo:'123',baz:456,qux:null}");
b.set("A.f5.mo", null);
ps = b.build();
- assertObjectEquals("{A:{'f1.mo':{baz:'2',foo:'1'},'f2.mo':{bar:'',foo:123},'f3.mo':{foo:'123'},'f4.mo':{baz:456,foo:'123'}}}", ps);
+ assertObjectEquals("{A:{'f1.mo':{baz:'2',foo:'1'},'f2.mo':{bar:'java.lang.StringBuilder',foo:123},'f3.mo':{foo:'123'},'f4.mo':{baz:456,foo:'123'}}}", ps);
assertType(Map.class, ps.getProperty("A.f1.mo"));
assertType(Map.class, ps.getProperty("A.f2.mo"));
assertType(Map.class, ps.getProperty("A.f3.mo"));
@@ -1288,7 +1283,7 @@ public class PropertyStore2Test {
testEquals(b1, b2);
b1.set("A.f1.lo", new Object[]{StringBuilder.class});
- b2.set("A.f1.lo", new Object[]{StringBuilder.class});
+ b2.set("A.f1.lo", new Object[]{StringBuffer.class});
testNotEquals(b1, b2);
b1.set("A.f1.lo", "foo");
@@ -1701,7 +1696,7 @@ public class PropertyStore2Test {
b = ps.builder();
ps = b.build();
- assertObjectEquals("{A:{'foo.b':true,'foo.c':'java.lang.String','foo.i':123,'foo.lc':['java.lang.String'],'foo.li':[123],'foo.lo':[''],'foo.ls':['bar'],'foo.mc':{foo:'java.lang.String'},'foo.mi':{foo:123},'foo.mo':{foo:''},'foo.ms':{foo:'bar'},'foo.o':'bar','foo.s':'bar','foo.sc':['java.lang.String'],'foo.si':[123],'foo.ss':['bar']}}", ps);
+ assertObjectEquals("{A:{'foo.b':true,'foo.c':'java.lang.String','foo.i':123,'foo.lc':['java.lang.String'],'foo.li':[123],'foo.lo':['java.lang.StringBuilder'],'foo.ls':['bar'],'foo.mc':{foo:'java.lang.String'},'foo.mi':{foo:123},'foo.mo':{foo:'java.lang.StringBuilder'},'foo.ms':{foo:'bar'},'foo.o':'bar','foo.s':'bar','foo.sc':['java.lang.String'],'foo.si':[123],'foo.ss':['bar']}}", ps);
}
@Test
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5BasicTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5BasicTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5BasicTest.java
new file mode 100644
index 0000000..f8195fd
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5BasicTest.java
@@ -0,0 +1,37 @@
+// ***************************************************************************************************************************
+// * 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.juneau.dto.html5;
+
+import static org.apache.juneau.dto.html5.HtmlBuilder.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+public class Html5BasicTest {
+
+ @Test
+ public void testToString() {
+ Form f = form("bar",
+ fieldset(
+ legend("foo:"),
+ "Name:", input("text"), br(),
+ "Email:", input("text"), br(),
+ "X:", keygen().name("X"),
+ label("label")._for("Name")
+ )
+ );
+
+ String r = f.toString();
+ assertEquals("<form action='bar'><fieldset><legend>foo:</legend>Name:<input type='text'/><br/>Email:<input type='text'/><br/>X:<keygen name='X'/><label for='Name'>label</label></fieldset></form>", r);
+ }
+}
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5BasicTests.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5BasicTests.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5BasicTests.java
deleted file mode 100644
index 4429833..0000000
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5BasicTests.java
+++ /dev/null
@@ -1,37 +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.juneau.dto.html5;
-
-import static org.apache.juneau.dto.html5.HtmlBuilder.*;
-import static org.junit.Assert.*;
-
-import org.junit.*;
-
-public class Html5BasicTests {
-
- @Test
- public void testToString() {
- Form f = form("bar",
- fieldset(
- legend("foo:"),
- "Name:", input("text"), br(),
- "Email:", input("text"), br(),
- "X:", keygen().name("X"),
- label("label")._for("Name")
- )
- );
-
- String r = f.toString();
- assertEquals("<form action='bar'><fieldset><legend>foo:</legend>Name:<input type='text'/><br/>Email:<input type='text'/><br/>X:<keygen name='X'/><label for='Name'>label</label></fieldset></form>", r);
- }
-}
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlIgnoreCommentsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlIgnoreCommentsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlIgnoreCommentsTest.java
new file mode 100644
index 0000000..0f9d792
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlIgnoreCommentsTest.java
@@ -0,0 +1,1251 @@
+// ***************************************************************************************************************************
+// * 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.juneau.xml;
+
+import java.text.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.xml.annotation.*;
+import org.junit.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
+
+/**
+ * Validates that comments in XML files are ignored.
+ */
+@RunWith(Parameterized.class)
+@SuppressWarnings("serial")
+public class XmlIgnoreCommentsTest {
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> getParameters() {
+
+ return Arrays.asList(new Object[][] {
+ { /* 0 */
+ "SimpleTypes-1",
+ String.class,
+ "foo",
+ "|<string>|foo|</string>|",
+ false
+ },
+ { /* 1 */
+ "SimpleTypes-2",
+ Boolean.class,
+ true,
+ "|<boolean>|true|</boolean>|",
+ false
+ },
+ { /* 2 */
+ "SimpleTypes-3",
+ int.class,
+ 123,
+ "|<number>|123|</number>|",
+ false
+ },
+ { /* 3 */
+ "SimpleTypes-4",
+ float.class,
+ 1.23f,
+ "|<number>|1.23|</number>|",
+ false
+ },
+ { /* 4 */
+ "SimpleTypes-5",
+ String.class,
+ null,
+ "|<null/>|",
+ false
+ },
+ { /* 5 */
+ "Arrays-1",
+ String[].class,
+ new String[]{"foo"},
+ "|<array>|<string>|foo|</string>|</array>|",
+ false
+ },
+ { /* 6 */
+ "Arrays-2",
+ String[].class,
+ new String[]{null},
+ "|<array>|<null/>|</array>|",
+ false
+ },
+ { /* 7 */
+ "Arrays-3",
+ Object[].class,
+ new Object[]{"foo"},
+ "|<array>|<string>|foo|</string>|</array>|",
+ false
+ },
+ { /* 8 */
+ "Arrays-4",
+ int[].class,
+ new int[]{123},
+ "|<array>|<number>|123|</number>|</array>|",
+ false
+ },
+ { /* 9 */
+ "Arrays-5",
+ boolean[].class,
+ new boolean[]{true},
+ "|<array>|<boolean>|true|</boolean>|</array>|",
+ false
+ },
+ { /* 10 */
+ "Arrays-6",
+ String[][].class,
+ new String[][]{{"foo"}},
+ "|<array>|<array>|<string>|foo|</string>|</array>|</array>|",
+ false
+ },
+ { /* 11 */
+ "MapWithStrings",
+ MapWithStrings.class,
+ new MapWithStrings().append("k1", "v1").append("k2", null),
+ "|<object>|<k1>|v1|</k1>|<k2 _type='null'/>|</object>|",
+ false
+ },
+ { /* 12 */
+ "MapsWithNumbers",
+ MapWithNumbers.class,
+ new MapWithNumbers().append("k1", 123).append("k2", 1.23).append("k3", null),
+ "|<object>|<k1>|123|</k1>|<k2>|1.23|</k2>|<k3 _type='null'/>|</object>|",
+ false
+ },
+ { /* 13 */
+ "MapWithObjects",
+ MapWithObjects.class,
+ new MapWithObjects().append("k1", "v1").append("k2", 123).append("k3", 1.23).append("k4", true).append("k5", null),
+ "|<object>|<k1>|v1|</k1>|<k2 _type='number'>|123|</k2>|<k3 _type='number'>|1.23|</k3>|<k4 _type='boolean'>|true|</k4>|<k5 _type='null'/>|</object>|",
+ false
+ },
+ { /* 14 */
+ "ListWithStrings",
+ ListWithStrings.class,
+ new ListWithStrings().append("foo").append(null),
+ "|<array>|<string>|foo|</string>|<null/>|</array>|",
+ false
+ },
+ { /* 15 */
+ "ListWithNumbers",
+ ListWithNumbers.class,
+ new ListWithNumbers().append(123).append(1.23).append(null),
+ "|<array>|<number>|123|</number>|<number>|1.23|</number>|<null/>|</array>|",
+ false
+ },
+ { /* 16 */
+ "ListWithObjects",
+ ListWithObjects.class,
+ new ListWithObjects().append("foo").append(123).append(1.23).append(true).append(null),
+ "|<array>|<string>|foo|</string>|<number>|123|</number>|<number>|1.23|</number>|<boolean>|true|</boolean>|<null/>|</array>|",
+ false
+ },
+ { /* 17 */
+ "BeanWithNormalProperties",
+ BeanWithNormalProperties.class,
+ new BeanWithNormalProperties().init(),
+ "|<object>"
+ +"|<a>|foo|</a>"
+ +"|<b>|123|</b>"
+ +"|<c>|bar|</c>"
+ +"|<d _type='number'>|456|</d>"
+ +"|<e>"
+ +"|<h>|qux|</h>"
+ +"|</e>"
+ +"|<f>"
+ +"|<string>|baz|</string>"
+ +"|</f>"
+ +"|<g>"
+ +"|<number>|789|</number>"
+ +"|</g>"
+ +"|</object>|",
+ false
+ },
+ { /* 18 */
+ "BeanWithMapProperties",
+ BeanWithMapProperties.class,
+ new BeanWithMapProperties().init(),
+ "|<object>"
+ +"|<a>"
+ +"|<k1>|foo|</k1>"
+ +"|</a>"
+ +"|<b>"
+ +"|<k2>|123|</k2>"
+ +"|</b>"
+ +"|<c>"
+ +"|<k3>|bar|</k3>"
+ +"|<k4 _type='number'>|456|</k4>"
+ +"|<k5 _type='boolean'>|true|</k5>"
+ +"|<k6 _type='null'/>"
+ +"|</c>"
+ +"|</object>|",
+ false
+ },
+ { /* 19 */
+ "BeanWithTypeName",
+ BeanWithTypeName.class,
+ new BeanWithTypeName().init(),
+ "|<X>|<a>|123|</a>|<b>|foo|</b>|</X>|",
+ false
+ },
+ { /* 20 */
+ "BeanWithPropertiesWithTypeNames",
+ BeanWithPropertiesWithTypeNames.class,
+ new BeanWithPropertiesWithTypeNames().init(),
+ "|<object>|<b1>|<b>|foo|</b>|</b1>|<b2 _type='B'>|<b>|foo|</b>|</b2>|</object>|",
+ false
+ },
+ { /* 21 */
+ "BeanWithPropertiesWithArrayTypeNames",
+ BeanWithPropertiesWithArrayTypeNames.class,
+ new BeanWithPropertiesWithArrayTypeNames().init(),
+ "|<object>"
+ +"|<b1>"
+ +"|<B>"
+ +"|<b>|foo|</b>"
+ +"|</B>"
+ +"|</b1>"
+ +"|<b2>"
+ +"|<B>"
+ +"|<b>|foo|</b>"
+ +"|</B>"
+ +"|</b2>"
+ +"|<b3>"
+ +"|<B>"
+ +"|<b>|foo|</b>"
+ +"|</B>"
+ +"|</b3>"
+ +"|</object>|",
+ false
+ },
+ { /* 22 */
+ "BeanWithPropertiesWithArray2dTypeNames",
+ BeanWithPropertiesWith2dArrayTypeNames.class,
+ new BeanWithPropertiesWith2dArrayTypeNames().init(),
+ "|<object>"
+ +"|<b1>"
+ +"|<array>"
+ +"|<B>"
+ +"|<b>|foo|</b>"
+ +"|</B>"
+ +"|</array>"
+ +"|</b1>"
+ +"|<b2>"
+ +"|<array>"
+ +"|<B>"
+ +"|<b>|foo|</b>"
+ +"|</B>"
+ +"|</array>"
+ +"|</b2>"
+ +"|<b3>"
+ +"|<array>"
+ +"|<B>"
+ +"|<b>|foo|</b>"
+ +"|</B>"
+ +"|</array>"
+ +"|</b3>"
+ +"|</object>|",
+ false
+ },
+ { /* 23 */
+ "BeanWithPropertiesWithMapTypeNames",
+ BeanWithPropertiesWithMapTypeNames.class,
+ new BeanWithPropertiesWithMapTypeNames().init(),
+ "|<object>"
+ +"|<b1>"
+ +"|<k1>"
+ +"|<b>|foo|</b>"
+ +"|</k1>"
+ +"|</b1>"
+ +"|<b2>"
+ +"|<k2 _type='B'>"
+ +"|<b>|foo|</b>"
+ +"|</k2>"
+ +"|</b2>"
+ +"|</object>|",
+ false
+ },
+ { /* 24 */
+ "BeanWithChildTypeNames",
+ BeanWithChildTypeNames.class,
+ new BeanWithChildTypeNames().init(),
+ "|<object>"
+ +"|<a>"
+ +"|<fx>|fx1|</fx>"
+ +"|</a>"
+ +"|<b _type='X'>"
+ +"|<fx>|fx1|</fx>"
+ +"|</b>"
+ +"|<c>"
+ +"|<X>"
+ +"|<fx>|fx1|</fx>"
+ +"|</X>"
+ +"|</c>"
+ +"|<d>"
+ +"|<X>"
+ +"|<fx>|fx1|</fx>"
+ +"|</X>"
+ +"|</d>"
+ +"|</object>|",
+ false
+ },
+ { /* 25 */
+ "BeanWithChildName",
+ BeanWithChildName.class,
+ new BeanWithChildName().init(),
+ "|<object>|<a>|<X>|foo|</X>|<X>|bar|</X>|</a>|<b>|<Y>|123|</Y>|<Y>|456|</Y>|</b>|</object>|",
+ false
+ },
+ { /* 26 */
+ "BeanWithXmlFormatAttrProperty",
+ BeanWithXmlFormatAttrProperty.class,
+ new BeanWithXmlFormatAttrProperty().init(),
+ "|<object a='foo' b='123'/>|",
+ false
+ },
+ { /* 27 */
+ "BeanWithXmlFormatAttrs",
+ BeanWithXmlFormatAttrs.class,
+ new BeanWithXmlFormatAttrs().init(),
+ "|<object a='foo' b='123'/>|",
+ false
+ },
+ { /* 28 */
+ "BeanWithXmlFormatElementProperty",
+ BeanWithXmlFormatElementProperty.class,
+ new BeanWithXmlFormatElementProperty().init(),
+ "|<object a='foo'><b>123</b></object>|",
+ false
+ },
+ { /* 29 */
+ "BeanWithXmlFormatAttrsProperty",
+ BeanWithXmlFormatAttrsProperty.class,
+ new BeanWithXmlFormatAttrsProperty().init(),
+ "|<object k1='foo' k2='123' b='456'/>|",
+ false
+ },
+ { /* 30 */
+ "BeanWithXmlFormatCollapsedProperty",
+ BeanWithXmlFormatCollapsedProperty.class,
+ new BeanWithXmlFormatCollapsedProperty().init(),
+ "|<object>|<A>|foo|</A>|<A>|bar|</A>|<B>|123|</B>|<B>|456|</B>|</object>|",
+ false
+ },
+ { /* 31 */
+ "BeanWithXmlFormatTextProperty",
+ BeanWithXmlFormatTextProperty.class,
+ new BeanWithXmlFormatTextProperty().init(),
+ "|<object a='foo'>|bar|</object>|",
+ false
+ },
+ { /* 32 */
+ "BeanWithXmlFormatXmlTextProperty",
+ BeanWithXmlFormatXmlTextProperty.class,
+ new BeanWithXmlFormatXmlTextProperty().init(),
+ "|<object a='foo'>|bar|<b>|baz|</b>|qux|</object>|",
+ false
+ },
+ { /* 33 */
+ "BeanWithXmlFormatElementsPropertyCollection",
+ BeanWithXmlFormatElementsPropertyCollection.class,
+ new BeanWithXmlFormatElementsPropertyCollection().init(),
+ "|<object a='foo'>|<string>|bar|</string>|<string>|baz|</string>|<number>|123|</number>|<boolean>|true|</boolean>|<null/>|</object>|",
+ false
+ },
+ { /* 34 */
+ "BeanWithMixedContent",
+ BeanWithMixedContent.class,
+ new BeanWithMixedContent().init(),
+ "|<object>|foo|<X fx='fx1'/>|bar|<Y fy='fy1'/>|baz|</object>|",
+ true
+ },
+ { /* 35 */
+ "BeanWithSpecialCharacters",
+ BeanWithSpecialCharacters.class,
+ new BeanWithSpecialCharacters().init(),
+ "|<object>|<a>|_x0020_ _x0008__x000C_
	
 _x0020_|</a>|</object>|",
+ false
+ },
+ { /* 36 */
+ "BeanWithSpecialCharacters2",
+ BeanWithSpecialCharacters2.class,
+ new BeanWithSpecialCharacters2().init(),
+ "|<_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>|<_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>|_x0020_ _x0008__x000C_
	
 _x0020_|</_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>|</_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>|",
+ false
+ },
+ { /* 37 */
+ "BeanWithNullProperties",
+ BeanWithNullProperties.class,
+ new BeanWithNullProperties(),
+ "|<object/>|",
+ false
+ },
+ { /* 38 */
+ "BeanWithAbstractFields",
+ BeanWithAbstractFields.class,
+ new BeanWithAbstractFields().init(),
+ "|<object>"
+ +"|<a>"
+ +"|<a>|foo|</a>"
+ +"|</a>"
+ +"|<ia _type='A'>"
+ +"|<a>|foo|</a>"
+ +"|</ia>"
+ +"|<aa _type='A'>"
+ +"|<a>|foo|</a>"
+ +"|</aa>"
+ +"|<o _type='A'>"
+ +"|<a>|foo|</a>"
+ +"|</o>"
+ +"|</object>|",
+ false
+ },
+ { /* 39 */
+ "BeanWithAbstractArrayFields",
+ BeanWithAbstractArrayFields.class,
+ new BeanWithAbstractArrayFields().init(),
+ "|<object>"
+ +"|<a>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</a>"
+ +"|<ia1>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</ia1>"
+ +"|<ia2>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</ia2>"
+ +"|<aa1>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</aa1>"
+ +"|<aa2>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</aa2>"
+ +"|<o1>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</o1>"
+ +"|<o2>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</o2>"
+ +"|</object>",
+ false
+ },
+ { /* 40 */
+ "BeanWithAbstractMapFields",
+ BeanWithAbstractMapFields.class,
+ new BeanWithAbstractMapFields().init(),
+ "|<object>"
+ +"|<a>"
+ +"|<k1>"
+ +"|<a>|foo|</a>"
+ +"|</k1>"
+ +"|</a>"
+ +"|<b>"
+ +"|<k2 _type='A'>"
+ +"|<a>|foo|</a>"
+ +"|</k2>"
+ +"|</b>"
+ +"|<c>"
+ +"|<k3 _type='A'>"
+ +"|<a>|foo|</a>"
+ +"|</k3>"
+ +"|</c>"
+ +"|</object>",
+ false
+ },
+ { /* 41 */
+ "BeanWithAbstractMapArrayFields",
+ BeanWithAbstractMapArrayFields.class,
+ new BeanWithAbstractMapArrayFields().init(),
+ "|<object>"
+ +"|<a>"
+ +"|<a1>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</a1>"
+ +"|</a>"
+ +"|<ia>"
+ +"|<ia1>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</ia1>"
+ +"|<ia2>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</ia2>"
+ +"|</ia>"
+ +"|<aa>"
+ +"|<aa1>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</aa1>"
+ +"|<aa2>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</aa2>"
+ +"|</aa>"
+ +"|<o>"
+ +"|<o1>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</o1>"
+ +"|<o2>"
+ +"|<A>"
+ +"|<a>|foo|</a>"
+ +"|</A>"
+ +"|</o2>"
+ +"|</o>"
+ +"|</object>",
+ false
+ },
+ { /* 42 */
+ "BeanWithWhitespaceTextFields-1",
+ BeanWithWhitespaceTextFields.class,
+ new BeanWithWhitespaceTextFields().init(null),
+ "|<object/>|",
+ false
+ },
+ { /* 43 */
+ "BeanWithWhitespaceTextFields-2",
+ BeanWithWhitespaceTextFields.class,
+ new BeanWithWhitespaceTextFields().init(""),
+ "|<object>|_xE000_|</object>|",
+ false
+ },
+ { /* 44 */
+ "BeanWithWhitespaceTextFields-3",
+ BeanWithWhitespaceTextFields.class,
+ new BeanWithWhitespaceTextFields().init(" "),
+ "|<object>|_x0020_|</object>|",
+ false
+ },
+ { /* 45 */
+ "BeanWithWhitespaceTextFields-4",
+ BeanWithWhitespaceTextFields.class,
+ new BeanWithWhitespaceTextFields().init(" "),
+ "|<object>|_x0020__x0020_|</object>|",
+ false
+ },
+ { /* 46 */
+ "BeanWithWhitespaceTextFields-5",
+ BeanWithWhitespaceTextFields.class,
+ new BeanWithWhitespaceTextFields().init(" foo\n\tbar "),
+ "|<object>|_x0020_foo
	bar_x0020_|</object>|",
+ false
+ },
+ { /* 47 */
+ "BeanWithWhitespaceTextPwsFields-1",
+ BeanWithWhitespaceTextPwsFields.class,
+ new BeanWithWhitespaceTextPwsFields().init(null),
+ "|<object/>|",
+ false
+ },
+ { /* 48 */
+ "BeanWithWhitespaceTextPwsFields-2",
+ BeanWithWhitespaceTextPwsFields.class,
+ new BeanWithWhitespaceTextPwsFields().init(""),
+ "|<object>|_xE000_|</object>|",
+ true
+ },
+ { /* 49 */
+ "BeanWithWhitespaceTextPwsFields-3",
+ BeanWithWhitespaceTextPwsFields.class,
+ new BeanWithWhitespaceTextPwsFields().init(" "),
+ "|<object>| |</object>|",
+ true
+ },
+ { /* 50 */
+ "BeanWithWhitespaceTextPwsFields-4",
+ BeanWithWhitespaceTextPwsFields.class,
+ new BeanWithWhitespaceTextPwsFields().init(" "),
+ "|<object>| |</object>|",
+ true
+ },
+ { /* 51 */
+ "BeanWithWhitespaceTextPwsFields-5",
+ BeanWithWhitespaceTextPwsFields.class,
+ new BeanWithWhitespaceTextPwsFields().init(" foobar "),
+ "|<object>| foobar |</object>|",
+ true
+ },
+ { /* 52 */
+ "BeanWithWhitespaceMixedFields-1",
+ BeanWithWhitespaceMixedFields.class,
+ new BeanWithWhitespaceMixedFields().init(null),
+ "|<object/>|",
+ false
+ },
+ { /* 53 */
+ "BeanWithWhitespaceMixedFields-3",
+ BeanWithWhitespaceMixedFields.class,
+ new BeanWithWhitespaceMixedFields().init(new String[]{""}),
+ "|<object>|_xE000_|</object>|",
+ true
+ },
+ { /* 54 */
+ "BeanWithWhitespaceMixedFields-4",
+ BeanWithWhitespaceMixedFields.class,
+ new BeanWithWhitespaceMixedFields().init(new String[]{" "}),
+ "|<object>|_x0020_|</object>|",
+ true
+ },
+ { /* 55 */
+ "BeanWithWhitespaceMixedFields-5",
+ BeanWithWhitespaceMixedFields.class,
+ new BeanWithWhitespaceMixedFields().init(new String[]{" "}),
+ "|<object>|_x0020__x0020_|</object>|",
+ true
+ },
+ { /* 56 */
+ "BeanWithWhitespaceMixedFields-6",
+ BeanWithWhitespaceMixedFields.class,
+ new BeanWithWhitespaceMixedFields().init(new String[]{" foobar "}),
+ "|<object>|_x0020_ foobar _x0020_|</object>|",
+ true
+ },
+ { /* 57 */
+ "BeanWithWhitespaceMixedPwsFields-1",
+ BeanWithWhitespaceMixedPwsFields.class,
+ new BeanWithWhitespaceMixedPwsFields().init(null),
+ "|<object/>|",
+ false
+ },
+ { /* 58 */
+ "BeanWithWhitespaceMixedPwsFields-3",
+ BeanWithWhitespaceMixedPwsFields.class,
+ new BeanWithWhitespaceMixedPwsFields().init(new String[]{""}),
+ "|<object>|_xE000_|</object>|",
+ true
+ },
+ { /* 59 */
+ "BeanWithWhitespaceMixedPwsFields-4",
+ BeanWithWhitespaceMixedPwsFields.class,
+ new BeanWithWhitespaceMixedPwsFields().init(new String[]{" "}),
+ "|<object>| |</object>|",
+ true
+ },
+ { /* 60 */
+ "BeanWithWhitespaceMixedPwsFields-5",
+ BeanWithWhitespaceMixedPwsFields.class,
+ new BeanWithWhitespaceMixedPwsFields().init(new String[]{" "}),
+ "|<object>| |</object>|",
+ true
+ },
+ { /* 61 */
+ "BeanWithWhitespaceMixedPwsFields-6",
+ BeanWithWhitespaceMixedPwsFields.class,
+ new BeanWithWhitespaceMixedPwsFields().init(new String[]{" foobar "}),
+ "|<object>| foobar |</object>|",
+ true
+ },
+ });
+ }
+
+ private String label;
+ private Class<?> type;
+ private Object expected;
+ private String input;
+ private boolean skipWsTests;
+
+ public XmlIgnoreCommentsTest(String label, Class<?> type, Object expected, String input, boolean skipWsTests) throws Exception {
+ this.label = label;
+ this.type = type;
+ this.expected = expected;
+ this.input = input;
+ this.skipWsTests = skipWsTests;
+ }
+
+ @Test
+ public void testNoComment() throws Exception {
+ try {
+ Object actual = XmlParser.DEFAULT.parse(input.replace("|", ""), type);
+ TestUtils.assertEqualObjects(expected, actual);
+ } catch (ComparisonFailure e) {
+ throw new ComparisonFailure(MessageFormat.format("Test ''{0}'' failed with comparison error", label), e.getExpected(), e.getActual());
+ } catch (Exception e) {
+ throw new FormattedRuntimeException(e, "Test ''{0}'' failed with error ''{1}''", label, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testNormalComment() throws Exception {
+ try {
+ Object actual = XmlParser.DEFAULT.parse(input.replace("|", "<!--x-->"), type);
+ TestUtils.assertEqualObjects(expected, actual);
+ } catch (ComparisonFailure e) {
+ throw new ComparisonFailure(MessageFormat.format("Test ''{0}'' failed with comparison error", label), e.getExpected(), e.getActual());
+ } catch (Exception e) {
+ throw new FormattedRuntimeException(e, "Test ''{0}'' failed with error ''{1}''", label, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testCommentWithWhitespace() throws Exception {
+ try {
+ Object actual = XmlParser.DEFAULT.parse(input.replace("|", " \n <!-- \n x \n --> \n "), type);
+ if (! skipWsTests)
+ TestUtils.assertEqualObjects(expected, actual);
+ } catch (ComparisonFailure e) {
+ throw new ComparisonFailure(MessageFormat.format("Test ''{0}'' failed with comparison error", label), e.getExpected(), e.getActual());
+ } catch (Exception e) {
+ throw new FormattedRuntimeException(e, "Test ''{0}'' failed with error ''{1}''", label, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDoubleCommentsWithWhitespace() throws Exception {
+ try {
+ Object actual = XmlParser.DEFAULT.parse(input.replace("|", " \n <!-- \n x \n --> \n \n <!-- \n x \n --> \n "), type);
+ if (! skipWsTests)
+ TestUtils.assertEqualObjects(expected, actual);
+ } catch (ComparisonFailure e) {
+ throw new ComparisonFailure(MessageFormat.format("Test ''{0}'' failed with comparison error", label), e.getExpected(), e.getActual());
+ } catch (Exception e) {
+ throw new FormattedRuntimeException(e, "Test ''{0}'' failed with error ''{1}''", label, e.getMessage());
+ }
+ }
+
+ //--------------------------------------------------------------------------------
+ // Test beans
+ //--------------------------------------------------------------------------------
+
+ public static class MapWithStrings extends LinkedHashMap<String,String> {
+ public MapWithStrings append(String key, String value) {
+ put(key, value);
+ return this;
+ }
+ }
+
+ public static class MapWithNumbers extends LinkedHashMap<String,Number> {
+ public MapWithNumbers append(String key, Number value) {
+ put(key, value);
+ return this;
+ }
+ }
+
+ public static class MapWithObjects extends LinkedHashMap<String,Object> {
+ public MapWithObjects append(String key, Object value) {
+ put(key, value);
+ return this;
+ }
+ }
+
+ public static class ListWithStrings extends ArrayList<String> {
+ public ListWithStrings append(String value) {
+ this.add(value);
+ return this;
+ }
+ }
+
+ public static class ListWithNumbers extends ArrayList<Number> {
+ public ListWithNumbers append(Number value) {
+ this.add(value);
+ return this;
+ }
+ }
+
+ public static class ListWithObjects extends ArrayList<Object> {
+ public ListWithObjects append(Object value) {
+ this.add(value);
+ return this;
+ }
+ }
+
+ public static class BeanWithNormalProperties {
+ public String a;
+ public int b;
+ public Object c;
+ public Object d;
+ public Bean1a e;
+ public String[] f;
+ public int[] g;
+
+ BeanWithNormalProperties init() {
+ a = "foo";
+ b = 123;
+ c = "bar";
+ d = 456;
+ e = new Bean1a().init();
+ f = new String[]{ "baz" };
+ g = new int[]{ 789 };
+ return this;
+ }
+ }
+
+ public static class Bean1a {
+ public String h;
+
+ Bean1a init() {
+ h = "qux";
+ return this;
+ }
+ }
+
+ public static class BeanWithMapProperties {
+ @BeanProperty(type=MapWithStrings.class)
+ public Map<String,String> a;
+ @BeanProperty(type=MapWithNumbers.class)
+ public Map<String,Number> b;
+ @BeanProperty(type=MapWithObjects.class)
+ public Map<String,Object> c;
+
+ BeanWithMapProperties init() {
+ a = new MapWithStrings().append("k1","foo");
+ b = new MapWithNumbers().append("k2",123);
+ c = new MapWithObjects().append("k3","bar").append("k4",456).append("k5",true).append("k6",null);
+ return this;
+ }
+ }
+
+ @Bean(typeName="X")
+ public static class BeanWithTypeName {
+ public int a;
+ public String b;
+
+ BeanWithTypeName init() {
+ a = 123;
+ b = "foo";
+ return this;
+ }
+ }
+
+ @Bean(beanDictionary={B.class})
+ public static class BeanWithPropertiesWithTypeNames {
+ public B b1;
+ public Object b2;
+
+ BeanWithPropertiesWithTypeNames init() {
+ b1 = new B().init();
+ b2 = new B().init();
+ return this;
+ }
+ }
+
+ @Bean(beanDictionary={B.class})
+ public static class BeanWithPropertiesWithArrayTypeNames {
+ public B[] b1;
+ public Object[] b2;
+ public Object[] b3;
+
+ BeanWithPropertiesWithArrayTypeNames init() {
+ b1 = new B[]{new B().init()};
+ b2 = new B[]{new B().init()};
+ b3 = new Object[]{new B().init()};
+ return this;
+ }
+ }
+
+ @Bean(beanDictionary={B.class})
+ public static class BeanWithPropertiesWith2dArrayTypeNames {
+ public B[][] b1;
+ public Object[][] b2;
+ public Object[][] b3;
+
+ BeanWithPropertiesWith2dArrayTypeNames init() {
+ b1 = new B[][]{{new B().init()}};
+ b2 = new B[][]{{new B().init()}};
+ b3 = new Object[][]{{new B().init()}};
+ return this;
+ }
+ }
+
+ @Bean(beanDictionary={B.class})
+ public static class BeanWithPropertiesWithMapTypeNames {
+ public Map<String,B> b1;
+ public Map<String,Object> b2;
+
+ BeanWithPropertiesWithMapTypeNames init() {
+ b1 = new HashMap<String,B>();
+ b1.put("k1", new B().init());
+ b2 = new HashMap<String,Object>();
+ b2.put("k2", new B().init());
+ return this;
+ }
+ }
+
+ @Bean(typeName="B")
+ public static class B {
+ public String b;
+
+ B init() {
+ b = "foo";
+ return this;
+ }
+ }
+
+ public static class BeanWithChildTypeNames {
+ public BeanX a;
+ @BeanProperty(beanDictionary=BeanX.class)
+ public Object b;
+ public BeanX[] c;
+ @BeanProperty(beanDictionary=BeanX.class)
+ public Object[] d;
+ BeanWithChildTypeNames init() {
+ a = new BeanX().init();
+ b = new BeanX().init();
+ c = new BeanX[]{new BeanX().init()};
+ d = new Object[]{new BeanX().init()};
+ return this;
+ }
+ }
+
+ public static class BeanWithChildName {
+ @Xml(childName = "X")
+ public String[] a;
+ @Xml(childName = "Y")
+ public int[] b;
+ BeanWithChildName init() {
+ a = new String[] { "foo", "bar" };
+ b = new int[] { 123, 456 };
+ return this;
+ }
+ }
+
+ public static class BeanWithXmlFormatAttrProperty {
+ @Xml(format=XmlFormat.ATTR)
+ public String a;
+ @Xml(format=XmlFormat.ATTR)
+ public int b;
+ BeanWithXmlFormatAttrProperty init() {
+ a = "foo";
+ b = 123;
+ return this;
+ }
+ }
+
+ @Xml(format=XmlFormat.ATTRS)
+ public static class BeanWithXmlFormatAttrs {
+ public String a;
+ public int b;
+ BeanWithXmlFormatAttrs init() {
+ a = "foo";
+ b = 123;
+ return this;
+ }
+ }
+
+ @Xml(format=XmlFormat.ATTRS)
+ public static class BeanWithXmlFormatElementProperty {
+ public String a;
+ @Xml(format=XmlFormat.ELEMENT)
+ public int b;
+ BeanWithXmlFormatElementProperty init() {
+ a = "foo";
+ b = 123;
+ return this;
+ }
+ }
+
+ public static class BeanWithXmlFormatAttrsProperty {
+ @Xml(format=XmlFormat.ATTRS)
+ public Map<String,Object> a;
+ @Xml(format=XmlFormat.ATTR)
+ public int b;
+ BeanWithXmlFormatAttrsProperty init() {
+ a = new ObjectMap().append("k1", "foo").append("k2", "123");
+ b = 456;
+ return this;
+ }
+ }
+
+ public static class BeanWithXmlFormatCollapsedProperty {
+ @Xml(childName="A",format=XmlFormat.COLLAPSED)
+ public String[] a;
+ @Xml(childName="B",format=XmlFormat.COLLAPSED)
+ public int[] b;
+ BeanWithXmlFormatCollapsedProperty init() {
+ a = new String[]{"foo","bar"};
+ b = new int[]{123,456};
+ return this;
+ }
+ }
+
+ public static class BeanWithXmlFormatTextProperty {
+ @Xml(format=XmlFormat.ATTR)
+ public String a;
+ @Xml(format=XmlFormat.TEXT)
+ public String b;
+ BeanWithXmlFormatTextProperty init() {
+ a = "foo";
+ b = "bar";
+ return this;
+ }
+ }
+
+ public static class BeanWithXmlFormatXmlTextProperty {
+ @Xml(format=XmlFormat.ATTR)
+ public String a;
+ @Xml(format=XmlFormat.XMLTEXT)
+ public String b;
+ BeanWithXmlFormatXmlTextProperty init() {
+ a = "foo";
+ b = "bar<b>baz</b>qux";
+ return this;
+ }
+ }
+
+ public static class BeanWithXmlFormatElementsPropertyCollection {
+ @Xml(format=XmlFormat.ATTR)
+ public String a;
+ @Xml(format=XmlFormat.ELEMENTS)
+ public Object[] b;
+ BeanWithXmlFormatElementsPropertyCollection init() {
+ a = "foo";
+ b = new Object[]{"bar","baz",123,true,null};
+ return this;
+ }
+ }
+
+ public static class BeanWithMixedContent {
+ @Xml(format=XmlFormat.MIXED)
+ @BeanProperty(beanDictionary={BeanXSimple.class, BeanYSimple.class})
+ public Object[] a;
+ BeanWithMixedContent init() {
+ a = new Object[]{
+ "foo",
+ new BeanXSimple().init(),
+ "bar",
+ new BeanYSimple().init(),
+ "baz"
+ };
+ return this;
+ }
+ }
+
+ @Bean(typeName="X")
+ public static class BeanX {
+ public String fx;
+ BeanX init() {
+ fx = "fx1";
+ return this;
+ }
+ }
+
+ @Bean(typeName="X")
+ public static class BeanXSimple {
+ @Xml(format=XmlFormat.ATTR)
+ public String fx;
+ BeanXSimple init() {
+ fx = "fx1";
+ return this;
+ }
+ }
+
+ @Bean(typeName="Y")
+ public static class BeanY {
+ public String fy;
+ BeanY init() {
+ fy = "fy1";
+ return this;
+ }
+ }
+
+ @Bean(typeName="Y")
+ public static class BeanYSimple {
+ @Xml(format=XmlFormat.ATTR)
+ public String fy;
+ BeanYSimple init() {
+ fy = "fy1";
+ return this;
+ }
+ }
+
+ public static class BeanWithSpecialCharacters {
+ public String a;
+
+ BeanWithSpecialCharacters init() {
+ a = " \b\f\n\t\r ";
+ return this;
+ }
+ }
+
+ @Bean(typeName=" \b\f\n\t\r ")
+ public static class BeanWithSpecialCharacters2 {
+
+ @BeanProperty(name=" \b\f\n\t\r ")
+ public String a;
+
+ BeanWithSpecialCharacters2 init() {
+ a = " \b\f\n\t\r ";
+ return this;
+ }
+ }
+
+ public static class BeanWithNullProperties {
+ public String a;
+ public String[] b;
+ }
+
+ @Bean(beanDictionary={A.class})
+ public static class BeanWithAbstractFields {
+ public A a;
+ public IA ia;
+ public AA aa;
+ public Object o;
+
+ BeanWithAbstractFields init() {
+ ia = new A().init();
+ aa = new A().init();
+ a = new A().init();
+ o = new A().init();
+ return this;
+ }
+ }
+
+ @Bean(beanDictionary={A.class})
+ public static class BeanWithAbstractArrayFields {
+ public A[] a;
+ public IA[] ia1, ia2;
+ public AA[] aa1, aa2;
+ public Object[] o1, o2;
+
+ BeanWithAbstractArrayFields init() {
+ a = new A[]{new A().init()};
+ ia1 = new A[]{new A().init()};
+ aa1 = new A[]{new A().init()};
+ o1 = new A[]{new A().init()};
+ ia2 = new IA[]{new A().init()};
+ aa2 = new AA[]{new A().init()};
+ o2 = new Object[]{new A().init()};
+ return this;
+ }
+ }
+
+ @Bean(beanDictionary={A.class})
+ public static class BeanWithAbstractMapFields {
+ public Map<String,A> a;
+ public Map<String,AA> b;
+ public Map<String,Object> c;
+
+ BeanWithAbstractMapFields init() {
+ a = new HashMap<String,A>();
+ b = new HashMap<String,AA>();
+ c = new HashMap<String,Object>();
+ a.put("k1", new A().init());
+ b.put("k2", new A().init());
+ c.put("k3", new A().init());
+ return this;
+ }
+ }
+
+ @Bean(beanDictionary={A.class})
+ public static class BeanWithAbstractMapArrayFields {
+ public Map<String,A[]> a;
+ public Map<String,IA[]> ia;
+ public Map<String,AA[]> aa;
+ public Map<String,Object[]> o;
+
+ BeanWithAbstractMapArrayFields init() {
+ a = new LinkedHashMap<String,A[]>();
+ ia = new LinkedHashMap<String,IA[]>();
+ aa = new LinkedHashMap<String,AA[]>();
+ o = new LinkedHashMap<String,Object[]>();
+ a.put("a1", new A[]{new A().init()});
+ ia.put("ia1", new A[]{new A().init()});
+ ia.put("ia2", new IA[]{new A().init()});
+ aa.put("aa1", new A[]{new A().init()});
+ aa.put("aa2", new AA[]{new A().init()});
+ o.put("o1", new A[]{new A().init()});
+ o.put("o2", new Object[]{new A().init()});
+ return this;
+ }
+ }
+
+ public static interface IA {
+ public String getA();
+ public void setA(String a);
+ }
+
+ public static abstract class AA implements IA {}
+
+ @Bean(typeName="A")
+ public static class A extends AA {
+ private String a;
+
+ @Override
+ public String getA() {
+ return a;
+ }
+
+ @Override
+ public void setA(String a) {
+ this.a = a;
+ }
+
+ A init() {
+ this.a = "foo";
+ return this;
+ }
+ }
+
+ public static class BeanWithWhitespaceTextFields {
+ @Xml(format=XmlFormat.TEXT)
+ public String a;
+
+ public BeanWithWhitespaceTextFields init(String s) {
+ a = s;
+ return this;
+ }
+ }
+
+ public static class BeanWithWhitespaceTextPwsFields {
+ @Xml(format=XmlFormat.TEXT_PWS)
+ public String a;
+
+ public BeanWithWhitespaceTextPwsFields init(String s) {
+ a = s;
+ return this;
+ }
+ }
+
+ public static class BeanWithWhitespaceMixedFields {
+ @Xml(format=XmlFormat.MIXED)
+ public String[] a;
+
+ public BeanWithWhitespaceMixedFields init(String[] s) {
+ a = s;
+ return this;
+ }
+ }
+
+ public static class BeanWithWhitespaceMixedPwsFields {
+ @Xml(format=XmlFormat.MIXED_PWS)
+ public String[] a;
+
+ public BeanWithWhitespaceMixedPwsFields init(String[] s) {
+ a = s;
+ return this;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlTestIgnoreComments.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlTestIgnoreComments.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlTestIgnoreComments.java
deleted file mode 100644
index 9e125ea..0000000
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlTestIgnoreComments.java
+++ /dev/null
@@ -1,1251 +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.juneau.xml;
-
-import java.text.*;
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.xml.annotation.*;
-import org.junit.*;
-import org.junit.runner.*;
-import org.junit.runners.*;
-
-/**
- * Validates that comments in XML files are ignored.
- */
-@RunWith(Parameterized.class)
-@SuppressWarnings("serial")
-public class XmlTestIgnoreComments {
-
- @Parameterized.Parameters
- public static Collection<Object[]> getParameters() {
-
- return Arrays.asList(new Object[][] {
- { /* 0 */
- "SimpleTypes-1",
- String.class,
- "foo",
- "|<string>|foo|</string>|",
- false
- },
- { /* 1 */
- "SimpleTypes-2",
- Boolean.class,
- true,
- "|<boolean>|true|</boolean>|",
- false
- },
- { /* 2 */
- "SimpleTypes-3",
- int.class,
- 123,
- "|<number>|123|</number>|",
- false
- },
- { /* 3 */
- "SimpleTypes-4",
- float.class,
- 1.23f,
- "|<number>|1.23|</number>|",
- false
- },
- { /* 4 */
- "SimpleTypes-5",
- String.class,
- null,
- "|<null/>|",
- false
- },
- { /* 5 */
- "Arrays-1",
- String[].class,
- new String[]{"foo"},
- "|<array>|<string>|foo|</string>|</array>|",
- false
- },
- { /* 6 */
- "Arrays-2",
- String[].class,
- new String[]{null},
- "|<array>|<null/>|</array>|",
- false
- },
- { /* 7 */
- "Arrays-3",
- Object[].class,
- new Object[]{"foo"},
- "|<array>|<string>|foo|</string>|</array>|",
- false
- },
- { /* 8 */
- "Arrays-4",
- int[].class,
- new int[]{123},
- "|<array>|<number>|123|</number>|</array>|",
- false
- },
- { /* 9 */
- "Arrays-5",
- boolean[].class,
- new boolean[]{true},
- "|<array>|<boolean>|true|</boolean>|</array>|",
- false
- },
- { /* 10 */
- "Arrays-6",
- String[][].class,
- new String[][]{{"foo"}},
- "|<array>|<array>|<string>|foo|</string>|</array>|</array>|",
- false
- },
- { /* 11 */
- "MapWithStrings",
- MapWithStrings.class,
- new MapWithStrings().append("k1", "v1").append("k2", null),
- "|<object>|<k1>|v1|</k1>|<k2 _type='null'/>|</object>|",
- false
- },
- { /* 12 */
- "MapsWithNumbers",
- MapWithNumbers.class,
- new MapWithNumbers().append("k1", 123).append("k2", 1.23).append("k3", null),
- "|<object>|<k1>|123|</k1>|<k2>|1.23|</k2>|<k3 _type='null'/>|</object>|",
- false
- },
- { /* 13 */
- "MapWithObjects",
- MapWithObjects.class,
- new MapWithObjects().append("k1", "v1").append("k2", 123).append("k3", 1.23).append("k4", true).append("k5", null),
- "|<object>|<k1>|v1|</k1>|<k2 _type='number'>|123|</k2>|<k3 _type='number'>|1.23|</k3>|<k4 _type='boolean'>|true|</k4>|<k5 _type='null'/>|</object>|",
- false
- },
- { /* 14 */
- "ListWithStrings",
- ListWithStrings.class,
- new ListWithStrings().append("foo").append(null),
- "|<array>|<string>|foo|</string>|<null/>|</array>|",
- false
- },
- { /* 15 */
- "ListWithNumbers",
- ListWithNumbers.class,
- new ListWithNumbers().append(123).append(1.23).append(null),
- "|<array>|<number>|123|</number>|<number>|1.23|</number>|<null/>|</array>|",
- false
- },
- { /* 16 */
- "ListWithObjects",
- ListWithObjects.class,
- new ListWithObjects().append("foo").append(123).append(1.23).append(true).append(null),
- "|<array>|<string>|foo|</string>|<number>|123|</number>|<number>|1.23|</number>|<boolean>|true|</boolean>|<null/>|</array>|",
- false
- },
- { /* 17 */
- "BeanWithNormalProperties",
- BeanWithNormalProperties.class,
- new BeanWithNormalProperties().init(),
- "|<object>"
- +"|<a>|foo|</a>"
- +"|<b>|123|</b>"
- +"|<c>|bar|</c>"
- +"|<d _type='number'>|456|</d>"
- +"|<e>"
- +"|<h>|qux|</h>"
- +"|</e>"
- +"|<f>"
- +"|<string>|baz|</string>"
- +"|</f>"
- +"|<g>"
- +"|<number>|789|</number>"
- +"|</g>"
- +"|</object>|",
- false
- },
- { /* 18 */
- "BeanWithMapProperties",
- BeanWithMapProperties.class,
- new BeanWithMapProperties().init(),
- "|<object>"
- +"|<a>"
- +"|<k1>|foo|</k1>"
- +"|</a>"
- +"|<b>"
- +"|<k2>|123|</k2>"
- +"|</b>"
- +"|<c>"
- +"|<k3>|bar|</k3>"
- +"|<k4 _type='number'>|456|</k4>"
- +"|<k5 _type='boolean'>|true|</k5>"
- +"|<k6 _type='null'/>"
- +"|</c>"
- +"|</object>|",
- false
- },
- { /* 19 */
- "BeanWithTypeName",
- BeanWithTypeName.class,
- new BeanWithTypeName().init(),
- "|<X>|<a>|123|</a>|<b>|foo|</b>|</X>|",
- false
- },
- { /* 20 */
- "BeanWithPropertiesWithTypeNames",
- BeanWithPropertiesWithTypeNames.class,
- new BeanWithPropertiesWithTypeNames().init(),
- "|<object>|<b1>|<b>|foo|</b>|</b1>|<b2 _type='B'>|<b>|foo|</b>|</b2>|</object>|",
- false
- },
- { /* 21 */
- "BeanWithPropertiesWithArrayTypeNames",
- BeanWithPropertiesWithArrayTypeNames.class,
- new BeanWithPropertiesWithArrayTypeNames().init(),
- "|<object>"
- +"|<b1>"
- +"|<B>"
- +"|<b>|foo|</b>"
- +"|</B>"
- +"|</b1>"
- +"|<b2>"
- +"|<B>"
- +"|<b>|foo|</b>"
- +"|</B>"
- +"|</b2>"
- +"|<b3>"
- +"|<B>"
- +"|<b>|foo|</b>"
- +"|</B>"
- +"|</b3>"
- +"|</object>|",
- false
- },
- { /* 22 */
- "BeanWithPropertiesWithArray2dTypeNames",
- BeanWithPropertiesWith2dArrayTypeNames.class,
- new BeanWithPropertiesWith2dArrayTypeNames().init(),
- "|<object>"
- +"|<b1>"
- +"|<array>"
- +"|<B>"
- +"|<b>|foo|</b>"
- +"|</B>"
- +"|</array>"
- +"|</b1>"
- +"|<b2>"
- +"|<array>"
- +"|<B>"
- +"|<b>|foo|</b>"
- +"|</B>"
- +"|</array>"
- +"|</b2>"
- +"|<b3>"
- +"|<array>"
- +"|<B>"
- +"|<b>|foo|</b>"
- +"|</B>"
- +"|</array>"
- +"|</b3>"
- +"|</object>|",
- false
- },
- { /* 23 */
- "BeanWithPropertiesWithMapTypeNames",
- BeanWithPropertiesWithMapTypeNames.class,
- new BeanWithPropertiesWithMapTypeNames().init(),
- "|<object>"
- +"|<b1>"
- +"|<k1>"
- +"|<b>|foo|</b>"
- +"|</k1>"
- +"|</b1>"
- +"|<b2>"
- +"|<k2 _type='B'>"
- +"|<b>|foo|</b>"
- +"|</k2>"
- +"|</b2>"
- +"|</object>|",
- false
- },
- { /* 24 */
- "BeanWithChildTypeNames",
- BeanWithChildTypeNames.class,
- new BeanWithChildTypeNames().init(),
- "|<object>"
- +"|<a>"
- +"|<fx>|fx1|</fx>"
- +"|</a>"
- +"|<b _type='X'>"
- +"|<fx>|fx1|</fx>"
- +"|</b>"
- +"|<c>"
- +"|<X>"
- +"|<fx>|fx1|</fx>"
- +"|</X>"
- +"|</c>"
- +"|<d>"
- +"|<X>"
- +"|<fx>|fx1|</fx>"
- +"|</X>"
- +"|</d>"
- +"|</object>|",
- false
- },
- { /* 25 */
- "BeanWithChildName",
- BeanWithChildName.class,
- new BeanWithChildName().init(),
- "|<object>|<a>|<X>|foo|</X>|<X>|bar|</X>|</a>|<b>|<Y>|123|</Y>|<Y>|456|</Y>|</b>|</object>|",
- false
- },
- { /* 26 */
- "BeanWithXmlFormatAttrProperty",
- BeanWithXmlFormatAttrProperty.class,
- new BeanWithXmlFormatAttrProperty().init(),
- "|<object a='foo' b='123'/>|",
- false
- },
- { /* 27 */
- "BeanWithXmlFormatAttrs",
- BeanWithXmlFormatAttrs.class,
- new BeanWithXmlFormatAttrs().init(),
- "|<object a='foo' b='123'/>|",
- false
- },
- { /* 28 */
- "BeanWithXmlFormatElementProperty",
- BeanWithXmlFormatElementProperty.class,
- new BeanWithXmlFormatElementProperty().init(),
- "|<object a='foo'><b>123</b></object>|",
- false
- },
- { /* 29 */
- "BeanWithXmlFormatAttrsProperty",
- BeanWithXmlFormatAttrsProperty.class,
- new BeanWithXmlFormatAttrsProperty().init(),
- "|<object k1='foo' k2='123' b='456'/>|",
- false
- },
- { /* 30 */
- "BeanWithXmlFormatCollapsedProperty",
- BeanWithXmlFormatCollapsedProperty.class,
- new BeanWithXmlFormatCollapsedProperty().init(),
- "|<object>|<A>|foo|</A>|<A>|bar|</A>|<B>|123|</B>|<B>|456|</B>|</object>|",
- false
- },
- { /* 31 */
- "BeanWithXmlFormatTextProperty",
- BeanWithXmlFormatTextProperty.class,
- new BeanWithXmlFormatTextProperty().init(),
- "|<object a='foo'>|bar|</object>|",
- false
- },
- { /* 32 */
- "BeanWithXmlFormatXmlTextProperty",
- BeanWithXmlFormatXmlTextProperty.class,
- new BeanWithXmlFormatXmlTextProperty().init(),
- "|<object a='foo'>|bar|<b>|baz|</b>|qux|</object>|",
- false
- },
- { /* 33 */
- "BeanWithXmlFormatElementsPropertyCollection",
- BeanWithXmlFormatElementsPropertyCollection.class,
- new BeanWithXmlFormatElementsPropertyCollection().init(),
- "|<object a='foo'>|<string>|bar|</string>|<string>|baz|</string>|<number>|123|</number>|<boolean>|true|</boolean>|<null/>|</object>|",
- false
- },
- { /* 34 */
- "BeanWithMixedContent",
- BeanWithMixedContent.class,
- new BeanWithMixedContent().init(),
- "|<object>|foo|<X fx='fx1'/>|bar|<Y fy='fy1'/>|baz|</object>|",
- true
- },
- { /* 35 */
- "BeanWithSpecialCharacters",
- BeanWithSpecialCharacters.class,
- new BeanWithSpecialCharacters().init(),
- "|<object>|<a>|_x0020_ _x0008__x000C_
	
 _x0020_|</a>|</object>|",
- false
- },
- { /* 36 */
- "BeanWithSpecialCharacters2",
- BeanWithSpecialCharacters2.class,
- new BeanWithSpecialCharacters2().init(),
- "|<_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>|<_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>|_x0020_ _x0008__x000C_
	
 _x0020_|</_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>|</_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>|",
- false
- },
- { /* 37 */
- "BeanWithNullProperties",
- BeanWithNullProperties.class,
- new BeanWithNullProperties(),
- "|<object/>|",
- false
- },
- { /* 38 */
- "BeanWithAbstractFields",
- BeanWithAbstractFields.class,
- new BeanWithAbstractFields().init(),
- "|<object>"
- +"|<a>"
- +"|<a>|foo|</a>"
- +"|</a>"
- +"|<ia _type='A'>"
- +"|<a>|foo|</a>"
- +"|</ia>"
- +"|<aa _type='A'>"
- +"|<a>|foo|</a>"
- +"|</aa>"
- +"|<o _type='A'>"
- +"|<a>|foo|</a>"
- +"|</o>"
- +"|</object>|",
- false
- },
- { /* 39 */
- "BeanWithAbstractArrayFields",
- BeanWithAbstractArrayFields.class,
- new BeanWithAbstractArrayFields().init(),
- "|<object>"
- +"|<a>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</a>"
- +"|<ia1>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</ia1>"
- +"|<ia2>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</ia2>"
- +"|<aa1>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</aa1>"
- +"|<aa2>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</aa2>"
- +"|<o1>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</o1>"
- +"|<o2>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</o2>"
- +"|</object>",
- false
- },
- { /* 40 */
- "BeanWithAbstractMapFields",
- BeanWithAbstractMapFields.class,
- new BeanWithAbstractMapFields().init(),
- "|<object>"
- +"|<a>"
- +"|<k1>"
- +"|<a>|foo|</a>"
- +"|</k1>"
- +"|</a>"
- +"|<b>"
- +"|<k2 _type='A'>"
- +"|<a>|foo|</a>"
- +"|</k2>"
- +"|</b>"
- +"|<c>"
- +"|<k3 _type='A'>"
- +"|<a>|foo|</a>"
- +"|</k3>"
- +"|</c>"
- +"|</object>",
- false
- },
- { /* 41 */
- "BeanWithAbstractMapArrayFields",
- BeanWithAbstractMapArrayFields.class,
- new BeanWithAbstractMapArrayFields().init(),
- "|<object>"
- +"|<a>"
- +"|<a1>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</a1>"
- +"|</a>"
- +"|<ia>"
- +"|<ia1>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</ia1>"
- +"|<ia2>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</ia2>"
- +"|</ia>"
- +"|<aa>"
- +"|<aa1>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</aa1>"
- +"|<aa2>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</aa2>"
- +"|</aa>"
- +"|<o>"
- +"|<o1>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</o1>"
- +"|<o2>"
- +"|<A>"
- +"|<a>|foo|</a>"
- +"|</A>"
- +"|</o2>"
- +"|</o>"
- +"|</object>",
- false
- },
- { /* 42 */
- "BeanWithWhitespaceTextFields-1",
- BeanWithWhitespaceTextFields.class,
- new BeanWithWhitespaceTextFields().init(null),
- "|<object/>|",
- false
- },
- { /* 43 */
- "BeanWithWhitespaceTextFields-2",
- BeanWithWhitespaceTextFields.class,
- new BeanWithWhitespaceTextFields().init(""),
- "|<object>|_xE000_|</object>|",
- false
- },
- { /* 44 */
- "BeanWithWhitespaceTextFields-3",
- BeanWithWhitespaceTextFields.class,
- new BeanWithWhitespaceTextFields().init(" "),
- "|<object>|_x0020_|</object>|",
- false
- },
- { /* 45 */
- "BeanWithWhitespaceTextFields-4",
- BeanWithWhitespaceTextFields.class,
- new BeanWithWhitespaceTextFields().init(" "),
- "|<object>|_x0020__x0020_|</object>|",
- false
- },
- { /* 46 */
- "BeanWithWhitespaceTextFields-5",
- BeanWithWhitespaceTextFields.class,
- new BeanWithWhitespaceTextFields().init(" foo\n\tbar "),
- "|<object>|_x0020_foo
	bar_x0020_|</object>|",
- false
- },
- { /* 47 */
- "BeanWithWhitespaceTextPwsFields-1",
- BeanWithWhitespaceTextPwsFields.class,
- new BeanWithWhitespaceTextPwsFields().init(null),
- "|<object/>|",
- false
- },
- { /* 48 */
- "BeanWithWhitespaceTextPwsFields-2",
- BeanWithWhitespaceTextPwsFields.class,
- new BeanWithWhitespaceTextPwsFields().init(""),
- "|<object>|_xE000_|</object>|",
- true
- },
- { /* 49 */
- "BeanWithWhitespaceTextPwsFields-3",
- BeanWithWhitespaceTextPwsFields.class,
- new BeanWithWhitespaceTextPwsFields().init(" "),
- "|<object>| |</object>|",
- true
- },
- { /* 50 */
- "BeanWithWhitespaceTextPwsFields-4",
- BeanWithWhitespaceTextPwsFields.class,
- new BeanWithWhitespaceTextPwsFields().init(" "),
- "|<object>| |</object>|",
- true
- },
- { /* 51 */
- "BeanWithWhitespaceTextPwsFields-5",
- BeanWithWhitespaceTextPwsFields.class,
- new BeanWithWhitespaceTextPwsFields().init(" foobar "),
- "|<object>| foobar |</object>|",
- true
- },
- { /* 52 */
- "BeanWithWhitespaceMixedFields-1",
- BeanWithWhitespaceMixedFields.class,
- new BeanWithWhitespaceMixedFields().init(null),
- "|<object/>|",
- false
- },
- { /* 53 */
- "BeanWithWhitespaceMixedFields-3",
- BeanWithWhitespaceMixedFields.class,
- new BeanWithWhitespaceMixedFields().init(new String[]{""}),
- "|<object>|_xE000_|</object>|",
- true
- },
- { /* 54 */
- "BeanWithWhitespaceMixedFields-4",
- BeanWithWhitespaceMixedFields.class,
- new BeanWithWhitespaceMixedFields().init(new String[]{" "}),
- "|<object>|_x0020_|</object>|",
- true
- },
- { /* 55 */
- "BeanWithWhitespaceMixedFields-5",
- BeanWithWhitespaceMixedFields.class,
- new BeanWithWhitespaceMixedFields().init(new String[]{" "}),
- "|<object>|_x0020__x0020_|</object>|",
- true
- },
- { /* 56 */
- "BeanWithWhitespaceMixedFields-6",
- BeanWithWhitespaceMixedFields.class,
- new BeanWithWhitespaceMixedFields().init(new String[]{" foobar "}),
- "|<object>|_x0020_ foobar _x0020_|</object>|",
- true
- },
- { /* 57 */
- "BeanWithWhitespaceMixedPwsFields-1",
- BeanWithWhitespaceMixedPwsFields.class,
- new BeanWithWhitespaceMixedPwsFields().init(null),
- "|<object/>|",
- false
- },
- { /* 58 */
- "BeanWithWhitespaceMixedPwsFields-3",
- BeanWithWhitespaceMixedPwsFields.class,
- new BeanWithWhitespaceMixedPwsFields().init(new String[]{""}),
- "|<object>|_xE000_|</object>|",
- true
- },
- { /* 59 */
- "BeanWithWhitespaceMixedPwsFields-4",
- BeanWithWhitespaceMixedPwsFields.class,
- new BeanWithWhitespaceMixedPwsFields().init(new String[]{" "}),
- "|<object>| |</object>|",
- true
- },
- { /* 60 */
- "BeanWithWhitespaceMixedPwsFields-5",
- BeanWithWhitespaceMixedPwsFields.class,
- new BeanWithWhitespaceMixedPwsFields().init(new String[]{" "}),
- "|<object>| |</object>|",
- true
- },
- { /* 61 */
- "BeanWithWhitespaceMixedPwsFields-6",
- BeanWithWhitespaceMixedPwsFields.class,
- new BeanWithWhitespaceMixedPwsFields().init(new String[]{" foobar "}),
- "|<object>| foobar |</object>|",
- true
- },
- });
- }
-
- private String label;
- private Class<?> type;
- private Object expected;
- private String input;
- private boolean skipWsTests;
-
- public XmlTestIgnoreComments(String label, Class<?> type, Object expected, String input, boolean skipWsTests) throws Exception {
- this.label = label;
- this.type = type;
- this.expected = expected;
- this.input = input;
- this.skipWsTests = skipWsTests;
- }
-
- @Test
- public void testNoComment() throws Exception {
- try {
- Object actual = XmlParser.DEFAULT.parse(input.replace("|", ""), type);
- TestUtils.assertEqualObjects(expected, actual);
- } catch (ComparisonFailure e) {
- throw new ComparisonFailure(MessageFormat.format("Test ''{0}'' failed with comparison error", label), e.getExpected(), e.getActual());
- } catch (Exception e) {
- throw new FormattedRuntimeException(e, "Test ''{0}'' failed with error ''{1}''", label, e.getMessage());
- }
- }
-
- @Test
- public void testNormalComment() throws Exception {
- try {
- Object actual = XmlParser.DEFAULT.parse(input.replace("|", "<!--x-->"), type);
- TestUtils.assertEqualObjects(expected, actual);
- } catch (ComparisonFailure e) {
- throw new ComparisonFailure(MessageFormat.format("Test ''{0}'' failed with comparison error", label), e.getExpected(), e.getActual());
- } catch (Exception e) {
- throw new FormattedRuntimeException(e, "Test ''{0}'' failed with error ''{1}''", label, e.getMessage());
- }
- }
-
- @Test
- public void testCommentWithWhitespace() throws Exception {
- try {
- Object actual = XmlParser.DEFAULT.parse(input.replace("|", " \n <!-- \n x \n --> \n "), type);
- if (! skipWsTests)
- TestUtils.assertEqualObjects(expected, actual);
- } catch (ComparisonFailure e) {
- throw new ComparisonFailure(MessageFormat.format("Test ''{0}'' failed with comparison error", label), e.getExpected(), e.getActual());
- } catch (Exception e) {
- throw new FormattedRuntimeException(e, "Test ''{0}'' failed with error ''{1}''", label, e.getMessage());
- }
- }
-
- @Test
- public void testDoubleCommentsWithWhitespace() throws Exception {
- try {
- Object actual = XmlParser.DEFAULT.parse(input.replace("|", " \n <!-- \n x \n --> \n \n <!-- \n x \n --> \n "), type);
- if (! skipWsTests)
- TestUtils.assertEqualObjects(expected, actual);
- } catch (ComparisonFailure e) {
- throw new ComparisonFailure(MessageFormat.format("Test ''{0}'' failed with comparison error", label), e.getExpected(), e.getActual());
- } catch (Exception e) {
- throw new FormattedRuntimeException(e, "Test ''{0}'' failed with error ''{1}''", label, e.getMessage());
- }
- }
-
- //--------------------------------------------------------------------------------
- // Test beans
- //--------------------------------------------------------------------------------
-
- public static class MapWithStrings extends LinkedHashMap<String,String> {
- public MapWithStrings append(String key, String value) {
- put(key, value);
- return this;
- }
- }
-
- public static class MapWithNumbers extends LinkedHashMap<String,Number> {
- public MapWithNumbers append(String key, Number value) {
- put(key, value);
- return this;
- }
- }
-
- public static class MapWithObjects extends LinkedHashMap<String,Object> {
- public MapWithObjects append(String key, Object value) {
- put(key, value);
- return this;
- }
- }
-
- public static class ListWithStrings extends ArrayList<String> {
- public ListWithStrings append(String value) {
- this.add(value);
- return this;
- }
- }
-
- public static class ListWithNumbers extends ArrayList<Number> {
- public ListWithNumbers append(Number value) {
- this.add(value);
- return this;
- }
- }
-
- public static class ListWithObjects extends ArrayList<Object> {
- public ListWithObjects append(Object value) {
- this.add(value);
- return this;
- }
- }
-
- public static class BeanWithNormalProperties {
- public String a;
- public int b;
- public Object c;
- public Object d;
- public Bean1a e;
- public String[] f;
- public int[] g;
-
- BeanWithNormalProperties init() {
- a = "foo";
- b = 123;
- c = "bar";
- d = 456;
- e = new Bean1a().init();
- f = new String[]{ "baz" };
- g = new int[]{ 789 };
- return this;
- }
- }
-
- public static class Bean1a {
- public String h;
-
- Bean1a init() {
- h = "qux";
- return this;
- }
- }
-
- public static class BeanWithMapProperties {
- @BeanProperty(type=MapWithStrings.class)
- public Map<String,String> a;
- @BeanProperty(type=MapWithNumbers.class)
- public Map<String,Number> b;
- @BeanProperty(type=MapWithObjects.class)
- public Map<String,Object> c;
-
- BeanWithMapProperties init() {
- a = new MapWithStrings().append("k1","foo");
- b = new MapWithNumbers().append("k2",123);
- c = new MapWithObjects().append("k3","bar").append("k4",456).append("k5",true).append("k6",null);
- return this;
- }
- }
-
- @Bean(typeName="X")
- public static class BeanWithTypeName {
- public int a;
- public String b;
-
- BeanWithTypeName init() {
- a = 123;
- b = "foo";
- return this;
- }
- }
-
- @Bean(beanDictionary={B.class})
- public static class BeanWithPropertiesWithTypeNames {
- public B b1;
- public Object b2;
-
- BeanWithPropertiesWithTypeNames init() {
- b1 = new B().init();
- b2 = new B().init();
- return this;
- }
- }
-
- @Bean(beanDictionary={B.class})
- public static class BeanWithPropertiesWithArrayTypeNames {
- public B[] b1;
- public Object[] b2;
- public Object[] b3;
-
- BeanWithPropertiesWithArrayTypeNames init() {
- b1 = new B[]{new B().init()};
- b2 = new B[]{new B().init()};
- b3 = new Object[]{new B().init()};
- return this;
- }
- }
-
- @Bean(beanDictionary={B.class})
- public static class BeanWithPropertiesWith2dArrayTypeNames {
- public B[][] b1;
- public Object[][] b2;
- public Object[][] b3;
-
- BeanWithPropertiesWith2dArrayTypeNames init() {
- b1 = new B[][]{{new B().init()}};
- b2 = new B[][]{{new B().init()}};
- b3 = new Object[][]{{new B().init()}};
- return this;
- }
- }
-
- @Bean(beanDictionary={B.class})
- public static class BeanWithPropertiesWithMapTypeNames {
- public Map<String,B> b1;
- public Map<String,Object> b2;
-
- BeanWithPropertiesWithMapTypeNames init() {
- b1 = new HashMap<String,B>();
- b1.put("k1", new B().init());
- b2 = new HashMap<String,Object>();
- b2.put("k2", new B().init());
- return this;
- }
- }
-
- @Bean(typeName="B")
- public static class B {
- public String b;
-
- B init() {
- b = "foo";
- return this;
- }
- }
-
- public static class BeanWithChildTypeNames {
- public BeanX a;
- @BeanProperty(beanDictionary=BeanX.class)
- public Object b;
- public BeanX[] c;
- @BeanProperty(beanDictionary=BeanX.class)
- public Object[] d;
- BeanWithChildTypeNames init() {
- a = new BeanX().init();
- b = new BeanX().init();
- c = new BeanX[]{new BeanX().init()};
- d = new Object[]{new BeanX().init()};
- return this;
- }
- }
-
- public static class BeanWithChildName {
- @Xml(childName = "X")
- public String[] a;
- @Xml(childName = "Y")
- public int[] b;
- BeanWithChildName init() {
- a = new String[] { "foo", "bar" };
- b = new int[] { 123, 456 };
- return this;
- }
- }
-
- public static class BeanWithXmlFormatAttrProperty {
- @Xml(format=XmlFormat.ATTR)
- public String a;
- @Xml(format=XmlFormat.ATTR)
- public int b;
- BeanWithXmlFormatAttrProperty init() {
- a = "foo";
- b = 123;
- return this;
- }
- }
-
- @Xml(format=XmlFormat.ATTRS)
- public static class BeanWithXmlFormatAttrs {
- public String a;
- public int b;
- BeanWithXmlFormatAttrs init() {
- a = "foo";
- b = 123;
- return this;
- }
- }
-
- @Xml(format=XmlFormat.ATTRS)
- public static class BeanWithXmlFormatElementProperty {
- public String a;
- @Xml(format=XmlFormat.ELEMENT)
- public int b;
- BeanWithXmlFormatElementProperty init() {
- a = "foo";
- b = 123;
- return this;
- }
- }
-
- public static class BeanWithXmlFormatAttrsProperty {
- @Xml(format=XmlFormat.ATTRS)
- public Map<String,Object> a;
- @Xml(format=XmlFormat.ATTR)
- public int b;
- BeanWithXmlFormatAttrsProperty init() {
- a = new ObjectMap().append("k1", "foo").append("k2", "123");
- b = 456;
- return this;
- }
- }
-
- public static class BeanWithXmlFormatCollapsedProperty {
- @Xml(childName="A",format=XmlFormat.COLLAPSED)
- public String[] a;
- @Xml(childName="B",format=XmlFormat.COLLAPSED)
- public int[] b;
- BeanWithXmlFormatCollapsedProperty init() {
- a = new String[]{"foo","bar"};
- b = new int[]{123,456};
- return this;
- }
- }
-
- public static class BeanWithXmlFormatTextProperty {
- @Xml(format=XmlFormat.ATTR)
- public String a;
- @Xml(format=XmlFormat.TEXT)
- public String b;
- BeanWithXmlFormatTextProperty init() {
- a = "foo";
- b = "bar";
- return this;
- }
- }
-
- public static class BeanWithXmlFormatXmlTextProperty {
- @Xml(format=XmlFormat.ATTR)
- public String a;
- @Xml(format=XmlFormat.XMLTEXT)
- public String b;
- BeanWithXmlFormatXmlTextProperty init() {
- a = "foo";
- b = "bar<b>baz</b>qux";
- return this;
- }
- }
-
- public static class BeanWithXmlFormatElementsPropertyCollection {
- @Xml(format=XmlFormat.ATTR)
- public String a;
- @Xml(format=XmlFormat.ELEMENTS)
- public Object[] b;
- BeanWithXmlFormatElementsPropertyCollection init() {
- a = "foo";
- b = new Object[]{"bar","baz",123,true,null};
- return this;
- }
- }
-
- public static class BeanWithMixedContent {
- @Xml(format=XmlFormat.MIXED)
- @BeanProperty(beanDictionary={BeanXSimple.class, BeanYSimple.class})
- public Object[] a;
- BeanWithMixedContent init() {
- a = new Object[]{
- "foo",
- new BeanXSimple().init(),
- "bar",
- new BeanYSimple().init(),
- "baz"
- };
- return this;
- }
- }
-
- @Bean(typeName="X")
- public static class BeanX {
- public String fx;
- BeanX init() {
- fx = "fx1";
- return this;
- }
- }
-
- @Bean(typeName="X")
- public static class BeanXSimple {
- @Xml(format=XmlFormat.ATTR)
- public String fx;
- BeanXSimple init() {
- fx = "fx1";
- return this;
- }
- }
-
- @Bean(typeName="Y")
- public static class BeanY {
- public String fy;
- BeanY init() {
- fy = "fy1";
- return this;
- }
- }
-
- @Bean(typeName="Y")
- public static class BeanYSimple {
- @Xml(format=XmlFormat.ATTR)
- public String fy;
- BeanYSimple init() {
- fy = "fy1";
- return this;
- }
- }
-
- public static class BeanWithSpecialCharacters {
- public String a;
-
- BeanWithSpecialCharacters init() {
- a = " \b\f\n\t\r ";
- return this;
- }
- }
-
- @Bean(typeName=" \b\f\n\t\r ")
- public static class BeanWithSpecialCharacters2 {
-
- @BeanProperty(name=" \b\f\n\t\r ")
- public String a;
-
- BeanWithSpecialCharacters2 init() {
- a = " \b\f\n\t\r ";
- return this;
- }
- }
-
- public static class BeanWithNullProperties {
- public String a;
- public String[] b;
- }
-
- @Bean(beanDictionary={A.class})
- public static class BeanWithAbstractFields {
- public A a;
- public IA ia;
- public AA aa;
- public Object o;
-
- BeanWithAbstractFields init() {
- ia = new A().init();
- aa = new A().init();
- a = new A().init();
- o = new A().init();
- return this;
- }
- }
-
- @Bean(beanDictionary={A.class})
- public static class BeanWithAbstractArrayFields {
- public A[] a;
- public IA[] ia1, ia2;
- public AA[] aa1, aa2;
- public Object[] o1, o2;
-
- BeanWithAbstractArrayFields init() {
- a = new A[]{new A().init()};
- ia1 = new A[]{new A().init()};
- aa1 = new A[]{new A().init()};
- o1 = new A[]{new A().init()};
- ia2 = new IA[]{new A().init()};
- aa2 = new AA[]{new A().init()};
- o2 = new Object[]{new A().init()};
- return this;
- }
- }
-
- @Bean(beanDictionary={A.class})
- public static class BeanWithAbstractMapFields {
- public Map<String,A> a;
- public Map<String,AA> b;
- public Map<String,Object> c;
-
- BeanWithAbstractMapFields init() {
- a = new HashMap<String,A>();
- b = new HashMap<String,AA>();
- c = new HashMap<String,Object>();
- a.put("k1", new A().init());
- b.put("k2", new A().init());
- c.put("k3", new A().init());
- return this;
- }
- }
-
- @Bean(beanDictionary={A.class})
- public static class BeanWithAbstractMapArrayFields {
- public Map<String,A[]> a;
- public Map<String,IA[]> ia;
- public Map<String,AA[]> aa;
- public Map<String,Object[]> o;
-
- BeanWithAbstractMapArrayFields init() {
- a = new LinkedHashMap<String,A[]>();
- ia = new LinkedHashMap<String,IA[]>();
- aa = new LinkedHashMap<String,AA[]>();
- o = new LinkedHashMap<String,Object[]>();
- a.put("a1", new A[]{new A().init()});
- ia.put("ia1", new A[]{new A().init()});
- ia.put("ia2", new IA[]{new A().init()});
- aa.put("aa1", new A[]{new A().init()});
- aa.put("aa2", new AA[]{new A().init()});
- o.put("o1", new A[]{new A().init()});
- o.put("o2", new Object[]{new A().init()});
- return this;
- }
- }
-
- public static interface IA {
- public String getA();
- public void setA(String a);
- }
-
- public static abstract class AA implements IA {}
-
- @Bean(typeName="A")
- public static class A extends AA {
- private String a;
-
- @Override
- public String getA() {
- return a;
- }
-
- @Override
- public void setA(String a) {
- this.a = a;
- }
-
- A init() {
- this.a = "foo";
- return this;
- }
- }
-
- public static class BeanWithWhitespaceTextFields {
- @Xml(format=XmlFormat.TEXT)
- public String a;
-
- public BeanWithWhitespaceTextFields init(String s) {
- a = s;
- return this;
- }
- }
-
- public static class BeanWithWhitespaceTextPwsFields {
- @Xml(format=XmlFormat.TEXT_PWS)
- public String a;
-
- public BeanWithWhitespaceTextPwsFields init(String s) {
- a = s;
- return this;
- }
- }
-
- public static class BeanWithWhitespaceMixedFields {
- @Xml(format=XmlFormat.MIXED)
- public String[] a;
-
- public BeanWithWhitespaceMixedFields init(String[] s) {
- a = s;
- return this;
- }
- }
-
- public static class BeanWithWhitespaceMixedPwsFields {
- @Xml(format=XmlFormat.MIXED_PWS)
- public String[] a;
-
- public BeanWithWhitespaceMixedPwsFields init(String[] s) {
- a = s;
- return this;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-marshall/TODO.txt
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/TODO.txt b/juneau-core/juneau-marshall/TODO.txt
index 44e619c..f314bd6 100644
--- a/juneau-core/juneau-marshall/TODO.txt
+++ b/juneau-core/juneau-marshall/TODO.txt
@@ -13,7 +13,5 @@
Create tests that ensure serializers don't close output but parsers do close input.
-Review property info in all contexts.
-Clean up RestClient/RestClientBuilder constructors.
$R{servletDescription} tags showing up in REST examples.
Examples should use dark LAF.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
index 71a751c..4c2fd99 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
@@ -945,7 +945,7 @@ public class BeanContext extends Context {
final String beanTypePropertyName;
- final int hashCode;
+ final int beanHashCode;
/**
* Constructor.
@@ -958,7 +958,7 @@ public class BeanContext extends Context {
public BeanContext(PropertyStore ps) {
super(ps);
- hashCode = ps.hashCode("BeanContext");
+ beanHashCode = ps.hashCode("BeanContext");
beansRequireDefaultConstructor = getProperty(BEAN_beansRequireDefaultConstructor, boolean.class, false);
beansRequireSerializable = getProperty(BEAN_beansRequireSerializable, boolean.class, false);
@@ -1032,13 +1032,13 @@ public class BeanContext extends Context {
timeZone = getInstanceProperty(BEAN_timeZone, TimeZone.class, null);
mediaType = getInstanceProperty(BEAN_mediaType, MediaType.class, null);
- if (! cmCacheCache.containsKey(hashCode)) {
+ if (! cmCacheCache.containsKey(beanHashCode)) {
ConcurrentHashMap<Class,ClassMeta> cm = new ConcurrentHashMap<>();
cm.putIfAbsent(String.class, new ClassMeta(String.class, this, null, null, findPojoSwaps(String.class), findChildPojoSwaps(String.class)));
cm.putIfAbsent(Object.class, new ClassMeta(Object.class, this, null, null, findPojoSwaps(Object.class), findChildPojoSwaps(Object.class)));
- cmCacheCache.putIfAbsent(hashCode, cm);
+ cmCacheCache.putIfAbsent(beanHashCode, cm);
}
- cmCache = cmCacheCache.get(hashCode);
+ cmCache = cmCacheCache.get(beanHashCode);
cmString = cmCache.get(String.class);
cmObject = cmCache.get(Object.class);
cmClass = cmCache.get(Class.class);
@@ -1797,20 +1797,6 @@ public class BeanContext extends Context {
return cmClass;
}
- @Override /* Object */
- public int hashCode() {
- return hashCode;
- }
-
- @Override /* Object */
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o instanceof BeanContext)
- return ((BeanContext)o).hashCode == hashCode;
- return false;
- }
-
@Override /* Context */
public ObjectMap asMap() {
return super.asMap()
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index 06178c3..ae78ab7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -15,6 +15,7 @@ package org.apache.juneau;
import java.util.*;
import org.apache.juneau.annotation.*;
+import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.serializer.*;
@@ -36,6 +37,7 @@ import org.apache.juneau.serializer.*;
public abstract class Context {
private final PropertyStore propertyStore;
+ private final int hashCode;
/**
* Constructor for this class.
@@ -47,6 +49,7 @@ public abstract class Context {
*/
public Context(PropertyStore ps) {
this.propertyStore = ps == null ? PropertyStore.DEFAULT : ps;
+ this.hashCode = new HashCode().add(getClass().getName()).add(ps).get();
}
/**
@@ -338,6 +341,22 @@ public abstract class Context {
public ObjectMap asMap() {
return new ObjectMap();
}
+
+ @Override /* Object */
+ public final int hashCode() {
+ return hashCode;
+ }
+
+ @Override /* Object */
+ public final boolean equals(Object o) {
+ // Context objects are considered equal if they're the same class and have the same set of properties.
+ if (o == null)
+ return false;
+ if (o.getClass() != this.getClass())
+ return false;
+ Context c = (Context)o;
+ return (c.propertyStore.equals(propertyStore));
+ }
@Override /* Object */
public final String toString() {
http://git-wip-us.apache.org/repos/asf/juneau/blob/77664769/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyConverter.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyConverter.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyConverter.java
index 939240c..99cb2d9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyConverter.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyConverter.java
@@ -66,13 +66,7 @@ interface PropertyConverter<T> {
static final PropertyConverter<Object> OBJECT_CONVERTER = new PropertyConverter<Object>() {
@Override
public Object convert(Object o, MutableProperty p) {
- try {
- if (o instanceof Class)
- return ((Class<?>)o).newInstance();
- return o;
- } catch (Exception e) {
- throw new ConfigException("Value ''{0}'' ({1}) cannot be converted to an Object on property ''{2}'' ({3}).", o, o.getClass().getSimpleName(), p.name, p.type);
- }
+ return o;
}
};
}