34
34
import java .util .Random ;
35
35
import java .util .function .BiFunction ;
36
36
import java .util .function .Function ;
37
+ import java .util .function .Supplier ;
37
38
import java .util .stream .Stream ;
38
39
39
40
import javax .xml .datatype .DatatypeFactory ;
@@ -162,7 +163,7 @@ private static ObjectMapper createObjectMapper() {
162
163
}
163
164
164
165
private Map <String , Object > transformAspectProperties () {
165
- return transformProperties ( aspect .getProperties () );
166
+ return transformProperties ( aspect .getProperties (), true );
166
167
}
167
168
168
169
/**
@@ -172,15 +173,15 @@ private Map<String, Object> transformAspectProperties() {
172
173
@ SuppressWarnings ( "squid:S2250" )
173
174
// Amount of elements in list is in regard to amount of properties in Aspect Model. Even in bigger aspects this
174
175
// should not lead to performance issues
175
- private Map <String , Object > transformProperties ( final List <Property > properties ) {
176
+ private Map <String , Object > transformProperties ( final List <Property > properties , final boolean useModelExampleValue ) {
176
177
return Stream .concat (
177
178
properties .stream ().filter ( recursiveProperty ::contains ).map ( this ::recursiveProperty ),
178
179
properties .stream ()
179
180
.filter ( property -> !recursiveProperty .contains ( property ) )
180
181
.filter ( property -> !property .isAbstract () )
181
182
.map ( property -> {
182
183
recursiveProperty .add ( property );
183
- final Map <String , Object > result = transformProperty ( new BasicProperty ( property ) );
184
+ final Map <String , Object > result = transformProperty ( new BasicProperty ( property ), useModelExampleValue );
184
185
recursiveProperty .remove ( property );
185
186
return result ;
186
187
} )
@@ -207,21 +208,22 @@ private Map<String, Object> recursiveProperty( final Property property ) {
207
208
* @param property the property to transform
208
209
* @return a map representing the property names as key and the property values as value
209
210
*/
210
- private Map <String , Object > transformProperty ( final BasicProperty property ) {
211
+ private Map <String , Object > transformProperty ( final BasicProperty property , final boolean useModelExampleValue ) {
211
212
return transformers .stream ()
212
- .map ( transformer -> transformer .apply ( property ) )
213
+ .map ( transformer -> transformer .apply ( property , useModelExampleValue ) )
213
214
.filter ( propertiesMap -> !propertiesMap .isEmpty () )
214
215
.findFirst ()
215
216
.orElseThrow ( () -> new IllegalArgumentException ( "No transformer for " + property .getName () + " available." ) );
216
217
}
217
218
218
- private Map <String , Object > transformCollectionProperty ( final BasicProperty property ) {
219
+ private Map <String , Object > transformCollectionProperty ( final BasicProperty property , final boolean useModelExampleValue ) {
219
220
final Characteristic characteristic = property .getCharacteristic ();
220
221
if ( characteristic .is ( Collection .class ) ) {
221
222
final List <Object > collectionValues = getCollectionValues ( property , (Collection ) characteristic );
222
223
return toMap ( property .getName (), collectionValues );
223
224
} else if ( isConstrainedCollection ( characteristic ) ) {
224
- return toMap ( property .getName (), getCollectionValues ( property , characteristic .as ( Trait .class ).getBaseCharacteristic ().as ( Collection .class ) ) );
225
+ return toMap ( property .getName (), getCollectionValues ( property , characteristic .as ( Trait .class ).getBaseCharacteristic ().as ( Collection .class ),
226
+ (LengthConstraint ) characteristic .as ( Trait .class ).getConstraints ().get ( 0 ) ) );
225
227
}
226
228
return ImmutableMap .of ();
227
229
}
@@ -235,23 +237,23 @@ private boolean isConstrainedCollection( final Characteristic characteristic ) {
235
237
trait .getConstraints ().get ( 0 ).is ( LengthConstraint .class );
236
238
}
237
239
238
- private Map <String , Object > transformAbstractEntityProperty ( final BasicProperty property ) {
240
+ private Map <String , Object > transformAbstractEntityProperty ( final BasicProperty property , final boolean useModelExampleValue ) {
239
241
final Optional <AbstractEntity > dataType = getForCharacteristic ( property .getCharacteristic (), AbstractEntity .class );
240
242
if ( dataType .isPresent () ) {
241
243
final AbstractEntity abstractEntity = dataType .get ();
242
244
final ComplexType extendingComplexType = abstractEntity .getExtendingElements ().get ( 0 );
243
- final Map <String , Object > generatedProperties = transformProperties ( extendingComplexType .getAllProperties () );
245
+ final Map <String , Object > generatedProperties = transformProperties ( extendingComplexType .getAllProperties (), useModelExampleValue );
244
246
generatedProperties .put ( "@type" , extendingComplexType .getName () );
245
247
return toMap ( property .getName (), generatedProperties );
246
248
}
247
249
return ImmutableMap .of ();
248
250
}
249
251
250
- private Map <String , Object > transformEntityProperty ( final BasicProperty property ) {
252
+ private Map <String , Object > transformEntityProperty ( final BasicProperty property , final boolean useModelExmplevalue ) {
251
253
final Optional <Entity > dataType = getForCharacteristic ( property .getCharacteristic (), Entity .class );
252
254
if ( dataType .isPresent () ) {
253
255
final Entity entity = dataType .get ();
254
- final Map <String , Object > generatedProperties = transformProperties ( entity .getAllProperties () );
256
+ final Map <String , Object > generatedProperties = transformProperties ( entity .getAllProperties (), useModelExmplevalue );
255
257
if ( entity .getExtends ().isPresent () ) {
256
258
generatedProperties .put ( "@type" , entity .getName () );
257
259
}
@@ -260,7 +262,7 @@ private Map<String, Object> transformEntityProperty( final BasicProperty propert
260
262
return ImmutableMap .of ();
261
263
}
262
264
263
- private Map <String , Object > transformEnumeration ( final BasicProperty property ) {
265
+ private Map <String , Object > transformEnumeration ( final BasicProperty property , final boolean useModelExampleValue ) {
264
266
return getForCharacteristic ( property .getCharacteristic (), Enumeration .class )
265
267
.map ( enumeration -> extractEnumerationValues ( property , enumeration ) )
266
268
.orElseGet ( ImmutableMap ::of );
@@ -271,24 +273,24 @@ private Map<String, Object> extractEnumerationValues( final BasicProperty proper
271
273
return toMap ( property .getName (), firstValue .accept ( valueToPayloadStructure , null ) );
272
274
}
273
275
274
- private Map <String , Object > transformEitherProperty ( final BasicProperty property ) {
276
+ private Map <String , Object > transformEitherProperty ( final BasicProperty property , final boolean useModelExampleValue ) {
275
277
final Characteristic characteristic = property .getCharacteristic ();
276
278
return getForCharacteristic ( characteristic , Either .class )
277
279
.map ( value -> transformProperty (
278
- new BasicProperty ( AspectModelJsonPayloadGenerator .EITHER_LEFT , value .getLeft (), Optional .empty () ) ) )
280
+ new BasicProperty ( AspectModelJsonPayloadGenerator .EITHER_LEFT , value .getLeft (), Optional .empty () ), useModelExampleValue ) )
279
281
.map ( value -> toMap ( property .getName (), value ) )
280
282
.orElseGet ( ImmutableMap ::of );
281
283
}
282
284
283
- private Map <String , Object > transformSimpleProperty ( final BasicProperty basicProperty ) {
284
- return toMap ( basicProperty .getName (), getExampleValueOrElseRandom ( basicProperty ) );
285
+ private Map <String , Object > transformSimpleProperty ( final BasicProperty basicProperty , final boolean useModelExampleValue ) {
286
+ return toMap ( basicProperty .getName (), getExampleValueOrElseRandom ( basicProperty , useModelExampleValue ) );
285
287
}
286
288
287
289
/**
288
290
* @param property the property to transform
289
291
* @return the {@link Property#getExampleValue()} or if absent a random value.
290
292
*/
291
- private Object getExampleValueOrElseRandom ( final BasicProperty property ) {
293
+ private Object getExampleValueOrElseRandom ( final BasicProperty property , final boolean useModelExampleValue ) {
292
294
final Characteristic characteristic = property .getCharacteristic ();
293
295
if ( characteristic .is ( State .class ) ) {
294
296
return characteristic .as ( State .class ).getDefaultValue ();
@@ -303,6 +305,10 @@ private Object getExampleValueOrElseRandom( final BasicProperty property ) {
303
305
}
304
306
final Characteristic effectiveCharacteristics = elementCharacteristics .orElse ( characteristic );
305
307
308
+ if ( !useModelExampleValue ) {
309
+ return generateExampleValue ( effectiveCharacteristics );
310
+ }
311
+
306
312
return property .getExampleValue ().map ( exampleValue ->
307
313
exampleValue .as ( ScalarValue .class ).getValue () ).orElseGet ( () -> generateExampleValue ( effectiveCharacteristics ) );
308
314
}
@@ -312,21 +318,37 @@ private Map<String, Object> toMap( final String key, final Object value ) {
312
318
}
313
319
314
320
private List <Object > getCollectionValues ( final BasicProperty property , final Collection collection ) {
321
+ return getCollectionValues ( property , collection , null );
322
+ }
323
+
324
+ private List <Object > getCollectionValues ( final BasicProperty property , final Collection collection , final LengthConstraint lengthConstraint ) {
315
325
final Type dataType = collection .getDataType ().orElseThrow ( () -> new IllegalArgumentException ( "DataType for collection is required." ) );
326
+
327
+ if ( dataType .is ( Scalar .class ) ) {
328
+ final Object payload = getExampleValueOrElseRandom ( property , lengthConstraint == null );
329
+ return payload instanceof List ? (List ) payload : ImmutableList .of ( payload );
330
+ }
331
+
332
+ final BigInteger minLength = lengthConstraint == null ? BigInteger .ONE : lengthConstraint .getMinValue ().orElse ( BigInteger .ONE );
333
+ final List <Object > returnValues = new ArrayList <>();
334
+ // Fill in minLength elements
335
+ for ( int i = 0 ; i < minLength .intValue (); i ++ ) {
336
+ returnValues .add ( generateCollectionValue ( dataType , minLength .intValue () ) );
337
+ }
338
+ return returnValues ;
339
+ }
340
+
341
+ private Object generateCollectionValue ( final Type dataType , final int minCount ) {
316
342
if ( dataType .is ( AbstractEntity .class ) ) {
317
343
final AbstractEntity abstractEntity = dataType .as ( AbstractEntity .class );
318
344
final ComplexType extendingComplexType = abstractEntity .getExtendingElements ().get ( 0 );
319
- final Map <String , Object > propertyValueMap = transformProperties ( extendingComplexType .getAllProperties () );
345
+ final Map <String , Object > propertyValueMap = transformProperties ( extendingComplexType .getAllProperties (), minCount < 2 );
320
346
propertyValueMap .put ( "@type" , extendingComplexType .getName () );
321
- return ImmutableList . of ( propertyValueMap ) ;
347
+ return propertyValueMap ;
322
348
}
323
349
if ( dataType .is ( Entity .class ) ) {
324
350
final Entity entity = dataType .as ( Entity .class );
325
- return ImmutableList .of ( transformProperties ( entity .getAllProperties () ) );
326
- }
327
- if ( dataType .is ( Scalar .class ) ) {
328
- final Object payload = getExampleValueOrElseRandom ( property );
329
- return payload instanceof List ? (List ) payload : ImmutableList .of ( payload );
351
+ return transformProperties ( entity .getAllProperties (), minCount < 2 );
330
352
}
331
353
throw new IllegalArgumentException ( String .format ( "DataType %s is unknown" , dataType ) );
332
354
}
@@ -348,7 +370,7 @@ private Object generateExampleValue( final Characteristic characteristic ) {
348
370
* Transforms an {@link BasicProperty} to a map.
349
371
* If no transformation can be applied, an empty map will returned.
350
372
*/
351
- private interface Transformer extends Function <BasicProperty , Map <String , Object >> {
373
+ private interface Transformer extends BiFunction <BasicProperty , Boolean , Map <String , Object >> {
352
374
}
353
375
354
376
private static class BasicProperty {
@@ -495,30 +517,40 @@ private Optional<DateFormat> getDateFormat( final String urn ) {
495
517
}
496
518
497
519
@ SuppressWarnings ( "unchecked" )
498
- private Object getRandomValue ( final LengthConstraint lengthConstraint ,
499
- final java .lang .reflect .Type exampleValueType , final Characteristic traitBaseCharacteristic ) {
500
- final BigInteger maxLength = lengthConstraint .getMaxValue ().orElse ( BigInteger .valueOf ( Integer .MAX_VALUE ) );
501
- final BigInteger minLength = lengthConstraint .getMinValue ().orElse ( BigInteger .ZERO );
502
-
520
+ private Object getRandomValue ( final LengthConstraint lengthConstraint , final java .lang .reflect .Type exampleValueType ,
521
+ final Characteristic traitBaseCharacteristic ) {
503
522
if ( traitBaseCharacteristic .is ( Collection .class ) ) {
504
- final List <Object > returnValues = new ArrayList <>();
505
- // Fill in minLength elements
506
- for ( int i = 0 ; i < minLength .intValue (); i ++ ) {
507
- returnValues .add ( defaultEasyRandom .nextObject ( (Class <?>) exampleValueType ) );
508
- }
509
- // Add between minLength and maxLength-minLength elements, but not more than 5
510
- final int amount = getRandomInteger ( minLength .intValue (), Math .min ( maxLength .intValue () - minLength .intValue (), 5 ) );
511
- for ( int i = 0 ; i < amount ; i ++ ) {
512
- returnValues .add ( defaultEasyRandom .nextObject ( (Class <?>) exampleValueType ) );
513
- }
514
- return returnValues ;
523
+ return getRandomValues ( lengthConstraint , () -> defaultEasyRandom .nextObject ( (Class <?>) exampleValueType ) );
515
524
}
516
525
526
+ final BigInteger maxLength = lengthConstraint .getMaxValue ().orElse ( BigInteger .valueOf ( 30 ) );
527
+ final BigInteger minLength = lengthConstraint .getMinValue ().orElse ( BigInteger .ZERO );
517
528
final EasyRandomParameters easyRandomParameters = new EasyRandomParameters ().stringLengthRange ( minLength .intValue (), maxLength .intValue () );
518
529
final EasyRandom easyRandom = new EasyRandom ( easyRandomParameters );
519
530
return easyRandom .nextObject ( (Class <?>) exampleValueType );
520
531
}
521
532
533
+ public List <Object > getRandomValues ( final LengthConstraint lengthConstraint , final Supplier <Object > valueGenerator ) {
534
+ final BigInteger maxLength =
535
+ lengthConstraint == null ? BigInteger .ONE : lengthConstraint .getMaxValue ().orElse ( BigInteger .valueOf ( Integer .MAX_VALUE ) );
536
+ final BigInteger minLength = lengthConstraint == null ? BigInteger .ONE : lengthConstraint .getMinValue ().orElse ( BigInteger .ZERO );
537
+
538
+ final List <Object > returnValues = new ArrayList <>();
539
+ // Fill in minLength elements
540
+ for ( int i = 0 ; i < minLength .intValue (); i ++ ) {
541
+ returnValues .add ( valueGenerator .get () );
542
+ }
543
+ if ( minLength .intValue () == maxLength .intValue () ) {
544
+ return returnValues ;
545
+ }
546
+ // Add between minLength and maxLength-minLength elements, but not more than 5
547
+ final int amount = getRandomInteger ( minLength .intValue (), Math .min ( maxLength .intValue () - minLength .intValue (), 5 ) );
548
+ for ( int i = 0 ; i < amount ; i ++ ) {
549
+ returnValues .add ( valueGenerator .get () );
550
+ }
551
+ return returnValues ;
552
+ }
553
+
522
554
private Number getRandomValue ( final RangeConstraint rangeConstraint , final java .lang .reflect .Type valueType , final Resource dataTypeResource ) {
523
555
final Number min = calculateLowerBound ( rangeConstraint , valueType , dataTypeResource );
524
556
final Number max = calculateUpperBound ( rangeConstraint , valueType , dataTypeResource );
0 commit comments