001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */ 
017    package org.apache.commons.betwixt.strategy;
018    
019    import java.io.Serializable;
020    
021    import org.apache.commons.betwixt.Options;
022    import org.apache.commons.betwixt.expression.Context;
023    
024    /** 
025     * <p>Strategy class for string &lt;-&gt; object conversions.
026     * Implementations of this interface are used by Betwixt to perform
027     * string &lt;-&gt; object conversions.
028     * This performs only the most basic conversions.
029     * Most applications will use a subclass.
030     * </p>
031     * <p>It is strongly recommended that (in order to support round tripping)
032     * that <code>objectToString</code> and <code>stringToObject</code>
033     * are inverse functions.
034     * In other words, given the same flavour, context and type the applying 
035     * objectToString to the result of stringToObject should be equal to the 
036     * original input.
037     * </p>
038     * @author Robert Burrell Donkin 
039     * @since 0.5
040     */
041    public class ObjectStringConverter implements Serializable {
042        
043        /** Standard name for option giving flavour */
044        public static final String FLAVOUR_OPTION_NAME 
045            = "org.apache.commons.betwixt.flavour";
046        
047        /**
048          * Converts an object to a string representation.
049          * This basic implementation returns object.toString() 
050          * or an empty string if the given object is null.
051          *
052          * @param object the object to be converted, possibly null
053          * @param type the property class of the object, not null
054          * @param flavour a string allow symantic differences in formatting to be communicated
055          * @param context the context, not null
056          * @deprecated 0.7 use {@link #objectToString(Object, Class, Context)} instead. 
057          * The preferred way to support flavours is by setting the
058          * <code>org.apache.commons.betwixt.FLAVOUR</code> option.
059          * This can then be retrieved by calling {@link Context#getOptions()}
060          * @return a String representation, not null
061          */
062        public String objectToString(Object object, Class type, String flavour, Context context) {
063            if ( object != null ) {
064                return object.toString();
065            } 
066            return "";
067        }
068        
069        /**
070          * Converts a string representation to an object.
071          * It is acceptable for an implementation to return the string if it cannot convert 
072          * the string to the given class type.
073          * This basic implementation just returns a string.
074          * 
075          * @param value the String to be converted
076          * @param type the property class to be returned (if possible), not null
077          * @param flavour a string allow symantic differences in formatting to be communicated
078          * @param context the context, not null
079          * @deprecated 0.7 use {@link #stringToObject(String, Class, Context)} instead.
080          * The preferred way to support flavours is by setting the
081          * <code>org.apache.commons.betwixt.FLAVOUR</code> option.
082          * This can then be retrieved by calling {@link Context#getOptions()}
083          * @return an Object converted from the String, not null
084          */
085        public Object stringToObject(String value, Class type, String flavour, Context context) {
086            return value;
087        }
088    
089        
090        /**
091          * Converts an object to a string representation.
092          * This basic implementation returns object.toString() 
093          * or an empty string if the given object is null.
094          *
095          * @since 0.7
096          * @param object the object to be converted, possibly null
097          * @param type the property class of the object, not null
098          * @param context the context, not null
099          * @return a String representation, not null
100          */
101        public String objectToString(Object object, Class type, Context context) {
102            String flavour = getFlavour(context);
103            return objectToString(object, type, flavour, context);
104        }
105        
106        /**
107          * Converts a string representation to an object.
108          * It is acceptable for an implementation to return the string if it cannot convert 
109          * the string to the given class type.
110          * This basic implementation just returns a string.
111          * 
112          * @since 0.7
113          * @param value the String to be converted
114          * @param type the property class to be returned (if possible), not null
115          * @param context the context, not null
116          * @return an Object converted from the String, not null
117          */
118        public Object stringToObject(String value, Class type, Context context) {
119            String flavour = getFlavour(context);
120            return stringToObject(value, type, flavour, context);
121        }
122    
123        /**
124         * Gets the current flavour from the context.
125         * @param context <code>Context</code>, not null
126         */
127        private String getFlavour(Context context) {
128            String flavour = null;
129            Options options = context.getOptions();
130            if (options != null) {
131                flavour = options.getValue(FLAVOUR_OPTION_NAME);
132            }
133            return flavour;
134        }
135    }