001
014
015 package com.liferay.portal.kernel.portlet;
016
017 import com.liferay.portal.kernel.util.AggregateResourceBundle;
018 import com.liferay.portal.kernel.util.ResourceBundleUtil;
019 import com.liferay.portal.kernel.util.ResourceBundleUtil.ResourceBundleLoader;
020 import com.liferay.registry.collections.ServiceReferenceMapperFactory;
021 import com.liferay.registry.collections.ServiceTrackerCollections;
022 import com.liferay.registry.collections.ServiceTrackerMap;
023 import com.liferay.registry.collections.ServiceTrackerMapListener;
024
025 import java.io.Closeable;
026
027 import java.util.Iterator;
028 import java.util.List;
029 import java.util.Map;
030 import java.util.ResourceBundle;
031 import java.util.Set;
032 import java.util.concurrent.ConcurrentHashMap;
033
034
039 public class ResourceBundleTracker implements Closeable {
040
041 public ResourceBundleTracker(String portletId) {
042 _serviceTrackerMap = ServiceTrackerCollections.openMultiValueMap(
043 ResourceBundle.class,
044 "(&(javax.portlet.name=" + portletId + ")(language.id=*))",
045 ServiceReferenceMapperFactory.<String, Object>create("language.id"),
046 new ResourceBundleTrackerServiceTrackerMapListener());
047 }
048
049 @Override
050 public void close() {
051 _serviceTrackerMap.close();
052 }
053
054 public ResourceBundle getResourceBundle(String languageId) {
055 ResourceBundle resourceBundle = _resourceBundles.get(languageId);
056
057 if (resourceBundle != null) {
058 return resourceBundle;
059 }
060
061 synchronized (_resourceBundles) {
062 resourceBundle = _resourceBundles.get(languageId);
063
064 if (resourceBundle == null) {
065 ResourceBundleUtil.loadResourceBundles(
066 _resourceBundles, languageId,
067 new ResourceBundleLoader() {
068
069 @Override
070 public ResourceBundle loadResourceBundle(
071 String languageId) {
072
073 List<ResourceBundle> resourceBundles =
074 _serviceTrackerMap.getService(languageId);
075
076 if ((resourceBundles == null) ||
077 resourceBundles.isEmpty()) {
078
079 return null;
080 }
081
082 int size = resourceBundles.size();
083
084 if (size == 1) {
085 return resourceBundles.get(0);
086 }
087
088 return new AggregateResourceBundle(
089 resourceBundles.toArray(
090 new ResourceBundle[size]));
091 }
092
093 });
094
095 resourceBundle = _resourceBundles.get(languageId);
096 }
097 }
098
099 return resourceBundle;
100 }
101
102 private final Map<String, ResourceBundle> _resourceBundles =
103 new ConcurrentHashMap<>();
104 private final ServiceTrackerMap<String, List<ResourceBundle>>
105 _serviceTrackerMap;
106
107 private class ResourceBundleTrackerServiceTrackerMapListener
108 implements ServiceTrackerMapListener
109 <String, ResourceBundle, List<ResourceBundle>> {
110
111 @Override
112 public void keyEmitted(
113 ServiceTrackerMap<String, List<ResourceBundle>>
114 serviceTrackerMap,
115 String languageId, ResourceBundle resourceBundle,
116 List<ResourceBundle> resourceBundles) {
117
118 synchronized (_resourceBundles) {
119 Set<String> keySet = _resourceBundles.keySet();
120 Iterator<String> iterator = keySet.iterator();
121
122 while (iterator.hasNext()) {
123 String sublanguageId = iterator.next();
124
125 if (!languageId.equals(sublanguageId) &&
126 sublanguageId.startsWith(languageId)) {
127
128 iterator.remove();
129 }
130 }
131 }
132 }
133
134 @Override
135 public void keyRemoved(
136 ServiceTrackerMap<String, List<ResourceBundle>>
137 serviceTrackerMap,
138 String languageId, ResourceBundle resourceBundle,
139 List<ResourceBundle> resourceBundles) {
140
141 synchronized (_resourceBundles) {
142 Set<String> keySet = _resourceBundles.keySet();
143 Iterator<String> iterator = keySet.iterator();
144
145 while (iterator.hasNext()) {
146 String sublanguageId = iterator.next();
147
148 if (sublanguageId.startsWith(languageId)) {
149 iterator.remove();
150 }
151 }
152 }
153 }
154
155 }
156
157 }