// Sort buckets and test names, to have consistent iterator
final SortedSet<String> sortedTestNames = new TreeSet<String>(tests.keySet());
for (String testName : sortedTestNames) {
final Set<Map<String, ?>> buckets = Sets.newLinkedHashSet();
final TestSpecification testSpecification = tests.get(testName);
final Entry<String, Integer>[] sortedBuckets = testSpecification.getBuckets().entrySet().toArray(new Map.Entry[testSpecification.getBuckets().size()]);
Arrays.sort(sortedBuckets, new Comparator<Entry<String, Integer>>() {
public int compare(final Entry<String, Integer> e0, final Entry<String, Integer> e1) {
if(e0.getValue().intValue() < e1.getValue().intValue()) {
return -1;
}
return e0.getValue() == e1.getValue() ? 0 : 1;
}
});
boolean foundFallbackValue = false;
for (final Entry<String, Integer> bucket : sortedBuckets) {
final String bucketName = bucket.getKey();
final String enumName = toEnumName(bucketName);
final Map<String, Object> bucketDef = Maps.newHashMap();
final String normalizedBucketName = toJavaIdentifier(bucketName);
bucketDef.put("value", bucket.getValue());
bucketDef.put("name", bucketName);
bucketDef.put("normalizedName", normalizedBucketName);
bucketDef.put("enumName", enumName);
bucketDef.put("javaClassName", uppercaseFirstChar(normalizedBucketName));
buckets.add(bucketDef);
foundFallbackValue = foundFallbackValue || (bucket.getValue() == testSpecification.getFallbackValue());
}
if (! foundFallbackValue) {
throw new IllegalArgumentException("Specified fallback value " + testSpecification.getFallbackValue() + " for test " + testName + " is not in the list of standard values: " + Arrays.toString(sortedBuckets));
}
final String name = toJavaIdentifier(testName);
final String enumName = toEnumName(name);
final Map<String, Object> testDef = Maps.newHashMap();
testDef.put("name", testName);
testDef.put("normalizedName", name);
testDef.put("enumName", enumName);
testDef.put("javaClassName", uppercaseFirstChar(name));
testDef.put("buckets", buckets);
testDef.put("defaultValue", testSpecification.getFallbackValue());
final List<Map<String, String>> nestedPayloadsList = new ArrayList<Map<String,String>>();
// Only define testDef.payloadJavaClass if the API user has
// claimed she expects a payload.
if (testSpecification.getPayload() != null) {
final String specifiedPayloadTypeName = testSpecification.getPayload().getType();
final PayloadType specifiedPayloadType = PayloadType.payloadTypeForName(specifiedPayloadTypeName);
if(specifiedPayloadType == PayloadType.MAP) {
testDef.put("isMap","true");
for(Map.Entry<String,String> entry : testSpecification.getPayload().getSchema().entrySet()) {
final Map<String,String> nestedPayloadsMap = Maps.newHashMap();
nestedPayloadsMap.put("key",entry.getKey());
final PayloadType payloadTypeForValue = PayloadType.payloadTypeForName(entry.getValue());
if(payloadTypeForValue != PayloadType.MAP) {
nestedPayloadsMap.put("value", payloadTypeForValue.javaClassName);
nestedPayloadsMap.put("valueWithoutArray",
payloadTypeForValue.javaClassName.substring(0, payloadTypeForValue.javaClassName.length() - 2));
if (PayloadType.STRING_ARRAY == payloadTypeForValue) {
nestedPayloadsMap.put("notANumber", "true");
}
nestedPayloadsMap.put("payloadTypeName", payloadTypeForValue.payloadTypeName);
nestedPayloadsList.add(nestedPayloadsMap);
} else {
throw new IllegalArgumentException("Nested Map Payloads are not allowed");
}
}
}
testDef.put("payloadJavaClass", specifiedPayloadType.javaClassName);
testDef.put("payloadAccessorName", specifiedPayloadType.javaAccessorName);
}
if (testSpecification.getDescription() != null) {
testDef.put("description", StringEscapeUtils.escapeJava(testSpecification.getDescription()));
}
testDef.put("nestedPayloadsList",nestedPayloadsList);
testDefs.add(testDef);
}