private boolean traverse(List<?> list, List<ErrorMessage> topLevelErrors) { boolean smurfFound = false; // traverse the tree in the response, and react to the known types for (Object data : list) { if (data instanceof DataList) { smurfFound = traverse(((DataList<?>) data).asList(), topLevelErrors); } else if (data instanceof DataProcessor.DemoData) { DataProcessor.DemoData content = (DataProcessor.DemoData) data; if (DemoComponent.SMURF.equals(content.content())) { topLevelErrors.add(new ErrorMessage("There's a smurf!")); smurfFound = true; } } if (smurfFound) { break; } } return smurfFound; }
@Override public void complete() { // Add headers addHeadersAndStatusFrom(processingResponse.data()); if ( ! explicitStatusSet) { // Set status from errors TODO: This could be decomplicated a bit List<ErrorMessage> errors = flattenErrors(processingResponse); boolean isSuccess = !(processingResponse.data().asList().isEmpty() && !errors.isEmpty()); // NOT success if ( no data AND are errors ) setStatus(getHttpResponseStatus(isSuccess, processingRequest, errors.size() == 0 ? null : errors.get(0), errors)); } }
@SuppressWarnings("unchecked") private Set<ErrorMessage> flattenErrors(Set<ErrorMessage> errors, Data data) { if (data.request() == null) return Collections.EMPTY_SET; // Not allowed, but handle anyway errors = addTo(errors, data.request().errors()); if (data instanceof DataList) { for (Data item : ((DataList<Data>) data).asList()) errors = flattenErrors(errors, item); } return errors; }
/** * This sets header and status from special Data items used for the purpose. * Do both at once to avoid traversing the data tree twice. */ @SuppressWarnings("unchecked") private void addHeadersAndStatusFrom(DataList<Data> dataList) { for (Data data : dataList.asList()) { if (data instanceof ResponseHeaders) { headers().addAll(((ResponseHeaders) data).headers()); } else if ( ! explicitStatusSet && (data instanceof ResponseStatus)) { setStatus(((ResponseStatus)data).code()); explicitStatusSet = true; } else if (data instanceof DataList) { addHeadersAndStatusFrom((DataList) data); } } }
@Override public Response process(Request request, Execution execution) { Response response; List<?> d; DemoProperty p = new DemoProperty(); String terms = request.properties().getString(TERMS); if (terms != null) { for (String s : splitter.split(terms)) { p.add(s); } } else { for (DemoConfig.Demo demo : defaultTermSet.demo()) { p.add(demo.term()); } } request.properties().set(DemoProperty.NAME_AS_COMPOUND, p); response = execution.process(request); d = response.data().asList(); traverse(d, response.data().request().errors()); return response; }