All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.jasperreports.engine.JRPropertiesMap Maven / Gradle / Ivy

There is a newer version: 6.21.3
Show newest version
/*
 * JasperReports - Free Java Reporting Library.
 * Copyright (C) 2001 - 2023 Cloud Software Group, 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.engine;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import net.sf.jasperreports.engine.design.events.JRPropertyChangeSupport;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Properties map of an JR element.
 * 

* The order of the properties (obtained by {@link #getPropertyNames() getPropertyNames()} * is the same as the order in which the properties were added. * * @author Lucian Chirita ([email protected]) */ public class JRPropertiesMap implements Serializable, Cloneable { private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID; private static final Log log = LogFactory.getLog(JRPropertiesMap.class); /** * @deprecated no longer used, {@link #setProperty(String, String)} now uses * the actual property name for the change event */ @Deprecated public static final String PROPERTY_VALUE = "value"; private Map propertiesMap; private List propertiesList; private JRPropertiesMap base; /** * Creates a properties map. */ public JRPropertiesMap() { } /** * Clones a properties map. * * @param propertiesMap the original properties map */ public JRPropertiesMap(JRPropertiesMap propertiesMap) { this(); this.base = propertiesMap.base; //this copies all properties from base to this instance //FIXME in some cases we might want to keep the properties in base String[] propertyNames = propertiesMap.getPropertyNames(); if (propertyNames != null && propertyNames.length > 0) { for(int i = 0; i < propertyNames.length; i++) { setProperty(propertyNames[i], propertiesMap.getProperty(propertyNames[i])); } } } protected synchronized void ensureInit() { if (propertiesMap == null) { init(); } } private void init() { // start with small collections propertiesMap = new HashMap<>(4, 0.75f); propertiesList = new ArrayList<>(2); } /** * Returns the names of the properties. * * @return the names of the properties */ public String[] getPropertyNames() { String[] names; if (hasOwnProperties()) { if (base == null) { names = propertiesList.toArray(new String[propertiesList.size()]); } else { LinkedHashSet namesSet = new LinkedHashSet<>(); collectPropertyNames(namesSet); names = namesSet.toArray(new String[namesSet.size()]); } } else if (base != null) { names = base.getPropertyNames(); } else { names = new String[0]; } return names; } public String[] getOwnPropertyNames() { String[] names; if (hasOwnProperties()) { names = propertiesList.toArray(new String[propertiesList.size()]); } else { names = new String[0]; } return names; } protected void collectPropertyNames(Collection names) { if (base != null) { base.collectPropertyNames(names); } if (propertiesList != null) { names.addAll(propertiesList); } } /** * Returns the value of a property. * * @param propName the name of the property * @return the value */ public String getProperty(String propName) { String val; if (hasOwnProperty(propName)) { val = getOwnProperty(propName); } else if (base != null) { val = base.getProperty(propName); } else { val = null; } return val; } /** * Decides whether the map contains a specified property. * * The method returns true even if the property value is null. * * @param propName the property name * @return true if and only if the map contains the property */ public boolean containsProperty(String propName) { return hasOwnProperty(propName) || base != null && base.containsProperty(propName); } protected boolean hasOwnProperty(String propName) { return propertiesMap != null && propertiesMap.containsKey(propName); } protected String getOwnProperty(String propName) { return propertiesMap != null ? (String) propertiesMap.get(propName) : null; } /** * Adds/sets a property value. * * @param propName the name of the property * @param value the value of the property */ public void setProperty(String propName, String value) { Object old = getOwnProperty(propName); ensureInit(); if (!hasOwnProperty(propName)) { propertiesList.add(propName); } propertiesMap.put(propName, value); if (hasEventSupport()) { getEventSupport().firePropertyChange(propName, old, value); } } /** * Removes a property. * * @param propName the property name */ public void removeProperty(String propName) { //FIXME base properties? if (hasOwnProperty(propName)) { String old = getOwnProperty(propName); propertiesList.remove(propName); propertiesMap.remove(propName); if (hasEventSupport()) { getEventSupport().firePropertyRemove(propName, old); } } } /** * Clones this property map. * * @return a clone of this property map */ public JRPropertiesMap cloneProperties() { return new JRPropertiesMap(this); } @Override public Object clone() { return this.cloneProperties(); } /** * Copies properties from a different map into this object. * * @param propertiesMap the map to copy properties from */ public void copyOwnProperties(JRPropertiesMap propertiesMap) { if (propertiesMap.propertiesList != null) { for (String prop : propertiesMap.propertiesList) { setProperty(prop, propertiesMap.getOwnProperty(prop)); } } } @Override public String toString() { return propertiesMap == null ? "" : propertiesMap.toString(); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); if (propertiesList == null && propertiesMap != null)// an instance from an old version has been deserialized { //recreate the properties list and map propertiesList = new ArrayList<>(propertiesMap.keySet()); propertiesMap = new HashMap<>(propertiesMap); } } /** * Checks whether there are any properties. * * @return whether there are any properties */ public boolean hasProperties() { return hasOwnProperties() || base != null && base.hasProperties(); } public boolean isEmpty() { // only checking base for null and not whether base has any properties return !hasOwnProperties() && base == null; } /** * Checks whether this object has properties of its own * (i.e. not inherited from the base properties). * * @return whether this object has properties of its own * @see #setBaseProperties(JRPropertiesMap) */ public boolean hasOwnProperties() { return propertiesList != null && !propertiesList.isEmpty(); } /** * Clones the properties map of a properties holder. * If the holder does not have any properties, null is returned. * * @param propertiesHolder the properties holder * @return a clone of the holder's properties map, or null * if the holder does not have any properties */ public static JRPropertiesMap getPropertiesClone(JRPropertiesHolder propertiesHolder) { JRPropertiesMap clone; if (propertiesHolder.hasProperties()) { clone = propertiesHolder.getPropertiesMap().cloneProperties(); } else { clone = null; } return clone; } /** * Returns the base properties map, if any. * * @return the base properties map * @see #setBaseProperties(JRPropertiesMap) */ public JRPropertiesMap getBaseProperties() { return base; } /** * Sets the base properties map. * *

* The base properties map are used as base/default properties for this * instance. All of the {@link #containsProperty(String)}, * {@link #getProperty(String)}, {@link #getPropertyNames()} and * {@link #hasProperties()} methods include base properties as well. *

* * @param base the base properties map */ public void setBaseProperties(JRPropertiesMap base) { this.base = base; } /** * Loads a properties file from a location. * * @param location the properties file URL * @return the properties file loaded as a in-memory properties map */ public static JRPropertiesMap loadProperties(URL location) { boolean close = true; InputStream stream = null; try { stream = location.openStream(); Properties props = new Properties(); props.load(stream); close = false; stream.close(); JRPropertiesMap properties = new JRPropertiesMap(); for (Enumeration names = props.propertyNames(); names.hasMoreElements(); ) { String name = (String) names.nextElement(); String value = props.getProperty(name); properties.setProperty(name, value); } return properties; } catch (IOException e) { throw new JRRuntimeException(e); } finally { if (close && stream != null) { try { stream.close(); } catch (IOException e) { if (log.isWarnEnabled()) { log.warn("Error closing stream for " + location, e); } } } } } private transient JRPropertyChangeSupport eventSupport; protected boolean hasEventSupport() { return eventSupport != null; } public JRPropertyChangeSupport getEventSupport() { synchronized (this) { if (eventSupport == null) { eventSupport = new JRPropertyChangeSupport(this); } } return eventSupport; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy