001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.oozie.client.rest; 019 020 import org.apache.oozie.client.BulkResponse; 021 import org.apache.oozie.client.BundleJob; 022 import org.apache.oozie.client.CoordinatorAction; 023 import org.apache.oozie.client.CoordinatorJob; 024 import org.apache.oozie.client.JMSConnectionInfo; 025 import org.apache.oozie.client.JMSConnectionInfoWrapper; 026 import org.apache.oozie.client.WorkflowAction; 027 import org.apache.oozie.client.WorkflowJob; 028 import org.apache.oozie.AppType; 029 import org.json.simple.JSONArray; 030 import org.json.simple.JSONObject; 031 import org.json.simple.JSONValue; 032 033 import java.lang.reflect.InvocationHandler; 034 import java.lang.reflect.Method; 035 import java.lang.reflect.Proxy; 036 import java.util.ArrayList; 037 import java.util.Date; 038 import java.util.HashMap; 039 import java.util.List; 040 import java.util.Map; 041 import java.util.Properties; 042 import java.util.Set; 043 044 /** 045 * JSON to bean converter for {@link WorkflowAction}, {@link WorkflowJob}, {@link CoordinatorAction} 046 * and {@link CoordinatorJob}. 047 * <p/> 048 * It uses JDK dynamic proxy to create bean instances. 049 */ 050 @SuppressWarnings("rawtypes") 051 public class JsonToBean { 052 053 private static class Property { 054 String label; 055 Class type; 056 boolean isList; 057 058 public Property(String label, Class type) { 059 this(label, type, false); 060 } 061 062 public Property(String label, Class type, boolean isList) { 063 this.label = label; 064 this.type = type; 065 this.isList = isList; 066 } 067 } 068 069 private static final Map<String, Property> WF_JOB = new HashMap<String, Property>(); 070 private static final Map<String, Property> WF_ACTION = new HashMap<String, Property>(); 071 private static final Map<String, Property> COORD_JOB = new HashMap<String, Property>(); 072 private static final Map<String, Property> COORD_ACTION = new HashMap<String, Property>(); 073 private static final Map<String, Property> BUNDLE_JOB = new HashMap<String, Property>(); 074 private static final Map<String, Property> BULK_RESPONSE = new HashMap<String, Property>(); 075 private static final Map<String, Property> JMS_CONNECTION_INFO = new HashMap<String, Property>(); 076 077 static { 078 WF_ACTION.put("getId", new Property(JsonTags.WORKFLOW_ACTION_ID, String.class)); 079 WF_ACTION.put("getName", new Property(JsonTags.WORKFLOW_ACTION_NAME, String.class)); 080 WF_ACTION.put("getType", new Property(JsonTags.WORKFLOW_ACTION_TYPE, String.class)); 081 WF_ACTION.put("getConf", new Property(JsonTags.WORKFLOW_ACTION_CONF, String.class)); 082 WF_ACTION.put("getStatus", new Property(JsonTags.WORKFLOW_ACTION_STATUS, WorkflowAction.Status.class)); 083 WF_ACTION.put("getRetries", new Property(JsonTags.WORKFLOW_ACTION_RETRIES, Integer.TYPE)); 084 WF_ACTION.put("getStartTime", new Property(JsonTags.WORKFLOW_ACTION_START_TIME, Date.class)); 085 WF_ACTION.put("getEndTime", new Property(JsonTags.WORKFLOW_ACTION_END_TIME, Date.class)); 086 WF_ACTION.put("getTransition", new Property(JsonTags.WORKFLOW_ACTION_TRANSITION, String.class)); 087 WF_ACTION.put("getData", new Property(JsonTags.WORKFLOW_ACTION_DATA, String.class)); 088 WF_ACTION.put("getStats", new Property(JsonTags.WORKFLOW_ACTION_STATS, String.class)); 089 WF_ACTION.put("getExternalChildIDs", new Property(JsonTags.WORKFLOW_ACTION_EXTERNAL_CHILD_IDS, String.class)); 090 WF_ACTION.put("getExternalId", new Property(JsonTags.WORKFLOW_ACTION_EXTERNAL_ID, String.class)); 091 WF_ACTION.put("getExternalStatus", new Property(JsonTags.WORKFLOW_ACTION_EXTERNAL_STATUS, String.class)); 092 WF_ACTION.put("getTrackerUri", new Property(JsonTags.WORKFLOW_ACTION_TRACKER_URI, String.class)); 093 WF_ACTION.put("getConsoleUrl", new Property(JsonTags.WORKFLOW_ACTION_CONSOLE_URL, String.class)); 094 WF_ACTION.put("getErrorCode", new Property(JsonTags.WORKFLOW_ACTION_ERROR_CODE, String.class)); 095 WF_ACTION.put("getErrorMessage", new Property(JsonTags.WORKFLOW_ACTION_ERROR_MESSAGE, String.class)); 096 WF_ACTION.put("toString", new Property(JsonTags.TO_STRING, String.class)); 097 098 WF_JOB.put("getExternalId", new Property(JsonTags.WORKFLOW_EXTERNAL_ID, String.class)); 099 WF_JOB.put("getAppPath", new Property(JsonTags.WORKFLOW_APP_PATH, String.class)); 100 WF_JOB.put("getAppName", new Property(JsonTags.WORKFLOW_APP_NAME, String.class)); 101 WF_JOB.put("getId", new Property(JsonTags.WORKFLOW_ID, String.class)); 102 WF_JOB.put("getConf", new Property(JsonTags.WORKFLOW_CONF, String.class)); 103 WF_JOB.put("getStatus", new Property(JsonTags.WORKFLOW_STATUS, WorkflowJob.Status.class)); 104 WF_JOB.put("getLastModifiedTime", new Property(JsonTags.WORKFLOW_LAST_MOD_TIME, Date.class)); 105 WF_JOB.put("getCreatedTime", new Property(JsonTags.WORKFLOW_CREATED_TIME, Date.class)); 106 WF_JOB.put("getStartTime", new Property(JsonTags.WORKFLOW_START_TIME, Date.class)); 107 WF_JOB.put("getEndTime", new Property(JsonTags.WORKFLOW_END_TIME, Date.class)); 108 WF_JOB.put("getUser", new Property(JsonTags.WORKFLOW_USER, String.class)); 109 WF_JOB.put("getGroup", new Property(JsonTags.WORKFLOW_GROUP, String.class)); 110 WF_JOB.put("getAcl", new Property(JsonTags.WORKFLOW_ACL, String.class)); 111 WF_JOB.put("getRun", new Property(JsonTags.WORKFLOW_RUN, Integer.TYPE)); 112 WF_JOB.put("getConsoleUrl", new Property(JsonTags.WORKFLOW_CONSOLE_URL, String.class)); 113 WF_JOB.put("getActions", new Property(JsonTags.WORKFLOW_ACTIONS, WorkflowAction.class, true)); 114 WF_JOB.put("getParentId", new Property(JsonTags.WORKFLOW_PARENT_ID, String.class)); 115 WF_JOB.put("toString", new Property(JsonTags.TO_STRING, String.class)); 116 117 COORD_ACTION.put("getId", new Property(JsonTags.COORDINATOR_ACTION_ID, String.class)); 118 COORD_ACTION.put("getJobId", new Property(JsonTags.COORDINATOR_JOB_ID, String.class)); 119 COORD_ACTION.put("getActionNumber", new Property(JsonTags.COORDINATOR_ACTION_NUMBER, Integer.TYPE)); 120 COORD_ACTION.put("getCreatedConf", new Property(JsonTags.COORDINATOR_ACTION_CREATED_CONF, String.class)); 121 COORD_ACTION.put("getCreatedTime", new Property(JsonTags.COORDINATOR_ACTION_CREATED_TIME, Date.class)); 122 COORD_ACTION.put("getNominalTime", new Property(JsonTags.COORDINATOR_ACTION_NOMINAL_TIME, Date.class)); 123 COORD_ACTION.put("getExternalId", new Property(JsonTags.COORDINATOR_ACTION_EXTERNALID, String.class)); 124 COORD_ACTION.put("getStatus", new Property(JsonTags.COORDINATOR_ACTION_STATUS, CoordinatorAction.Status.class)); 125 COORD_ACTION.put("getRunConf", new Property(JsonTags.COORDINATOR_ACTION_RUNTIME_CONF, String.class)); 126 COORD_ACTION 127 .put("getLastModifiedTime", new Property(JsonTags.COORDINATOR_ACTION_LAST_MODIFIED_TIME, Date.class)); 128 COORD_ACTION 129 .put("getMissingDependencies", new Property(JsonTags.COORDINATOR_ACTION_MISSING_DEPS, String.class)); 130 COORD_ACTION.put("getPushMissingDependencies", new Property(JsonTags.COORDINATOR_ACTION_PUSH_MISSING_DEPS, 131 String.class)); 132 COORD_ACTION.put("getExternalStatus", new Property(JsonTags.COORDINATOR_ACTION_EXTERNAL_STATUS, String.class)); 133 COORD_ACTION.put("getTrackerUri", new Property(JsonTags.COORDINATOR_ACTION_TRACKER_URI, String.class)); 134 COORD_ACTION.put("getConsoleUrl", new Property(JsonTags.COORDINATOR_ACTION_CONSOLE_URL, String.class)); 135 COORD_ACTION.put("getErrorCode", new Property(JsonTags.COORDINATOR_ACTION_ERROR_CODE, String.class)); 136 COORD_ACTION.put("getErrorMessage", new Property(JsonTags.COORDINATOR_ACTION_ERROR_MESSAGE, String.class)); 137 COORD_ACTION.put("toString", new Property(JsonTags.TO_STRING, String.class)); 138 139 COORD_JOB.put("getAppPath", new Property(JsonTags.COORDINATOR_JOB_PATH, String.class)); 140 COORD_JOB.put("getAppName", new Property(JsonTags.COORDINATOR_JOB_NAME, String.class)); 141 COORD_JOB.put("getId", new Property(JsonTags.COORDINATOR_JOB_ID, String.class)); 142 COORD_JOB.put("getConf", new Property(JsonTags.COORDINATOR_JOB_CONF, String.class)); 143 COORD_JOB.put("getStatus", new Property(JsonTags.COORDINATOR_JOB_STATUS, CoordinatorJob.Status.class)); 144 COORD_JOB.put("getExecutionOrder", 145 new Property(JsonTags.COORDINATOR_JOB_EXECUTIONPOLICY, CoordinatorJob.Execution.class)); 146 COORD_JOB.put("getFrequency", new Property(JsonTags.COORDINATOR_JOB_FREQUENCY, String.class)); 147 COORD_JOB.put("getTimeUnit", new Property(JsonTags.COORDINATOR_JOB_TIMEUNIT, CoordinatorJob.Timeunit.class)); 148 COORD_JOB.put("getTimeZone", new Property(JsonTags.COORDINATOR_JOB_TIMEZONE, String.class)); 149 COORD_JOB.put("getConcurrency", new Property(JsonTags.COORDINATOR_JOB_CONCURRENCY, Integer.TYPE)); 150 COORD_JOB.put("getTimeout", new Property(JsonTags.COORDINATOR_JOB_TIMEOUT, Integer.TYPE)); 151 COORD_JOB.put("getLastActionTime", new Property(JsonTags.COORDINATOR_JOB_LAST_ACTION_TIME, Date.class)); 152 COORD_JOB.put("getNextMaterializedTime", 153 new Property(JsonTags.COORDINATOR_JOB_NEXT_MATERIALIZED_TIME, Date.class)); 154 COORD_JOB.put("getStartTime", new Property(JsonTags.COORDINATOR_JOB_START_TIME, Date.class)); 155 COORD_JOB.put("getEndTime", new Property(JsonTags.COORDINATOR_JOB_END_TIME, Date.class)); 156 COORD_JOB.put("getPauseTime", new Property(JsonTags.COORDINATOR_JOB_PAUSE_TIME, Date.class)); 157 COORD_JOB.put("getUser", new Property(JsonTags.COORDINATOR_JOB_USER, String.class)); 158 COORD_JOB.put("getGroup", new Property(JsonTags.COORDINATOR_JOB_GROUP, String.class)); 159 COORD_JOB.put("getAcl", new Property(JsonTags.COORDINATOR_JOB_ACL, String.class)); 160 COORD_JOB.put("getConsoleUrl", new Property(JsonTags.COORDINATOR_JOB_CONSOLE_URL, String.class)); 161 COORD_JOB.put("getActions", new Property(JsonTags.COORDINATOR_ACTIONS, CoordinatorAction.class, true)); 162 COORD_JOB.put("toString", new Property(JsonTags.TO_STRING, String.class)); 163 164 BUNDLE_JOB.put("getActions", new Property(JsonTags.COORDINATOR_ACTIONS, CoordinatorAction.class, true)); 165 166 BUNDLE_JOB.put("getAppPath",new Property(JsonTags.BUNDLE_JOB_PATH, String.class)); 167 BUNDLE_JOB.put("getAppName",new Property(JsonTags.BUNDLE_JOB_NAME, String.class)); 168 BUNDLE_JOB.put("getId",new Property(JsonTags.BUNDLE_JOB_ID, String.class)); 169 BUNDLE_JOB.put("getExternalId",new Property(JsonTags.BUNDLE_JOB_EXTERNAL_ID, String.class)); 170 BUNDLE_JOB.put("getConf",new Property(JsonTags.BUNDLE_JOB_CONF, String.class)); 171 BUNDLE_JOB.put("getStatus",new Property(JsonTags.BUNDLE_JOB_STATUS, BundleJob.Status.class)); 172 BUNDLE_JOB.put("getTimeUnit",new Property(JsonTags.BUNDLE_JOB_TIMEUNIT, BundleJob.Timeunit.class)); 173 BUNDLE_JOB.put("getTimeout",new Property(JsonTags.BUNDLE_JOB_TIMEOUT, Integer.TYPE)); 174 BUNDLE_JOB.put("getKickoffTime",new Property(JsonTags.BUNDLE_JOB_KICKOFF_TIME, Date.class)); 175 BUNDLE_JOB.put("getStartTime",new Property(JsonTags.BUNDLE_JOB_START_TIME, Date.class)); 176 BUNDLE_JOB.put("getEndTime",new Property(JsonTags.BUNDLE_JOB_END_TIME, Date.class)); 177 BUNDLE_JOB.put("getPauseTime",new Property(JsonTags.BUNDLE_JOB_PAUSE_TIME, Date.class)); 178 BUNDLE_JOB.put("getCreatedTime",new Property(JsonTags.BUNDLE_JOB_CREATED_TIME, Date.class)); 179 BUNDLE_JOB.put("getUser",new Property(JsonTags.BUNDLE_JOB_USER, String.class)); 180 BUNDLE_JOB.put("getGroup",new Property(JsonTags.BUNDLE_JOB_GROUP, String.class)); 181 BUNDLE_JOB.put("getConsoleUrl",new Property(JsonTags.BUNDLE_JOB_CONSOLE_URL, String.class)); 182 BUNDLE_JOB.put("getCoordinators",new Property(JsonTags.BUNDLE_COORDINATOR_JOBS, CoordinatorJob.class, true)); 183 BUNDLE_JOB.put("toString", new Property(JsonTags.TO_STRING, String.class)); 184 185 BULK_RESPONSE.put("getBundle", new Property(JsonTags.BULK_RESPONSE_BUNDLE, BundleJob.class, false)); 186 BULK_RESPONSE.put("getCoordinator", new Property(JsonTags.BULK_RESPONSE_COORDINATOR, CoordinatorJob.class, false)); 187 BULK_RESPONSE.put("getAction", new Property(JsonTags.BULK_RESPONSE_ACTION, CoordinatorAction.class, false)); 188 189 JMS_CONNECTION_INFO.put("getTopicPatternProperties", new Property(JsonTags.JMS_TOPIC_PATTERN, Properties.class)); 190 JMS_CONNECTION_INFO.put("getJNDIProperties", new Property(JsonTags.JMS_JNDI_PROPERTIES, Properties.class)); 191 JMS_CONNECTION_INFO.put("getTopicPrefix", new Property(JsonTags.JMS_TOPIC_PREFIX, String.class)); 192 } 193 194 /** 195 * The dynamic proxy invocation handler used to convert JSON values to bean properties using a mapping. 196 */ 197 private static class JsonInvocationHandler implements InvocationHandler { 198 private final Map<String, Property> mapping; 199 private final JSONObject json; 200 201 /** 202 * Invocation handler constructor. 203 * 204 * @param mapping property to JSON/type-info mapping. 205 * @param json the json object to back the property values. 206 */ 207 public JsonInvocationHandler(Map<String, Property> mapping, JSONObject json) { 208 this.mapping = mapping; 209 this.json = json; 210 } 211 212 @Override 213 public Object invoke(Object o, Method method, Object[] objects) throws Throwable { 214 Property prop = mapping.get(method.getName()); 215 if (prop == null) { 216 throw new RuntimeException("Undefined method mapping: " + method.getName()); 217 } 218 if (prop.isList) { 219 if (prop.type == WorkflowAction.class) { 220 return createWorkflowActionList((JSONArray) json.get(prop.label)); 221 } 222 else if (prop.type == CoordinatorAction.class) { 223 return createCoordinatorActionList((JSONArray) json.get(prop.label)); 224 } 225 else if (prop.type == CoordinatorJob.class) { 226 return createCoordinatorJobList((JSONArray) json.get(prop.label)); 227 } 228 else { 229 throw new RuntimeException("Unsupported list type : " + prop.type.getSimpleName()); 230 } 231 } 232 else { 233 return parseType(prop.type, json.get(prop.label)); 234 } 235 } 236 237 @SuppressWarnings("unchecked") 238 private Object parseType(Class type, Object obj) { 239 if (type == String.class) { 240 return obj == null ? obj : obj.toString(); 241 } 242 else if (type == Integer.TYPE) { 243 return (obj != null) ? new Integer(((Long) obj).intValue()) : new Integer(0); 244 } 245 else if (type == Long.TYPE) { 246 return (obj != null) ? obj : new Long(0); 247 } 248 else if (type == Date.class) { 249 return JsonUtils.parseDateRfc822((String) obj); 250 } 251 else if (type.isEnum()) { 252 return Enum.valueOf(type, (String) obj); 253 } 254 else if (type == WorkflowAction.class) { 255 return createWorkflowAction((JSONObject) obj); 256 } 257 else if (type == Properties.class){ 258 JSONObject jsonMap = (JSONObject)JSONValue.parse((String)obj); 259 Properties props = new Properties(); 260 Set<Map.Entry> entrySet = jsonMap.entrySet(); 261 for (Map.Entry jsonEntry: entrySet){ 262 props.put(jsonEntry.getKey(), jsonEntry.getValue()); 263 } 264 return props; 265 } 266 else if (type == CoordinatorJob.class) { 267 return createCoordinatorJob((JSONObject) obj); 268 } 269 else if (type == CoordinatorAction.class) { 270 return createCoordinatorAction((JSONObject) obj); 271 } 272 else if (type == BundleJob.class) { 273 return createBundleJob((JSONObject) obj); 274 } 275 else { 276 throw new RuntimeException("Unsupported type : " + type.getSimpleName()); 277 } 278 } 279 } 280 281 /** 282 * Creates a workflow action bean from a JSON object. 283 * 284 * @param json json object. 285 * @return a workflow action bean populated with the JSON object values. 286 */ 287 public static WorkflowAction createWorkflowAction(JSONObject json) { 288 return (WorkflowAction) Proxy.newProxyInstance(JsonToBean.class.getClassLoader(), 289 new Class[]{WorkflowAction.class}, 290 new JsonInvocationHandler(WF_ACTION, json)); 291 } 292 293 /** 294 * Creates a list of workflow action beans from a JSON array. 295 * 296 * @param json json array. 297 * @return a list of workflow action beans from a JSON array. 298 */ 299 public static List<WorkflowAction> createWorkflowActionList(JSONArray json) { 300 List<WorkflowAction> list = new ArrayList<WorkflowAction>(); 301 for (Object obj : json) { 302 list.add(createWorkflowAction((JSONObject) obj)); 303 } 304 return list; 305 } 306 307 /** 308 * Creates a workflow job bean from a JSON object. 309 * 310 * @param json json object. 311 * @return a workflow job bean populated with the JSON object values. 312 */ 313 public static WorkflowJob createWorkflowJob(JSONObject json) { 314 return (WorkflowJob) Proxy.newProxyInstance(JsonToBean.class.getClassLoader(), 315 new Class[]{WorkflowJob.class}, 316 new JsonInvocationHandler(WF_JOB, json)); 317 } 318 319 /** 320 * Creates a list of workflow job beans from a JSON array. 321 * 322 * @param json json array. 323 * @return a list of workflow job beans from a JSON array. 324 */ 325 public static List<WorkflowJob> createWorkflowJobList(JSONArray json) { 326 List<WorkflowJob> list = new ArrayList<WorkflowJob>(); 327 for (Object obj : json) { 328 list.add(createWorkflowJob((JSONObject) obj)); 329 } 330 return list; 331 } 332 333 /** 334 * Creates a coordinator action bean from a JSON object. 335 * 336 * @param json json object. 337 * @return a coordinator action bean populated with the JSON object values. 338 */ 339 public static CoordinatorAction createCoordinatorAction(JSONObject json) { 340 return (CoordinatorAction) Proxy.newProxyInstance(JsonToBean.class.getClassLoader(), 341 new Class[]{CoordinatorAction.class}, 342 new JsonInvocationHandler(COORD_ACTION, json)); 343 } 344 345 /** 346 * Creates a list of coordinator action beans from a JSON array. 347 * 348 * @param json json array. 349 * @return a list of coordinator action beans from a JSON array. 350 */ 351 public static List<CoordinatorAction> createCoordinatorActionList(JSONArray json) { 352 List<CoordinatorAction> list = new ArrayList<CoordinatorAction>(); 353 for (Object obj : json) { 354 list.add(createCoordinatorAction((JSONObject) obj)); 355 } 356 return list; 357 } 358 359 /** 360 * Creates a coordinator job bean from a JSON object. 361 * 362 * @param json json object. 363 * @return a coordinator job bean populated with the JSON object values. 364 */ 365 public static CoordinatorJob createCoordinatorJob(JSONObject json) { 366 return (CoordinatorJob) Proxy.newProxyInstance(JsonToBean.class.getClassLoader(), 367 new Class[]{CoordinatorJob.class}, 368 new JsonInvocationHandler(COORD_JOB, json)); 369 } 370 371 372 /** 373 * Creates a JMSInfo bean from a JSON object. 374 * 375 * @param json json object. 376 * @return a coordinator job bean populated with the JSON object values. 377 */ 378 public static JMSConnectionInfo createJMSConnectionInfo(JSONObject json) { 379 final JMSConnectionInfoWrapper jmsInfo = (JMSConnectionInfoWrapper) Proxy.newProxyInstance( 380 JsonToBean.class.getClassLoader(), new Class[] { JMSConnectionInfoWrapper.class }, 381 new JsonInvocationHandler(JMS_CONNECTION_INFO, json)); 382 383 return new JMSConnectionInfo() { 384 @Override 385 public String getTopicPrefix() { 386 return jmsInfo.getTopicPrefix(); 387 } 388 389 @Override 390 public String getTopicPattern(AppType appType) { 391 return (String)jmsInfo.getTopicPatternProperties().get(appType.name()); 392 } 393 394 @Override 395 public Properties getJNDIProperties() { 396 return jmsInfo.getJNDIProperties(); 397 } 398 }; 399 } 400 401 /** 402 * Creates a list of coordinator job beans from a JSON array. 403 * 404 * @param json json array. 405 * @return a list of coordinator job beans from a JSON array. 406 */ 407 public static List<CoordinatorJob> createCoordinatorJobList(JSONArray json) { 408 List<CoordinatorJob> list = new ArrayList<CoordinatorJob>(); 409 for (Object obj : json) { 410 list.add(createCoordinatorJob((JSONObject) obj)); 411 } 412 return list; 413 } 414 415 /** 416 * Creates a bundle job bean from a JSON object. 417 * 418 * @param json json object. 419 * @return a bundle job bean populated with the JSON object values. 420 */ 421 public static BundleJob createBundleJob(JSONObject json) { 422 return (BundleJob) Proxy.newProxyInstance(JsonToBean.class.getClassLoader(), 423 new Class[]{BundleJob.class}, 424 new JsonInvocationHandler(BUNDLE_JOB, json)); 425 } 426 427 /** 428 * Creates a list of bundle job beans from a JSON array. 429 * 430 * @param json json array. 431 * @return a list of bundle job beans from a JSON array. 432 */ 433 public static List<BundleJob> createBundleJobList(JSONArray json) { 434 List<BundleJob> list = new ArrayList<BundleJob>(); 435 for (Object obj : json) { 436 list.add(createBundleJob((JSONObject) obj)); 437 } 438 return list; 439 } 440 441 /** 442 * Creates a Bulk response object from a JSON object. 443 * 444 * @param json json object. 445 * @return a Bulk response object populated with the JSON object values. 446 */ 447 public static BulkResponse createBulkResponse(JSONObject json) { 448 return (BulkResponse) Proxy.newProxyInstance(JsonToBean.class.getClassLoader(), 449 new Class[]{BulkResponse.class}, 450 new JsonInvocationHandler(BULK_RESPONSE, json)); 451 } 452 453 /** 454 * Creates a list of bulk response beans from a JSON array. 455 * 456 * @param json json array. 457 * @return a list of bulk response beans from a JSON array. 458 */ 459 public static List<BulkResponse> createBulkResponseList(JSONArray json) { 460 List<BulkResponse> list = new ArrayList<BulkResponse>(); 461 for (Object obj : json) { 462 list.add(createBulkResponse((JSONObject) obj)); 463 } 464 return list; 465 } 466 467 }