View Javadoc

1   /*
2    * Copyright 2004-2005, 2008 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at
7    * 
8    * http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package net.sf.morph.transform.converters;
17  
18  import java.util.Locale;
19  
20  import net.sf.composite.util.ObjectUtils;
21  import net.sf.morph.reflect.BeanReflector;
22  
23  /**
24   * <p>
25   * Converts a bean to a textual representation (String or StringBuffer only).
26   * The string representation is comprised of a prefix, a textual representation
27   * of the array contents, and a suffix. The textual representation of the array
28   * contents is in turn made up of the string representation of each of the
29   * elements in the array separated by a separator character.  Conversions to
30   * characters will only succeed if the result of the conversion is a single
31   * character in length.
32   * </p>
33   * 
34   * <p>
35   * For example, if the prefix is <code>{</code>, the suffix is <code>}</code>,
36   * the separator is <code>,</code> and the contents of the array are the
37   * Integers <code>1</code>,<code>2</code> and <code>3</code>, the array
38   * will be converted to the text <code>{1,2,3}</code>.
39   * </p>
40   * 
41   * @author Matt Sgarlata
42   * @since Feb 15, 2005
43   */
44  public class BeanToPrettyTextConverter extends BaseToPrettyTextConverter {
45  	/** Default prefix */
46  	public static final String DEFAULT_PREFIX = "[";
47  	/** Default suffix */
48  	public static final String DEFAULT_SUFFIX = "]";
49  	/** Default separator */
50  	public static final String DEFAULT_SEPARATOR = ",";
51  	/** Default name/value separator */
52  	public static final String DEFAULT_NAME_VALUE_SEPARATOR = "=";
53  
54  	private String nameValueSeparator = DEFAULT_NAME_VALUE_SEPARATOR;
55  	private boolean showPropertyNames = true;	
56  
57  	/**
58  	 * Create a new BeanToPrettyTextConverter.
59  	 */
60  	public BeanToPrettyTextConverter() {
61  	    setPrefix(DEFAULT_PREFIX);
62  	    setSuffix(DEFAULT_SUFFIX);
63  	    setSeparator(DEFAULT_SEPARATOR);
64      }
65  
66  	/**
67  	 * {@inheritDoc}
68  	 */
69  	protected Object convertImpl(Class destinationClass, Object source,
70  		Locale locale) throws Exception {
71  
72  		BeanReflector beanReflector = getBeanReflector();
73  
74  		StringBuffer buffer = new StringBuffer();
75  		// can't pass prefix to constructor because if it's null we'll get a NPE
76  		if (getPrefix() != null) {
77  			buffer.append(getPrefix());
78  		}
79  		String[] propertyNames = beanReflector.getPropertyNames(source);
80  		boolean separatorNeeded = false;
81  		if (!ObjectUtils.isEmpty(propertyNames)) {
82  			String propertyName = propertyNames[0];
83  			Object value;
84  			if (beanReflector.isReadable(source, propertyName)) {
85  				value = beanReflector.get(source, propertyName);			
86  				append(buffer, propertyName, value, locale);
87  				if (value != null || isShowNullValues()) {
88  					separatorNeeded = true;
89  				}
90  			}
91  			for (int i = 1; i < propertyNames.length; i++) {
92  				propertyName = propertyNames[i];
93  				if (beanReflector.isReadable(source, propertyName)) {
94  					value = beanReflector.get(source, propertyName);
95  					if (value != null || isShowNullValues()) {
96  						if (separatorNeeded) {
97  							buffer.append(getSeparator());
98  						}
99  						separatorNeeded = true;
100 					}
101 					append(buffer, propertyNames[i], value, locale);
102 				}
103 			}
104 		}
105 		if (getSuffix() != null) {
106 			buffer.append(getSuffix());
107 		}
108 		return getTextConverter().convert(destinationClass, buffer, locale);
109 	}
110 
111 	private void append(StringBuffer buffer, String propertyName, Object value,
112 			Locale locale) {		
113 		if (value == null && !isShowNullValues()) {
114 			return;
115 		}
116 		if (isShowPropertyNames()) {
117 			buffer.append(propertyName).append(getNameValueSeparator());
118 		}
119 		buffer.append(getToTextConverter().convert(String.class, value, locale));
120 	}
121 
122 	/**
123 	 * {@inheritDoc}
124 	 */
125 	protected Class[] getSourceClassesImpl() throws Exception {
126 		return getBeanReflector().getReflectableClasses();
127 	}
128 
129 	/**
130 	 * Get the name/value separator.
131 	 * @return String
132 	 */
133 	public String getNameValueSeparator() {
134 		return nameValueSeparator;
135 	}
136 
137 	/**
138 	 * Set the name/value separator.
139 	 * @param nameValueSeparator
140 	 */
141 	public void setNameValueSeparator(String nameValueSeparator) {
142 		this.nameValueSeparator = nameValueSeparator;
143 	}
144 
145 	/**
146 	 * Learn whether this BeanToPrettyTextConverter is configured to show property names.
147 	 * @return boolean
148 	 */
149 	public boolean isShowPropertyNames() {
150 		return showPropertyNames;
151 	}
152 
153 	/**
154 	 * Set whether this BeanToPrettyTextConverter should show property names. Default <code>true</code>.
155 	 * @param showPropertyNames
156 	 */
157 	public void setShowPropertyNames(boolean showPropertyNames) {
158 		this.showPropertyNames = showPropertyNames;
159 	}
160 }