Skip to content

Commit c912c9c

Browse files
committed
v1.6.0: Java modules support
1 parent 24ee213 commit c912c9c

File tree

88 files changed

+1925
-1604
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+1925
-1604
lines changed

README.md

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -60,31 +60,44 @@ for a higher control compared to the EasyML Facade.
6060

6161
### Release Notes
6262

63-
!Release 1.5.2
63+
Release 1.6.0 (requires Java 9, recommended up to Java 17)
64+
- XMLWriter and XMLReader use getters and setters.
65+
- feature: support for Java 9 modules.
66+
- NON-BACKWARD COMPATIBLE refactor of ReflectionUtil.
67+
68+
69+
Release 1.5.3
70+
- refactor: remove deprecated Class.newInstance() usages.
71+
- refactor: limited reflection usage from Properties, EnumSet, EnumMap,
72+
SingletonList, SingletonSet, SingletonMap strategies.
73+
- feature: added java.util.concurrent.atomic strategies.
74+
- feature: added java.util.Collections emptyList, emptyMap, emptySet strategies.
75+
76+
77+
Release 1.5.2 (requires Java 8, recommended up to Java 9)
6478
- feature: added generic mechanism for cache clearing.
6579

6680

67-
!Release 1.5.1
81+
Release 1.5.1
6882
- feature: added functional API.
6983
- feature: added CalendarStrategy and OptionalStrategy.
7084
- feature: added java.time strategies.
7185
- performance: added caching to SerializableStrategy.
7286
- refactor: remove Profile feature.
7387

7488

75-
!Release 1.5.0
76-
- requires Java 8 or later.
89+
Release 1.5.0 (requires Java 8)
90+
- feature: support for Java 9 security.
7791
- NON-BACKWARD COMPATIBLE refactor of ReflectionUtil.
78-
- feature: support for Java 9 security model.
7992

8093

81-
!Release 1.4.7
94+
Release 1.4.7
8295
- last Java 7 compatible release.
8396
- bugfix: performance regression in Serialization strategy.
8497
- remove AccessibleObject.isAccessible calls.
8598

8699

87-
!Release 1.4.6
100+
Release 1.4.6
88101
- remove deprecated v1.3.4 object-o and array-o strategies.
89102
- replaced MarshalContext aliasFor methods with aliasOrNameFor methods.
90103
- bugfix: EnumStrategy marshalling fix.
@@ -93,20 +106,20 @@ for a higher control compared to the EasyML Facade.
93106
- feature: added serialization serialPersistentFields support.
94107

95108

96-
!Release 1.4.5
109+
Release 1.4.5
97110
- performance: improved n.s.e.EasyML.deserialize() speed by reusing the
98111
XmlPullParser when available.
99112
- refactor: minor code improvements.
100113

101114

102-
!Release 1.4.4
115+
Release 1.4.4
103116
- refactor: made n.s.e.m.CompositeStrategy.unmarshalInit return type more
104117
loose to better support readResolve in n.s.e.m.j.i.ExternalizableStrategy.
105118
- refactor: n.s.e.XMLReader and n.s.e.XMLWriter use HashMap instead of
106119
ConcurrentHashMap if not in shared mode (i.e. if in standalone mode).
107120

108121

109-
!Release 1.4.3
122+
Release 1.4.3
110123
- feature: new n.s.e.m.j.i.ExternalizableStrategy offers support for the
111124
Java Externalizable protocol.
112125
- feature: new n.s.e.XMLReader.hasMore method.
@@ -116,35 +129,40 @@ EasyML.Profile.Generic for more portable XML.
116129
object input and output streams.
117130

118131

119-
!Release 1.4.2
132+
Release 1.4.2
120133
- bugfix: n.s.e.m.j.i.SerializableStrategy GetFieldImpl readFields fix.
121134

122135

123-
!Release 1.4.1
136+
Release 1.4.1
124137
- bugfix: XMLWriter text driver empty line when pretty printing.
125138

126139

127-
!Release 1.4.0
140+
Release 1.4.0
128141
- NON-BACKWARD COMPATIBLE refactor: EasyML now immutable(removed setters).
129142
- feature: EasyMLBuilder for easyml customization.
130143

131144

132-
!Release 1.3.10
145+
Release 1.3.11
146+
- bugfix: n.s.e.m.j.i.SerializableStrategy GetFieldImpl readFields fix.
147+
- bugfix: XMLWriter text driver startElement impl improvement.
148+
149+
150+
Release 1.3.10
133151
- bugfix: XMLWriter text driver empty line when pretty printing.
134152
- javadoc: improvements.
135153

136154

137-
!Release 1.3.9
155+
Release 1.3.9
138156
- feature: EasyML, XMLReader, XMLWriter custom XML root tag setting.
139157
- refactor: source level 1.7 warnings fixed.
140158

141159

142-
!Release 1.3.8
160+
Release 1.3.8
143161
- performance: EasyML cache reflected class constructors.
144162
- feature: EasyML, XMLReader, XMLWriter clearCache() methods.
145163

146164

147-
!Release 1.3.7
165+
Release 1.3.7
148166
- performance: EasyML and XMLReader cache reflected classes and fields.
149167
This is done via n.s.e.m.UnmarshalContext's classFor() and fieldFor().
150168
Distinct EasyML instances have separate caches.
@@ -154,13 +172,13 @@ XMLReaders share caches only when isSharedConfiguration().
154172
- bugfix: remove duplicate encoded.clear() from XMLWriter.reset().
155173

156174

157-
!Release 1.3.6
175+
Release 1.3.6
158176
- feature: added n.s.e.EasyML.releaseCurrentReader()
159-
and n.s.e.EasyML.releaseCurrentWriter() methods.
177+
and n.s.e.EasyML.releaseCurrentWriter() methods.
160178
- performance: removed the redundant easyml version attribute.
161179

162180

163-
!Release 1.3.5
181+
Release 1.3.5
164182
- performance: reduced the impact of class aliasing and field aliasing
165183
features, even when NOT used, on serialize() and deserialize() times.
166184
- performance: n.s.e.u.ReflectionUtil unsafe instantiation method now
@@ -172,7 +190,7 @@ security reasons.
172190
it was deprecated since version 1.2.2.
173191
- refactor: renamed "object-o", "array-o" to "objectx", "arrayx"
174192
- bugfix: object field values could get inverted at read if ALL of the
175-
following conditions hold:
193+
following conditions hold:
176194
1. skipDefaults is enabled.
177195
2. instance has same name fields on different inheritance levels.
178196
3. instance defines default values on each level.
@@ -184,32 +202,32 @@ XML outputted by versions 1.3.5 down to 1.2.1 and will produce only
184202
1.3.5 formatted XML.
185203

186204

187-
!Release 1.3.4
205+
Release 1.3.4
188206
- performance: n.s.e.XMLWriterTextDriver improvements allow EasyML to
189-
perform up to 20% faster. The performance improvement is more
190-
pronounced when pretty printing is enabled.
207+
perform up to 20% faster. The performance improvement is more
208+
pronounced when pretty printing is enabled.
191209

192210

193-
!Release 1.3.3
211+
Release 1.3.3
194212
- doc: better javadoc for n.s.e.EasyML, n.s.e.XMLReader, n.s.e.XMLWriter.
195213
- bugfix: include position descriptor in each InvalidFormatException case.
196214
- bugfix: n.s.e.XMLReaderTextDriver.consumeFully() fix.
197215

198216

199-
!Release 1.3.2
217+
Release 1.3.2
200218
- performance: n.s.e.EasyML serialize() and deserialize() methods use
201219
ThreadLocal internally for XMLWriter and XMLReader instance reuse,
202220
in order to improve performance, while remaining thread-safe.
203221

204222

205-
!Release 1.3.1
223+
Release 1.3.1
206224
- feature: added n.s.e.EasyML newReader() and newWriter methods in order
207225
to expose more API features at facade level.
208226
- bugfix: prevent shared-config readers and writers from allowing config
209227
modifications.
210228

211229

212-
!Release 1.3.0
230+
Release 1.3.0
213231
- NON-BACKWARD COMPATIBLE refactor:
214232
merged n.s.e.ExtendedEasyML into n.s.e.EasyML.
215233
- feature: n.s.e.EasyML facade is now thread-safe while the thread-unsafe
@@ -222,25 +240,3 @@ multithread features.
222240
Note: except for the last mentioned bugfix, all other changes were made
223241
to offer an easier and faster API for multithreaded environments.
224242

225-
226-
!Release 1.2.6
227-
- feature: fail first security policy enforcement for n.s.e.XMLReader
228-
readObject and readArray.
229-
- bugfix: security policy now validates params at add and addHierarchy.
230-
- bugfix: consume remaining XML on security policy exception, to allow
231-
subsequent reads, if possible.
232-
- bugfix: better XMLWriter and XMLReader close method impls.
233-
234-
235-
!Release 1.2.5
236-
- feature: n.s.e.EasyML and n.s.e.XMLReader: new securityPolicy settings
237-
used to configure, if needed, black- or whitelists for objects found at
238-
deserialization time.
239-
240-
241-
!Release 1.2.4
242-
- NON-BACKWARD COMPATIBLE refactor: n.s.e.m.CompositeStrategy: removed the
243-
"defTarget" parameter as it was only used when skipDefaults was true
244-
and it was buggy in some cases such as a bean setting a property in a
245-
default sub-bean (composition, not inheritance) within it's default constructor.
246-

easyml/src/net/sourceforge/easyml/EasyML.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
import net.sourceforge.easyml.marshalling.java.time.*;
3333
import net.sourceforge.easyml.marshalling.java.util.*;
3434
import net.sourceforge.easyml.marshalling.java.util.concurrent.ConcurrentHashMapStrategy;
35+
import net.sourceforge.easyml.marshalling.java.util.concurrent.atomic.AtomicBooleanStrategy;
36+
import net.sourceforge.easyml.marshalling.java.util.concurrent.atomic.AtomicIntegerStrategy;
37+
import net.sourceforge.easyml.marshalling.java.util.concurrent.atomic.AtomicLongStrategy;
38+
import net.sourceforge.easyml.marshalling.java.util.concurrent.atomic.AtomicReferenceStrategy;
3539
import net.sourceforge.easyml.marshalling.java.util.regex.PatternStrategy;
3640
import org.w3c.dom.Document;
3741
import org.xmlpull.v1.XmlPullParser;
@@ -80,7 +84,7 @@
8084
* objects.<br/>
8185
*
8286
* @author Victor Cordis ( cordis.victor at gmail.com)
83-
* @version 1.5.1
87+
* @version 1.5.3
8488
* @see XMLReader
8589
* @see XMLWriter
8690
* @since 1.0
@@ -246,6 +250,9 @@ public static void defaultConfiguration(XMLWriter writer) {
246250
composite.add(CalendarStrategy.INSTANCE);
247251
composite.add(EnumMapStrategy.INSTANCE);
248252
composite.add(EnumSetStrategy.INSTANCE);
253+
composite.add(EmptyListStrategy.INSTANCE);
254+
composite.add(EmptyMapStrategy.INSTANCE);
255+
composite.add(EmptySetStrategy.INSTANCE);
249256
composite.add(HashMapStrategy.INSTANCE);
250257
composite.add(HashSetStrategy.INSTANCE);
251258
composite.add(HashtableStrategy.INSTANCE);
@@ -262,10 +269,16 @@ public static void defaultConfiguration(XMLWriter writer) {
262269
composite.add(StackStrategy.INSTANCE);
263270
composite.add(TreeMapStrategy.INSTANCE);
264271
composite.add(TreeSetStrategy.INSTANCE);
272+
simple.add(TimeZoneStrategy.INSTANCE);
265273
simple.add(UUIDStrategy.INSTANCE);
266274
composite.add(VectorStrategy.INSTANCE);
267275
// util.concurrent:
268276
composite.add(ConcurrentHashMapStrategy.INSTANCE);
277+
// util.concurrent.atomic:
278+
simple.add(AtomicBooleanStrategy.INSTANCE);
279+
simple.add(AtomicIntegerStrategy.INSTANCE);
280+
simple.add(AtomicLongStrategy.INSTANCE);
281+
composite.add(AtomicReferenceStrategy.INSTANCE);
269282
// util.regex:
270283
composite.add(PatternStrategy.INSTANCE);
271284
}
@@ -330,6 +343,9 @@ public static void defaultConfiguration(XMLReader reader) {
330343
composite.put(CalendarStrategy.NAME, CalendarStrategy.INSTANCE);
331344
composite.put(EnumMapStrategy.NAME, EnumMapStrategy.INSTANCE);
332345
composite.put(EnumSetStrategy.NAME, EnumSetStrategy.INSTANCE);
346+
composite.put(EmptyListStrategy.NAME, EmptyListStrategy.INSTANCE);
347+
composite.put(EmptyMapStrategy.NAME, EmptyMapStrategy.INSTANCE);
348+
composite.put(EmptySetStrategy.NAME, EmptySetStrategy.INSTANCE);
333349
composite.put(HashMapStrategy.NAME, HashMapStrategy.INSTANCE);
334350
composite.put(HashSetStrategy.NAME, HashSetStrategy.INSTANCE);
335351
composite.put(HashtableStrategy.NAME, HashtableStrategy.INSTANCE);
@@ -346,10 +362,16 @@ public static void defaultConfiguration(XMLReader reader) {
346362
composite.put(StackStrategy.NAME, StackStrategy.INSTANCE);
347363
composite.put(TreeMapStrategy.NAME, TreeMapStrategy.INSTANCE);
348364
composite.put(TreeSetStrategy.NAME, TreeSetStrategy.INSTANCE);
365+
simple.put(TimeZoneStrategy.NAME, TimeZoneStrategy.INSTANCE);
349366
simple.put(UUIDStrategy.NAME, UUIDStrategy.INSTANCE);
350367
composite.put(VectorStrategy.NAME, VectorStrategy.INSTANCE);
351368
// util.concurrent:
352369
composite.put(ConcurrentHashMapStrategy.NAME, ConcurrentHashMapStrategy.INSTANCE);
370+
// util.concurrent.atomic:
371+
simple.put(AtomicBooleanStrategy.NAME, AtomicBooleanStrategy.INSTANCE);
372+
simple.put(AtomicIntegerStrategy.NAME, AtomicIntegerStrategy.INSTANCE);
373+
simple.put(AtomicLongStrategy.NAME, AtomicLongStrategy.INSTANCE);
374+
composite.put(AtomicReferenceStrategy.NAME, AtomicReferenceStrategy.INSTANCE);
353375
// util.regex:
354376
composite.put(PatternStrategy.NAME, PatternStrategy.INSTANCE);
355377
}

easyml/src/net/sourceforge/easyml/XMLReader.java

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@
2020

2121
import net.sourceforge.easyml.marshalling.*;
2222
import net.sourceforge.easyml.marshalling.dtd.*;
23-
import net.sourceforge.easyml.marshalling.java.io.SerializableStrategy;
2423
import net.sourceforge.easyml.marshalling.java.lang.*;
2524
import net.sourceforge.easyml.util.ReflectionUtil;
26-
import net.sourceforge.easyml.util.ValueType;
25+
import net.sourceforge.easyml.util.ReflectionUtil.ValueType;
2726
import net.sourceforge.easyml.util.XMLUtil;
2827
import org.w3c.dom.Document;
2928
import org.xmlpull.v1.XmlPullParser;
@@ -32,7 +31,10 @@
3231
import java.io.InputStream;
3332
import java.io.InputStreamReader;
3433
import java.io.Reader;
35-
import java.lang.reflect.*;
34+
import java.lang.reflect.Array;
35+
import java.lang.reflect.Field;
36+
import java.lang.reflect.InvocationTargetException;
37+
import java.lang.reflect.Modifier;
3638
import java.text.ParseException;
3739
import java.text.SimpleDateFormat;
3840
import java.util.*;
@@ -63,7 +65,7 @@
6365
* shared configuration can be created, via constructors.
6466
*
6567
* @author Victor Cordis ( cordis.victor at gmail.com)
66-
* @version 1.5.1
68+
* @version 1.6.0
6769
* @see XMLWriter
6870
* @since 1.0
6971
*/
@@ -646,12 +648,12 @@ public void alias(Class c, String alias) {
646648
alias0(c, alias);
647649
}
648650

649-
private void alias0(Object toAlias, String alias) {
651+
private void alias0(Object aliased, String alias) {
650652
if (alias == null || alias.isEmpty() || !XMLUtil.isLegalXMLText(alias)) {
651653
throw new IllegalArgumentException("alias: null, empty, or contains illegal XML chars: " + alias);
652654
}
653655
this.checkNotSharedConfiguration();
654-
this.cachedAliasingReflection.put(alias, toAlias);
656+
this.cachedAliasingReflection.put(alias, aliased);
655657
}
656658

657659
/**
@@ -908,20 +910,25 @@ private Object read0(Class componentType) {
908910
return this.readArray0(componentType); // also consumes element end.
909911
}
910912
throw new InvalidFormatException(this.driver.positionDescriptor(), "invalid element start: " + localPartName);
911-
} catch (ClassNotFoundException iB) {
912-
throw new InvalidFormatException(this.driver.positionDescriptor(), "unknown object class: " + iB.getMessage(), iB);
913-
} catch (InstantiationException iDC) {
914-
throw new InvalidFormatException(this.driver.positionDescriptor(), "invalid object constructor: " + iDC.getMessage(), iDC);
915-
} catch (IllegalAccessException iDC) {
916-
throw new InvalidFormatException(this.driver.positionDescriptor(), "invalid object constructor modifier: " + iDC.getMessage(), iDC);
913+
} catch (ClassNotFoundException ex) {
914+
throw new InvalidFormatException(this.driver.positionDescriptor(), "unknown element class: " + ex.getMessage(), ex);
915+
} catch (NoSuchMethodException ex) {
916+
throw new InvalidFormatException(this.driver.positionDescriptor(), "invalid element class: " + ex.getMessage(), ex);
917+
} catch (IllegalAccessException ex) {
918+
throw new InvalidFormatException(this.driver.positionDescriptor(), "invalid element class: " + ex.getMessage(), ex);
919+
} catch (InstantiationException ex) {
920+
throw new InvalidFormatException(this.driver.positionDescriptor(), "failed element class instantiation: " + ex.getMessage(), ex);
921+
} catch (InvocationTargetException ex) {
922+
throw new InvalidFormatException(this.driver.positionDescriptor(), "failed element class invocation: " + ex.getMessage(), ex);
917923
}
918924
}
919925

920926
// read0: readObj:
921-
private Object readObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
927+
private Object readObject()
928+
throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
922929
// read object attributes and create instance and mark it as visited:
923930
Class cls = this.context.classFor(this.driver.elementRequiredAttribute(DTD.ATTRIBUTE_CLASS));
924-
final Object ret = cls.newInstance();
931+
final Object ret = ReflectionUtil.instantiate(cls);
925932
// security check:
926933
this.ensureSecurityPolicy(ret);
927934
this.decoded.put(this.driver.elementRequiredAttribute(DTD.ATTRIBUTE_ID), ret);
@@ -942,15 +949,18 @@ private Object readObject() throws ClassNotFoundException, InstantiationExceptio
942949
cls = cls.getSuperclass();
943950
}
944951
// check if field is indeed an instance property:
945-
if (f == null || !ReflectionUtil.isFieldProperty(f)) {
952+
if (f == null) {
946953
throw new InvalidFormatException(this.driver.positionDescriptor(), "undefined property: " + cls.getName() + '.' + localPartName);
947954
}
948-
ReflectionUtil.setAccessible(f);
955+
final ReflectionUtil.FieldInfo fi = ReflectionUtil.fieldInfoForWrite(f);
956+
if (!fi.isProperty) {
957+
throw new InvalidFormatException(this.driver.positionDescriptor(), "not a property: " + cls.getName() + '.' + localPartName);
958+
}
949959
// move down in the property value and read it:
950960
if (!this.driver.next() || !this.driver.atElementStart()) {
951961
throw new InvalidFormatException(this.driver.positionDescriptor(), "expected element start");
952962
}
953-
f.set(ret, this.read0(f.getType().getComponentType()));
963+
ReflectionUtil.writeProperty(ret, this.read0(f.getType().getComponentType()), f, fi.accessor);
954964
} else if (this.driver.atElementEnd() && this.driver.elementName().equals(DTD.ELEMENT_OBJECT)) {
955965
this.driver.next(); // consume object element end.
956966
return ret;

0 commit comments

Comments
 (0)