001
014
015 package com.liferay.portlet;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.model.Portlet;
020 import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
021 import com.liferay.portal.kernel.portlet.FriendlyURLMapperTracker;
022 import com.liferay.portal.kernel.portlet.Route;
023 import com.liferay.portal.kernel.portlet.Router;
024 import com.liferay.portal.kernel.util.HttpUtil;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.kernel.xml.Document;
029 import com.liferay.portal.kernel.xml.Element;
030 import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
031 import com.liferay.registry.Filter;
032 import com.liferay.registry.Registry;
033 import com.liferay.registry.RegistryUtil;
034 import com.liferay.registry.ServiceReference;
035 import com.liferay.registry.ServiceRegistration;
036 import com.liferay.registry.ServiceTracker;
037 import com.liferay.registry.ServiceTrackerCustomizer;
038
039 import java.util.HashMap;
040 import java.util.List;
041 import java.util.Map;
042 import java.util.concurrent.ConcurrentHashMap;
043
044
047 public class FriendlyURLMapperTrackerImpl implements FriendlyURLMapperTracker {
048
049 public FriendlyURLMapperTrackerImpl(Portlet portlet) {
050 _portlet = portlet;
051
052 Registry registry = RegistryUtil.getRegistry();
053
054 Filter filter = registry.getFilter(
055 "(&(javax.portlet.name=" + portlet.getPortletId() +
056 ")(objectClass=" + FriendlyURLMapper.class.getName() + "))");
057
058 _serviceTracker = registry.trackServices(
059 filter, new FriendlyURLMapperServiceTrackerCustomizer());
060
061 _serviceTracker.open();
062 }
063
064 @Override
065 public void close() {
066 for (Map.Entry<FriendlyURLMapper, ServiceRegistration<?>> entry :
067 _serviceRegistrations.entrySet()) {
068
069 ServiceRegistration<?> serviceRegistration = entry.getValue();
070
071 serviceRegistration.unregister();
072 }
073
074 _serviceTracker.close();
075 }
076
077 @Override
078 public FriendlyURLMapper getFriendlyURLMapper() {
079 return _serviceTracker.getService();
080 }
081
082 @Override
083 public void register(FriendlyURLMapper friendlyURLMapper) {
084 Registry registry = RegistryUtil.getRegistry();
085
086 Map<String, Object> properties = new HashMap<>();
087
088 properties.put("javax.portlet.name", _portlet.getPortletId());
089
090 ServiceRegistration<?> serviceRegistration = registry.registerService(
091 FriendlyURLMapper.class, friendlyURLMapper, properties);
092
093 _serviceRegistrations.put(friendlyURLMapper, serviceRegistration);
094 }
095
096 @Override
097 public void unregister(FriendlyURLMapper friendlyURLMapper) {
098 ServiceRegistration<?> serviceRegistration =
099 _serviceRegistrations.remove(friendlyURLMapper);
100
101 if (serviceRegistration != null) {
102 serviceRegistration.unregister();
103 }
104 }
105
106
109 protected String getContent(ClassLoader classLoader, String fileName)
110 throws Exception {
111
112 String queryString = HttpUtil.getQueryString(fileName);
113
114 if (Validator.isNull(queryString)) {
115 return StringUtil.read(classLoader, fileName);
116 }
117
118 int pos = fileName.indexOf(StringPool.QUESTION);
119
120 String xml = StringUtil.read(classLoader, fileName.substring(0, pos));
121
122 Map<String, String[]> parameterMap = HttpUtil.getParameterMap(
123 queryString);
124
125 if (parameterMap == null) {
126 return xml;
127 }
128
129 for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
130 String name = entry.getKey();
131 String[] values = entry.getValue();
132
133 if (values.length == 0) {
134 continue;
135 }
136
137 String value = values[0];
138
139 xml = StringUtil.replace(xml, "@" + name + "@", value);
140 }
141
142 return xml;
143 }
144
145 private static final Log _log = LogFactoryUtil.getLog(
146 FriendlyURLMapperTrackerImpl.class);
147
148 private final Portlet _portlet;
149 private final Map<FriendlyURLMapper, ServiceRegistration<?>>
150 _serviceRegistrations = new ConcurrentHashMap<>();
151 private final ServiceTracker<FriendlyURLMapper, FriendlyURLMapper>
152 _serviceTracker;
153
154 private class FriendlyURLMapperServiceTrackerCustomizer
155 implements
156 ServiceTrackerCustomizer<FriendlyURLMapper, FriendlyURLMapper> {
157
158 @Override
159 public FriendlyURLMapper addingService(
160 ServiceReference<FriendlyURLMapper> serviceReference) {
161
162 Registry registry = RegistryUtil.getRegistry();
163
164 FriendlyURLMapper friendlyURLMapper = registry.getService(
165 serviceReference);
166
167 try {
168 if (Validator.isNotNull(_portlet.getFriendlyURLMapping())) {
169 friendlyURLMapper.setMapping(
170 _portlet.getFriendlyURLMapping());
171 }
172
173 friendlyURLMapper.setPortletId(_portlet.getPortletId());
174 friendlyURLMapper.setPortletInstanceable(
175 _portlet.isInstanceable());
176
177 String friendlyURLRoutes = (String)serviceReference.getProperty(
178 "com.liferay.portlet.friendly-url-routes");
179
180 if (Validator.isNotNull(_portlet.getFriendlyURLRoutes())) {
181 friendlyURLRoutes = _portlet.getFriendlyURLRoutes();
182 }
183
184 String xml = null;
185
186 if (Validator.isNotNull(friendlyURLRoutes)) {
187 Class<?> clazz = friendlyURLMapper.getClass();
188
189 xml = getContent(clazz.getClassLoader(), friendlyURLRoutes);
190 }
191
192 friendlyURLMapper.setRouter(newFriendlyURLRouter(xml));
193 }
194 catch (Exception e) {
195 _log.error(e, e);
196
197 return null;
198 }
199
200 return friendlyURLMapper;
201 }
202
203 @Override
204 public void modifiedService(
205 ServiceReference<FriendlyURLMapper> serviceReference,
206 FriendlyURLMapper friendlyURLMapper) {
207 }
208
209 @Override
210 public void removedService(
211 ServiceReference<FriendlyURLMapper> serviceReference,
212 FriendlyURLMapper friendlyURLMapper) {
213
214 Registry registry = RegistryUtil.getRegistry();
215
216 registry.ungetService(serviceReference);
217 }
218
219 protected Router newFriendlyURLRouter(String xml) throws Exception {
220 if (Validator.isNull(xml)) {
221 return null;
222 }
223
224 Document document = UnsecureSAXReaderUtil.read(xml, true);
225
226 Element rootElement = document.getRootElement();
227
228 List<Element> routeElements = rootElement.elements("route");
229
230 Router router = new RouterImpl(routeElements.size());
231
232 for (Element routeElement : routeElements) {
233 String pattern = routeElement.elementText("pattern");
234
235 Route route = router.addRoute(pattern);
236
237 for (Element generatedParameterElement :
238 routeElement.elements("generated-parameter")) {
239
240 String name = generatedParameterElement.attributeValue(
241 "name");
242 String value = generatedParameterElement.getText();
243
244 route.addGeneratedParameter(name, value);
245 }
246
247 for (Element ignoredParameterElement :
248 routeElement.elements("ignored-parameter")) {
249
250 String name = ignoredParameterElement.attributeValue(
251 "name");
252
253 route.addIgnoredParameter(name);
254 }
255
256 for (Element implicitParameterElement :
257 routeElement.elements("implicit-parameter")) {
258
259 String name = implicitParameterElement.attributeValue(
260 "name");
261 String value = implicitParameterElement.getText();
262
263 route.addImplicitParameter(name, value);
264 }
265
266 for (Element overriddenParameterElement :
267 routeElement.elements("overridden-parameter")) {
268
269 String name = overriddenParameterElement.attributeValue(
270 "name");
271 String value = overriddenParameterElement.getText();
272
273 route.addOverriddenParameter(name, value);
274 }
275 }
276
277 return router;
278 }
279
280 }
281
282 }