Java tutorial
/* * Copyright (C) 2005 - 2014 TIBCO Software Inc. All rights reserved. * http://www.jaspersoft.com. * * Unless you have purchased a commercial license agreement from Jaspersoft, * the following license terms apply: * * This program 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. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl; import java.util.Date; import java.util.Map; import net.sf.jasperreports.data.cache.DataCacheHandler; import net.sf.jasperreports.data.cache.DataSnapshot; import net.sf.jasperreports.data.cache.PopulatedSnapshotCacheHandler; import net.sf.jasperreports.engine.ReportContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.jaspersoft.jasperserver.api.common.domain.ExecutionContext; import com.jaspersoft.jasperserver.api.engine.jasperreports.domain.impl.ReportUnitRequestBase; import com.jaspersoft.jasperserver.api.engine.jasperreports.service.DataCacheProvider; import com.jaspersoft.jasperserver.api.engine.jasperreports.service.DataSnapshotService; import com.jaspersoft.jasperserver.api.engine.jasperreports.util.DefaultDataCacheSnapshot; import com.jaspersoft.jasperserver.api.metadata.common.domain.Resource; import com.jaspersoft.jasperserver.api.metadata.data.cache.DataCacheSnapshot; import com.jaspersoft.jasperserver.api.metadata.data.cache.DataSnapshotPersistentMetadata; import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportUnit; /** * @author Lucian Chirita (lucianc@users.sourceforge.net) * @version $Id: StandardDataCacheProvider.java 47331 2014-07-18 09:13:06Z kklein $ */ public class StandardDataCacheProvider implements DataCacheProvider { private static final Log log = LogFactory.getLog(StandardDataCacheProvider.class); private ReportLoadingService reportLoadingService; private DataSnapshotService dataSnapshotService; private String dataSnapshotProviderParameter = "com.jaspersoft.jasperserver.data.snapshot.provider";//default value public DataCacheSnapshot setReportExecutionCache(ExecutionContext context, ReportUnitRequestBase request, ReportUnit reportUnit, Map<String, Object> dataParameters) { if (!(request.isUseDataSnapshot() || (dataSnapshotService.isSnapshotRecordingEnabled() && request.isRecordDataSnapshot()))) { // nothing to do if (log.isDebugEnabled()) { log.debug("no data caching"); } return null; } ReportContext reportContext = request.getReportContext(); if (reportContext == null) { if (log.isDebugEnabled()) { log.debug("no report context"); } return null; } ReportDataCacheProvider cacheProvider = (ReportDataCacheProvider) reportContext .getParameterValue(getDataSnapshotProviderParameter()); if (cacheProvider == null) { cacheProvider = createReportCacheProvider(); reportContext.setParameterValue(dataSnapshotProviderParameter, cacheProvider); } DataCacheHandler cacheHandler = null; // check if we have a populated snapshot DataCacheSnapshot dataSnapshot = loadDataSnapshot(context, request, reportUnit, dataParameters, cacheProvider); if (dataSnapshot != null) { if (log.isDebugEnabled()) { log.debug("found data snapshot"); } // use a cache handler that provides the snapshot cacheHandler = new PopulatedSnapshotCacheHandler(dataSnapshot.getSnapshot()); } else if (dataSnapshotService.isSnapshotRecordingEnabled() && request.isRecordDataSnapshot()) { if (log.isDebugEnabled()) { log.debug("creating recording cache handler"); } // create a recording cache handler cacheHandler = cacheProvider.createRecordHandler(dataParameters); } if (cacheHandler != null) { // populate the cache handler if we have one reportContext.setParameterValue(DataCacheHandler.PARAMETER_DATA_CACHE_HANDLER, cacheHandler); } return dataSnapshot; } public void handleInvalidSnapshot(ExecutionContext context, ReportUnitRequestBase request, ReportUnit reportUnit, Map<String, Object> dataParameters) { ReportContext reportContext = request.getReportContext(); if (reportContext == null) { if (log.isDebugEnabled()) { log.debug("no report context"); } return; } DataCacheHandler cacheHandler = (DataCacheHandler) reportContext .getParameterValue(DataCacheHandler.PARAMETER_DATA_CACHE_HANDLER); if (cacheHandler != null && cacheHandler.isSnapshotPopulated()) { if (log.isDebugEnabled()) { log.debug("removing populated data snapshot"); } // removing the populated data cache reportContext.setParameterValue(DataCacheHandler.PARAMETER_DATA_CACHE_HANDLER, null); } ReportDataCacheProvider cacheProvider = (ReportDataCacheProvider) reportContext .getParameterValue(getDataSnapshotProviderParameter()); // the cache provider should already exist if (cacheProvider != null) { DataCacheSnapshot snapshot = cacheProvider.getSnapshot(); if (snapshot != null && snapshot.isSaved()) { // clear the invalid snapshot cacheProvider.setSnapshot(null); // an invalid saved snapshot is treated like an non existing snapshot cacheProvider.setHadSavedSnapshot(false); } // create a recording cache handler if (dataSnapshotService.isSnapshotRecordingEnabled() && request.isRecordDataSnapshot()) { if (log.isDebugEnabled()) { log.debug("creating recording cache handler"); } DataCacheHandler recordingHandler = cacheProvider.createRecordHandler(dataParameters); reportContext.setParameterValue(DataCacheHandler.PARAMETER_DATA_CACHE_HANDLER, recordingHandler); } } } protected ReportDataCacheProvider createReportCacheProvider() { return new ReportDataCacheProvider(); } protected DataCacheSnapshot loadDataSnapshot(ExecutionContext context, ReportUnitRequestBase request, ReportUnit reportUnit, Map<String, Object> dataParameters, ReportDataCacheProvider cacheProvider) { if (reportUnit.getDataSnapshotId() != null) { // if the report has a snapshot Id, set the flag in the report provider cacheProvider.setHadSavedSnapshot(true); } if (!request.isUseDataSnapshot()) { if (log.isDebugEnabled()) { log.debug("not using data snapshot"); } return null; } DataCacheSnapshot dataSnapshot = cacheProvider.getSnapshot(); if (dataSnapshot != null) { if (!parametersMatch(dataParameters, dataSnapshot.getMetadata().getParameters())) { if (log.isDebugEnabled()) { log.debug("current snapshot doesn't match the parameters"); } cacheProvider.clearSnapshot(); dataSnapshot = null; } } if (dataSnapshot == null) { // try to load the persistent snapshot dataSnapshot = useSavedDataSnapshot(context, reportUnit, dataParameters, cacheProvider); } return dataSnapshot; } protected DataCacheSnapshot useSavedDataSnapshot(ExecutionContext context, ReportUnit reportUnit, Map<String, Object> dataParameters, ReportDataCacheProvider cacheProvider) { DataSnapshotPersistentMetadata persistentSnapshot = loadSavedDataSnapshot(context, reportUnit); if (persistentSnapshot == null) { // this means no or out of date snapshot, reset the flag cacheProvider.setHadSavedSnapshot(false); return null; } if (!parametersMatch(dataParameters, persistentSnapshot.getSnapshotMetadata().getParameters())) { // the cached/saved snapshot is the latest version but doesn't match the parameters if (log.isDebugEnabled()) { log.debug("cached data snapshot " + reportUnit.getDataSnapshotId() + " with version " + persistentSnapshot.getVersion() + " doesn't match the parameters"); } return null; } if (log.isDebugEnabled()) { log.debug("found matching saved data snapshot " + reportUnit.getDataSnapshotId() + " at version " + persistentSnapshot.getVersion()); } DataSnapshot snapshotContents = dataSnapshotService.getSnapshotContents(context, persistentSnapshot.getContentsId()); if (snapshotContents == null) { if (log.isDebugEnabled()) { log.debug("data snapshot contents " + persistentSnapshot.getContentsId() + " not found for " + reportUnit.getURIString()); } return null; } DefaultDataCacheSnapshot dataSnapshot = new DefaultDataCacheSnapshot(snapshotContents, persistentSnapshot.getSnapshotMetadata()); cacheProvider.setSavedDataSnapshot(dataSnapshot); return dataSnapshot; } public DataSnapshotPersistentMetadata loadSavedDataSnapshot(ExecutionContext context, ReportUnit reportUnit) { Long snapshotId = reportUnit.getDataSnapshotId(); if (snapshotId == null) { return null; } if (!dataSnapshotService.isSnapshotPersistenceEnabled()) { // if snapshot persistence is disabled, don't use saved snapshots if (log.isDebugEnabled()) { log.debug("snapshot persistence is disabled, not using snapshot " + snapshotId + " for report " + reportUnit.getURIString()); } return null; } // try to load the persistent snapshot if (log.isDebugEnabled()) { log.debug("loading saved data snapshot " + snapshotId + " for " + reportUnit.getURIString()); } DataSnapshotPersistentMetadata persistentSnapshot = dataSnapshotService.getSnapshotMetadata(context, snapshotId); if (persistentSnapshot == null) { if (log.isDebugEnabled()) { log.debug("data snapshot " + snapshotId + " not found for " + reportUnit.getURIString()); } return null; } Date snapshotDate = persistentSnapshot.getSnapshotMetadata().getSnapshotDate(); Resource dataSource = getReportLoadingService().getFinalResource(context, reportUnit.getDataSource(), Resource.class); Date dataSourceTimestamp = dataSource == null ? null : dataSource.getUpdateDate(); if (dataSourceTimestamp != null && !snapshotDate.after(dataSourceTimestamp)) { // snapshot is older than data source, considering invalid if (log.isDebugEnabled()) { log.debug("data snapshot " + snapshotId + " of " + reportUnit.getURIString() + " is older (" + snapshotDate + ") than data source (" + dataSourceTimestamp + ")"); } return null; } return persistentSnapshot; } public DataCacheSnapshot getDataSnapshot(ExecutionContext context, ReportContext reportContext) { ReportDataCacheProvider cacheProvider = (ReportDataCacheProvider) reportContext .getParameterValue(getDataSnapshotProviderParameter()); if (cacheProvider == null) { if (log.isDebugEnabled()) { log.debug("no cache provider found"); } return null; } return cacheProvider.getSnapshot(); } public boolean parametersMatch(Map<String, Object> dataParameters, Map<String, Object> snapshotParams) { boolean match = true; for (Map.Entry<String, Object> dataParamsEntry : dataParameters.entrySet()) { String key = dataParamsEntry.getKey(); Object value = dataParamsEntry.getValue(); Object snapshotValue = snapshotParams == null ? null : snapshotParams.get(key); if (value == null ? (snapshotValue != null) : (snapshotValue == null || !value.equals(snapshotValue))) { match = false; break; } } return match; } public void snapshotSaved(ExecutionContext context, ReportContext reportContext, DataCacheSnapshot snapshot, Long savedSnapshotId) { // the only thing we need to do is mark the snapshot as saved if (!snapshot.isSaved()) { ReportDataCacheProvider cacheProvider = (ReportDataCacheProvider) reportContext .getParameterValue(getDataSnapshotProviderParameter()); if (cacheProvider != null) { cacheProvider.setSavedDataSnapshot(snapshot); cacheProvider.setHadSavedSnapshot(true); } } } public SnapshotSaveStatus getSnapshotSaveStatus(ReportContext reportContext) { ReportDataCacheProvider cacheProvider = reportContext == null ? null : (ReportDataCacheProvider) reportContext.getParameterValue(getDataSnapshotProviderParameter()); SnapshotSaveStatus status; if (cacheProvider == null) { // should not happen, so let's be conservative status = SnapshotSaveStatus.NO_CHANGE; } else { DataCacheSnapshot snapshot = cacheProvider.getSnapshot(); boolean hadSavedSnapshot = cacheProvider.hadSavedSnapshot(); if (!dataSnapshotService.isSnapshotPersistenceEnabled() || snapshot == null || !snapshot.getSnapshot().isPersistable()) { // if we can't save a snapshot, check if we had a saved snapshot that we need to delete status = hadSavedSnapshot ? SnapshotSaveStatus.UPDATED : SnapshotSaveStatus.NO_CHANGE; } else if (snapshot.isSaved()) { // already saved snapshot status = SnapshotSaveStatus.NO_CHANGE; } else { // we have a new snapshot to save, check if there is an old one status = hadSavedSnapshot ? SnapshotSaveStatus.UPDATED : SnapshotSaveStatus.NEW; } } return status; } public String getDataSnapshotProviderParameter() { return dataSnapshotProviderParameter; } public void setDataSnapshotProviderParameter(String dataSnapshotProviderParameter) { this.dataSnapshotProviderParameter = dataSnapshotProviderParameter; } public ReportLoadingService getReportLoadingService() { return reportLoadingService; } public void setReportLoadingService(ReportLoadingService reportLoadingService) { this.reportLoadingService = reportLoadingService; } public DataSnapshotService getDataSnapshotService() { return dataSnapshotService; } public void setDataSnapshotService(DataSnapshotService dataSnapshotService) { this.dataSnapshotService = dataSnapshotService; } }