1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.struts;
24  
25  import com.liferay.portal.kernel.log.Log;
26  import com.liferay.portal.kernel.log.LogFactoryUtil;
27  import com.liferay.portal.kernel.util.LocaleUtil;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.StringUtil;
30  
31  import java.io.InputStream;
32  
33  import java.net.URL;
34  
35  import java.util.Enumeration;
36  import java.util.Map;
37  import java.util.Properties;
38  import java.util.concurrent.locks.Lock;
39  import java.util.concurrent.locks.ReadWriteLock;
40  import java.util.concurrent.locks.ReentrantReadWriteLock;
41  
42  import javax.servlet.ServletContext;
43  
44  import org.apache.struts.util.MessageResourcesFactory;
45  import org.apache.struts.util.PropertyMessageResources;
46  
47  /**
48   * <a href="MultiMessageResources.java.html"><b><i>View Source</i></b></a>
49   *
50   * @author Brian Wing Shun Chan
51   * @author Bruno Farache
52   */
53  public class MultiMessageResources extends PropertyMessageResources {
54  
55      public MultiMessageResources(
56          MessageResourcesFactory factory, String config) {
57  
58          this(factory, config, true);
59      }
60  
61      public MultiMessageResources(
62          MessageResourcesFactory factory, String config, boolean returnNull) {
63  
64          super(factory, config, returnNull);
65  
66          _localeReadWriteLock = new ReentrantReadWriteLock();
67  
68          _localeReadLock = _localeReadWriteLock.readLock();
69          _localeWriteLock = _localeReadWriteLock.writeLock();
70  
71          _messagesReadWriteLock = new ReentrantReadWriteLock();
72  
73          _messagesReadLock = _messagesReadWriteLock.readLock();
74          _messagesWriteLock = _messagesReadWriteLock.writeLock();
75      }
76  
77      public Map<String, String> getMessages() {
78          _messagesReadLock.lock();
79  
80          try {
81              return messages;
82          }
83          finally {
84              _messagesReadLock.unlock();
85          }
86      }
87  
88      public void putLocale(String localeKey) {
89          _localeWriteLock.lock();
90  
91          try {
92              locales.put(localeKey, localeKey);
93          }
94          finally {
95              _localeWriteLock.unlock();
96          }
97      }
98  
99      public Properties putMessages(Properties properties, String localeKey) {
100         Properties oldProperties = new Properties();
101 
102         if (properties.size() < 1) {
103             return oldProperties;
104         }
105 
106         _messagesWriteLock.lock();
107 
108         try {
109             Enumeration<Object> names = properties.keys();
110 
111             while (names.hasMoreElements()) {
112                 String key = (String)names.nextElement();
113 
114                 String message = getMessage(
115                     LocaleUtil.fromLanguageId(localeKey), key);
116 
117                 if (message != null) {
118                     oldProperties.put(key, message);
119                 }
120 
121                 messages.put(
122                     messageKey(localeKey, key), properties.getProperty(key));
123             }
124         }
125         finally {
126             _messagesWriteLock.unlock();
127         }
128 
129         return oldProperties;
130     }
131 
132     public void setServletContext(ServletContext servletContext) {
133         _servletContext = servletContext;
134     }
135 
136     public void loadLocale(String localeKey) {
137         _localeReadLock.lock();
138 
139         try {
140             if (locales.containsKey(localeKey)) {
141                 return;
142             }
143         }
144         finally {
145             _localeReadLock.unlock();
146         }
147 
148         _localeWriteLock.lock();
149 
150         try {
151             if (locales.containsKey(localeKey)) {
152                 return;
153             }
154 
155             locales.put(localeKey, localeKey);
156         }
157         finally {
158             _localeWriteLock.unlock();
159         }
160 
161         String[] names = StringUtil.split(
162             config.replace(StringPool.PERIOD, StringPool.SLASH));
163 
164         for (int i = 0; i < names.length; i++) {
165             String name = names[i];
166 
167             if (localeKey.length() > 0) {
168                 name += "_" + localeKey;
169             }
170 
171             name += ".properties";
172 
173             _loadProperties(name, localeKey, false);
174         }
175 
176         for (int i = 0; i < names.length; i++) {
177             String name = names[i];
178 
179             if (localeKey.length() > 0) {
180                 name += "_" + localeKey;
181             }
182 
183             name += ".properties";
184 
185             _loadProperties(name, localeKey, true);
186         }
187     }
188 
189     private void _loadProperties(
190         String name, String localeKey, boolean useServletContext) {
191 
192         Properties properties = new Properties();
193 
194         try {
195             URL url = null;
196 
197             if (useServletContext) {
198                 url = _servletContext.getResource("/WEB-INF/" + name);
199             }
200             else {
201                 ClassLoader classLoader = getClass().getClassLoader();
202 
203                 url = classLoader.getResource(name);
204             }
205 
206             if (_log.isInfoEnabled()) {
207                 _log.info(
208                     "Attempting to load " + name + " " + localeKey + " " +
209                         useServletContext);
210             }
211 
212             if (url != null) {
213                 InputStream is = url.openStream();
214 
215                 properties.load(is);
216 
217                 is.close();
218 
219                 if (_log.isInfoEnabled()) {
220                     _log.info(
221                         "Loading " + url + " with " + properties.size() +
222                             " values");
223                 }
224             }
225         }
226         catch (Exception e) {
227             _log.warn(e);
228         }
229 
230         putMessages(properties, localeKey);
231     }
232 
233     private static Log _log =
234         LogFactoryUtil.getLog(MultiMessageResources.class);
235 
236     private Lock _localeReadLock;
237     private ReadWriteLock _localeReadWriteLock;
238     private Lock _localeWriteLock;
239     private Lock _messagesReadLock;
240     private ReadWriteLock _messagesReadWriteLock;
241     private Lock _messagesWriteLock;
242     private transient ServletContext _servletContext;
243 
244 }