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 2020/03/07 23:24:43 UTC

[juneau] branch master updated: JUNEAU-197

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 5a64f33  JUNEAU-197
5a64f33 is described below

commit 5a64f33c6c64afe119b2c80b3cf39e800cdfd0fb
Author: JamesBognar <ja...@apache.org>
AuthorDate: Sat Mar 7 18:24:26 2020 -0500

    JUNEAU-197
    
    @BeanConfig(bpi) does not override @Bean(bpi)
---
 .../apache/juneau/BeanConfigAnnotationTest.java    |  43 ++++++++
 .../main/java/org/apache/juneau/BeanContext.java   |  13 ++-
 .../apache/juneau/annotation/BeanConfigApply.java  | 122 +++++++++++++++++++++
 ...rentHashMap.java => TwoKeyConcurrentCache.java} |  23 +++-
 4 files changed, 194 insertions(+), 7 deletions(-)

diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/BeanConfigAnnotationTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/BeanConfigAnnotationTest.java
index ee506b4..f79272a 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/BeanConfigAnnotationTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/BeanConfigAnnotationTest.java
@@ -308,4 +308,47 @@ public class BeanConfigAnnotationTest {
 		check("true", bc.isUseInterfaceProxies());
 		check("false", bc.isUseJavaBeanIntrospector());
 	}
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// @BeanConfig(bpi/bpx) should override @Bean(bpi/bpx)
+	//-----------------------------------------------------------------------------------------------------------------
+
+	@BeanConfig(bpi="b,c,d", bpx="c")
+	@Bean(bpi="a,b,c", bpx="b")
+	static class D {
+		public int a, b, c, d;
+
+		public static D create() {
+			D d = new D();
+			d.a = 1;
+			d.b = 2;
+			d.c = 3;
+			d.d = 4;
+			return d;
+		}
+	}
+
+	private static ClassInfo d = ClassInfo.of(D.class);
+
+//	@Test
+//	public void beanBpiBpxCombined_noBeanConfig() throws Exception {
+//		String json = SimpleJson.DEFAULT.toString(D.create());
+//		assertEquals("{a:1,c:3}", json);
+//		D d = SimpleJson.DEFAULT.read(json, D.class);
+//		json = SimpleJson.DEFAULT.toString(d);
+//		assertEquals("{a:1,c:3}", json);
+//	}
+//
+//	@Test
+//	public void beanBpiBpxCombined_beanConfigOverride() throws Exception {
+//		AnnotationList al = c.getAnnotationListChildFirst(null);
+//		JsonSerializer js = JsonSerializer.create().simple().applyAnnotations(al, sr).build();
+//		JsonParser jp = JsonParser.create().applyAnnotations(al, sr).build();
+//
+//		String json = js.serialize(D.create());
+//		assertEquals("{b:2,d:4}", json);
+//		D d = jp.parse(json, D.class);
+//		json = js.serialize(d);
+//		assertEquals("{b:2,d:4}", json);
+//	}
 }
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 9512b49..309841e 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
@@ -2381,12 +2381,13 @@ public class BeanContext extends Context implements MetaProvider {
 		for (Annotation a : ps.getListProperty(BEAN_annotations, Annotation.class)) {
 			try {
 				Method m = a.getClass().getMethod("on");
+				m.setAccessible(true);
 				String on = (String)m.invoke(a);
 				rmb.append(on, a);
 			} catch (NoSuchMethodException e) {
 				throw new ConfigException("Invalid annotation @{0} used in BEAN_annotations property.  Annotation must define an on() method.", a.getClass().getSimpleName());
 			} catch (Exception e) {
-				throw new ConfigException(e, "Invalid annotation @{0} used in BEAN_annotations property.");
+				throw new ConfigException(e, "Invalid annotation @{0} used in BEAN_annotations property.", a.getClass().getName());
 			}
 		}
 		this.annotations = rmb.build();
@@ -3227,11 +3228,11 @@ public class BeanContext extends Context implements MetaProvider {
 
 	private static final boolean DISABLE_ANNOTATION_CACHING = ! Boolean.getBoolean("juneau.disableAnnotationCaching");
 
-	private TwoKeyConcurrentHashMap<Class<?>,Class<? extends Annotation>,Optional<Annotation>> classAnnotationCache = new TwoKeyConcurrentHashMap<>();
-	private TwoKeyConcurrentHashMap<Class<?>,Class<? extends Annotation>,Optional<Annotation>> declaredClassAnnotationCache = new TwoKeyConcurrentHashMap<>();
-	private TwoKeyConcurrentHashMap<Method,Class<? extends Annotation>,Optional<Annotation>> methodAnnotationCache = new TwoKeyConcurrentHashMap<>();
-	private TwoKeyConcurrentHashMap<Field,Class<? extends Annotation>,Optional<Annotation>> fieldAnnotationCache = new TwoKeyConcurrentHashMap<>();
-	private TwoKeyConcurrentHashMap<Constructor<?>,Class<? extends Annotation>,Optional<Annotation>> constructorAnnotationCache = new TwoKeyConcurrentHashMap<>();
+	private TwoKeyConcurrentCache<Class<?>,Class<? extends Annotation>,Optional<Annotation>> classAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
+	private TwoKeyConcurrentCache<Class<?>,Class<? extends Annotation>,Optional<Annotation>> declaredClassAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
+	private TwoKeyConcurrentCache<Method,Class<? extends Annotation>,Optional<Annotation>> methodAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
+	private TwoKeyConcurrentCache<Field,Class<? extends Annotation>,Optional<Annotation>> fieldAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
+	private TwoKeyConcurrentCache<Constructor<?>,Class<? extends Annotation>,Optional<Annotation>> constructorAnnotationCache = new TwoKeyConcurrentCache<>(DISABLE_ANNOTATION_CACHING);
 
 	@Override /* MetaProvider */
 	public <A extends Annotation> A getAnnotation(Class<A> a, Class<?> c) {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanConfigApply.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanConfigApply.java
index e2e2a6d..0b92ad7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanConfigApply.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/BeanConfigApply.java
@@ -14,7 +14,9 @@ package org.apache.juneau.annotation;
 
 import static org.apache.juneau.BeanContext.*;
 import static org.apache.juneau.BeanTraverseContext.*;
+import static org.apache.juneau.internal.StringUtils.*;
 
+import java.lang.annotation.*;
 import java.util.*;
 
 import org.apache.juneau.*;
@@ -23,6 +25,7 @@ import org.apache.juneau.marshall.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.reflect.*;
 import org.apache.juneau.svl.*;
+import org.apache.juneau.transform.*;
 
 /**
  * Applies {@link BeanConfig} annotations to a {@link PropertyStoreBuilder}.
@@ -184,6 +187,125 @@ public class BeanConfigApply extends ConfigApply<BeanConfig> {
 			psb.addTo(BEAN_annotations, a.applyURI());
 		if (a.applySwap().length > 0)
 			psb.addTo(BEAN_annotations, a.applySwap());
+
+//		if (a.bpi().length > 0)
+//			for (Map.Entry<String,String> e : stringsMap(a.bpi(), "bpi").entrySet())
+//				psb.addTo(BEAN_annotations, bean(e.getKey(), e.getValue(), null, null, null));
+//		for (CS e : a.bpiMap())
+//			psb.addTo(BEAN_annotations, bean(e.k().getName(), e.v(), null, null, null));
+//
+//		if (a.bpx().length > 0)
+//			for (Map.Entry<String,String> e : stringsMap(a.bpx(), "bpx").entrySet())
+//				psb.addTo(BEAN_annotations, bean(e.getKey(), null, e.getValue(), null, null));
+//		for (CS e : a.bpxMap())
+//			psb.addTo(BEAN_annotations, bean(e.k().getName(), null, e.v(), null, null));
+//
+//		if (a.bpro().length > 0)
+//			for (Map.Entry<String,String> e : stringsMap(a.bpro(), "bpro").entrySet())
+//				psb.addTo(BEAN_annotations, bean(e.getKey(), null, null, e.getValue(), null));
+//		for (CS e : a.bproMap())
+//			psb.addTo(BEAN_annotations, bean(e.k().getName(), null, null, e.v(), null));
+//
+//		if (a.bpwo().length > 0)
+//			for (Map.Entry<String,String> e : stringsMap(a.bpwo(), "bpwo").entrySet())
+//				psb.addTo(BEAN_annotations, bean(e.getKey(), null, null, null, e.getValue()));
+//		for (CS e : a.bpwoMap())
+//			psb.addTo(BEAN_annotations, bean(e.k().getName(), null, null, null, e.v()));
+	}
+
+	private static Bean bean(final String on, final String bpi, final String bpx, final String bpro, final String bpwo) {
+		return new Bean() {
+
+			@Override
+			public Class<? extends Annotation> annotationType() {
+				return Bean.class;
+			}
+
+			@Override
+			public Class<?>[] beanDictionary() {
+				return new Class[0];
+			}
+
+			@Override
+			public String bpi() {
+				return emptyIfNull(bpi);
+			}
+
+			@Override
+			public String bpx() {
+				return emptyIfNull(bpx);
+			}
+
+			@Override
+			public String bpro() {
+				return emptyIfNull(bpro);
+			}
+
+			@Override
+			public String bpwo() {
+				return emptyIfNull(bpwo);
+			}
+
+			@Override
+			public Class<?>[] dictionary() {
+				return new Class[0];
+			}
+
+			@Override
+			public String excludeProperties() {
+				return "";
+			}
+
+			@Override
+			public boolean fluentSetters() {
+				return false;
+			}
+
+			@Override
+			public Class<?> interfaceClass() {
+				return Object.class;
+			}
+
+			@Override
+			public String on() {
+				return on;
+			}
+
+			@Override
+			public String properties() {
+				return "";
+			}
+
+			@Override
+			public Class<? extends PropertyFilter> propertyFilter() {
+				return PropertyFilter.class;
+			}
+
+			@Override
+			public Class<? extends PropertyNamer> propertyNamer() {
+				return PropertyNamerDefault.class;
+			}
+
+			@Override
+			public boolean sort() {
+				return false;
+			}
+
+			@Override
+			public Class<?> stopClass() {
+				return Object.class;
+			}
+
+			@Override
+			public String typeName() {
+				return "";
+			}
+
+			@Override
+			public String typePropertyName() {
+				return "";
+			}
+		};
 	}
 
 	private Locale locale(String in) {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/TwoKeyConcurrentHashMap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/TwoKeyConcurrentCache.java
similarity index 86%
rename from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/TwoKeyConcurrentHashMap.java
rename to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/TwoKeyConcurrentCache.java
index 6a4829a..a5d65ca 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/TwoKeyConcurrentHashMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/TwoKeyConcurrentCache.java
@@ -21,9 +21,26 @@ import java.util.concurrent.*;
  * @param <K2> Key part 2 type.
  * @param <V> Value type.
  */
-public class TwoKeyConcurrentHashMap<K1,K2,V> extends ConcurrentHashMap<TwoKeyConcurrentHashMap.Key<K1,K2>,V> {
+public class TwoKeyConcurrentCache<K1,K2,V> extends ConcurrentHashMap<TwoKeyConcurrentCache.Key<K1,K2>,V> {
 	private static final long serialVersionUID = 1L;
 
+	private final boolean disabled;
+
+	/**
+	 * Constructor.
+	 */
+	public TwoKeyConcurrentCache() {
+		this.disabled = false;
+	}
+
+	/**
+	 * Constructor.
+	 * @param disabled If <jk>true</jk>, get/put operations are no-ops.
+	 */
+	public TwoKeyConcurrentCache(boolean disabled) {
+		this.disabled = disabled;
+	}
+
 	/**
 	 * Adds an entry to this map.
 	 *
@@ -33,6 +50,8 @@ public class TwoKeyConcurrentHashMap<K1,K2,V> extends ConcurrentHashMap<TwoKeyCo
 	 * @return The previous value if there was one.
 	 */
 	public V put(K1 key1, K2 key2, V value) {
+		if (disabled)
+			return null;
 		Key<K1,K2> key = new Key<>(key1, key2);
 		return super.put(key, value);
 	}
@@ -45,6 +64,8 @@ public class TwoKeyConcurrentHashMap<K1,K2,V> extends ConcurrentHashMap<TwoKeyCo
 	 * @return The previous value if there was one.
 	 */
 	public V get(K1 key1, K2 key2) {
+		if (disabled)
+			return null;
 		Key<K1,K2> key = new Key<>(key1, key2);
 		return super.get(key);
 	}