Java tutorial
/* ================================================================== * DatumDataSourceManagedLoggerJob.java - Aug 26, 2014 2:44:36 PM * * Copyright 2007-2014 SolarNetwork.net Dev Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * ================================================================== */ package net.solarnetwork.node.job; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import net.solarnetwork.node.DatumDataSource; import net.solarnetwork.node.MultiDatumDataSource; import net.solarnetwork.node.dao.DatumDao; import net.solarnetwork.node.domain.Datum; import net.solarnetwork.node.settings.KeyedSettingSpecifier; import net.solarnetwork.node.settings.SettingSpecifier; import net.solarnetwork.node.settings.SettingSpecifierProvider; import net.solarnetwork.util.OptionalService; import org.quartz.JobExecutionContext; import org.quartz.StatefulJob; import org.springframework.context.MessageSource; import org.springframework.dao.DuplicateKeyException; /** * Extension of {@link DatumDataSourceLoggerJob} designed to be used as a * managed service. * * <p> * This class implements {@link SettingSpecifierProvider} but delegates that API * to the configured {@link #getDatumDataSource()}. * </p> * * @author matt * @version 1.0 */ public class DatumDataSourceManagedLoggerJob<T extends Datum> extends AbstractJob implements StatefulJob, SettingSpecifierProvider { private DatumDataSource<T> datumDataSource = null; private MultiDatumDataSource<T> multiDatumDataSource = null; private OptionalService<DatumDao<T>> datumDao = null; @Override protected void executeInternal(JobExecutionContext jobContext) throws Exception { try { if (multiDatumDataSource != null) { executeForMultiDatumDataSource(jobContext); } else { executeForDatumDataSource(jobContext); } } catch (Throwable e) { logThrowable(e); } } private void executeForDatumDataSource(JobExecutionContext jobContext) { if (log.isDebugEnabled()) { log.debug("Collecting [{}] from [{}]", datumDataSource.getDatumType().getSimpleName(), datumDataSource); } T datum = datumDataSource.readCurrentDatum(); if (datum != null) { persistDatum(Collections.singleton(datum)); } else { log.info("No data returned from [{}]", datumDataSource); } } private void executeForMultiDatumDataSource(JobExecutionContext jobContext) { if (log.isDebugEnabled()) { log.debug("Collecting [{}] from [{}]", multiDatumDataSource.getMultiDatumType().getSimpleName(), multiDatumDataSource); } Collection<T> datum = multiDatumDataSource.readMultipleDatum(); if (datum != null && datum.size() > 0) { persistDatum(datum); } else { log.info("No data returned from [{}]", multiDatumDataSource); } } private void persistDatum(Collection<T> datumList) { if (datumList == null || datumList.size() < 1) { return; } if (log.isInfoEnabled()) { log.info("Got Datum to persist: {}", (datumList.size() == 1 ? datumList.iterator().next().toString() : datumList.toString())); } DatumDao<T> dao = datumDao.service(); if (dao == null) { log.info("No DatumDao available to persist {}, not saving", datumList); return; } for (T datum : datumList) { try { dao.storeDatum(datum); log.debug("Persisted Datum {}", datum); } catch (DuplicateKeyException e) { // we ignore duplicate key exceptions, as we sometimes collect the same // datum multiple times for redundancy log.info("Duplicate datum {}; not persisting", datum); } } } private SettingSpecifierProvider getSettingSpecifierProvider() { if (multiDatumDataSource instanceof SettingSpecifierProvider) { return (SettingSpecifierProvider) multiDatumDataSource; } if (datumDataSource instanceof SettingSpecifierProvider) { return (SettingSpecifierProvider) datumDataSource; } return null; } @Override public String getSettingUID() { SettingSpecifierProvider delegate = getSettingSpecifierProvider(); if (delegate != null) { return delegate.getSettingUID(); } return getDatumDataSource().getClass().getName(); } @Override public String getDisplayName() { SettingSpecifierProvider delegate = getSettingSpecifierProvider(); if (delegate != null) { return delegate.getDisplayName(); } return null; } @Override public MessageSource getMessageSource() { SettingSpecifierProvider delegate = getSettingSpecifierProvider(); if (delegate != null) { return delegate.getMessageSource(); } return null; } @Override public List<SettingSpecifier> getSettingSpecifiers() { SettingSpecifierProvider delegate = getSettingSpecifierProvider(); if (delegate == null) { return Collections.emptyList(); } List<SettingSpecifier> result = new ArrayList<SettingSpecifier>(); final String prefix = (multiDatumDataSource != null ? "multiDatumDataSource." : "datumDataSource."); for (SettingSpecifier spec : delegate.getSettingSpecifiers()) { if (spec instanceof KeyedSettingSpecifier<?>) { KeyedSettingSpecifier<?> keyedSpec = (KeyedSettingSpecifier<?>) spec; result.add(keyedSpec.mappedTo(prefix)); } else { result.add(spec); } } return result; } public DatumDataSource<T> getDatumDataSource() { return datumDataSource; } public void setDatumDataSource(DatumDataSource<T> datumDataSource) { this.datumDataSource = datumDataSource; } public MultiDatumDataSource<T> getMultiDatumDataSource() { return multiDatumDataSource; } public void setMultiDatumDataSource(MultiDatumDataSource<T> multiDatumDataSource) { this.multiDatumDataSource = multiDatumDataSource; } public OptionalService<DatumDao<T>> getDatumDao() { return datumDao; } public void setDatumDao(OptionalService<DatumDao<T>> datumDao) { this.datumDao = datumDao; } }