View Javadoc

1   /*
2    * Copyright 2006-2007 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of 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,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.batch.support;
18  
19  import java.io.IOException;
20  import java.io.StringReader;
21  import java.io.StringWriter;
22  import java.util.Arrays;
23  import java.util.List;
24  import java.util.Properties;
25  
26  import org.springframework.util.DefaultPropertiesPersister;
27  import org.springframework.util.PropertiesPersister;
28  import org.springframework.util.StringUtils;
29  
30  /**
31   * Utility to convert a Properties object to a String and back. Ideally this
32   * utility should have been used to convert to string in order to convert that
33   * string back to a Properties Object. Attempting to convert a string obtained
34   * by calling Properties.toString() will return an invalid Properties object.
35   * The format of Properties is that used by {@link PropertiesPersister} from the
36   * Spring Core, so a String in the correct format for a Spring property editor
37   * is fine (key=value pairs separated by new lines).
38   * 
39   * @author Lucas Ward
40   * @author Dave Syer
41   * 
42   * @see PropertiesPersister
43   */
44  public final class PropertiesConverter {
45  
46  	private static final PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
47  
48  	private static final String LINE_SEPARATOR = System.getProperty("line.separator");
49  
50  	// prevents the class from being instantiated
51  	private PropertiesConverter() {
52  	};
53  
54  	/**
55  	 * Parse a String to a Properties object. If string is null, an empty
56  	 * Properties object will be returned. The input String is a set of
57  	 * name=value pairs, delimited by either newline or comma (for brevity). If
58  	 * the input String contains a newline it is assumed that the separator is
59  	 * newline, otherwise comma.
60  	 * 
61  	 * @param stringToParse String to parse.
62  	 * @return Properties parsed from each string.
63  	 * @see PropertiesPersister
64  	 */
65  	public static Properties stringToProperties(String stringToParse) {
66  
67  		if (stringToParse == null) {
68  			return new Properties();
69  		}
70  
71  		if (!contains(stringToParse, "\n")) {
72  			stringToParse = StringUtils.arrayToDelimitedString(
73  					StringUtils.commaDelimitedListToStringArray(stringToParse), "\n");
74  		}
75  
76  		StringReader stringReader = new StringReader(stringToParse);
77  
78  		Properties properties = new Properties();
79  
80  		try {
81  			propertiesPersister.load(properties, stringReader);
82  			// Exception is only thrown by StringReader after it is closed,
83  			// so never in this case.
84  		}
85  		catch (IOException ex) {
86  			throw new IllegalStateException("Error while trying to parse String to java.util.Properties,"
87  					+ " given String: " + properties);
88  		}
89  
90  		return properties;
91  	}
92  
93  	/**
94  	 * Convert Properties object to String. This is only necessary for
95  	 * compatibility with converting the String back to a properties object. If
96  	 * an empty properties object is passed in, a blank string is returned,
97  	 * otherwise it's string representation is returned.
98  	 * 
99  	 * @param propertiesToParse
100 	 * @return String representation of properties object
101 	 */
102 	public static String propertiesToString(Properties propertiesToParse) {
103 
104 		// If properties is empty, return a blank string.
105 		if (propertiesToParse == null || propertiesToParse.size() == 0) {
106 			return "";
107 		}
108 
109 		StringWriter stringWriter = new StringWriter();
110 
111 		try {
112 			propertiesPersister.store(propertiesToParse, stringWriter, null);
113 		}
114 		catch (IOException ex) {
115 			// Exception is never thrown by StringWriter
116 			throw new IllegalStateException("Error while trying to convert properties to string");
117 		}
118 
119 		// If the value is short enough (and doesn't contain commas), convert to
120 		// comma-separated...
121 		String value = stringWriter.toString();
122 		if (value.length() < 160) {
123 			List<String> list = Arrays.asList(StringUtils.delimitedListToStringArray(value, LINE_SEPARATOR,
124 					LINE_SEPARATOR));
125 			String shortValue = StringUtils.collectionToCommaDelimitedString(list.subList(1, list.size()));
126 			int count = StringUtils.countOccurrencesOf(shortValue, ",");
127 			if (count == list.size() - 2) {
128 				value = shortValue;
129 			}
130 			if (value.endsWith(",")) {
131 				value = value.substring(0, value.length() - 1);
132 			}
133 		}
134 		return value;
135 	}
136 
137 	private static boolean contains(String str, String searchStr) {
138 		return str.indexOf(searchStr) != -1;
139 	}
140 }