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.war.cascade.handlers; import com.jaspersoft.jasperserver.api.common.domain.impl.ExecutionContextImpl; import com.jaspersoft.jasperserver.api.engine.common.service.EngineService; import com.jaspersoft.jasperserver.api.engine.common.service.ReportInputControlInformation; import com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.EhcacheEngineService; import com.jaspersoft.jasperserver.api.metadata.common.domain.InputControl; import com.jaspersoft.jasperserver.api.metadata.common.domain.ListOfValuesItem; import com.jaspersoft.jasperserver.api.metadata.common.domain.Query; import com.jaspersoft.jasperserver.api.metadata.common.domain.Resource; import com.jaspersoft.jasperserver.api.metadata.common.domain.ResourceReference; import com.jaspersoft.jasperserver.api.metadata.common.domain.client.ListOfValuesItemImpl; import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportDataSource; import com.jaspersoft.jasperserver.api.metadata.jasperreports.service.ReportDataSourceService; import com.jaspersoft.jasperserver.war.cascade.CachedEngineService; import com.jaspersoft.jasperserver.war.cascade.CachedRepositoryService; import com.jaspersoft.jasperserver.war.cascade.CascadeResourceNotFoundException; import com.jaspersoft.jasperserver.war.cascade.handlers.converters.DataConverterService; import com.jaspersoft.jasperserver.war.cascade.token.FilterResolver; import org.apache.commons.collections.OrderedMap; import org.apache.commons.collections.OrderedMapIterator; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; /** * @author Yaroslav.Kovalchyk * @version $Id: QueryValuesLoader.java 48468 2014-08-21 07:47:20Z yuriy.plakosh $ */ @Service public class QueryValuesLoader implements ValuesLoader { public static final String COLUMN_VALUE_SEPARATOR = " | "; @javax.annotation.Resource protected FilterResolver filterResolver; @javax.annotation.Resource protected CachedRepositoryService cachedRepositoryService; @javax.annotation.Resource protected CachedEngineService cachedEngineService; @javax.annotation.Resource protected EngineService engineService; @javax.annotation.Resource private DataConverterService dataConverterService; @Override public List<ListOfValuesItem> loadValues(InputControl inputControl, ResourceReference dataSource, Map<String, Object> parameters, Map<String, Class<?>> parameterTypes, ReportInputControlInformation info) throws CascadeResourceNotFoundException { List<ListOfValuesItem> result = null; ResourceReference dataSourceForQuery = resolveDatasource(inputControl, dataSource); final Query query = cachedRepositoryService.getResource(Query.class, inputControl.getQuery()); Map<String, Object> domainSchemaParameters = new HashMap<String, Object>(); //TODO Extract this parameter extension to separate interface prepareDomainDataSource(dataSourceForQuery, domainSchemaParameters); Map<String, Object> executionParameters = filterAndFillMissingQueryParameters(query, parameters, domainSchemaParameters); Map<String, Class<?>> executionParameterTypes = filterParameterTypes(executionParameters.keySet(), parameterTypes); if (parameters != null && parameters.containsKey(EhcacheEngineService.IC_REFRESH_KEY)) { executionParameters.put(EhcacheEngineService.IC_REFRESH_KEY, "true"); } /* Typed results are returned */ OrderedMap results = cachedEngineService.executeQuery(ExecutionContextImpl.getRuntimeExecutionContext(), inputControl.getQuery(), inputControl.getQueryValueColumn(), inputControl.getQueryVisibleColumns(), dataSourceForQuery, executionParameters, executionParameterTypes, inputControl.getName()); if (results != null) { OrderedMapIterator it = results.orderedMapIterator(); while (it.hasNext()) { if (result == null) result = new ArrayList<ListOfValuesItem>(results.size()); Object valueColumn = it.next(); Object[] visibleColumns = (Object[]) it.getValue(); StringBuilder label = new StringBuilder(); for (int i = 0; i < visibleColumns.length; i++) { Object visibleColumn = visibleColumns[i]; String visibleColumnName = inputControl.getQueryVisibleColumns()[i]; boolean isVisibleColumnMatchesValueColumn = inputControl.getQueryValueColumn() .equals(visibleColumnName); if (label.length() > 0) { label.append(COLUMN_VALUE_SEPARATOR); } String formattedValue = formatValueToString(visibleColumn, isVisibleColumnMatchesValueColumn, inputControl, info); label.append( visibleColumn != null ? formattedValue : InputControlHandler.NULL_SUBSTITUTION_LABEL); } ListOfValuesItem item = new ListOfValuesItemImpl(); item.setLabel(label.toString()); if (valueColumn instanceof BigDecimal) { valueColumn = ((BigDecimal) valueColumn).stripTrailingZeros(); } item.setValue(valueColumn); result.add(item); } } return result; } private String formatValueToString(Object visibleColumn, boolean isVisibleColumnMatchesValueColumn, InputControl inputControl, ReportInputControlInformation info) throws CascadeResourceNotFoundException { if (isVisibleColumnMatchesValueColumn) { return dataConverterService.formatSingleValue(visibleColumn, inputControl, info); } else { return dataConverterService.formatSingleValue(visibleColumn, (InputControl) null, null); } } /** * DomainFilterResolver needs access to the domain schema, which it can get from * the param map. FilterCore doesn't need this, and it would allocate a connection * that's not needed. */ protected void prepareDomainDataSource(ResourceReference dataSourceRef, Map<String, Object> parameters) throws CascadeResourceNotFoundException { ReportDataSource dataSource = (ReportDataSource) cachedRepositoryService.getResource(Resource.class, dataSourceRef); if (filterResolver.paramTestNeedsDataSourceInit(dataSource)) { parameters.putAll(cachedEngineService.getSLParameters(dataSource)); } } /** * Create new Map with specified parameters, add only those which are used in query, find missing parameters and assign value Null to them. * This is done because we indicate Nothing selection in single select control as absence of parameter in map, * but QueryManipulator sets query to empty string and Executor throws exception if parameter is absent, * so we set Null as most suitable value as yet. * * @param query Query * @param parameters Map<String, Object> * @return Map<String, Object> copy of map, where missing parameters filled with Null values. */ protected Map<String, Object> filterAndFillMissingQueryParameters(Query query, Map<String, Object> parameters, Map<String, Object> domainSchemaParameters) { HashMap<String, Object> parametersWithSchema = new HashMap<String, Object>(); parametersWithSchema.putAll(parameters); parametersWithSchema.putAll(domainSchemaParameters); Set<String> queryParameterNames = filterResolver.getParameterNames(query.getSql(), parametersWithSchema); HashMap<String, Object> resolvedParameters = new HashMap<String, Object>(); for (String queryParameterName : queryParameterNames) { // If parameter is missing, set Null. resolvedParameters.put(queryParameterName, parameters.get(queryParameterName)); } resolvedParameters.putAll(domainSchemaParameters); return resolvedParameters; } /** * Filter only specified parameter types * @param parameters Parameter names * @param parameterTypes Map of parameter types * @return Filtered map of parameter types */ protected Map<String, Class<?>> filterParameterTypes(Set<String> parameters, Map<String, Class<?>> parameterTypes) { Map<String, Class<?>> filteredParameterTypes = new HashMap<String, Class<?>>(parameters.size()); for (String parameterName : parameters) { if (parameterTypes.containsKey(parameterName)) { filteredParameterTypes.put(parameterName, parameterTypes.get(parameterName)); } } return filteredParameterTypes; } @Override public Set<String> getMasterDependencies(InputControl inputControl, ResourceReference dataSource) throws CascadeResourceNotFoundException { Map<String, Object> filterParameters = new HashMap<String, Object>(); ResourceReference dataSourceForQuery = resolveDatasource(inputControl, dataSource); prepareDomainDataSource(dataSourceForQuery, filterParameters); Query query = cachedRepositoryService.getResource(Query.class, inputControl.getQuery()); String querySQL = query.getSql(); return filterResolver.getParameterNames(querySQL, filterParameters); } protected ResourceReference resolveDatasource(InputControl inputControl, ResourceReference reportDatasource) throws CascadeResourceNotFoundException { ResourceReference queryReference = inputControl.getQuery(); ResourceReference resolvedDatasource = reportDatasource; if (queryReference != null) { Resource queryResource = cachedRepositoryService.getResource(Resource.class, queryReference); if (queryResource instanceof Query && ((Query) queryResource).getDataSource() != null) { resolvedDatasource = ((Query) queryResource).getDataSource(); } } return resolvedDatasource; } }