Java tutorial
/** * Copyright (c) 2014 by the original author or authors. * * This code is free software; you can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package ch.sdi.report; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Component; import ch.sdi.core.impl.data.Dataset; import ch.sdi.core.impl.data.Person; import ch.sdi.report.ReportMsg.ReportType; /** * Global singleton for collecting ReportMsg items in order to render a report at the end of the * data import. * <p> * * @version 1.0 (20.11.2014) * @author Heri */ @Component public class SdiReporter { /** logger for this class */ private Logger myLog = LogManager.getLogger(SdiReporter.class); private List<ReportMsg> myMessages = new ArrayList<ReportMsg>(); /** * Constructor * */ public SdiReporter() { super(); } /** * Clears all ReportMsg from internal memory */ public void reset() { myLog.info("resetting " + this.getClass().getSimpleName()); myMessages = new ArrayList<ReportMsg>(); } /** * Adds given ReportMsg to the internal memory * <p> * @param aMsg */ public void add(ReportMsg aMsg) { // Since wie are already in a call from a logger there would be an error entry if we call // the logger again ("Recursive call to appender "). So log this asynchroneously: CompletableFuture.supplyAsync(() -> "adding a message").thenAcceptAsync(myLog::trace); myMessages.add(aMsg); } /** * Renders the report * <p> * @return */ public String getReport() { myLog.debug("Rendering the report"); StringBuilder result = new StringBuilder(); DateFormat df = new SimpleDateFormat("dd.MM.yyyy, hh:mm:ss"); appendTitle(result, "Import " + df.format(new Date()), "*"); result.append("\n"); appendSimpleEntry(result, "Source:", findSimpleStringEntry(ReportType.COLLECTOR_CFG, "InputSource")); result.append("\n"); Collection<ReportMsg> preparsedFiltered = findOfTypes(ReportType.PREPARSE_FILTER); appendSummary(result, preparsedFiltered); Collection<ReportMsg> parsed = findOfTypes(ReportType.COLLECTOR); appendSummary(result, parsed); Collection<ReportMsg> parsedProblems = findOfTypes(ReportType.COLLECTOR_PROBLEM); appendSummary(result, parsedProblems); Collection<ReportMsg> postparsedFiltered = findOfTypes(ReportType.POSTPARSE_FILTER); appendSummary(result, postparsedFiltered); Collection<ReportMsg> skippedNoEmail = findOfTypes(ReportType.SKIPPED_NO_EMAIL); appendSummary(result, skippedNoEmail); Collection<ReportMsg> processed = findOfTypes(ReportType.TARGET); appendSummary(result, processed); Collection<ReportMsg> processFailed = findOfTypes(ReportType.TARGET_PROBLEM); appendSummary(result, processFailed); result.append("\n"); appendProcessedPersons(result, processed); result.append("\n"); appendFailedPersons(result, processFailed); result.append("\n"); appendSkippedNoEmail(result, skippedNoEmail); result.append("\n"); appendFiltered(result, postparsedFiltered); result.append("\n"); appendTitle(result, "All collected report messages (unformatted)", "-"); result.append("" + myMessages); return result.toString(); } /** * @param aResult * @param aFiltered */ private void appendFiltered(StringBuilder aSb, Collection<ReportMsg> aFiltered) { appendTitle(aSb, "Filtered while collecting the raw data", "-"); aFiltered.stream() .filter(msg -> (msg.getKey().equals("Skpped Persons (no mail address)")) && msg.getValue() instanceof Collection) .map(msg -> Collection.class.cast(msg.getValue())).forEach(list -> appendDatasetList(aSb, list)); } /** * @param aSb * @param aList * @return */ private void appendDatasetList(StringBuilder aSb, Collection<?> aList) { aList.stream().filter(p -> p instanceof Dataset).map(p -> Dataset.class.cast(p)) .forEach(p -> appendDataset(aSb, p)); } /** * @param aSb * @param aP * @return */ private void appendDataset(StringBuilder aSb, Dataset aDataset) { aSb.append(" ").append(aDataset).append("\n"); } /** * @param aResult * @param aSkippedNoEmail */ private void appendSkippedNoEmail(StringBuilder aSb, Collection<ReportMsg> aSkippedNoEmail) { appendTitle(aSb, "Skipped because there is no email address", "-"); aSkippedNoEmail.stream() .filter(msg -> (msg.getKey().equals("Skpped Persons (no mail address)")) && msg.getValue() instanceof Collection) .map(msg -> Collection.class.cast(msg.getValue())).forEach(list -> appendPersonList(aSb, list)); } /** * @param aResult * @param aProcessFailed */ private void appendFailedPersons(StringBuilder aSb, Collection<ReportMsg> aProcessFailed) { appendTitle(aSb, "Failed during processing", "-"); aProcessFailed.stream() .filter(msg -> (msg.getKey().equals("FailedPersons")) && msg.getValue() instanceof Collection) .map(msg -> Collection.class.cast(msg.getValue())).forEach(list -> appendPersonList(aSb, list)); } /** * @param aResult * @param aProcessed */ private void appendProcessedPersons(StringBuilder aSb, Collection<ReportMsg> aProcessed) { appendTitle(aSb, "Processed Persons", "-"); aProcessed.stream() .filter(msg -> (msg.getKey().equals("ProcessedPersons")) && msg.getValue() instanceof Collection) .map(msg -> Collection.class.cast(msg.getValue())).forEach(list -> appendPersonList(aSb, list)); aSb.append("\n"); appendTitle(aSb, "Persons already in target platform (duplicate)", "-"); aProcessed.stream() .filter(msg -> (msg.getKey().equals("DuplicatePersons")) && msg.getValue() instanceof Collection) .map(msg -> Collection.class.cast(msg.getValue())).forEach(list -> appendPersonList(aSb, list)); } private void appendPersonList(StringBuilder aSb, Collection<?> list) { list.stream().filter(p -> p instanceof Person).map(p -> Person.class.cast(p)) .forEach(p -> appendSimplePerson(aSb, p)); } private void appendSimplePerson(StringBuilder aSb, Person<?> p) { aSb.append(" ").append(p.getEMail()).append(" (").append(p.getGivenname()).append(" ") .append(p.getFamilyName()).append(")\n"); } /** * @param aResult * @param aMessages */ private void appendSummary(StringBuilder aSb, Collection<ReportMsg> aMessages) { aMessages.forEach(msg -> { Object value = msg.getValue(); if (value instanceof Collection) { value = ((Collection<?>) value).size(); } appendSimpleEntry(aSb, msg.getKey(), value); }); } /** * */ private void appendSimpleEntry(StringBuilder aSb, String aName, Object aValue) { aSb.append(aName).append(": ").append(aValue).append("\n"); } /** * @param aResult * @param aTitle * @param aUnderlineChar */ private void appendTitle(StringBuilder aSb, String aTitle, String aUnderlineChar) { aSb.append(aTitle).append("\n"); for (int i = 0; i < aTitle.length(); i++) { aSb.append(aUnderlineChar); } aSb.append("\n"); } private String findSimpleStringEntry(ReportType aReportType, String aKey) { return findSimpleEntry(aReportType, aKey, String.class); } /** * @param aCollector * @param aString * @return */ private <T> T findSimpleEntry(ReportType aReportType, String aKey, Class<T> aClass) { Collection<ReportMsg> messages = findOfTypes(aReportType); for (ReportMsg msg : messages) { if (msg.getKey().equals(aKey)) { Object o = msg.getValue(); if (aClass.isInstance(o)) { return aClass.cast(o); } // if aClass.isInstance( obj ) myLog.warn("Entry found for report type " + aReportType + " and key " + aKey + ", but not of desired type! Entry: " + o.getClass().getName() + "; expected: " + aClass.getName()); return null; } // if key.equals( aKey ) } myLog.warn("No entry found for report type " + aReportType + " and key " + aKey); return null; } /** * @param aReportType * @return */ private Collection<ReportMsg> findOfTypes(ReportType aReportType) { return myMessages.stream().filter(msg -> msg.getType() == aReportType).collect(Collectors.toSet()); } }