net.sf.jasperreports.functions.annotations.FunctionsInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasperreports Show documentation
Show all versions of jasperreports Show documentation
Free Java Reporting Library
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2019 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 part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
package net.sf.jasperreports.functions.annotations;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.util.MessageProvider;
import net.sf.jasperreports.engine.util.MessageUtil;
import net.sf.jasperreports.functions.FunctionsBundle;
import net.sf.jasperreports.functions.FunctionsRegistryFactory;
import net.sf.jasperreports.functions.FunctionsUtil;
/**
* @author Teodor Danciu ([email protected])
*/
public class FunctionsInfo
{
/**
*
*/
public static final String DEFAULT_MESSAGES_BUNDLE = "jasperreports_messages";
public static final String PROPERTY_SUFFIX_NAME = "name";
public static final String PROPERTY_SUFFIX_DESCRIPTION = "description";
public static final String PROPERTY_SUFFIX_TYPE = "type";
public static final String PROPERTY_PARAMETER_REQUIRED = FunctionsRegistryFactory.FUNCTIONS_CLASSES_PROPERTY_PREFIX +"parameter.required";
public static final String PROPERTY_PARAMETER_OPTIONAL = FunctionsRegistryFactory.FUNCTIONS_CLASSES_PROPERTY_PREFIX +"parameter.optional";
/**
*
*/
private final JasperReportsContext jasperReportsContext;
private final Locale locale;
private final MessageUtil messageUtil;
private final Map categories = new HashMap();
/**
*
*/
private FunctionsInfo(JasperReportsContext jasperReportsContext, Locale locale)
{
this.jasperReportsContext = jasperReportsContext;
this.locale = locale;
this.messageUtil = MessageUtil.getInstance(jasperReportsContext);
addFunctions();
}
/**
*
*/
public static FunctionsInfo getInstance(JasperReportsContext jasperReportsContext, Locale locale)
{
return new FunctionsInfo(jasperReportsContext, locale);
}
/**
*
*/
public Collection getCategories()
{
return categories.values();
}
/**
*
*/
protected void addFunctions()
{
List bundles = FunctionsUtil.getInstance(jasperReportsContext).getAllFunctionBundles();
for (FunctionsBundle bundle : bundles)
{
List> functionClasses = bundle.getFunctionClasses();
if(functionClasses != null && !functionClasses.isEmpty())
{
for (Class functionClass : functionClasses)
{
addFunctionClass(functionClass);
}
}
}
}
/**
*
*/
protected void addFunctionClass(Class functionClass)
{
FunctionCategories categories = functionClass.getAnnotation(FunctionCategories.class);
Set defaultCategories = addCategories(categories);
MessageProvider provider = getMessageProvider(functionClass);
Method[] methods = functionClass.getMethods();
if (methods != null && methods.length > 0)
{
for (Method method : methods)
{
addFunction(method, provider, defaultCategories, getBoundaryMethods(method, methods));
}
}
}
/**
*
*/
protected Set addCategories(FunctionCategories categories)
{
Set categoryIds = null;
if(categories != null)
{
categoryIds = new HashSet();
for(Class categoryClass : categories.value())
{
String categoryId = addCategoryClass(categoryClass);
categoryIds.add(categoryId);
}
}
return categoryIds;
}
/**
*
*/
protected void addFunction(Method functionMethod, MessageProvider provider, Set categoryIds, Method[] boundaryMethods)
{
Function function = functionMethod.getAnnotation(Function.class);
if(function != null)
{
String functionId = functionMethod.getDeclaringClass().getName() + "." + function.value();
FunctionBean functionBean =
new FunctionBean(
functionId,
getName(functionId, provider),
getDescription(functionId, provider),
functionMethod.getReturnType()
);
FunctionParameters functionParameters = functionMethod.getAnnotation(FunctionParameters.class);
Class[] minParameters = boundaryMethods[0].getParameterTypes();
Class[] maxParameters = boundaryMethods[1].getParameterTypes();
int params = 0, requiredParams = minParameters.length;
if (functionParameters != null && functionParameters.value().length > 0)
{
for(FunctionParameter functionParameter : functionParameters.value())
{
addFunctionParameter(functionBean, functionParameter, provider, maxParameters[params], params < requiredParams);
++params;
}
}
FunctionParameter functionParameter = functionMethod.getAnnotation(FunctionParameter.class);
if(functionParameter != null)
{
addFunctionParameter(functionBean, functionParameter, provider, maxParameters[params], params < requiredParams);
}
FunctionCategories functionCategories = functionMethod.getAnnotation(FunctionCategories.class);
Set functionCategoryIds = addCategories(functionCategories);
if (functionCategoryIds != null && functionCategoryIds.size() > 0)
{
categoryIds = functionCategoryIds;
}
for(String categoryId : categoryIds)
{
FunctionCategoryBean categoryBean = categories.get(categoryId);
categoryBean.addFunction(functionBean);
}
}
}
/**
*
*/
protected void addFunctionParameter(FunctionBean functionBean, FunctionParameter functionParameter, MessageProvider provider, Class type, boolean isRequired)
{
String parameterId = functionBean.getId() + "." + functionParameter.value();
FunctionParameterBean functionParameterBean =
new FunctionParameterBean(
parameterId,
getName(parameterId, provider),
getDescription(parameterId, provider),
type,
isRequired
);
functionBean.addParameter(functionParameterBean);
}
/**
*
*/
protected String addCategoryClass(Class categoryClass)
{
MessageProvider provider = getMessageProvider(categoryClass);
String categoryId = categoryClass.getName();
FunctionCategory category = categoryClass.getAnnotation(FunctionCategory.class);
if(category != null && category.value() != null && category.value().trim().length() > 0)
{
categoryId = category.value();
}
FunctionCategoryBean categoryBean = new FunctionCategoryBean(
categoryId,
getName(categoryId, provider),
getDescription(categoryId, provider));
categories.put(categoryId, categoryBean);
return categoryId;
}
/**
*
*/
private MessageProvider getMessageProvider(Class clazz)
{
FunctionMessagesBundle functionMessagesBundle = clazz.getAnnotation(FunctionMessagesBundle.class);
String messagesBundle =
functionMessagesBundle == null
? getDefaultMessageBundle(clazz)
: functionMessagesBundle.value();
return messageUtil.getMessageProvider(messagesBundle);//FIXME cache them
}
/**
*
*/
private String getDefaultMessageBundle(Class clazz)
{
return clazz.getPackage().getName() + "." + DEFAULT_MESSAGES_BUNDLE;
}
/**
*
*/
private String getName(String key, MessageProvider provider)
{
return provider.getMessage(key + "." + PROPERTY_SUFFIX_NAME, null, locale);
}
/**
*
*/
private String getDescription(String key, MessageProvider provider)
{
return provider.getMessage(key + "." + PROPERTY_SUFFIX_DESCRIPTION, null, locale);
}
/**
* Returns an array of 2 overloaded methods: the first one provides the minimum number of arguments
* and the second one provides the maximum number of arguments
*/
private Method[] getBoundaryMethods(Method method, Method[] methods) {
Method minMethod = method, maxMethod = method;
int minParams = method.getParameterTypes().length;
int maxParams = method.getParameterTypes().length;
String name = method.getName();
for(Method m : methods) {
if(name.equals(m.getName())) {
int params = m.getParameterTypes().length;
if(params < minParams) {
minParams = params;
minMethod = m;
} else if(params > maxParams){
maxParams = params;
maxMethod = m;
}
}
}
return new Method[] {minMethod, maxMethod};
}
}