1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.struts;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.util.LocaleUtil;
20  import com.liferay.portal.kernel.util.StringPool;
21  import com.liferay.portal.kernel.util.StringUtil;
22  
23  import java.io.InputStream;
24  
25  import java.net.URL;
26  
27  import java.util.Enumeration;
28  import java.util.Map;
29  import java.util.Properties;
30  import java.util.concurrent.locks.Lock;
31  import java.util.concurrent.locks.ReadWriteLock;
32  import java.util.concurrent.locks.ReentrantReadWriteLock;
33  
34  import javax.servlet.ServletContext;
35  
36  import org.apache.struts.util.MessageResourcesFactory;
37  import org.apache.struts.util.PropertyMessageResources;
38  
39  /**
40   * <a href="MultiMessageResources.java.html"><b><i>View Source</i></b></a>
41   *
42   * @author Brian Wing Shun Chan
43   * @author Bruno Farache
44   */
45  public class MultiMessageResources extends PropertyMessageResources {
46  
47      public MultiMessageResources(
48          MessageResourcesFactory factory, String config) {
49  
50          this(factory, config, true);
51      }
52  
53      public MultiMessageResources(
54          MessageResourcesFactory factory, String config, boolean returnNull) {
55  
56          super(factory, config, returnNull);
57  
58          _localeReadWriteLock = new ReentrantReadWriteLock();
59  
60          _localeReadLock = _localeReadWriteLock.readLock();
61          _localeWriteLock = _localeReadWriteLock.writeLock();
62  
63          _messagesReadWriteLock = new ReentrantReadWriteLock();
64  
65          _messagesReadLock = _messagesReadWriteLock.readLock();
66          _messagesWriteLock = _messagesReadWriteLock.writeLock();
67      }
68  
69      public Map<String, String> getMessages() {
70          _messagesReadLock.lock();
71  
72          try {
73              return messages;
74          }
75          finally {
76              _messagesReadLock.unlock();
77          }
78      }
79  
80      public void putLocale(String localeKey) {
81          _localeWriteLock.lock();
82  
83          try {
84              locales.put(localeKey, localeKey);
85          }
86          finally {
87              _localeWriteLock.unlock();
88          }
89      }
90  
91      public Properties putMessages(Properties properties, String localeKey) {
92          Properties oldProperties = new Properties();
93  
94          if (properties.size() < 1) {
95              return oldProperties;
96          }
97  
98          _messagesWriteLock.lock();
99  
100         try {
101             Enumeration<Object> names = properties.keys();
102 
103             while (names.hasMoreElements()) {
104                 String key = (String)names.nextElement();
105 
106                 String message = getMessage(
107                     LocaleUtil.fromLanguageId(localeKey), key);
108 
109                 if (message != null) {
110                     oldProperties.put(key, message);
111                 }
112 
113                 messages.put(
114                     messageKey(localeKey, key), properties.getProperty(key));
115             }
116         }
117         finally {
118             _messagesWriteLock.unlock();
119         }
120 
121         return oldProperties;
122     }
123 
124     public void setServletContext(ServletContext servletContext) {
125         _servletContext = servletContext;
126     }
127 
128     public void loadLocale(String localeKey) {
129         _localeReadLock.lock();
130 
131         try {
132             if (locales.containsKey(localeKey)) {
133                 return;
134             }
135         }
136         finally {
137             _localeReadLock.unlock();
138         }
139 
140         _localeWriteLock.lock();
141 
142         try {
143             if (locales.containsKey(localeKey)) {
144                 return;
145             }
146 
147             locales.put(localeKey, localeKey);
148         }
149         finally {
150             _localeWriteLock.unlock();
151         }
152 
153         String[] names = StringUtil.split(
154             config.replace(StringPool.PERIOD, StringPool.SLASH));
155 
156         for (int i = 0; i < names.length; i++) {
157             String name = names[i];
158 
159             if (localeKey.length() > 0) {
160                 name += "_" + localeKey;
161             }
162 
163             name += ".properties";
164 
165             _loadProperties(name, localeKey, false);
166         }
167 
168         for (int i = 0; i < names.length; i++) {
169             String name = names[i];
170 
171             if (localeKey.length() > 0) {
172                 name += "_" + localeKey;
173             }
174 
175             name += ".properties";
176 
177             _loadProperties(name, localeKey, true);
178         }
179     }
180 
181     private void _loadProperties(
182         String name, String localeKey, boolean useServletContext) {
183 
184         Properties properties = new Properties();
185 
186         try {
187             URL url = null;
188 
189             if (useServletContext) {
190                 url = _servletContext.getResource("/WEB-INF/" + name);
191             }
192             else {
193                 ClassLoader classLoader = getClass().getClassLoader();
194 
195                 url = classLoader.getResource(name);
196             }
197 
198             if (_log.isInfoEnabled()) {
199                 _log.info(
200                     "Attempting to load " + name + " " + localeKey + " " +
201                         useServletContext);
202             }
203 
204             if (url != null) {
205                 InputStream is = url.openStream();
206 
207                 properties.load(is);
208 
209                 is.close();
210 
211                 if (_log.isInfoEnabled()) {
212                     _log.info(
213                         "Loading " + url + " with " + properties.size() +
214                             " values");
215                 }
216             }
217         }
218         catch (Exception e) {
219             _log.warn(e);
220         }
221 
222         putMessages(properties, localeKey);
223     }
224 
225     private static Log _log = LogFactoryUtil.getLog(
226         MultiMessageResources.class);
227 
228     private Lock _localeReadLock;
229     private ReadWriteLock _localeReadWriteLock;
230     private Lock _localeWriteLock;
231     private Lock _messagesReadLock;
232     private ReadWriteLock _messagesReadWriteLock;
233     private Lock _messagesWriteLock;
234     private transient ServletContext _servletContext;
235 
236 }