// // Copyright (c)1998-2011 Pearson Education, Inc. or its affiliate(s). // All rights reserved. // package openadk.library.tools.mapping; import java.util.Map; import java.util.Set; import openadk.library.*; import org.apache.commons.jxpath.Variables; /** * * A FieldAdaptor implementation that contains field values to assign to the * supplied SIFDataObject, where each entry in the map is keyed by the * local application-defined name of a field and the value is the text * value to assign to the corresponding element or attribute of the * SIFDataObject, in the SIF 1.5r1 text format.<p> * * This class is most useful for agents that were written using the 1.x version * of the ADK and offers compatibility with the Mappings implementation used in * that release. Values mapped to and from the Map used in this class will match * the textual representation of those values in the 1.x version of the ADK. For example, * a SIF date field that is mapped to this class will map to and from the SIF 1.5 format * for dates, which was yyyyMMdd.<p> * * The Data-to-Text formatting is controlled by the {@link openadk.library.ADK#getTextFormatter()} * property, which defaults to SIF 1.5 formatting. If you wish to supply your own text formatter, * you can call the constructor overload that accepts a SIFFormatter instance. * * * To use this class,<p> * * <ol> * <li> * Create an instance and optionally populate the Map with known field * values that will not be subject to the mapping process. If pre-loading * the Map, the key of each entry should be the local * application-defined field name and the value should be the string * value of that field. Any field added to the Map before calling * this method will not be subject to mapping rules, unless the * {@link openadk.library.tools.mapping.ObjectMapAdaptor#setOverwriteValues(boolean)} * property is set to <code>True</code>. * </li> * <li> * Use this class instance with the {@link openadk.library.tools.mapping.Mappings} * class,by calling the appropriate <code>map</code> method and passing the SIFDataObject * instance to retrieve field values from for insertion into the * Map. The method first looks up the ObjectMapping instance * corresponding to the SIF Data Object type. If no ObjectMapping * has been defined for the object type, no action is taken and the * method returns successfully without exception. Otherwise, all * field rules defined by the ObjectMapping are evaluated in order. * If a rule evaluates successfully, the corresponding element or * attribute value will be inserted into the HashMap. A rule will * not be evaluated if the associated field already exists in the * Map, unless the * {@link openadk.library.tools.mapping.ObjectMapAdaptor#setOverwriteValues(boolean)} * property is set to <code>True</code>. * </li> * </ol> * * @see openadk.library.ADK#setTextFormatter(SIFFormatter) * @see openadk.library.ADK#getTextFormatter() * @see openadk.library.tools.mapping.Mappings * * @author Andrew Elmhorst * * @version 2.0 * */ public class StringMapAdaptor extends ObjectMapAdaptor { private SIFFormatter fDataFormatter; private boolean fLooseDataTypeParsing = true; /** * Creates an instance of StringMapAdaptor that uses the specified Map * @param dataMap The <code>Map</code> to use for SIF Data mapping operations */ public StringMapAdaptor( Map dataMap ) { this( dataMap, ADK.getTextFormatter() ); } /** * Creates an instance of StringMapAdaptor that uses the specified map and * specified SIFFormatter instance for deriving String values from SIF datatypes * @param dataMap The <code>Map</code> to use for SIF Data mapping operations * @param formatter The formatter to use for converting SIF native datatypes to * text and back again. */ public StringMapAdaptor(Map dataMap, SIFFormatter formatter ) { super( dataMap ); fDataFormatter = formatter; } /** * @see openadk.library.tools.mapping.ObjectMapAdaptor#toMapValue(openadk.library.SIFSimpleType) */ @Override protected Object toMapValue( SIFSimpleType value ) { // Store items in the map using a string value return value.toString( fDataFormatter ); } /** * @see openadk.library.tools.mapping.ObjectMapAdaptor#fromMapValue(String, java.lang.Object, openadk.library.SIFTypeConverter) */ @Override protected SIFSimpleType fromMapValue( String fieldName, Object mapValue, SIFTypeConverter typeConverter ) { // Items are stored in the map as string values. Convert them using the typeConverter's parse method if( mapValue == null ){ return null; } try { return typeConverter.parse( fDataFormatter, (String)mapValue ); } catch( ADKParsingException adkpe ) { if( fLooseDataTypeParsing ){ // TT 2998 Add support for ignoring type parse exceptions // on Outbound data. If it fails to parse, ignore if( ( ADK.debug & ADK.DBG_MESSAGING_DETAILED ) > 0 ){ ADK.getLog().warn( "Unable to parse value for outbound mapping for field " + fieldName + ". Ignored error: " + adkpe.getMessage() , adkpe ); } return null; } else { throw new NumberFormatException( adkpe.getMessage() ); } } } /** * Sets whether or not data type conversion from string to SIF Types throws an Exception or not * @param fLooseDataTypeParsing TRUE if the ADK should suppress exceptions for data type parsing errors */ public void setLooseDataTypeParsing(boolean fLooseDataTypeParsing) { this.fLooseDataTypeParsing = fLooseDataTypeParsing; } /** * Sets whether or not data type conversion from string to SIF Types throws an Exception or not * @return TRUE if the ADK suppresses exceptions for data type parsing errors */ public boolean getLooseDataTypeParsing() { return fLooseDataTypeParsing; } }