001/* 002 * Copyright 2006-2007 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.batch.support; 018 019import java.io.IOException; 020import java.io.StringReader; 021import java.io.StringWriter; 022import java.util.Arrays; 023import java.util.List; 024import java.util.Properties; 025 026import org.springframework.util.DefaultPropertiesPersister; 027import org.springframework.util.PropertiesPersister; 028import org.springframework.util.StringUtils; 029 030/** 031 * Utility to convert a Properties object to a String and back. Ideally this 032 * utility should have been used to convert to string in order to convert that 033 * string back to a Properties Object. Attempting to convert a string obtained 034 * by calling Properties.toString() will return an invalid Properties object. 035 * The format of Properties is that used by {@link PropertiesPersister} from the 036 * Spring Core, so a String in the correct format for a Spring property editor 037 * is fine (key=value pairs separated by new lines). 038 * 039 * @author Lucas Ward 040 * @author Dave Syer 041 * 042 * @see PropertiesPersister 043 */ 044public final class PropertiesConverter { 045 046 private static final PropertiesPersister propertiesPersister = new DefaultPropertiesPersister(); 047 048 private static final String LINE_SEPARATOR = System.getProperty("line.separator"); 049 050 // prevents the class from being instantiated 051 private PropertiesConverter() { 052 } 053 054 /** 055 * Parse a String to a Properties object. If string is null, an empty 056 * Properties object will be returned. The input String is a set of 057 * name=value pairs, delimited by either newline or comma (for brevity). If 058 * the input String contains a newline it is assumed that the separator is 059 * newline, otherwise comma. 060 * 061 * @param stringToParse String to parse. 062 * @return Properties parsed from each string. 063 * @see PropertiesPersister 064 */ 065 public static Properties stringToProperties(String stringToParse) { 066 067 if (stringToParse == null) { 068 return new Properties(); 069 } 070 071 if (!contains(stringToParse, "\n")) { 072 stringToParse = StringUtils.arrayToDelimitedString( 073 StringUtils.commaDelimitedListToStringArray(stringToParse), "\n"); 074 } 075 076 StringReader stringReader = new StringReader(stringToParse); 077 078 Properties properties = new Properties(); 079 080 try { 081 propertiesPersister.load(properties, stringReader); 082 // Exception is only thrown by StringReader after it is closed, 083 // so never in this case. 084 } 085 catch (IOException ex) { 086 throw new IllegalStateException("Error while trying to parse String to java.util.Properties," 087 + " given String: " + properties); 088 } 089 090 return properties; 091 } 092 093 /** 094 * Convert Properties object to String. This is only necessary for 095 * compatibility with converting the String back to a properties object. If 096 * an empty properties object is passed in, a blank string is returned, 097 * otherwise it's string representation is returned. 098 * 099 * @param propertiesToParse contains the properties be converted. 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}