package nl.ipo.cds.etl; import static nl.idgis.commons.jobexecutor.JobLogger.LogLevel.ERROR; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import nl.idgis.commons.jobexecutor.JobLogger; import nl.idgis.commons.jobexecutor.JobLogger.LogLevel; import nl.ipo.cds.attributemapping.operations.OperationType; import nl.ipo.cds.attributemapping.operations.discover.OperationDiscoverer; import nl.ipo.cds.dao.ManagerDao; import nl.ipo.cds.dao.attributemapping.AttributeMappingDao; import nl.ipo.cds.dao.attributemapping.OperationDTO; import nl.ipo.cds.domain.CodeListMapping; import nl.ipo.cds.domain.Dataset; import nl.ipo.cds.domain.DatasetFilter; import nl.ipo.cds.domain.EtlJob; import nl.ipo.cds.domain.FeatureType; import nl.ipo.cds.etl.db.DBWriterFactory; import nl.ipo.cds.etl.featurecollection.ExceptionReport; import nl.ipo.cds.etl.featurecollection.FeatureCollection; import nl.ipo.cds.etl.featurecollection.WFSResponse; import nl.ipo.cds.etl.featurecollection.WFSResponseReader; import nl.ipo.cds.etl.featuretype.FeatureTypeNotFoundException; import nl.ipo.cds.etl.filtering.FeatureClipper; import nl.ipo.cds.etl.log.EventLogger; import nl.ipo.cds.etl.process.DatasetMetadata; import nl.ipo.cds.etl.process.HarvesterException; import nl.ipo.cds.etl.theme.AttributeDescriptor; import nl.ipo.cds.etl.theme.ThemeConfig; import nl.ipo.cds.utils.UrlUtils; import nl.ipo.cds.validation.gml.codelists.AtomCodeListFactory; import nl.ipo.cds.validation.gml.codelists.CodeListFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.deegree.cs.exceptions.UnknownCRSException; import org.deegree.feature.types.AppSchema; public class DefaultDatasetHandlers<T extends PersistableFeature> implements DatasetHandlers<T> { private final ThemeConfig<T> themeConfig; protected final ManagerDao managerDao; private final Collection<OperationType> operationTypes; private static final Log technicalLog = LogFactory.getLog(AbstractProcess.class); private final static LogLevel LOG_LEVEL = LogLevel.ERROR; public DefaultDatasetHandlers( final OperationDiscoverer operationDiscoverer, final ThemeConfig<T> themeConfig, final ManagerDao managerDao) { this.themeConfig = themeConfig; this.managerDao = managerDao; this.operationTypes = operationDiscoverer.getOperationTypes(); } @Override public Class<T> getBeanClass() { return themeConfig.getFeatureTypeClass(); } @Override public DBWriterFactory<T> getDBWriterFactory(String... constColumns) { return new DBWriterFactory<T>(getBeanClass(), constColumns); } @Override public ThemeConfig<T> getThemeConfig() { return themeConfig; } @Override public Map<AttributeDescriptor<?>, OperationDTO> getAttributeMappings( final EtlJob job, final FeatureType featureType) { final Dataset dataset = getDatasetForJob(job); final AttributeMappingDao attributeMappingDao = new AttributeMappingDao( managerDao, featureType.getAttributes(), operationTypes); if (dataset == null) { return new HashMap<AttributeDescriptor<?>, OperationDTO>(); } final Map<AttributeDescriptor<?>, OperationDTO> mappings = new HashMap<AttributeDescriptor<?>, OperationDTO>(); for (final AttributeDescriptor<?> ad : themeConfig .getAttributeDescriptors()) { mappings.put(ad, attributeMappingDao.getAttributeMapping(dataset, ad)); } return mappings; } @Override public FeatureClipper getFeatureClipper(final EtlJob job, final JobLogger logger) { return null; } @Override public DatasetFilter getDatasetFilter(final EtlJob job) { final Dataset dataset = getDatasetForJob(job); if (dataset == null) { return null; } return managerDao.getDatasetFilter(dataset); } @Override public CodeListFactory getCodeListFactory(final EtlJob job) { final List<CodeListMapping> mappings = managerDao.getCodeListMappings(); final Map<String, String> codeListMappings = new HashMap<String, String>(); for (final CodeListMapping mapping : mappings) { codeListMappings.put(mapping.getCodeSpace(), mapping.getUrl()); } return new AtomCodeListFactory(codeListMappings); } private Dataset getDatasetForJob(final EtlJob job) { for (final Dataset dataset : managerDao.getDatasetsByUUID(job.getUuid())) { if (dataset.getBronhouder().getId().equals(job.getBronhouder().getId()) && dataset.getDatasetType().getId().equals(job.getDatasetType().getId())) { return dataset; } } return null; } @Override public FeatureCollection retrieveFeaturesFromBronhouder(EtlJob job, FeatureProcessor featureProcessor, final EventLogger<AbstractProcess.MessageKey> userLog, final DatasetMetadata md) { AppSchema appSchema = null; try { appSchema = themeConfig.getSchemaHarvester() .parseApplicationSchema(md); } catch (HarvesterException e) { technicalLog.debug(String.format( "Failed to get application schema from WFS: %s", e.getMessage()), e); return null; } InputStream is = null; try { is = initConnection(job, job.getDatasetUrl(), userLog); if (is == null) { return null; } String featureTypeName = md.getFeatureTypeName(); XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance() .createXMLStreamReader(is); return retrieveFeaturesFromWfs(job, featureTypeName, userLog, xmlStreamReader, appSchema); } catch (Exception e) { technicalLog.debug(String.format( "Failed to initiate GetFeature request to WFS: %s", e.getMessage()), e); userLog.logEvent(job, AbstractProcess.MessageKey.XML_FEATURES_EXCEPTION, LogLevel.ERROR, e.getMessage()); } return null; } protected InputStream initConnection(EtlJob job, String url, final EventLogger<AbstractProcess.MessageKey> userLog) throws IOException { try { return UrlUtils.open(new URL (url)); } catch (IOException e) { userLog.logEvent(job, AbstractProcess.MessageKey.XML_FEATURES_HTTP_ERROR, ERROR, e.getMessage()); throw e; } } private FeatureCollection retrieveFeaturesFromWfs(EtlJob job, final String featureTypeName, final EventLogger<AbstractProcess.MessageKey> userLog, XMLStreamReader xmlStreamReader, final AppSchema appSchema) throws XMLStreamException, FeatureTypeNotFoundException, UnknownCRSException { WFSResponseReader wfsResponseReader = new WFSResponseReader(); WFSResponse wfsResponse = wfsResponseReader.parseWFSResponse( xmlStreamReader, appSchema, featureTypeName); if (wfsResponse.isFeatureCollection()) { return wfsResponse.getFeatureCollection(); } String message = null; if (wfsResponse.isExceptionReport()) { ExceptionReport exceptionReport = wfsResponse.getExceptionReport(); message = userLog.logEvent( job, AbstractProcess.MessageKey.WFS_EXCEPTIONREPORT, LOG_LEVEL, exceptionReport.hasExceptionCode() ? exceptionReport .getExceptionCode() : "onbekend", exceptionReport.hasLocator() ? exceptionReport.getLocator() : "onbekend", exceptionReport.hasExceptionText() ? exceptionReport .getExceptionText() : "onbekend"); } else { message = userLog.logEvent(job, AbstractProcess.MessageKey.WFS_UNPARSEBLE_RESPONSE, LOG_LEVEL); } technicalLog.warn(message); return null; } }