| package jpos.config.simple; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // This software is provided "AS IS". The JavaPOS working group (including |
| // each of the Corporate members, contributors and individuals) MAKES NO |
| // REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, |
| // EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED |
| // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| // NON-INFRINGEMENT. The JavaPOS working group shall not be liable for |
| // any damages suffered as a result of using, modifying or distributing this |
| // software or its derivatives. Permission to use, copy, modify, and distribute |
| // the software and its documentation for any purpose is hereby granted. |
| // |
| // The JavaPOS Config/Loader (aka JCL) is now under the CPL license, which |
| // is an OSS Apache-like license. The complete license is located at: |
| // http://oss.software.ibm.com/developerworks/opensource/license-cpl.html |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| import jpos.config.JposEntry; |
| |
| import java.util.*; |
| import java.io.Serializable; |
| |
| import jpos.config.*; |
| import jpos.util.JposEntryUtility; |
| |
| /** |
| * This is a simple implementation of the JposEntry interface using a Hashtable |
| * to collect the properties |
| * @since 0.1 (Philly 99 meeting) |
| * @author E. Michael Maximilien (maxim@us.ibm.com) |
| */ |
| public class SimpleEntry implements JposEntry, Serializable, Comparable |
| { |
| //-------------------------------------------------------------------------- |
| // Ctor(s) |
| // |
| |
| /** |
| * Default ctor (sets the JposRegPopulator to null) |
| * @since 1.3 (Washington DC 2001 meeting) |
| */ |
| public SimpleEntry() { regPopulator = null; } |
| |
| /** |
| * One argument ctor taking the JposRegPopulator for this entry |
| * @param populator the JposRegPopulator for this entry |
| * @since 1.3 (Washington DC 2001 meeting) |
| */ |
| public SimpleEntry( JposRegPopulator populator ) { regPopulator = populator; } |
| |
| /** |
| * One argument ctor taking the JposRegPopulator for this entry |
| * @param logicalName the logical name for this entry |
| * @param populator the JposRegPopulator for this entry |
| * @since 1.3 (Washington DC 2001 meeting) |
| */ |
| public SimpleEntry( String logicalName, JposRegPopulator populator ) |
| { |
| this( populator ); |
| |
| addProperty( LOGICAL_NAME_PROP_NAME, logicalName ); |
| } |
| |
| /** |
| * One argument ctor taking the LogicalName this entry |
| * @param logicalName the logical name string for this entry |
| * @since 2.0.0 |
| */ |
| SimpleEntry( String logicalName ) { addProperty( LOGICAL_NAME_PROP_NAME, logicalName ); } |
| |
| //-------------------------------------------------------------------------- |
| // Public instance methods |
| // |
| |
| /** |
| * @return count of number of properties |
| * @since 0.1 (Philly 99 meeting) |
| */ |
| public int getPropertyCount() { return properties.size(); } |
| |
| /** |
| * @return an enumerator for the properties names |
| * @since 0.1 (Philly 99 meeting) |
| */ |
| public Enumeration getPropertyNames() { return properties.keys(); } |
| |
| /** |
| * @return true if there is a property by the name specified |
| * @param propName the property name String |
| * @since 0.1 (Philly 99 meeting) |
| */ |
| public boolean hasPropertyWithName( String propName ) { return properties.containsKey( propName ); } |
| |
| /** |
| * @return true if there is a property by the value specified |
| * NOTE: Object.equals method will be used to compare |
| * @param propValue the property's value Object |
| * @since 0.1 (Philly 99 meeting) |
| */ |
| public boolean hasPropertyWithValue( Object propValue ) { return properties.contains( propValue ); } |
| |
| /** |
| * @return the property's value Object |
| * @param propName the property's propName String |
| * @since 0.1 (Philly 99 meeting) |
| */ |
| public Object getPropertyValue( String propName ) { return properties.get( propName ); } |
| |
| /** |
| * @return the property's type |
| * @param propName the property's name String |
| * @since 2.0.0 |
| */ |
| public Class getPropertyType( String propName ) { return getPropertyValue( propName ).getClass(); } |
| |
| /** |
| * Modifies the property value of the property passed |
| * @return the oldPropValue or null if this property does not exist |
| * @param propName the property name |
| * @param propValue the new property value |
| * @since 1.3 (Tokyo 2001 meeting) |
| * @throws java.lang.IllegalArgumentException if the propName or propValue is null |
| */ |
| public Object modifyPropertyValue( String propName, Object propValue ) throws IllegalArgumentException |
| { |
| checkNull( propName ); |
| checkNull( propValue ); |
| |
| if( hasPropertyWithName( propName ) == false ) |
| return null; |
| |
| Object oldValue = removeProperty( propName ); |
| |
| addProperty( propName, propValue ); |
| |
| return oldValue; |
| } |
| |
| /** |
| * Adds a property to the JposEntry object. |
| * NOTE: any property with the same name gets overlaid |
| * @param propName the name of this property (should be unique per property) |
| * @param propValue the properties value Object |
| * @since 0.1 (Philly 99 meeting) |
| * @throws java.lang.IllegalArgumentException if the propName or propValue is null |
| */ |
| public Object addProperty( String propName, Object propValue ) throws IllegalArgumentException |
| { |
| checkNull( propName ); |
| checkNull( propValue ); |
| |
| return properties.put( propName, propValue ); |
| } |
| |
| /** |
| * Looks for a property with name specified and removes it. If none exist then |
| * does nothing and return null |
| * @return the value for the name passed |
| * @param propName the name String of the property to remove |
| * @since 0.1 (Philly 99 meeting) |
| */ |
| public Object removeProperty( String propName ) { return properties.remove( propName ); } |
| |
| /** |
| * @return true if the two JposEntries have the same properties |
| * @since 0.1 (Philly 99 meeting) |
| */ |
| public boolean equals( JposEntry otherEntry ) |
| { |
| if( otherEntry == null ) return false; |
| |
| if( getPropertyCount() != otherEntry.getPropertyCount() ) return false; |
| |
| Enumeration otherPropNames = otherEntry.getPropertyNames(); |
| |
| while( otherPropNames.hasMoreElements() ) |
| { |
| String name = (String)otherPropNames.nextElement(); |
| Object value = otherEntry.getPropertyValue( name ); |
| |
| if( !hasPropertyWithName( name ) ) return false; |
| |
| if( !getPropertyValue( name ).equals( value ) ) return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * @return a copy of this JposEntry object |
| * @since 1.3 (Tokyo 2001 meeting) |
| */ |
| public JposEntry copy() |
| { |
| JposEntry entryCopy = new SimpleEntry(); |
| |
| Enumeration entryNames = getPropertyNames(); |
| |
| while( entryNames.hasMoreElements() ) |
| { |
| String propName = (String)entryNames.nextElement(); |
| entryCopy.addProperty( propName,getPropertyValue( propName ) ); |
| } |
| |
| return entryCopy; |
| } |
| |
| /** |
| * @return the JposRegPopulator that loads/saves this entry. If null the default |
| * populator is used |
| * @since 1.3 (Washington DC 2001 meeting) |
| */ |
| public JposRegPopulator getRegPopulator() { return regPopulator; } |
| |
| /** |
| * @return the logical name for this JposEntry. This is a shortcut for easily getting |
| * the logical name vs getting a property and passing the logical name constant |
| * @see jpos.config.JposEntry#getPropertyValue |
| * @see jpos.config.JposEntry#LOGICAL_NAME_PROP_NAME |
| * @since 1.3 (Washington DC 2001 meeting) |
| */ |
| public String getLogicalName() { return (String)getPropertyValue( JposEntry.LOGICAL_NAME_PROP_NAME ); } |
| |
| /** |
| * @return the JposEntry.Prop with name specified or null if no such property exist |
| * @param propName the property name |
| * @since 2.0.0 |
| */ |
| public JposEntry.Prop getProp( String propName ) |
| { |
| Object propValue = getPropertyValue( propName ); |
| |
| if( propValue == null ) return null; |
| |
| return new Prop( propName, propValue ); |
| } |
| |
| /** |
| * @return an Iterator over the properties in this JposEntry as JposEntry.Prop objects |
| * @since 1.3 (Washington DC 2001) |
| */ |
| public Iterator getProps() |
| { |
| List list = new ArrayList(); |
| |
| Enumeration names = getPropertyNames(); |
| |
| while( names.hasMoreElements() ) |
| { |
| String name = (String)names.nextElement(); |
| |
| list.add( new Prop( name, getPropertyValue( name ) ) ); |
| } |
| |
| return list.iterator(); |
| } |
| |
| /** |
| * Adds a new property |
| * @param prop the JposEntry.Prop to add |
| * @since 1.3 (Washington DC 2001 meeting) |
| * @throws java.lang.IllegalArgumentException if the argument is null |
| */ |
| public void add( JposEntry.Prop prop ) throws IllegalArgumentException |
| { |
| checkNull( prop ); |
| |
| addProperty( prop.getName(), prop.getValue() ); |
| } |
| |
| /** |
| * Removes the property |
| * @param prop the JposEntry.Prop to remove |
| * @since 1.3 (Washington DC 2001 meeting) |
| */ |
| public void remove( JposEntry.Prop prop ) { removeProperty( prop.getName() ); } |
| |
| /** |
| * Modifies the property with name of property passed with the new value if |
| * that property currently exist in the entry otherwise does nothing |
| * @param prop the JposEntry.Prop to modify |
| * @since 2.0.0 |
| * @throws java.lang.IllegalArgumentException if the prop is null |
| */ |
| public void modify( JposEntry.Prop prop ) throws IllegalArgumentException |
| { |
| checkNull( prop ); |
| |
| if( hasPropertyWithName( prop.getName() ) == false ) return; |
| |
| modifyPropertyValue( prop.getName(), prop.getValue() ); |
| } |
| |
| /** |
| * @return true if this entry has the property passed |
| * @param prop the JposEntry.Prop to check for |
| * @since 1.3 (Washington DC 2001 meeting) |
| */ |
| public boolean hasProp( JposEntry.Prop prop ) { return hasPropertyWithName( prop.getName() ); } |
| |
| /** |
| * @return a JposEntry.Prop object created with the <name, value, type> tripplet |
| * passed as arguments |
| * @param propName the property name |
| * @param propValue the property value |
| * @param propType the property type (valid for this value) |
| * @throws jpos.config.JposConfigException if any of the argument is null or the |
| * property value and type mismatch or this is not a valid property type |
| * @see jpos.config.JposEntryConst#PROP_TYPES |
| * @since 2.0.0 |
| */ |
| public JposEntry.Prop createProp( String propName, Object propValue, Class propType ) throws JposConfigException |
| { |
| if( propName == null || propValue == null || propType == null ) |
| throw new JposConfigException( "Cannot create JposEntry.Prop with null argument" ); |
| |
| if( JposEntryUtility.validatePropValue( propValue, propType ) == false ) |
| throw new JposConfigException( "Cannot create JposEntry.Prop with invalid value or type" ); |
| |
| return new Prop( propName, propValue ); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // Public overidden methods |
| // |
| |
| /** |
| * @return true if the two JposEntries have the same properties |
| * @since 1.3 (SF 2K meeting) |
| */ |
| public boolean equals( Object object ) |
| { |
| if( object instanceof JposEntry ) |
| return equals( (JposEntry)object ); |
| |
| return false; |
| } |
| |
| /** |
| * @return 0 if two entries are the same -1 if this is less or 1 of more than other |
| * the comparison for > and < uses the logicalName of the entry to decide |
| * @param otherEntry the other JposEntry |
| */ |
| public int compareTo( Object other ) |
| { |
| if( other == null || ( (other instanceof JposEntry ) == false ) ) |
| throw new RuntimeException( "Cannot compare: " + other + " with JposEntry: " + this ); |
| |
| JposEntry otherEntry = (JposEntry)other; |
| |
| if( equals( otherEntry ) ) return 0; |
| |
| return getLogicalName().compareTo( otherEntry.getLogicalName() ); |
| } |
| |
| /** |
| * @return a String representation of this entry |
| * @since 1.3 (SF 2K meeting) |
| */ |
| public String toString() |
| { |
| StringBuffer sb = new StringBuffer(); |
| |
| sb.append( "<JposEntry logicalName=\"" + getPropertyValue( JposEntry.LOGICAL_NAME_PROP_NAME ) + "\">\n" ); |
| sb.append( "\t<creation factoryClass=\"" + getPropertyValue( JposEntry.SI_FACTORY_CLASS_PROP_NAME ) + "\" serviceClass=\"" + getPropertyValue( JposEntry.SERVICE_CLASS_PROP_NAME ) + "\"/>\n" ); |
| sb.append( "\t<vendor name=\"" + getPropertyValue( JposEntry.VENDOR_NAME_PROP_NAME ) + "\" url=" + getPropertyValue( JposEntry.VENDOR_URL_PROP_NAME ) + "\"/>\n" ); |
| sb.append( "\t<jpos category=\"" + getPropertyValue( JposEntry.DEVICE_CATEGORY_PROP_NAME ) + "\" version=\"" + getPropertyValue( JposEntry.JPOS_VERSION_PROP_NAME ) + "\"/>\n" ); |
| sb.append( "\t<product description=\"" + getPropertyValue( JposEntry.PRODUCT_DESCRIPTION_PROP_NAME ) + "\" name=\"" + getPropertyValue( JposEntry.PRODUCT_NAME_PROP_NAME ) + "\" url=\"" + getPropertyValue( JposEntry.PRODUCT_URL_PROP_NAME ) + "\"/>\n" ); |
| |
| sb.append( "\n" ); |
| |
| Enumeration otherPropNames = JposEntryUtility.getNonRequiredPropNames( this ); |
| while( otherPropNames.hasMoreElements() ) |
| { |
| String name = (String)otherPropNames.nextElement(); |
| String value = getPropertyValue( name ).toString(); |
| String typeClassName = JposEntryUtility.shortClassName( value.getClass() ); |
| |
| sb.append( "\t<prop name=\"" + name + "\" value=\"" + value + |
| "\" type=\"" + typeClassName +"\"/>\n" ); |
| } |
| |
| sb.append( "</JposEntry>\n" ); |
| |
| return sb.toString(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // Package methods |
| // |
| |
| /** |
| * Sets the JposRegPopulator that loads/saves this entry. If null the default |
| * populator is used |
| * @since 1.3 (Washington DC 2001 meeting) |
| */ |
| void setRegPopulator( JposRegPopulator populator ) { regPopulator = populator; } |
| |
| //--------------------------------------------------------------------- |
| // Class methods |
| // |
| |
| /** |
| * Checks that the Object argument is not null and if it is throw a IllegalArgumentException |
| * @param object the Object argument |
| * @throws java.lang.IllegalArgumentException if the object is null |
| */ |
| protected static void checkNull( Object object ) throws IllegalArgumentException |
| { |
| if( object == null ) |
| throw new IllegalArgumentException( "Invalid null argument passed for a JposEntry property value or name" ); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // Instance variables |
| // |
| |
| private Hashtable properties = new Hashtable(); |
| private transient JposRegPopulator regPopulator = null; |
| |
| //------------------------------------------------------------------------- |
| // Inner classes |
| // |
| |
| /** |
| * Inner class to represent a property of a JposEntry |
| * @author E. Michael Maximilien |
| * @since 1.3 (Washington DC 2001) |
| */ |
| public static class Prop implements JposEntry.Prop, Comparable |
| { |
| //--------------------------------------------------------------------- |
| // Ctor(s) |
| // |
| |
| /** |
| * Creates a JposEntry.Prop object |
| * @param name the name of this property |
| * @param value the value of this property |
| * @throws java.lang.IllegalArgumentException if any of the arguments are null |
| */ |
| public Prop( String name, Object value ) throws IllegalArgumentException |
| { |
| checkNull( name ); |
| checkNull( value ); |
| |
| this.name = name; |
| this.value = value; |
| this.typeClass = value.getClass(); |
| } |
| |
| //--------------------------------------------------------------------- |
| // Public methods |
| // |
| |
| /** @return the name of this property */ |
| public String getName() { return name; } |
| |
| /** @return the value of this property (the value is returned as an Object) */ |
| public Object getValue() { return value; } |
| |
| /** @return the value of this property as a String */ |
| public String getValueAsString() { return String.valueOf( value ); } |
| |
| /** |
| * Returns the Class object that is the type of this property value |
| * possible values returned are the java.lang wrapper classes for the |
| * primitive types e.g. Integer, Byte, Boolean, ... |
| * @return the type of this property as a java.lang.Class object |
| */ |
| public Class getType() { return typeClass; } |
| |
| /** |
| * Sets the name of this property |
| * @param s the String object |
| * @throws java.lang.IllegalArgumentException if the argument is null |
| */ |
| public void setName( String s ) throws IllegalArgumentException |
| { |
| checkNull( s ); |
| |
| name = s; |
| } |
| |
| /** |
| * Sets the value of this property (String). Also sets its Type. |
| * <p><b>This is the default type of any property</b></p> |
| * @param objValue the object's value |
| * @throws java.lang.IllegalArgumentException if the value is null or |
| * that this is not a valid typed property value |
| */ |
| public void setValue( Object objValue ) throws IllegalArgumentException |
| { |
| checkNull( objValue ); |
| |
| if( JposEntryUtility.validatePropValue( objValue, objValue.getClass() ) == false ) |
| throw new IllegalArgumentException( "Cannot set property named = " + getName() + |
| " with value = " + objValue + |
| " invalid value or type" ); |
| |
| setValue( objValue, objValue.getClass() ); |
| } |
| |
| /** |
| * @return true if the property is of the type specified by the Class |
| * object passed |
| * @param type the Class object |
| */ |
| public boolean isOfType( Class type ) |
| { |
| if( type == null || typeClass == null ) return false; |
| |
| return typeClass.equals( type ); |
| } |
| |
| /** @return a new copy of this JposEntry.Prop object */ |
| public JposEntry.Prop copy() { return new SimpleEntry.Prop( getName(), getValue() ); } |
| |
| //--------------------------------------------------------------------- |
| // Public overridden |
| // |
| |
| /** |
| * @return true if this and otherProp have same name and value |
| * @param otherProp the other JposEntry.Prop |
| */ |
| public boolean equals( Object otherProp ) |
| { |
| if( otherProp == null ) return false; |
| |
| if( !( otherProp instanceof JposEntry.Prop ) ) return false; |
| |
| JposEntry.Prop prop = (JposEntry.Prop)otherProp; |
| |
| return ( getName().equals( prop.getName() ) ) && |
| ( getValue().equals( prop.getValue() ) ); |
| } |
| |
| |
| /** |
| * @return 0 if two entries are the same -1 if this is less or 1 of more than other |
| * the comparison for > and < uses the logicalName of the entry to decide |
| * @param otherEntry the other JposEntry |
| */ |
| public int compareTo( Object other ) |
| { |
| if( other == null || ( (other instanceof JposEntry.Prop ) == false ) ) |
| throw new RuntimeException( "Cannot compare: " + other + " with JposEntry.Prop: " + this ); |
| |
| JposEntry.Prop otherEntryProp = (JposEntry.Prop)other; |
| |
| if( equals( otherEntryProp ) ) return 0; |
| |
| return getName().compareTo( otherEntryProp.getName() ); |
| } |
| |
| /** @return a unique key for this object */ |
| public int hashCode() { return getName().hashCode(); } |
| |
| //--------------------------------------------------------------------- |
| // Private methods |
| // |
| |
| /** |
| * Sets the value of this property as an Object that must match the |
| * the type specified. Also sets its Type. |
| * @param object the Object value (must be one of wrapper for primitive types |
| * or java.lang.String) |
| * @param type the java.lang.Class object matching the object type |
| * @throws java.lang.IllegalArgumentException if the object value type does not |
| * match the Class type |
| */ |
| private void setValue( Object object, Class type ) throws IllegalArgumentException |
| { |
| checkNull( object ); |
| checkNull( type ); |
| |
| if( !object.getClass().equals( type ) ) |
| throw new IllegalArgumentException( "Value and value type not in agreement for property named = " + name ); |
| |
| value = object; |
| typeClass = type; |
| } |
| |
| //--------------------------------------------------------------------- |
| // Instance variables |
| // |
| |
| private String name = ""; |
| private Object value = null; |
| private Class typeClass = null; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // Public constants |
| // |
| |
| /** |
| * serialVersionUID constant to maintain serialization compatibility between releases |
| * @since 1.3 (SF 2K meeting) |
| */ |
| public static final long serialVersionUID = 6937048853319310114L; |
| } |