Skip to content

Commit dd40d48

Browse files
author
James Bognar
committed
Add support for setting Session properties via setProperty
1 parent 48cadfd commit dd40d48

39 files changed

Lines changed: 397 additions & 58 deletions

File tree

juneau-core/juneau-assertions/src/main/java/org/apache/juneau/assertions/Assertion.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
*/
6161
@SuppressWarnings({
6262
"java:S115", // Constants use UPPER_snakeCase convention (e.g., MSG_parameterCannotBeNull); System.err/out usage is intentional for assertion error output
63-
"java:S106" // System.out/err usage acceptable for assertion output
63+
"java:S106", // System.out/err usage acceptable for assertion output
64+
"resource" // out field assigned to System.err which is a JVM-managed singleton not owned by this class
6465
})
6566
public class Assertion {
6667

juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/conversion/ConversionFinder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,8 @@ public interface ConversionFinder {
5454
* @param outType The output type class.
5555
* @return A {@link Conversion} function, or <jk>null</jk> if no conversion is available.
5656
*/
57+
@SuppressWarnings({
58+
"java:S1452" // Wildcards unavoidable; concrete I/O types are only known at runtime
59+
})
5760
Conversion<?,?> findConversion(Class<?> inType, Class<?> outType);
5861
}

juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
* </ul>
5757
*/
5858
@SuppressWarnings({
59-
"java:S115" // Constants use UPPER_snakeCase convention
59+
"java:S115", // Constants use UPPER_snakeCase convention
60+
"resource" // ConfigStore and other Closeable fields are owned by the caller; lifecycle managed externally
6061
})
6162
public class Config extends Context implements ConfigEventListener {
6263

juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"rawtypes", // Raw types necessary for generic type handling
5959
"unchecked", // Type erasure requires unchecked casts
6060
"java:S115", // Constants use UPPER_snakeCase naming convention
61+
"java:S2176" // Inheritance depth exceeds 5; necessary to participate in the serializer session hierarchy
6162
})
6263
public class RdfSerializerSession extends WriterSerializerSession {
6364

@@ -304,7 +305,7 @@ private String encodeTextInvalidChars(Object o) {
304305
}
305306

306307
private String getUri(Object uri, Object uri2) {
307-
var s = (String)null;
308+
String s = null;
308309
if (nn(uri))
309310
s = uri.toString();
310311
if ((s == null || s.isEmpty()) && nn(uri2))
@@ -320,11 +321,10 @@ private String getUri(Object uri, Object uri2) {
320321
private RDFNode serializeAnything(Object o, boolean isURI, ClassMeta<?> eType, String attrName, BeanPropertyMeta bpm, Resource parentResource) throws SerializeException {
321322
var m = model;
322323

323-
var aType = (ClassMeta<?>)null; // The actual type
324-
var wType = (ClassMeta<?>)null; // The wrapped type
325-
ClassMeta<?> sType = object(); // The serialized type
324+
ClassMeta<?> wType = null; // The wrapped type
325+
ClassMeta<?> sType; // The serialized type
326326

327-
aType = push2(attrName, o, eType);
327+
var aType = push2(attrName, o, eType); // The actual type
328328

329329
if (eType == null)
330330
eType = object();
@@ -368,7 +368,7 @@ private RDFNode serializeAnything(Object o, boolean isURI, ClassMeta<?> eType, S
368368

369369
var typeName = getBeanTypeName(this, eType, aType, bpm);
370370

371-
var n = (RDFNode)null;
371+
RDFNode n = null;
372372

373373
if (o == null || sType.isChar() && ((Character)o).charValue() == 0) {
374374
if (nn(bpm)) {
@@ -398,7 +398,7 @@ private RDFNode serializeAnything(Object o, boolean isURI, ClassMeta<?> eType, S
398398

399399
} else if (sType.isMap() || (nn(wType) && wType.isMap())) {
400400
if (o instanceof BeanMap o2) {
401-
var uri = (Object)null;
401+
Object uri = null;
402402
var rbm = getRdfBeanMeta(o2.getMeta());
403403
if (rbm.hasBeanUri())
404404
uri = rbm.getBeanUriProperty().get(o2, null);
@@ -413,7 +413,7 @@ private RDFNode serializeAnything(Object o, boolean isURI, ClassMeta<?> eType, S
413413

414414
} else if (sType.isBean()) {
415415
var bm = toBeanMap(o);
416-
var uri = (Object)null;
416+
Object uri = null;
417417
RdfBeanMeta rbm = getRdfBeanMeta(bm.getMeta());
418418
if (rbm.hasBeanUri())
419419
uri = rbm.getBeanUriProperty().get(bm, null);
@@ -466,9 +466,7 @@ private void serializeBeanMap(BeanMap<?> m, Resource r, String typeName) throws
466466
}
467467

468468
var checkNull = (Predicate<Object>)(x -> isKeepNullProperties() || nn(x));
469-
m.forEachValue(checkNull, (pMeta, key, value, thrown) -> {
470-
l.add(new BeanPropertyValue(pMeta, key, value, thrown));
471-
});
469+
m.forEachValue(checkNull, (pMeta, key, value, thrown) -> l.add(new BeanPropertyValue(pMeta, key, value, thrown)));
472470

473471
Collections.reverse(l);
474472
l.forEach(x -> {
@@ -564,14 +562,13 @@ else if (isAutoDetectNamespaces())
564562
@Override /* Overridden from Serializer */
565563
protected void doSerialize(SerializerPipe out, Object o) throws SerializeException {
566564

567-
var r = (Resource)null;
568-
569565
var cm = getClassMetaForObject(o);
570566
if (isLooseCollections() && nn(cm) && cm.isCollectionOrArray()) {
571567
Collection c = cm.isCollection() ? (Collection)o : toList(cm.inner(), o);
572568
forEachEntry(c, x -> serializeAnything(x, false, object(), "root", null, null));
573569
} else {
574570
RDFNode n = serializeAnything(o, false, getExpectedRootType(o), "root", null, null);
571+
Resource r;
575572
if (n.isLiteral()) {
576573
r = model.createResource();
577574
r.addProperty(pValue, n);

juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4916,18 +4916,10 @@ final ClassMeta[] findParameters(Type o, Class c) {
49164916
if (! (o instanceof ParameterizedType)) {
49174917
while (nn(c)) {
49184918
o = c.getGenericSuperclass();
4919+
if (!(o instanceof ParameterizedType))
4920+
o = Arrays.stream(c.getGenericInterfaces()).filter(t -> t instanceof ParameterizedType).findFirst().orElse(null);
49194921
if (o instanceof ParameterizedType)
49204922
break;
4921-
boolean found = false;
4922-
for (var t : c.getGenericInterfaces()) {
4923-
o = t;
4924-
if (o instanceof ParameterizedType) {
4925-
found = true;
4926-
break;
4927-
}
4928-
}
4929-
if (found)
4930-
break;
49314923
c = c.getSuperclass();
49324924
}
49334925
}

juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ public class BeanSession extends ContextSession implements ConverterSession {
5858
private static final String PROP_locale = "locale";
5959
private static final String PROP_mediaType = "mediaType";
6060
private static final String PROP_timeZone = "timeZone";
61+
private static final String PROP_BeanSession_locale = "BeanSession.locale";
62+
private static final String PROP_BeanSession_mediaType = "BeanSession.mediaType";
63+
private static final String PROP_BeanSession_timeZone = "BeanSession.timeZone";
6164

6265
// Argument name constants for assertArgNotNull
6366
private static final String ARG_ctx = "ctx";
@@ -180,8 +183,21 @@ public Builder properties(Map<String,Object> value) {
180183

181184
@Override /* Overridden from Builder */
182185
public Builder property(String key, Object value) {
183-
super.property(key, value);
184-
return this;
186+
if (key == null) {
187+
super.property(key, value); // delegates null-key validation to base class
188+
return this;
189+
}
190+
switch (key) {
191+
case PROP_locale, PROP_BeanSession_locale:
192+
return locale(cvt(value, Locale.class));
193+
case PROP_mediaType, PROP_BeanSession_mediaType:
194+
return mediaType(cvt(value, MediaType.class));
195+
case PROP_timeZone, PROP_BeanSession_timeZone:
196+
return timeZone(cvt(value, TimeZone.class));
197+
default:
198+
super.property(key, value);
199+
return this;
200+
}
185201
}
186202

187203
/**

juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,9 @@ public synchronized String getNotABeanReason() {
650650
*
651651
* @return An empty optional, or <jk>null</jk> if this isn't an optional.
652652
*/
653+
@SuppressWarnings({
654+
"java:S2789" // null intentionally signals "not an Optional type"; callers check for null
655+
})
653656
public Optional<?> getOptionalDefault() {
654657
if (isOptional())
655658
return opt(getElementType().getOptionalDefault());
@@ -869,7 +872,7 @@ public boolean hasMutaterFrom(Class<?> c) {
869872
// array conversions from element types, which can produce false positives here.
870873
if (inner().isArray() && c.isArray())
871874
return false;
872-
// Exclude Collections and Maps: BeanSession handles collection/map conversion directly;
875+
// Exclude Collections and MapsBeanSession handles collection/map conversion directly.
873876
// BasicConverter's generic conversions produce false positives that Mutaters never did.
874877
if (Collection.class.isAssignableFrom(inner()) || Map.class.isAssignableFrom(inner()))
875878
return false;
@@ -907,7 +910,7 @@ public boolean hasMutaterTo(Class<?> c) {
907910
// array conversions from element types, which can produce false positives here.
908911
if (inner().isArray() && c.isArray())
909912
return false;
910-
// Exclude Collection/Map targets: BeanSession handles collection/map conversion directly;
913+
// Exclude Collection/Map targetsBeanSession handles collection/map conversion directly.
911914
// BasicConverter's generic conversions produce false positives that Mutaters never did.
912915
if (Collection.class.isAssignableFrom(c) || Map.class.isAssignableFrom(c))
913916
return false;

juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ContextSession.java

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.function.*;
2929

3030
import org.apache.juneau.commons.collections.*;
31+
import org.apache.juneau.commons.conversion.*;
3132
import org.apache.juneau.commons.function.*;
3233
import org.apache.juneau.commons.reflect.*;
3334

@@ -46,6 +47,7 @@ public abstract class ContextSession {
4647

4748
// Property name constants
4849
private static final String PROP_debug = "debug";
50+
private static final String PROP_ContextSession_debug = "ContextSession.debug";
4951

5052
// Argument name constants for assertArgNotNull
5153
private static final String ARG_ctx = "ctx";
@@ -66,6 +68,18 @@ public abstract static class Builder {
6668
private Context ctx;
6769
private Memoizer<LinkedHashMap<String,Object>> properties;
6870

71+
/**
72+
* Convenience method for converting values using {@link BasicConverter}.
73+
*
74+
* @param <T> The target type.
75+
* @param value The value to convert.
76+
* @param type The target class.
77+
* @return The converted value.
78+
*/
79+
protected static <T> T cvt(Object value, Class<T> type) {
80+
return BasicConverter.INSTANCE.to(value, null, null, type);
81+
}
82+
6983
/**
7084
* Constructor.
7185
*
@@ -141,28 +155,38 @@ public Builder debug(Boolean value) {
141155
public Builder properties(Map<String,Object> value) {
142156
assertArgNotNull(ARG_value, value);
143157
properties.reset();
144-
properties.get().putAll(value);
158+
value.forEach(this::property);
145159
return this;
146160
}
147161

148162
/**
149163
* Adds a property to this session.
150164
*
165+
* <p>
166+
* If the key matches a known session property (e.g. <js>"debug"</js> or <js>"ContextSession.debug"</js>),
167+
* the value is converted via {@link BasicConverter} and routed to the corresponding typed setter.
168+
* Unknown keys are stored in the raw session properties map.
169+
*
151170
* @param key The property key.
152171
* <br>Cannot be <jk>null</jk>.
153172
* @param value The property value.
154-
* <br>Can be <jk>null</jk> (removes the property).
173+
* <br>Can be <jk>null</jk> (resets typed properties to their default; removes raw properties).
155174
* @return This object.
156175
*/
157176
public Builder property(String key, Object value) {
158177
assertArgNotNull(ARG_key, key);
159-
var map = properties.get();
160-
if (value == null) {
161-
map.remove(key);
162-
} else {
163-
map.put(key, value);
178+
switch (key) {
179+
case PROP_debug, PROP_ContextSession_debug:
180+
return debug(cvt(value, Boolean.class));
181+
default:
182+
var map = properties.get();
183+
if (value == null) {
184+
map.remove(key);
185+
} else {
186+
map.put(key, value);
187+
}
188+
return this;
164189
}
165-
return this;
166190
}
167191

168192
/**

juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ public class ParserSession extends BeanSession {
6161
private static final String PROP_javaMethod = "javaMethod";
6262
private static final String PROP_listener = "listener";
6363
private static final String PROP_outer = "outer";
64+
private static final String PROP_schema = "schema";
65+
private static final String PROP_ParserSession_javaMethod = "ParserSession.javaMethod";
66+
private static final String PROP_ParserSession_outer = "ParserSession.outer";
67+
private static final String PROP_ParserSession_schema = "ParserSession.schema";
6468

6569
// Argument name constants for assertArgNotNull
6670
private static final String ARG_ctx = "ctx";
@@ -157,8 +161,21 @@ public Builder properties(Map<String,Object> value) {
157161

158162
@Override /* Overridden from Builder */
159163
public Builder property(String key, Object value) {
160-
super.property(key, value);
161-
return this;
164+
if (key == null) {
165+
super.property(key, value);
166+
return this;
167+
}
168+
switch (key) {
169+
case PROP_javaMethod, PROP_ParserSession_javaMethod:
170+
return javaMethod(cvt(value, Method.class));
171+
case PROP_outer, PROP_ParserSession_outer:
172+
return outer(value);
173+
case PROP_schema, PROP_ParserSession_schema:
174+
return schema(cvt(value, HttpPartSchema.class));
175+
default:
176+
super.property(key, value);
177+
return this;
178+
}
162179
}
163180

164181
/**

juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParserSession.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public class ReaderParserSession extends ParserSession {
4747
// Property name constants
4848
private static final String PROP_fileCharset = "fileCharset";
4949
private static final String PROP_streamCharset = "streamCharset";
50+
private static final String PROP_ReaderParserSession_fileCharset = "ReaderParserSession.fileCharset";
51+
private static final String PROP_ReaderParserSession_streamCharset = "ReaderParserSession.streamCharset";
5052

5153
// Argument name constants for assertArgNotNull
5254
private static final String ARG_ctx = "ctx";
@@ -150,8 +152,19 @@ public Builder properties(Map<String,Object> value) {
150152

151153
@Override /* Overridden from Builder */
152154
public Builder property(String key, Object value) {
153-
super.property(key, value);
154-
return this;
155+
if (key == null) {
156+
super.property(key, value);
157+
return this;
158+
}
159+
switch (key) {
160+
case PROP_fileCharset, PROP_ReaderParserSession_fileCharset:
161+
return fileCharset(cvt(value, Charset.class));
162+
case PROP_streamCharset, PROP_ReaderParserSession_streamCharset:
163+
return streamCharset(cvt(value, Charset.class));
164+
default:
165+
super.property(key, value);
166+
return this;
167+
}
155168
}
156169

157170
@Override /* Overridden from Builder */

0 commit comments

Comments
 (0)