1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.atlassian.jira.rest.client.internal.json;
18
19 import com.atlassian.jira.rest.client.domain.CimFieldInfo;
20 import com.google.common.collect.ImmutableSet;
21 import com.google.common.collect.Lists;
22 import com.google.common.collect.Maps;
23 import com.google.common.collect.Sets;
24 import org.codehaus.jettison.json.JSONArray;
25 import org.codehaus.jettison.json.JSONException;
26 import org.codehaus.jettison.json.JSONObject;
27
28 import javax.annotation.Nullable;
29 import java.net.URI;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36
37
38
39
40
41 public class CimFieldsInfoMapJsonParser implements JsonObjectParser<Map<String, CimFieldInfo>> {
42
43 private final FieldSchemaJsonParser fieldSchemaJsonParser = new FieldSchemaJsonParser();
44
45 protected final Map<String, JsonObjectParser> registeredAllowedValueParsers = new HashMap<String, JsonObjectParser>() {{
46 put("project", new BasicProjectJsonParser());
47 put("version", new VersionJsonParser());
48 put("issuetype", new BasicIssueTypeJsonParser());
49 put("priority", new BasicPriorityJsonParser());
50 put("customFieldOption", new CustomFieldOptionJsonParser());
51 put("component", new BasicComponentJsonParser());
52 }};
53
54 @Override
55 public Map<String, CimFieldInfo> parse(JSONObject json) throws JSONException {
56 final Map<String, CimFieldInfo> res = Maps.newHashMapWithExpectedSize(json.length());
57 final Iterator keysIterator = json.keys();
58 while (keysIterator.hasNext()) {
59 final String id = (String) keysIterator.next();
60 res.put(id, parseIssueFieldInfo(json.getJSONObject(id), id));
61 }
62 return res;
63 }
64
65 private CimFieldInfo parseIssueFieldInfo(JSONObject json, String id) throws JSONException {
66 final boolean required = json.getBoolean("required");
67 final String name = JsonParseUtil.getOptionalString(json, "name");
68 final FieldSchema schema = fieldSchemaJsonParser.parse(json.getJSONObject("schema"));
69 final Set<StandardOperation> operations = parseOperations(json.getJSONArray("operations"));
70 final Iterable<Object> allowedValues = parseAllowedValues(json.optJSONArray("allowedValues"), schema);
71 final URI autoCompleteUri = JsonParseUtil.parseOptionalURI(json, "autoCompleteUrl");
72
73 return new CimFieldInfo(id, required, name, schema, operations, allowedValues, autoCompleteUri);
74 }
75
76 private Iterable<Object> parseAllowedValues(@Nullable JSONArray allowedValues, FieldSchema fieldSchema) throws JSONException {
77 if (allowedValues == null || allowedValues.equals(JSONObject.NULL)) {
78 return null;
79 }
80
81 if (allowedValues.length() == 0) {
82 return Collections.emptyList();
83 }
84
85 JsonObjectParser<Object> allowedValuesJsonParser = getParserFor(fieldSchema);
86 if (allowedValuesJsonParser != null) {
87 JSONArray valuesToParse;
88
89 final boolean isProjectCF = "project".equals(fieldSchema.getType())
90 && "com.atlassian.jira.plugin.system.customfieldtypes:project".equals(fieldSchema.getCustom());
91 final boolean isVersionCF = "version".equals(fieldSchema.getType())
92 && "com.atlassian.jira.plugin.system.customfieldtypes:version".equals(fieldSchema.getCustom());
93 final boolean isMultiVersionCF = "array".equals(fieldSchema.getType())
94 && "version".equals(fieldSchema.getItems())
95 && "com.atlassian.jira.plugin.system.customfieldtypes:multiversion".equals(fieldSchema.getCustom());
96
97 if ((isProjectCF || isVersionCF || isMultiVersionCF) && allowedValues.get(0) instanceof JSONArray) {
98 valuesToParse = allowedValues.getJSONArray(0);
99 }
100 else {
101 valuesToParse = allowedValues;
102 }
103 return GenericJsonArrayParser.create(allowedValuesJsonParser).parse(valuesToParse);
104 }
105 else {
106
107 int itemsLength = allowedValues.length();
108 List<Object> res = Lists.newArrayListWithExpectedSize(itemsLength);
109 for (int i = 0; i < itemsLength; i++) {
110 res.add(allowedValues.get(i));
111 }
112 return res;
113 }
114 }
115
116 private Set<StandardOperation> parseOperations(JSONArray operations) throws JSONException {
117 int operationsCount = operations.length();
118 final Set<StandardOperation> res = Sets.newHashSetWithExpectedSize(operationsCount);
119 for (int i = 0; i < operationsCount; i++) {
120 String opName = operations.getString(i);
121 StandardOperation op = StandardOperation.valueOf(opName.toUpperCase());
122 res.add(op);
123 }
124 return res;
125 }
126
127 private JsonObjectParser<Object> getParserFor(FieldSchema fieldSchema) throws JSONException {
128 final Set<String> customFieldsTypesWithFieldOption = ImmutableSet.of(
129 "com.atlassian.jira.plugin.system.customfieldtypes:multicheckboxes",
130 "com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons",
131 "com.atlassian.jira.plugin.system.customfieldtypes:select",
132 "com.atlassian.jira.plugin.system.customfieldtypes:cascadingselect"
133 );
134 String type = "array".equals(fieldSchema.getType()) ? fieldSchema.getItems() : fieldSchema.getType();
135 final String custom = fieldSchema.getCustom();
136 if (custom != null && customFieldsTypesWithFieldOption.contains(custom)) {
137 type = "customFieldOption";
138 }
139 @SuppressWarnings("unchecked")
140 final JsonObjectParser<Object> jsonParser = registeredAllowedValueParsers.get(type);
141 if (jsonParser == null) {
142 throw new JSONException("Cannot find parser for field witch schema: " + fieldSchema);
143 }
144 else {
145 return jsonParser;
146 }
147 }
148 }