/* * This is eMonocot, a global online biodiversity information resource. * * Copyright © 2011–2015 The Board of Trustees of the Royal Botanic Gardens, Kew and The University of Oxford * * eMonocot is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * eMonocot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * The complete text of the GNU Affero General Public License is in the source repository as the file * ‘COPYING’. It is also available from <http://www.gnu.org/licenses/>. */ package org.emonocot.job.dwc; import java.util.List; import org.emonocot.harvest.common.AbstractRecordAnnotator; import org.emonocot.job.dwc.exception.CannotFindRecordException; import org.emonocot.job.dwc.exception.DarwinCoreProcessingException; import org.emonocot.model.Annotation; import org.emonocot.model.Base; import org.emonocot.model.constants.AnnotationCode; import org.emonocot.model.constants.AnnotationType; import org.emonocot.model.constants.RecordType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.ItemProcessListener; import org.springframework.batch.core.ItemReadListener; import org.springframework.batch.core.ItemWriteListener; import org.springframework.batch.item.file.FlatFileParseException; import org.springframework.validation.BindException; /** * * @author ben * */ public class DwCProcessingExceptionProcessListener extends AbstractRecordAnnotator implements ItemProcessListener<Base, Base>, ItemReadListener<Base>, ItemWriteListener<Base> { private Logger logger = LoggerFactory.getLogger(DwCProcessingExceptionProcessListener.class); public void beforeProcess(final Base item) { } public void afterProcess(final Base item, final Base result) { } public final void onProcessError(final Base item, final Exception e) { logger.error("Process Error " + e.getMessage(), e); Annotation annotation = new Annotation(); try { annotation.setRecordType(RecordType.valueOf(item.getClass().getSimpleName())); } catch (Exception ex) { annotation.setRecordType(getRecordType()); } annotation.setJobId(stepExecution.getJobExecutionId()); if (e instanceof DarwinCoreProcessingException) { DarwinCoreProcessingException dwcpe = (DarwinCoreProcessingException) e; logger.debug(dwcpe.getCode() + " | " + dwcpe.getMessage()); annotation.setCode(dwcpe.getCode()); annotation.setValue(dwcpe.getValue()); annotation.setType(dwcpe.getType()); } else { annotation.setCode(AnnotationCode.BadData);//TODO Replace with generic 'Something went wrong' annotation.setValue(stepExecution.getStepName() + " for " + item == null ? " unparsed item" : item.getIdentifier()); annotation.setType(AnnotationType.Error); } annotation.setText(e.getMessage()); super.annotate(annotation); } private RecordType getRecordType() { return DwCProcessingExceptionProcessListener.stepNameToRecordType(stepExecution.getStepName()); } /** * * @return the record type we are currently processing */ public static RecordType stepNameToRecordType(String stepName) { switch(stepName) { case "processCoreFile": return RecordType.Taxon; case "processDescriptionFile": return RecordType.Description; case "processIdentifierFile": return RecordType.Identifier; case "processImageFile": case "handleBinaryImages": return RecordType.Image; case "processReferenceFile": return RecordType.Reference; case "processDistributionFile": return RecordType.Distribution; case "processMeasurementOrFactFile": return RecordType.MeasurementOrFact; case "processVernacularNameFile": return RecordType.VernacularName; case "processTypeAndSpecimenFile": return RecordType.TypeAndSpecimen; case "processKeyFile": return RecordType.IdentificationKey; default: return null; } } public void afterRead(final Base base) { } public void beforeRead() { } public final void onReadError(final Exception e) { logger.error("Read Error " + e.getMessage()); if (e instanceof FlatFileParseException) { FlatFileParseException ffpe = (FlatFileParseException) e; StringBuffer message = new StringBuffer(); message.append(ffpe.getMessage()); final Annotation annotation = new Annotation(); if (ffpe.getCause() != null) { message.append(" " + ffpe.getCause().getMessage()); logger.debug("FlatFileParseException | " + ffpe.getMessage() + " Cause " + ffpe.getCause().getMessage()); if (ffpe.getCause().getClass() .equals(CannotFindRecordException.class)) { annotation.setCode(AnnotationCode.BadIdentifier); CannotFindRecordException cfre = (CannotFindRecordException) ffpe .getCause(); annotation.setValue(cfre.getValue()); } else if (ffpe.getCause().getClass() .equals(BindException.class)) { annotation.setCode(AnnotationCode.BadField); BindException be = (BindException) ffpe.getCause(); annotation.setValue(be.getFieldError().getField()); } else { annotation.setCode(AnnotationCode.BadRecord); } } else { logger.debug("FlatFileParseException | " + ffpe.getMessage()); } annotation.setJobId(stepExecution.getJobExecutionId()); annotation.setRecordType(getRecordType()); annotation.setType(AnnotationType.Error); annotation.setText(message.toString()); super.annotate(annotation); } } @Override public void beforeWrite(List<? extends Base> items) { } @Override public void afterWrite(List<? extends Base> items) { } @Override public void onWriteError(Exception exception, List<? extends Base> items) { logger.error(exception.getLocalizedMessage()); } }