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