net.solarnetwork.node.job.DatumDataSourceManagedLoggerJob.java Source code

Java tutorial

Introduction

Here is the source code for net.solarnetwork.node.job.DatumDataSourceManagedLoggerJob.java

Source

/* ==================================================================
 * 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;
    }

}