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.portlet.FriendlyURLMapper;
020 import com.liferay.portal.kernel.portlet.FriendlyURLMapperTracker;
021 import com.liferay.portal.kernel.portlet.Route;
022 import com.liferay.portal.kernel.portlet.Router;
023 import com.liferay.portal.kernel.util.StringUtil;
024 import com.liferay.portal.kernel.util.Validator;
025 import com.liferay.portal.kernel.xml.Document;
026 import com.liferay.portal.kernel.xml.Element;
027 import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
028 import com.liferay.portal.model.Portlet;
029 import com.liferay.portal.model.PortletApp;
030 import com.liferay.registry.Filter;
031 import com.liferay.registry.Registry;
032 import com.liferay.registry.RegistryUtil;
033 import com.liferay.registry.ServiceReference;
034 import com.liferay.registry.ServiceRegistration;
035 import com.liferay.registry.ServiceTracker;
036 import com.liferay.registry.ServiceTrackerCustomizer;
037
038 import java.util.HashMap;
039 import java.util.Map;
040 import java.util.concurrent.ConcurrentHashMap;
041
042 import javax.servlet.ServletContext;
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 private static final Log _log = LogFactoryUtil.getLog(
107 FriendlyURLMapperTrackerImpl.class);
108
109 private final Portlet _portlet;
110 private final Map<FriendlyURLMapper, ServiceRegistration<?>>
111 _serviceRegistrations = new ConcurrentHashMap<>();
112 private final ServiceTracker<FriendlyURLMapper, FriendlyURLMapper>
113 _serviceTracker;
114
115 private class FriendlyURLMapperServiceTrackerCustomizer
116 implements
117 ServiceTrackerCustomizer<FriendlyURLMapper, FriendlyURLMapper> {
118
119 @Override
120 public FriendlyURLMapper addingService(
121 ServiceReference<FriendlyURLMapper> serviceReference) {
122
123 Registry registry = RegistryUtil.getRegistry();
124
125 FriendlyURLMapper friendlyURLMapper = registry.getService(
126 serviceReference);
127
128 try {
129 if (Validator.isNotNull(_portlet.getFriendlyURLMapping())) {
130 friendlyURLMapper.setMapping(
131 _portlet.getFriendlyURLMapping());
132 }
133
134 friendlyURLMapper.setPortletId(_portlet.getPortletId());
135 friendlyURLMapper.setPortletInstanceable(
136 _portlet.isInstanceable());
137
138 String friendlyURLRoutes = (String)serviceReference.getProperty(
139 "com.liferay.portlet.friendly-url-routes");
140
141 if (Validator.isNotNull(_portlet.getFriendlyURLRoutes())) {
142 friendlyURLRoutes = _portlet.getFriendlyURLRoutes();
143 }
144
145 friendlyURLMapper.setRouter(
146 newFriendlyURLRouter(friendlyURLRoutes));
147 }
148 catch (Exception e) {
149 _log.error(e, e);
150
151 return null;
152 }
153
154 return friendlyURLMapper;
155 }
156
157 @Override
158 public void modifiedService(
159 ServiceReference<FriendlyURLMapper> serviceReference,
160 FriendlyURLMapper service) {
161 }
162
163 @Override
164 public void removedService(
165 ServiceReference<FriendlyURLMapper> serviceReference,
166 FriendlyURLMapper service) {
167
168 Registry registry = RegistryUtil.getRegistry();
169
170 registry.ungetService(serviceReference);
171 }
172
173 protected Router newFriendlyURLRouter(String friendlyURLRoutes)
174 throws Exception {
175
176 if (Validator.isNull(friendlyURLRoutes)) {
177 return null;
178 }
179
180 Router router = new RouterImpl();
181
182 ClassLoader classLoader = getClassLoader();
183
184 String xml = StringUtil.read(classLoader, friendlyURLRoutes);
185
186 Document document = UnsecureSAXReaderUtil.read(xml, true);
187
188 Element rootElement = document.getRootElement();
189
190 for (Element routeElement : rootElement.elements("route")) {
191 String pattern = routeElement.elementText("pattern");
192
193 Route route = router.addRoute(pattern);
194
195 for (Element generatedParameterElement :
196 routeElement.elements("generated-parameter")) {
197
198 String name = generatedParameterElement.attributeValue(
199 "name");
200 String value = generatedParameterElement.getText();
201
202 route.addGeneratedParameter(name, value);
203 }
204
205 for (Element ignoredParameterElement :
206 routeElement.elements("ignored-parameter")) {
207
208 String name = ignoredParameterElement.attributeValue(
209 "name");
210
211 route.addIgnoredParameter(name);
212 }
213
214 for (Element implicitParameterElement :
215 routeElement.elements("implicit-parameter")) {
216
217 String name = implicitParameterElement.attributeValue(
218 "name");
219 String value = implicitParameterElement.getText();
220
221 route.addImplicitParameter(name, value);
222 }
223
224 for (Element overriddenParameterElement :
225 routeElement.elements("overridden-parameter")) {
226
227 String name = overriddenParameterElement.attributeValue(
228 "name");
229 String value = overriddenParameterElement.getText();
230
231 route.addOverriddenParameter(name, value);
232 }
233 }
234
235 return router;
236 }
237
238 private ClassLoader getClassLoader() {
239 PortletApp portletApp = _portlet.getPortletApp();
240
241 ServletContext servletContext = portletApp.getServletContext();
242
243 return servletContext.getClassLoader();
244 }
245
246 }
247
248 }