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.StringUtil;
29  
30  import java.io.InputStream;
31  
32  import java.net.URL;
33  
34  import java.util.Enumeration;
35  import java.util.Map;
36  import java.util.Properties;
37  import java.util.concurrent.locks.Lock;
38  import java.util.concurrent.locks.ReadWriteLock;
39  import java.util.concurrent.locks.ReentrantReadWriteLock;
40  
41  import javax.servlet.ServletContext;
42  
43  import org.apache.struts.util.MessageResourcesFactory;
44  import org.apache.struts.util.PropertyMessageResources;
45  
46  /**
47   * <a href="MultiMessageResources.java.html"><b><i>View Source</i></b></a>
48   *
49   * @author Brian Wing Shun Chan
50   * @author Bruno Farache
51   */
52  public class MultiMessageResources extends PropertyMessageResources {
53  
54      public MultiMessageResources(
55          MessageResourcesFactory factory, String config) {
56  
57          this(factory, config, true);
58      }
59  
60      public MultiMessageResources(
61          MessageResourcesFactory factory, String config, boolean returnNull) {
62  
63          super(factory, config, returnNull);
64  
65          _localeReadWriteLock = new ReentrantReadWriteLock();
66  
67          _localeReadLock = _localeReadWriteLock.readLock();
68          _localeWriteLock = _localeReadWriteLock.writeLock();
69  
70          _messagesReadWriteLock = new ReentrantReadWriteLock();
71  
72          _messagesReadLock = _messagesReadWriteLock.readLock();
73          _messagesWriteLock = _messagesReadWriteLock.writeLock();
74      }
75  
76      public Map<String, String> getMessages() {
77          _messagesReadLock.lock();
78  
79          try {
80              return messages;
81          }
82          finally {
83              _messagesReadLock.unlock();
84          }
85      }
86  
87      public void putLocale(String localeKey) {
88          _localeWriteLock.lock();
89  
90          try {
91              locales.put(localeKey, localeKey);
92          }
93          finally {
94              _localeWriteLock.unlock();
95          }
96      }
97  
98      public Properties putMessages(Properties props, String localeKey) {
99          Properties oldProps = new Properties();
100 
101         if (props.size() < 1) {
102             return oldProps;
103         }
104 
105         _messagesWriteLock.lock();
106 
107         try {
108             Enumeration<Object> names = props.keys();
109 
110             while (names.hasMoreElements()) {
111                 String key = (String)names.nextElement();
112 
113                 String message = getMessage(
114                     LocaleUtil.fromLanguageId(localeKey), key);
115 
116                 if (message != null) {
117                     oldProps.put(key, message);
118                 }
119 
120                 messages.put(
121                     messageKey(localeKey, key), props.getProperty(key));
122             }
123         }
124         finally {
125             _messagesWriteLock.unlock();
126         }
127 
128         return oldProps;
129     }
130 
131     public void setServletContext(ServletContext servletContext) {
132         _servletContext = servletContext;
133     }
134 
135     public void loadLocale(String localeKey) {
136         _localeReadLock.lock();
137 
138         try {
139             if (locales.containsKey(localeKey)) {
140                 return;
141             }
142         }
143         finally {
144             _localeReadLock.unlock();
145         }
146 
147         _localeWriteLock.lock();
148 
149         try {
150             if (locales.containsKey(localeKey)) {
151                 return;
152             }
153 
154             locales.put(localeKey, localeKey);
155         }
156         finally {
157             _localeWriteLock.unlock();
158         }
159 
160         String[] names = StringUtil.split(config.replace('.', '/'));
161 
162         for (int i = 0; i < names.length; i++) {
163             String name = names[i];
164 
165             if (localeKey.length() > 0) {
166                 name += "_" + localeKey;
167             }
168 
169             name += ".properties";
170 
171             _loadProps(name, localeKey, false);
172         }
173 
174         for (int i = 0; i < names.length; i++) {
175             String name = names[i];
176 
177             if (localeKey.length() > 0) {
178                 name += "_" + localeKey;
179             }
180 
181             name += ".properties";
182 
183             _loadProps(name, localeKey, true);
184         }
185     }
186 
187     private void _loadProps(
188         String name, String localeKey, boolean useServletContext) {
189 
190         Properties props = new Properties();
191 
192         try {
193             URL url = null;
194 
195             if (useServletContext) {
196                 url = _servletContext.getResource("/WEB-INF/" + name);
197             }
198             else {
199                 ClassLoader classLoader = getClass().getClassLoader();
200 
201                 url = classLoader.getResource(name);
202             }
203 
204             if (_log.isInfoEnabled()) {
205                 _log.info(
206                     "Attempting to load " + name + " " + localeKey + " " +
207                         useServletContext);
208             }
209 
210             if (url != null) {
211                 InputStream is = url.openStream();
212 
213                 props.load(is);
214 
215                 is.close();
216 
217                 if (_log.isInfoEnabled()) {
218                     _log.info(
219                         "Loading " + url + " with " + props.size() + " values");
220                 }
221             }
222         }
223         catch (Exception e) {
224             _log.warn(e);
225         }
226 
227         putMessages(props, localeKey);
228     }
229 
230     private static Log _log =
231         LogFactoryUtil.getLog(MultiMessageResources.class);
232 
233     private Lock _localeReadLock;
234     private ReadWriteLock _localeReadWriteLock;
235     private Lock _localeWriteLock;
236     private Lock _messagesReadLock;
237     private ReadWriteLock _messagesReadWriteLock;
238     private Lock _messagesWriteLock;
239     private transient ServletContext _servletContext;
240 
241 }