Conditions | 72 |
Total Lines | 405 |
Code Lines | 268 |
Lines | 85 |
Ratio | 20.99 % |
Changes | 9 | ||
Bugs | 1 | Features | 3 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like unicon.matthews.xapi.service.DefaultXapiToCaliperConversionService.fromXapi(Statement) often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | /** |
||
201 | public Event fromXapi(Statement statement) { |
||
202 | // EVENT TIME |
||
203 | LocalDateTime eventTime = null; |
||
204 | String timestamp = statement.getTimestamp(); |
||
205 | if (StringUtils.isNotBlank(timestamp)) { |
||
206 | if (timestamp.endsWith("Z")) { |
||
207 | Instant instant = Instant.parse(timestamp); |
||
208 | eventTime = LocalDateTime.ofInstant(instant, ZoneId.of(ZoneOffset.UTC.getId())); |
||
209 | } |
||
210 | else { |
||
211 | ZonedDateTime zdt = ZonedDateTime.parse(timestamp); |
||
212 | ZonedDateTime utc_zone = zdt.toLocalDateTime().atZone(ZoneOffset.UTC); |
||
213 | eventTime = utc_zone.toLocalDateTime(); |
||
214 | } |
||
215 | |||
216 | } |
||
217 | else { |
||
218 | eventTime = LocalDateTime.now(ZoneId.of(ZoneOffset.UTC.getId())); |
||
219 | } |
||
220 | // EVENT TIME END |
||
221 | |||
222 | // ACTOR |
||
223 | Agent caliperActor = null; |
||
224 | String actorId = null; |
||
225 | XApiActor xapiActor = statement.getActor(); |
||
226 | if (xapiActor != null) { |
||
227 | |||
228 | String actorType = null; |
||
229 | Map<String, String> actorExtensions = new HashMap<>(); |
||
230 | String actorName = xapiActor.getName(); |
||
231 | |||
232 | String openId = xapiActor.getOpenid(); |
||
233 | String mbox = xapiActor.getMbox(); |
||
234 | XApiAccount xapiAccount = xapiActor.getAccount(); |
||
235 | |||
236 | if (StringUtils.isNotBlank(openId)) { |
||
237 | actorId = openId; |
||
238 | actorType = ACTOR_TYPE_OPENID; |
||
239 | } |
||
240 | else if (StringUtils.isNotBlank(mbox)) { |
||
241 | actorId = mbox; |
||
242 | actorType = ACTOR_TYPE_MBOX; |
||
243 | } |
||
244 | else if (xapiAccount != null) { |
||
245 | String accountName = xapiAccount.getName(); |
||
246 | String homePage = xapiAccount.getHomePage(); |
||
247 | |||
248 | if (StringUtils.isNotBlank(homePage)) { |
||
249 | |||
250 | if (StringUtils.isNotBlank(accountName)) { |
||
251 | actorId = accountName; |
||
252 | actorExtensions.put("HOMEPAGE", homePage); |
||
253 | } |
||
254 | else { |
||
255 | actorId = homePage; |
||
256 | } |
||
257 | } |
||
258 | else if (StringUtils.isNotBlank(accountName)) { |
||
259 | actorId = accountName; |
||
260 | } |
||
261 | |||
262 | actorType = ACTOR_TYPE_ACCOUNT; |
||
263 | } |
||
264 | |||
265 | caliperActor |
||
266 | = new Agent.Builder() |
||
267 | .withContext(Context.CONTEXT.getValue()) |
||
268 | .withName(actorName) |
||
269 | .withId(actorId) |
||
270 | .withType(actorType) |
||
271 | .withExtensions(actorExtensions) |
||
272 | .build(); |
||
273 | } |
||
274 | // ACTOR END |
||
275 | |||
276 | // RESULT |
||
277 | Entity caliperResult = null; |
||
278 | XApiResult xapiResult = statement.getResult(); |
||
279 | if (xapiResult != null) { |
||
280 | Map<String,String> resultExtensions = null; |
||
281 | Map<URI,java.lang.Object> xapiResultExtensions = xapiResult.getExtensions(); |
||
282 | if (xapiResultExtensions != null && !xapiResultExtensions.isEmpty()) { |
||
283 | resultExtensions = new HashMap<>(); |
||
284 | for (Map.Entry<URI,java.lang.Object> entry : xapiResultExtensions.entrySet()) { |
||
285 | resultExtensions.put(entry.getKey().toString(),entry.getValue().toString()); |
||
286 | } |
||
287 | } |
||
288 | |||
289 | Double score = null; |
||
290 | XApiScore xapiScore = xapiResult.getScore(); |
||
291 | if (xapiScore != null) { |
||
292 | score = xapiScore.getRaw(); |
||
293 | } |
||
294 | |||
295 | caliperResult |
||
296 | = new Entity.Builder() |
||
297 | .withId(UUID.randomUUID().toString()) |
||
298 | .withContext(Context.CONTEXT.getValue()) |
||
299 | .withExtensions(resultExtensions) |
||
300 | .withActor(actorId) |
||
301 | .withType("http://purl.imsglobal.org/caliper/v1/Result") |
||
302 | .withTotalScore(score) |
||
303 | .build(); |
||
304 | } |
||
305 | // END Result |
||
306 | |||
307 | // ACTION |
||
308 | String caliperAction = null; |
||
309 | XApiVerb xapiVerb = statement.getVerb(); |
||
310 | if (xapiVerb != null) { |
||
311 | String verbId = xapiVerb.getId(); |
||
312 | caliperAction = xApiVerbToCaliperAction(verbId); |
||
313 | } |
||
314 | // ACTION END |
||
315 | |||
316 | // OBJECT |
||
317 | Entity caliperObject = null; |
||
318 | XApiObject xapiObject = statement.getObject(); |
||
319 | if (xapiObject != null) { |
||
320 | |||
321 | String objectType = xapiObjectTypeToCaliperEntityType(null); |
||
322 | String objectName = null; |
||
323 | String objectDescription = null; |
||
324 | Map<String,String> objectExtensions = null; |
||
325 | String objectId = xapiObject.getId(); |
||
326 | |||
327 | XApiObjectDefinition xapiObjectDefinition = xapiObject.getDefinition(); |
||
328 | if (xapiObjectDefinition != null) { |
||
329 | String xapiObjectDefinitionType = xapiObjectDefinition.getType(); |
||
330 | if (StringUtils.isNotBlank(xapiObjectDefinitionType)) { |
||
331 | objectType = xapiObjectTypeToCaliperEntityType(xapiObjectDefinitionType); |
||
332 | } |
||
333 | |||
334 | Map<String,String> names = xapiObjectDefinition.getName(); |
||
335 | if (names != null) { |
||
336 | if (names.size() == 1) { |
||
337 | objectName = CollectionUtils.get(names, 0).getValue(); |
||
338 | } |
||
339 | else { |
||
340 | // default to en? |
||
341 | objectName = names.get("en"); |
||
342 | } |
||
343 | } |
||
344 | |||
345 | Map<String,String> descriptions = xapiObjectDefinition.getDescription(); |
||
346 | if (descriptions != null) { |
||
347 | if (descriptions.size() == 1) { |
||
348 | objectDescription = CollectionUtils.get(descriptions, 0).getValue(); |
||
349 | } |
||
350 | else { |
||
351 | // default to en? |
||
352 | objectDescription = descriptions.get("en"); |
||
353 | } |
||
354 | } |
||
355 | |||
356 | Map<URI,java.lang.Object> extensions = xapiObjectDefinition.getExtensions(); |
||
357 | if (extensions != null && !extensions.isEmpty()) { |
||
358 | objectExtensions = new HashMap<String,String>(extensions.size()); |
||
359 | for (URI key : extensions.keySet()) { |
||
360 | objectExtensions.put(key.toString(), extensions.get(key).toString()); |
||
361 | } |
||
362 | } |
||
363 | } |
||
364 | |||
365 | caliperObject |
||
366 | = new Entity.Builder() |
||
367 | .withId(objectId) |
||
368 | .withContext(Context.CONTEXT.getValue()) |
||
369 | .withType(objectType) |
||
370 | .withName(objectName) |
||
371 | .withDescription(objectDescription) |
||
372 | .withExtensions(objectExtensions) |
||
373 | .build(); |
||
374 | } |
||
375 | // OBJECT END |
||
376 | |||
377 | Group caliperGroup = null; |
||
378 | XApiContext xapiContext = statement.getContext(); |
||
379 | if (xapiContext != null) { |
||
380 | Map<String,String> contextExtensions = null; |
||
381 | Map<URI,java.lang.Object> extensions = xapiContext.getExtensions(); |
||
382 | if (extensions != null && !extensions.isEmpty()) { |
||
383 | contextExtensions = new HashMap<String,String>(extensions.size()); |
||
384 | for (URI key : extensions.keySet()) { |
||
385 | contextExtensions.put(key.toString(), extensions.get(key).toString()); |
||
386 | } |
||
387 | } |
||
388 | |||
389 | XApiContextActivities xapiContextActivities = xapiContext.getContextActivities(); |
||
390 | if (xapiContextActivities != null) { |
||
391 | List<XApiObject> contextActivityParents = xapiContextActivities.getParent(); |
||
392 | |||
393 | if (contextActivityParents != null && contextActivityParents.size() == 1 |
||
394 | && contextActivityParents.get(0).getId().contains("portal/site")) { |
||
395 | caliperGroup |
||
396 | = new Group.Builder() |
||
397 | .withId(StringUtils.substringAfterLast(contextActivityParents.get(0).getId(), "/")) |
||
398 | .withContext(Context.CONTEXT.getValue()) |
||
399 | .withType("http://purl.imsglobal.org/caliper/v1/lis/CourseSection") |
||
400 | .build(); |
||
401 | } |
||
402 | |||
403 | if (caliperGroup == null) { |
||
404 | List<XApiObject> groupings = xapiContextActivities.getGrouping(); |
||
405 | if (groupings != null && !groupings.isEmpty()) { |
||
406 | XApiObject grouping = null; |
||
407 | String id = null; |
||
408 | String type = null; |
||
409 | |||
410 | if (groupings.size() == 1) { |
||
411 | grouping = groupings.get(0); |
||
412 | |||
413 | if (extensions != null) { |
||
414 | Object paramMap = null; |
||
415 | try { |
||
416 | paramMap = extensions.get(new URI("http://lrs.learninglocker.net/define/extensions/moodle_logstore_standard_log")); |
||
417 | } |
||
418 | catch (URISyntaxException e) { |
||
419 | // TODO |
||
420 | } |
||
421 | if (paramMap != null && paramMap instanceof Map) { |
||
422 | Map<String, String> groupExtMap = (Map<String, String>)paramMap; |
||
423 | id = groupExtMap.get("courseid"); |
||
424 | type = "http://purl.imsglobal.org/caliper/v1/lis/CourseSection"; |
||
425 | } |
||
426 | } |
||
427 | } |
||
428 | else { |
||
429 | for (XApiObject xo : groupings) { |
||
430 | grouping = xo; |
||
431 | XApiObjectDefinition xapiObjectDefinition = xo.getDefinition(); |
||
432 | if (xapiObjectDefinition != null) { |
||
433 | if ("http://lrs.learninglocker.net/define/type/moodle/course".equals(xapiObjectDefinition.getType())) { |
||
434 | type = "http://purl.imsglobal.org/caliper/v1/lis/CourseSection"; |
||
435 | Map<URI, Object> groupExt = xapiObjectDefinition.getExtensions(); |
||
436 | if (groupExt != null) { |
||
437 | try { |
||
438 | Object paramMap = groupExt.get(new URI("http://lrs.learninglocker.net/define/extensions/moodle_course")); |
||
439 | if (paramMap instanceof Map) { |
||
440 | Map<String, String> groupExtMap = (Map<String, String>)paramMap; |
||
441 | id = groupExtMap.get("id"); |
||
442 | } |
||
443 | |||
444 | } |
||
445 | catch (URISyntaxException e) { |
||
446 | //TODO |
||
447 | } |
||
448 | } |
||
449 | |||
450 | break; |
||
451 | } |
||
452 | } |
||
453 | } |
||
454 | } |
||
455 | |||
456 | if (grouping != null) { |
||
457 | String name = null; |
||
458 | String description = null; |
||
459 | XApiObjectDefinition xapiObjectDefinition = grouping.getDefinition(); |
||
460 | if (xapiObjectDefinition != null) { |
||
461 | |||
462 | if (StringUtils.isBlank(type) && StringUtils.isNoneBlank(xapiObjectDefinition.getType())) { |
||
463 | type = xapiObjectDefinition.getType(); |
||
464 | } |
||
465 | |||
466 | Map<String,String> names =xapiObjectDefinition.getName(); |
||
467 | if (names != null) { |
||
468 | if (names.size() == 1) { |
||
469 | name = CollectionUtils.get(names, 0).getValue(); |
||
470 | } |
||
471 | else { |
||
472 | // default to en? |
||
473 | name = names.get("en"); |
||
474 | } |
||
475 | } |
||
476 | |||
477 | Map<String,String> descriptions = xapiObjectDefinition.getDescription(); |
||
478 | if (descriptions != null) { |
||
479 | if (descriptions.size() == 1) { |
||
480 | description = CollectionUtils.get(descriptions, 0).getValue(); |
||
481 | } |
||
482 | else { |
||
483 | // default to en? |
||
484 | description = descriptions.get("en"); |
||
485 | } |
||
486 | } |
||
487 | } |
||
488 | |||
489 | List<XApiObject> parents = xapiContextActivities.getParent(); |
||
490 | SubOrganizationOf subOrganizationOf = null; |
||
491 | View Code Duplication | if (parents != null && parents.size() == 1) { |
|
492 | XApiObject parent = parents.get(0); |
||
493 | String parentId = parent.getId(); |
||
494 | String parentType = "http://purl.imsglobal.org/caliper/v1/lis/CourseOffering"; |
||
495 | String parentName = null; |
||
496 | String parentDescription = null; |
||
497 | XApiObjectDefinition parentXapiObjectDefinition = parent.getDefinition(); |
||
498 | if (parentXapiObjectDefinition != null) { |
||
499 | |||
500 | if (StringUtils.isNoneBlank(parentXapiObjectDefinition.getType())) { |
||
501 | parentType = parentXapiObjectDefinition.getType(); |
||
502 | } |
||
503 | |||
504 | Map<String,String> names = parentXapiObjectDefinition.getName(); |
||
505 | if (names != null) { |
||
506 | if (names.size() == 1) { |
||
507 | parentName = CollectionUtils.get(names, 0).getValue(); |
||
508 | } |
||
509 | else { |
||
510 | // default to en? |
||
511 | parentName = names.get("en"); |
||
512 | } |
||
513 | } |
||
514 | |||
515 | Map<String,String> descriptions = parentXapiObjectDefinition.getDescription(); |
||
516 | if (descriptions != null) { |
||
517 | if (descriptions.size() == 1) { |
||
518 | parentDescription = CollectionUtils.get(descriptions, 0).getValue(); |
||
519 | } |
||
520 | else { |
||
521 | // default to en? |
||
522 | parentDescription = descriptions.get("en"); |
||
523 | } |
||
524 | } |
||
525 | |||
526 | subOrganizationOf |
||
527 | = new SubOrganizationOf.Builder() |
||
528 | .withId(parentId) |
||
529 | .withContext(Context.CONTEXT.getValue()) |
||
530 | .withType(parentType) |
||
531 | .withName(parentName) |
||
532 | .withDescription(parentDescription) |
||
533 | .build(); |
||
534 | } |
||
535 | } |
||
536 | |||
537 | caliperGroup |
||
538 | = new Group.Builder() |
||
539 | .withId(id) |
||
540 | .withContext(Context.CONTEXT.getValue()) |
||
541 | .withType(type) |
||
542 | .withName(name) |
||
543 | .withDescription(description) |
||
544 | .withExtensions(contextExtensions) |
||
545 | .withSubOrganizationOf(subOrganizationOf) |
||
546 | .build(); |
||
547 | } |
||
548 | View Code Duplication | else if (xapiContextActivities.getParent() != null) { |
|
549 | XApiObject parent = xapiContextActivities.getParent().get(0); |
||
550 | String name = null; |
||
551 | String description = null; |
||
552 | XApiObjectDefinition xapiObjectDefinition = parent.getDefinition(); |
||
553 | if (xapiObjectDefinition != null) { |
||
554 | if (StringUtils.isBlank(type) && StringUtils.isNoneBlank(xapiObjectDefinition.getType())) { |
||
555 | type = xapiObjectDefinition.getType(); |
||
556 | } |
||
557 | |||
558 | Map<String,String> names = xapiObjectDefinition.getName(); |
||
559 | if (names != null) { |
||
560 | if (names.size() == 1) { |
||
561 | name = CollectionUtils.get(names, 0).getValue(); |
||
562 | } |
||
563 | else { |
||
564 | // default to en? |
||
565 | name = names.get("en"); |
||
566 | } |
||
567 | } |
||
568 | |||
569 | Map<String,String> descriptions = xapiObjectDefinition.getDescription(); |
||
570 | if (descriptions != null) { |
||
571 | if (descriptions.size() == 1) { |
||
572 | description = CollectionUtils.get(descriptions, 0).getValue(); |
||
573 | } |
||
574 | else { |
||
575 | // default to en? |
||
576 | description = descriptions.get("en"); |
||
577 | } |
||
578 | } |
||
579 | } |
||
580 | |||
581 | caliperGroup |
||
582 | = new Group.Builder() |
||
583 | .withId(parent.getId()) |
||
584 | .withContext(Context.CONTEXT.getValue()) |
||
585 | .withType(type) |
||
586 | .withName(name) |
||
587 | .withDescription(description) |
||
588 | .withExtensions(contextExtensions) |
||
589 | .build(); |
||
590 | } |
||
591 | } |
||
592 | } |
||
593 | } |
||
594 | } |
||
595 | |||
596 | return |
||
597 | new Event.Builder() |
||
598 | .withAction(caliperAction) |
||
599 | .withAgent(caliperActor) |
||
600 | .withObject(caliperObject) |
||
601 | .withEventTime(eventTime) |
||
602 | .withContext(xapiToCaliperType(statement)) |
||
603 | .withGroup(caliperGroup) |
||
604 | .withGenerated(caliperResult) |
||
605 | .build(); |
||
606 | |||
818 |
The Java documentation explain EnumMap.