001/* 002 * Copyright 2002-2017 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.beans.propertyeditors; 018 019import java.beans.PropertyEditorSupport; 020import java.util.Locale; 021import java.util.ResourceBundle; 022 023import org.springframework.util.Assert; 024import org.springframework.util.StringUtils; 025 026/** 027 * {@link java.beans.PropertyEditor} implementation for standard JDK 028 * {@link java.util.ResourceBundle ResourceBundles}. 029 * 030 * <p>Only supports conversion <i>from</i> a String, but not <i>to</i> a String. 031 * 032 * Find below some examples of using this class in a (properly configured) 033 * Spring container using XML-based metadata: 034 * 035 * <pre class="code"> <bean id="errorDialog" class="..."> 036 * <!-- 037 * the 'messages' property is of type java.util.ResourceBundle. 038 * the 'DialogMessages.properties' file exists at the root of the CLASSPATH 039 * --> 040 * <property name="messages" value="DialogMessages"/> 041 * </bean></pre> 042 * 043 * <pre class="code"> <bean id="errorDialog" class="..."> 044 * <!-- 045 * the 'DialogMessages.properties' file exists in the 'com/messages' package 046 * --> 047 * <property name="messages" value="com/messages/DialogMessages"/> 048 * </bean></pre> 049 * 050 * <p>A 'properly configured' Spring {@link org.springframework.context.ApplicationContext container} 051 * might contain a {@link org.springframework.beans.factory.config.CustomEditorConfigurer} 052 * definition such that the conversion can be effected transparently: 053 * 054 * <pre class="code"> <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> 055 * <property name="customEditors"> 056 * <map> 057 * <entry key="java.util.ResourceBundle"> 058 * <bean class="org.springframework.beans.propertyeditors.ResourceBundleEditor"/> 059 * </entry> 060 * </map> 061 * </property> 062 * </bean></pre> 063 * 064 * <p>Please note that this {@link java.beans.PropertyEditor} is <b>not</b> 065 * registered by default with any of the Spring infrastructure. 066 * 067 * <p>Thanks to David Leal Valmana for the suggestion and initial prototype. 068 * 069 * @author Rick Evans 070 * @author Juergen Hoeller 071 * @since 2.0 072 */ 073public class ResourceBundleEditor extends PropertyEditorSupport { 074 075 /** 076 * The separator used to distinguish between the base name and the locale 077 * (if any) when {@link #setAsText(String) converting from a String}. 078 */ 079 public static final String BASE_NAME_SEPARATOR = "_"; 080 081 082 @Override 083 public void setAsText(String text) throws IllegalArgumentException { 084 Assert.hasText(text, "'text' must not be empty"); 085 String name = text.trim(); 086 087 int separator = name.indexOf(BASE_NAME_SEPARATOR); 088 if (separator == -1) { 089 setValue(ResourceBundle.getBundle(name)); 090 } 091 else { 092 // The name potentially contains locale information 093 String baseName = name.substring(0, separator); 094 if (!StringUtils.hasText(baseName)) { 095 throw new IllegalArgumentException("Invalid ResourceBundle name: '" + text + "'"); 096 } 097 String localeString = name.substring(separator + 1); 098 Locale locale = StringUtils.parseLocaleString(localeString); 099 setValue(locale != null ? ResourceBundle.getBundle(baseName, locale) : ResourceBundle.getBundle(baseName)); 100 } 101 } 102 103}