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