package org.jconfig;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.event.EventListenerList;
import org.jconfig.event.CategoryChangedEvent;
import org.jconfig.event.CategoryListener;
import org.jconfig.event.ConfigurationChangedEventImpl;
import org.jconfig.event.PropertyChangedEvent;
import org.jconfig.event.PropertyListener;
/**
* This class is the result of countless discussions of what
* a Category should be. After determing that it should be
* another class, and that we can do something useful, we
* created this Category.
*
* A Category is a logical extension of the Configuration
* has Categories has Properties has Value frame-of-mind.
* The primary goal is to reduce redundancy in source code
* when using setter and getters that include Category
* information.
*
* @since 2.2
* @author Andreas Mecky <andreas.mecky@xcom.de>
* @author Terry Dye <terry.dye@xcom.de>
*
* Changes: The helper methods for the primitives did not replaced variables
* @author Lubos Pochman lubosp@myway.com
*/
public class DefaultCategory implements Category {
private static final VariableManager vm = VariableManager.getInstance();
private String extendsCategory;
private String name = null;
// The Properties object. Stink normal Properties file.
// Perhaps I'll extend the Properties Object one day
// when I write the generator to make nice type-safe
// getter and setter methods.
private Properties properties = new Properties();
// The List of ConfigurationListeners
private EventListenerList listenerList = new EventListenerList();
// the name of the configuration that this category belongs to
private String configurationName;
/**
* @since 2.2
* @param categoryName
*/
public DefaultCategory(String categoryName) {
// System.err.println("new DefaultCategory("+categoryName+")");
name = categoryName;
}
/**
* Sets the property with the value given. This will override any
* existing property values if the property name is duplicated.
* This will create a new property if no property exists.
*
* Setting the value to <null> will remove the property
* from the Category;
*
* @since 2.2
* @param propertyName
* @param propertyValue
* @return
*/
public Category setProperty(String propertyName, String propertyValue) {
String temp = getProperty(propertyName);
if( propertyValue == null ) {
properties.remove(propertyName);
firePropertyChangedEvent(
new ConfigurationChangedEventImpl(
PropertyChangedEvent.PROPERTY_REMOVED, this,
propertyName, temp, propertyValue));
return this;
}
properties.setProperty(propertyName, propertyValue);
if(temp == null) {
firePropertyChangedEvent(
new ConfigurationChangedEventImpl(
PropertyChangedEvent.PROPERTY_ADDED, this,
propertyName, temp, propertyValue));
}
else {
if (!temp.equals(propertyValue)) // thanks to Thorsten Jungbluth for the fix
firePropertyChangedEvent(
new ConfigurationChangedEventImpl(
PropertyChangedEvent.PROPERTY_CHANGED, this,
propertyName, temp, propertyValue));
}
return this;
}
/**
* Searches for the property with the specified key in this property list.
* If the key is not found in this property list, the default property list,
* and its defaults, recursively, are then checked. The method returns
* <code>null</code> if the property is not found.
*
* @since 2.2
* @param key the property key.
* @return the value in this property list with the specified key value.
*/
public String getProperty(String propertyName) {
String value = properties.getProperty(propertyName);
if (value != null) {
return vm.replaceVariables(value,getConfigurationName());
} else {
return value;
}
}
/**
* Searches for the property with the specified key in this property list.
* If the key is not found in this property list, the default property list,
* and its defaults, recursively, are then checked. The method returns the
* default value argument if the property is not found.
*
* @since 2.2
* @param propertyName The property name.
* @param defaultValue The default value.
* @return the value in this property list with the specified key value or
* the defaultValue.
*/
public String getProperty(String propertyName, String defaultValue) {
String temp = properties.getProperty(propertyName, vm.replaceVariables(defaultValue,getConfigurationName()));
if(temp != null) {
return vm.replaceVariables(temp,getConfigurationName());
}
return properties.getProperty(propertyName, vm.replaceVariables(defaultValue,getConfigurationName()));
}
/**
* Returns the name of this category.
*
* @since 2.2
* @return The name of the category.
*/
public String getCategoryName() {
return name;
}
/**
* Adds the specified category listener to receive category
* changed events from this category.
*
* @since 2.2
* @param listener The ConfigurationListener
*/
public void addCategoryListener(CategoryListener listener) {
listenerList.add(CategoryListener.class, listener);
}
/**
* Removes the specified category listener from the category
* change events from this category.
*
* @since 2.2
* @param listener The ConfigurationListener
*/
public void removeCategoryListener(CategoryListener listener) {
listenerList.remove(CategoryListener.class, listener);
}
/**
* Deliver category changed event to all listeners that are registered
* with our listener list.
*
* @since 2.2
* @param event The ConfigurationChangedEvent
*/
public void fireCategoryChangedEvent(CategoryChangedEvent event) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == CategoryListener.class) {
// Lazily create the event:
((CategoryListener) listeners[i + 1]).categoryChanged(event);
}
}
}
/**
* Return all properties related to this category
*
* @since 2.2
* @return The Properties
*/
public Properties getProperties() {
return properties;
}
public String[] getArray(String key) {
return getArray(key,null,",");
}
public String[] getArray(String key,String separator) {
return getArray(key,null,separator);
}
public String[] getArray(String key, String[] defaultValue) {
return getArray(key,defaultValue,",");
}
public String[] getArray(String key, String[] defaultValue,String separator) {
String value = properties.getProperty(key);
if ( value == null ) {
return defaultValue;
}
Vector all = new Vector();
StringTokenizer sto = new StringTokenizer(value,separator);
while ( sto.hasMoreElements() ) {
String val = (String)sto.nextElement();
val = vm.replaceVariables(val,configurationName);
all.add(val);
}
return (String[])all.toArray(new String[0]);
}
/**
* Helper method to allow for strong-binding within Properties.
*
* @since 2.2
* @param name The name of the property
* @param defaultValue The default value
* @return If the String value can be converted to Boolean, the
* value will be return, otherwise the the default value.
*/
public boolean getBooleanProperty(String name, boolean defaultValue) {
String value = properties.getProperty(name);
if ( value == null ) {
return defaultValue;
} else {
try {
return Boolean.valueOf(vm.replaceVariables(value,getConfigurationName())).booleanValue();
} catch (Exception e) {
return defaultValue;
}
}
}
/**
* Helper method to allow for strong-binding within Properties.
*
* @since 2.2
* @param name
* @param value
*/
public void setBooleanProperty(String name, boolean value) {
Boolean bool = new Boolean(value);
setProperty(name, bool.toString());
}
/**
* Helper method to allow for strong-binding within Properties.
*
* @since 2.2
* @param name The name of the property
* @param defaultValue The default value
* @return If the String value can be converted to Boolean, the
* value will be return, otherwise the the default value.
*/
public char getCharProperty(String name, char defaultValue) {
String value = properties.getProperty(name);
if (value == null) {
return defaultValue;
} else {
String subValue = vm.replaceVariables(value,getConfigurationName());
if (subValue.length() == 1) {
return subValue.charAt(0);
} else {
return defaultValue;
}
}
}
/**
* Helper method to allow for strong-binding within Properties.
*
* @since 2.2
* @param string
* @param c
*/
public void setCharProperty(String key, char value) {
Character temp = new Character(value);
setProperty(key, temp.toString());
}
/**
* Helper method to allow for strong-binding within Properties.
*
* @since 2.2
* @param name The name of the property
* @param defaultValue The default value
* @return If the String value can be converted to Boolean, the
* value will be return, otherwise the the default value.
*/
public double getDoubleProperty(String name, double defaultValue) {
String value = properties.getProperty(name);
if (value == null) {
return defaultValue;
} else {
try {
return Double.parseDouble(vm.replaceVariables(value,getConfigurationName()));
} catch (Exception e) {
return defaultValue;
}
}
}
/**
* Helper method to allow for strong-binding within Properties.
* <br/>
* This method does not support any kind of inheritance! Use the
* configuration.getIntProperty method instead
*
* @since 2.2
* @param name The name of the property
* @param defaultValue The default value
* @return If the String value can be converted to Boolean, the
* value will be return, otherwise the the default value.
*/
public int getIntProperty(String name, int defaultValue) {
String value = properties.getProperty(name);
if (value == null) {
return defaultValue;
} else {
try {
return Integer.parseInt(vm.replaceVariables(value,getConfigurationName()));
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
}
/**
* Helper method to allow for strong-binding within Properties.
*
* @since 2.2
* @param string
* @param i
*/
public void setIntProperty(String key, int value) {
Integer temp = new Integer(value);
setProperty(key, temp.toString());
}
/**
* Helper method to allow for strong-binding within Properties.
* <br/>
* This method does not support any kind of inheritance! Use the
* configuration.getIntProperty method instead
*
* @since 2.2
* @param name The name of the property
* @param defaultValue The default value
* @return If the String value can be converted to Boolean, the
* value will be return, otherwise the the default value.
*/
public long getLongProperty(String name, long defaultValue) {
String value = (String)properties.get(name);
value = getProperty(name);
if (value == null) {
return defaultValue;
} else {
try {
return Long.parseLong(vm.replaceVariables(value,getConfigurationName()));
} catch (Exception e) {
return defaultValue;
}
}
}
/**
* Helper method to allow for strong-binding within Properties.
*
* @since 2.2
* @param string
* @param l
*/
public void setLongProperty(String key, long value) {
Long temp = new Long(value);
setProperty(key, temp.toString());
}
/**
* Getter for property configurationName.
*
* @since 2.2
* @return Value of property configurationName.
*
*/
public String getConfigurationName() {
return configurationName;
}
/**
* Setter for property configurationName.
*
* @since 2.2
* @param configurationName New value of property configurationName.
*
*/
public void setConfigurationName(String configurationName) {
this.configurationName = configurationName;
}
/**
* Helper method to allow for strong-binding within Properties.
*
* @since 2.2
* @param key
* @param value
*/
public void setDoubleProperty(String key, double value) {
Double temp = new Double(value);
setProperty(key, temp.toString());
}
/**
* Adds the given listener to the list that wish to receive the
* {@link org.jconfig.event.PropertyChangedEvent PropertyChangedEvent}.
*
* @since 2.2
* @param listener
*/
public void addPropertyListener( PropertyListener listener ) {
listenerList.add( PropertyListener.class, listener );
}
/**
* Removes the given listener to the list that wish to receive the
* {@link org.jconfig.event.PropertyChangedEvent PropertyChangedEvent}.
*
* @since 2.2
* @param listener
*/
public void removePropertyListener( PropertyListener listener ) {
listenerList.remove( PropertyListener.class, listener );
}
/**
* Notifies all {@link PropertyListener PropertyListeners} of changes
* to the property (added, removed, changed).
*
* @param event
*/
public void firePropertyChangedEvent(PropertyChangedEvent event) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == PropertyListener.class) {
// Lazily create the event:
((PropertyListener) listeners[i + 1]).propertyChanged(event);
}
}
fireCategoryChangedEvent((CategoryChangedEvent)event);
}
public void setExtendsCategory(String extendsCategory) {
this.extendsCategory = extendsCategory;
}
public String getExtendsCategory() {
return extendsCategory;
}
public void renameCategory(String newName) {
name = newName;
}
}