package net.sf.jasperreports.engine.design; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.net.URLStreamHandlerFactory; import java.sql.Connection; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.ListIterator; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import java.util.TimeZone; import net.sf.jasperreports.engine.JRAbstractScriptlet; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRExpression; import net.sf.jasperreports.engine.JRField; import net.sf.jasperreports.engine.JRGroup; import net.sf.jasperreports.engine.JRParameter; import net.sf.jasperreports.engine.JRQuery; import net.sf.jasperreports.engine.JRRuntimeException; import net.sf.jasperreports.engine.JRSortField; import net.sf.jasperreports.engine.JRVariable; import net.sf.jasperreports.engine.JRVirtualizer; import net.sf.jasperreports.engine.base.JRBaseDataset; import net.sf.jasperreports.engine.query.JRQueryExecuterFactory; import net.sf.jasperreports.engine.util.FileResolver; import net.sf.jasperreports.engine.util.FormatFactory; import net.sf.jasperreports.engine.util.JRQueryExecuterUtils; public class JRDesignDataset extends JRBaseDataset { private static final long serialVersionUID = 10200L; public static final String PROPERTY_FIELDS = "fields"; public static final String PROPERTY_FILTER_EXPRESSION = "filterExpression"; public static final String PROPERTY_GROUPS = "groups"; public static final String PROPERTY_NAME = "name"; public static final String PROPERTY_PARAMETERS = "parameters"; public static final String PROPERTY_QUERY = "query"; public static final String PROPERTY_RESOURCE_BUNDLE = "resourceBundle"; public static final String PROPERTY_SCRIPTLET_CLASS = "scriptletClass"; public static final String PROPERTY_SORT_FIELDS = "sortFields"; public static final String PROPERTY_VARIABLES = "variables"; protected Map parametersMap = new HashMap(); protected List parametersList = new ArrayList(); protected Map fieldsMap = new HashMap(); protected List fieldsList = new ArrayList(); protected Map sortFieldsMap = new HashMap(); protected List sortFieldsList = new ArrayList(); protected Map variablesMap = new HashMap(); protected List variablesList = new ArrayList(); protected Map groupsMap = new HashMap(); protected List groupsList = new ArrayList(); private class QueryLanguageChangeListener implements PropertyChangeListener, Serializable { private static final long serialVersionUID = 10200L; private final JRDesignDataset this$0; private QueryLanguageChangeListener() {} public void propertyChange(PropertyChangeEvent evt) { JRDesignDataset.this.queryLanguageChanged((String)evt.getOldValue(), (String)evt.getNewValue()); } } private PropertyChangeListener queryLanguageChangeListener = new QueryLanguageChangeListener(); private static final Object[] BUILT_IN_PARAMETERS = new Object[] { "REPORT_PARAMETERS_MAP", Map.class, "REPORT_CONNECTION", Connection.class, "REPORT_MAX_COUNT", Integer.class, "REPORT_DATA_SOURCE", JRDataSource.class, "REPORT_SCRIPTLET", JRAbstractScriptlet.class, "REPORT_LOCALE", Locale.class, "REPORT_RESOURCE_BUNDLE", ResourceBundle.class, "REPORT_TIME_ZONE", TimeZone.class, "REPORT_FORMAT_FACTORY", FormatFactory.class, "REPORT_CLASS_LOADER", ClassLoader.class, "REPORT_URL_HANDLER_FACTORY", URLStreamHandlerFactory.class, "REPORT_FILE_RESOLVER", FileResolver.class }; private static final Object[] BUILT_IN_PARAMETERS_MAIN = new Object[] { "REPORT_VIRTUALIZER", JRVirtualizer.class, "IS_IGNORE_PAGINATION", Boolean.class, "REPORT_TEMPLATES", Collection.class }; public JRDesignDataset(boolean isMain) { super(isMain); addBuiltinParameters(BUILT_IN_PARAMETERS); if (isMain) addBuiltinParameters(BUILT_IN_PARAMETERS_MAIN); try { if (isMain) { addVariable(createPageNumberVariable()); addVariable(createColumnNumberVariable()); } addVariable(createReportCountVariable()); if (isMain) { addVariable(createPageCountVariable()); addVariable(createColumnCountVariable()); } } catch (JRException e) {} } private static JRDesignVariable createPageCountVariable() { JRDesignVariable variable = new JRDesignVariable(); variable.setName("PAGE_COUNT"); variable.setValueClass(Integer.class); variable.setResetType((byte)2); variable.setCalculation((byte)1); variable.setSystemDefined(true); JRDesignExpression expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(1)"); variable.setExpression((JRExpression)expression); expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(0)"); variable.setInitialValueExpression((JRExpression)expression); return variable; } private static JRDesignVariable createColumnNumberVariable() { JRDesignVariable variable = new JRDesignVariable(); variable.setName("COLUMN_NUMBER"); variable.setValueClass(Integer.class); variable.setResetType((byte)2); variable.setCalculation((byte)8); variable.setSystemDefined(true); JRDesignExpression expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(1)"); variable.setInitialValueExpression((JRExpression)expression); return variable; } private static JRDesignVariable createPageNumberVariable() { JRDesignVariable variable = new JRDesignVariable(); variable.setName("PAGE_NUMBER"); variable.setValueClass(Integer.class); variable.setResetType((byte)1); variable.setCalculation((byte)8); variable.setSystemDefined(true); JRDesignExpression expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(1)"); variable.setInitialValueExpression((JRExpression)expression); return variable; } private static JRDesignVariable createColumnCountVariable() { JRDesignVariable variable = new JRDesignVariable(); variable.setName("COLUMN_COUNT"); variable.setValueClass(Integer.class); variable.setResetType((byte)3); variable.setCalculation((byte)1); variable.setSystemDefined(true); JRDesignExpression expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(1)"); variable.setExpression((JRExpression)expression); expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(0)"); variable.setInitialValueExpression((JRExpression)expression); return variable; } private void addBuiltinParameters(Object[] parametersArray) { for (int i = 0; i < parametersArray.length; i++) { JRDesignParameter parameter = new JRDesignParameter(); parameter.setName((String)parametersArray[i++]); parameter.setValueClass((Class)parametersArray[i]); parameter.setSystemDefined(true); try { addParameter((JRParameter)parameter); } catch (JRException e) {} } } private static JRDesignVariable createReportCountVariable() { JRDesignVariable variable = new JRDesignVariable(); variable.setName("REPORT_COUNT"); variable.setValueClass(Integer.class); variable.setResetType((byte)1); variable.setCalculation((byte)1); variable.setSystemDefined(true); JRDesignExpression expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(1)"); variable.setExpression((JRExpression)expression); expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(0)"); variable.setInitialValueExpression((JRExpression)expression); return variable; } public void setName(String name) { Object old = this.name; this.name = name; getEventSupport().firePropertyChange("name", old, this.name); } public JRParameter[] getParameters() { JRParameter[] parametersArray = new JRParameter[this.parametersList.size()]; this.parametersList.toArray((Object[])parametersArray); return parametersArray; } public List getParametersList() { return this.parametersList; } public Map getParametersMap() { return this.parametersMap; } public void addParameter(JRParameter parameter) throws JRException { if (this.parametersMap.containsKey(parameter.getName())) throw new JRException("Duplicate declaration of parameter : " + parameter.getName()); this.parametersList.add(parameter); this.parametersMap.put(parameter.getName(), parameter); getEventSupport().fireCollectionElementAddedEvent("parameters", parameter, this.parametersList.size() - 1); } public JRParameter removeParameter(String parameterName) { return removeParameter((JRParameter)this.parametersMap.get(parameterName)); } public JRParameter removeParameter(JRParameter parameter) { if (parameter != null) { int idx = this.parametersList.indexOf(parameter); if (idx >= 0) { this.parametersList.remove(idx); this.parametersMap.remove(parameter.getName()); getEventSupport().fireCollectionElementRemovedEvent("parameters", parameter, idx); } } return parameter; } public void setQuery(JRDesignQuery query) { Object old = query; String oldLanguage = null; if (this.query != null) { ((JRDesignQuery)this.query).removePropertyChangeListener("language", this.queryLanguageChangeListener); oldLanguage = this.query.getLanguage(); } this.query = (JRQuery)query; String newLanguage = null; if (query != null) { query.addPropertyChangeListener("language", this.queryLanguageChangeListener); newLanguage = query.getLanguage(); } queryLanguageChanged(oldLanguage, newLanguage); getEventSupport().firePropertyChange("query", old, this.query); } public void setScriptletClass(String scriptletClass) { Object old = this.scriptletClass; this.scriptletClass = scriptletClass; if (scriptletClass == null) { ((JRDesignParameter)this.parametersMap.get("REPORT_SCRIPTLET")).setValueClass(JRAbstractScriptlet.class); } else { ((JRDesignParameter)this.parametersMap.get("REPORT_SCRIPTLET")).setValueClassName(scriptletClass); } getEventSupport().firePropertyChange("scriptletClass", old, this.scriptletClass); } public JRField[] getFields() { JRField[] fieldsArray = new JRField[this.fieldsList.size()]; this.fieldsList.toArray((Object[])fieldsArray); return fieldsArray; } public List getFieldsList() { return this.fieldsList; } public Map getFieldsMap() { return this.fieldsMap; } public void addField(JRField field) throws JRException { if (this.fieldsMap.containsKey(field.getName())) throw new JRException("Duplicate declaration of field : " + field.getName()); this.fieldsList.add(field); this.fieldsMap.put(field.getName(), field); getEventSupport().fireCollectionElementAddedEvent("fields", field, this.fieldsList.size() - 1); } public JRField removeField(String fieldName) { return removeField((JRField)this.fieldsMap.get(fieldName)); } public JRField removeField(JRField field) { if (field != null) { int idx = this.fieldsList.indexOf(field); if (idx >= 0) { this.fieldsList.remove(idx); this.fieldsMap.remove(field.getName()); getEventSupport().fireCollectionElementRemovedEvent("fields", field, idx); } } return field; } public JRSortField[] getSortFields() { JRSortField[] sortFieldsArray = new JRSortField[this.sortFieldsList.size()]; this.sortFieldsList.toArray((Object[])sortFieldsArray); return sortFieldsArray; } public List getSortFieldsList() { return this.sortFieldsList; } public void addSortField(JRSortField sortField) throws JRException { if (this.sortFieldsMap.containsKey(sortField.getName())) throw new JRException("Duplicate declaration of sort field : " + sortField.getName()); this.sortFieldsList.add(sortField); this.sortFieldsMap.put(sortField.getName(), sortField); getEventSupport().fireCollectionElementAddedEvent("sortFields", sortField, this.sortFieldsList.size() - 1); } public JRSortField removeSortField(String fieldName) { return removeSortField((JRSortField)this.sortFieldsMap.get(fieldName)); } public JRSortField removeSortField(JRSortField sortField) { if (sortField != null) { int idx = this.sortFieldsList.indexOf(sortField); if (idx >= 0) { this.sortFieldsList.remove(idx); this.sortFieldsMap.remove(sortField.getName()); getEventSupport().fireCollectionElementRemovedEvent("sortFields", sortField, idx); } } return sortField; } public JRVariable[] getVariables() { JRVariable[] variablesArray = new JRVariable[this.variablesList.size()]; this.variablesList.toArray((Object[])variablesArray); return variablesArray; } public List getVariablesList() { return this.variablesList; } public Map getVariablesMap() { return this.variablesMap; } public void addVariable(JRDesignVariable variable) throws JRException { addVariable(variable, false); } protected void addVariable(JRDesignVariable variable, boolean system) throws JRException { int addedIdx; if (this.variablesMap.containsKey(variable.getName())) throw new JRException("Duplicate declaration of variable : " + variable.getName()); if (system) { ListIterator it = this.variablesList.listIterator(); while (it.hasNext()) { JRVariable var = it.next(); if (!var.isSystemDefined()) { it.previous(); break; } } it.add(variable); addedIdx = it.previousIndex(); } else { this.variablesList.add(variable); addedIdx = this.variablesList.size() - 1; } this.variablesMap.put(variable.getName(), variable); getEventSupport().fireCollectionElementAddedEvent("variables", variable, addedIdx); } public JRVariable removeVariable(String variableName) { return removeVariable((JRVariable)this.variablesMap.get(variableName)); } public JRVariable removeVariable(JRVariable variable) { if (variable != null) { int idx = this.variablesList.indexOf(variable); if (idx >= 0) { this.variablesList.remove(idx); this.variablesMap.remove(variable.getName()); getEventSupport().fireCollectionElementRemovedEvent("variables", variable, idx); } } return variable; } public JRGroup[] getGroups() { JRGroup[] groupsArray = new JRGroup[this.groupsList.size()]; this.groupsList.toArray((Object[])groupsArray); return groupsArray; } public List getGroupsList() { return this.groupsList; } public Map getGroupsMap() { return this.groupsMap; } public void addGroup(JRDesignGroup group) throws JRException { if (this.groupsMap.containsKey(group.getName())) throw new JRException("Duplicate declaration of group : " + group.getName()); JRDesignVariable countVariable = new JRDesignVariable(); countVariable.setName(group.getName() + "_COUNT"); countVariable.setValueClass(Integer.class); countVariable.setResetType((byte)4); countVariable.setResetGroup((JRGroup)group); countVariable.setCalculation((byte)1); countVariable.setSystemDefined(true); JRDesignExpression expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(1)"); countVariable.setExpression((JRExpression)expression); expression = new JRDesignExpression(); expression.setValueClass(Integer.class); expression.setText("new Integer(0)"); countVariable.setInitialValueExpression((JRExpression)expression); addVariable(countVariable, true); group.setCountVariable((JRVariable)countVariable); this.groupsList.add(group); this.groupsMap.put(group.getName(), group); getEventSupport().fireCollectionElementAddedEvent("groups", group, this.groupsList.size() - 1); } public JRGroup removeGroup(String groupName) { return removeGroup((JRGroup)this.groupsMap.get(groupName)); } public JRGroup removeGroup(JRGroup group) { if (group != null) { removeVariable(group.getCountVariable()); int idx = this.groupsList.indexOf(group); if (idx >= 0) { this.groupsList.remove(idx); this.groupsMap.remove(group.getName()); getEventSupport().fireCollectionElementRemovedEvent("groups", group, idx); } } return group; } public void setResourceBundle(String resourceBundle) { Object old = this.resourceBundle; this.resourceBundle = resourceBundle; getEventSupport().firePropertyChange("resourceBundle", old, this.resourceBundle); } protected void queryLanguageChanged(String oldLanguage, String newLanguage) { try { if (oldLanguage != null) { JRQueryExecuterFactory queryExecuterFactory = JRQueryExecuterUtils.getQueryExecuterFactory(oldLanguage); Object[] builtinParameters = queryExecuterFactory.getBuiltinParameters(); if (builtinParameters != null) removeBuiltinParameters(builtinParameters); } if (newLanguage != null) { JRQueryExecuterFactory queryExecuterFactory = JRQueryExecuterUtils.getQueryExecuterFactory(newLanguage); Object[] builtinParameters = queryExecuterFactory.getBuiltinParameters(); if (builtinParameters != null) { addBuiltinParameters(builtinParameters); sortSystemParamsFirst(); } } } catch (JRException e) { throw new JRRuntimeException(e); } } private void sortSystemParamsFirst() { Collections.sort(this.parametersList, new Comparator() { private final JRDesignDataset this$0; public int compare(Object o1, Object o2) { JRParameter p1 = (JRParameter)o1; JRParameter p2 = (JRParameter)o2; boolean s1 = p1.isSystemDefined(); boolean s2 = p2.isSystemDefined(); return s1 ? (s2 ? 0 : -1) : (s2 ? 1 : 0); } }); } private void removeBuiltinParameters(Object[] builtinParameters) { for (int i = 0; i < builtinParameters.length; i += 2) { String parameterName = (String)builtinParameters[i]; JRParameter parameter = (JRParameter)this.parametersMap.get(parameterName); if (parameter.isSystemDefined()) removeParameter(parameter); } } public void setProperty(String propName, String value) { getPropertiesMap().setProperty(propName, value); } public void setFilterExpression(JRExpression expression) { Object old = this.filterExpression; this.filterExpression = expression; getEventSupport().firePropertyChange("filterExpression", old, this.filterExpression); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); if (this.sortFieldsMap == null) this.sortFieldsMap = new HashMap(); if (this.sortFieldsList == null) this.sortFieldsList = new ArrayList(); } public Object clone() { JRDesignDataset clone = (JRDesignDataset)super.clone(); if (this.parametersList != null) { clone.parametersList = new ArrayList(this.parametersList.size()); clone.parametersMap = new HashMap(this.parametersList.size()); for (int i = 0; i < this.parametersList.size(); i++) { JRParameter parameter = (JRParameter)((JRParameter)this.parametersList.get(i)).clone(); clone.parametersList.add(parameter); clone.parametersMap.put(parameter.getName(), parameter); } } if (this.fieldsList != null) { clone.fieldsList = new ArrayList(this.fieldsList.size()); clone.fieldsMap = new HashMap(this.fieldsList.size()); for (int i = 0; i < this.fieldsList.size(); i++) { JRField field = (JRField)((JRField)this.fieldsList.get(i)).clone(); clone.fieldsList.add(field); clone.fieldsMap.put(field.getName(), field); } } if (this.sortFieldsList != null) { clone.sortFieldsList = new ArrayList(this.sortFieldsList.size()); clone.sortFieldsMap = new HashMap(this.sortFieldsList.size()); for (int i = 0; i < this.sortFieldsList.size(); i++) { JRSortField sortField = (JRSortField)((JRSortField)this.sortFieldsList.get(i)).clone(); clone.sortFieldsList.add(sortField); clone.sortFieldsMap.put(sortField.getName(), sortField); } } if (this.variablesList != null) { clone.variablesList = new ArrayList(this.variablesList.size()); clone.variablesMap = new HashMap(this.variablesList.size()); for (int i = 0; i < this.variablesList.size(); i++) { JRVariable variable = (JRVariable)((JRVariable)this.variablesList.get(i)).clone(); clone.variablesList.add(variable); clone.variablesMap.put(variable.getName(), variable); } } if (this.groupsList != null) { clone.groupsList = new ArrayList(this.groupsList.size()); clone.groupsMap = new HashMap(this.groupsList.size()); for (int i = 0; i < this.groupsList.size(); i++) { JRGroup group = (JRGroup)((JRGroup)this.groupsList.get(i)).clone(); clone.groupsList.add(group); clone.groupsMap.put(group.getName(), group); } } return clone; } }