001
014
015 package com.liferay.portal.kernel.portlet.bridges.mvc;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.ClassUtil;
020 import com.liferay.portal.kernel.util.InstanceFactory;
021 import com.liferay.portal.kernel.util.ListUtil;
022 import com.liferay.portal.kernel.util.StringBundler;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.registry.Filter;
027 import com.liferay.registry.Registry;
028 import com.liferay.registry.RegistryUtil;
029 import com.liferay.registry.ServiceReference;
030 import com.liferay.registry.ServiceTracker;
031 import com.liferay.registry.ServiceTrackerCustomizer;
032 import com.liferay.registry.util.StringPlus;
033
034 import java.util.ArrayList;
035 import java.util.List;
036 import java.util.Map;
037 import java.util.concurrent.ConcurrentHashMap;
038
039
042 public class MVCCommandCache {
043
044 public MVCCommandCache(
045 MVCCommand emptyMVCCommand, String packagePrefix, String portletName,
046 String mvcCommandClassName, String mvcCommandPostFix) {
047
048 _emptyMVCCommand = emptyMVCCommand;
049 _mvcComandPostFix = mvcCommandPostFix;
050
051 if (Validator.isNotNull(packagePrefix) &&
052 !packagePrefix.endsWith(StringPool.PERIOD)) {
053
054 packagePrefix = packagePrefix + StringPool.PERIOD;
055 }
056
057 _packagePrefix = packagePrefix;
058
059 Registry registry = RegistryUtil.getRegistry();
060
061 Filter filter = registry.getFilter(
062 "(&(javax.portlet.name=" + portletName +")(mvc.command.name=*)" +
063 "(objectClass=" + mvcCommandClassName + "))");
064
065 _serviceTracker = registry.trackServices(
066 filter, new MVCCommandServiceTrackerCustomizer());
067
068 _serviceTracker.open();
069 }
070
071 public void close() {
072 _serviceTracker.close();
073 }
074
075 public MVCCommand getMVCCommand(String mvcCommandName) {
076 String className = null;
077
078 try {
079 MVCCommand mvcCommand = _mvcCommandCache.get(mvcCommandName);
080
081 if (mvcCommand != null) {
082 return mvcCommand;
083 }
084
085 if (Validator.isNull(_packagePrefix)) {
086 return _emptyMVCCommand;
087 }
088
089 StringBundler sb = new StringBundler(4);
090
091 sb.append(_packagePrefix);
092 sb.append(Character.toUpperCase(mvcCommandName.charAt(0)));
093 sb.append(mvcCommandName.substring(1));
094 sb.append(_mvcComandPostFix);
095
096 className = sb.toString();
097
098 mvcCommand = (MVCCommand)InstanceFactory.newInstance(className);
099
100 _mvcCommandCache.put(mvcCommandName, mvcCommand);
101
102 return mvcCommand;
103 }
104 catch (Exception e) {
105 if (_log.isWarnEnabled()) {
106 _log.warn("Unable to instantiate MVCCommand " + className);
107 }
108
109 _mvcCommandCache.put(mvcCommandName, _emptyMVCCommand);
110
111 return _emptyMVCCommand;
112 }
113 }
114
115 public List<? extends MVCCommand> getMVCCommands(String key) {
116 List<MVCCommand> mvcCommands = _mvcCommands.get(key);
117
118 String[] mvcCommandNames = StringUtil.split(key);
119
120 if ((mvcCommands != null) &&
121 (mvcCommands.size() == mvcCommandNames.length)) {
122
123 return mvcCommands;
124 }
125
126 mvcCommands = new ArrayList<>();
127
128 for (String mvcCommandName : mvcCommandNames) {
129 MVCCommand mvcCommand = getMVCCommand(mvcCommandName);
130
131 if (mvcCommand != _emptyMVCCommand) {
132 mvcCommands.add(mvcCommand);
133 }
134 else {
135 if (_log.isWarnEnabled()) {
136 _log.warn("Unable to find MVCCommand " + key);
137 }
138 }
139 }
140
141 _mvcCommands.put(key, mvcCommands);
142
143 for (MVCCommand mvcCommand : mvcCommands) {
144 String mvcCommandClassName = ClassUtil.getClassName(mvcCommand);
145
146 List<String> keys = _mvcCommandKeys.get(mvcCommandClassName);
147
148 if (keys == null) {
149 keys = new ArrayList<>();
150
151 _mvcCommandKeys.put(mvcCommandClassName, keys);
152 }
153
154 keys.add(key);
155 }
156
157 return mvcCommands;
158 }
159
160 public boolean isEmpty() {
161 return _mvcCommandCache.isEmpty();
162 }
163
164 private static final Log _log = LogFactoryUtil.getLog(
165 MVCCommandCache.class);
166
167 private final MVCCommand _emptyMVCCommand;
168 private final String _mvcComandPostFix;
169 private final Map<String, MVCCommand> _mvcCommandCache =
170 new ConcurrentHashMap<>();
171 private final Map<String, List<String>> _mvcCommandKeys =
172 new ConcurrentHashMap<>();
173 private final Map<String, List<MVCCommand>> _mvcCommands =
174 new ConcurrentHashMap<>();
175 private final String _packagePrefix;
176 private final ServiceTracker<MVCCommand, MVCCommand> _serviceTracker;
177
178 private class MVCCommandServiceTrackerCustomizer
179 implements ServiceTrackerCustomizer<MVCCommand, MVCCommand> {
180
181 @Override
182 public MVCCommand addingService(
183 ServiceReference<MVCCommand> serviceReference) {
184
185 Registry registry = RegistryUtil.getRegistry();
186
187 MVCCommand mvcCommand = registry.getService(serviceReference);
188
189 List<String> mvcCommandNames = StringPlus.asList(
190 serviceReference.getProperty("mvc.command.name"));
191
192 for (String mvcCommandName : mvcCommandNames) {
193 _mvcCommandCache.put(mvcCommandName, mvcCommand);
194 }
195
196 return mvcCommand;
197 }
198
199 @Override
200 public void modifiedService(
201 ServiceReference<MVCCommand> serviceReference,
202 MVCCommand mvcCommand) {
203 }
204
205 @Override
206 public void removedService(
207 ServiceReference<MVCCommand> serviceReference,
208 MVCCommand mvcCommand) {
209
210 Registry registry = RegistryUtil.getRegistry();
211
212 registry.ungetService(serviceReference);
213
214 List<String> mvcCommandNames = StringPlus.asList(
215 serviceReference.getProperty("mvc.command.name"));
216
217 for (String mvcCommandName : mvcCommandNames) {
218 _mvcCommandCache.remove(mvcCommandName);
219
220 for (List<MVCCommand> mvcCommands : _mvcCommands.values()) {
221 mvcCommands.remove(mvcCommand);
222 }
223
224 String mvcCommandClassName = ClassUtil.getClassName(mvcCommand);
225
226 List<String> mvcCommandKeys = _mvcCommandKeys.remove(
227 mvcCommandClassName);
228
229 if (ListUtil.isNotEmpty(mvcCommandKeys)) {
230 for (String mvcCommandKey : mvcCommandKeys) {
231 _mvcCommandCache.remove(mvcCommandKey);
232 }
233 }
234 }
235 }
236
237 }
238
239 }