1
14
15 package com.liferay.portal.deploy.hot;
16
17 import com.liferay.portal.kernel.configuration.Configuration;
18 import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
19 import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
20 import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
21 import com.liferay.portal.kernel.deploy.hot.HotDeployException;
22 import com.liferay.portal.kernel.log.Log;
23 import com.liferay.portal.kernel.log.LogFactoryUtil;
24 import com.liferay.portal.kernel.plugin.PluginPackage;
25 import com.liferay.portal.kernel.plugin.Version;
26 import com.liferay.portal.kernel.servlet.PortletServlet;
27 import com.liferay.portal.kernel.servlet.ServletContextPool;
28 import com.liferay.portal.kernel.util.GetterUtil;
29 import com.liferay.portal.kernel.util.HttpUtil;
30 import com.liferay.portal.kernel.util.StringPool;
31 import com.liferay.portal.kernel.util.Validator;
32 import com.liferay.portal.kernel.xml.DocumentException;
33 import com.liferay.portal.plugin.PluginPackageImpl;
34 import com.liferay.portal.plugin.PluginPackageUtil;
35 import com.liferay.portal.service.ServiceComponentLocalServiceUtil;
36
37 import java.io.IOException;
38 import java.io.InputStream;
39
40 import java.util.Properties;
41 import java.util.jar.Attributes;
42 import java.util.jar.Manifest;
43
44 import javax.servlet.ServletContext;
45
46
52 public class PluginPackageHotDeployListener extends BaseHotDeployListener {
53
54 public static PluginPackage readPluginPackage(ServletContext servletContext)
55 throws DocumentException, IOException {
56
57 PluginPackage pluginPackage = null;
58
59 String servletContextName = servletContext.getServletContextName();
60
61 String xml = HttpUtil.URLtoString(
62 servletContext.getResource("/WEB-INF/liferay-plugin-package.xml"));
63
64 if (_log.isInfoEnabled()) {
65 if (servletContextName == null) {
66 _log.info("Reading plugin package for the root context");
67 }
68 else {
69 _log.info("Reading plugin package for " + servletContextName);
70 }
71 }
72
73 if (xml == null) {
74 if (_log.isDebugEnabled()) {
75 _log.debug("Reading plugin package from MANIFEST.MF");
76 }
77
78 Attributes attributes = null;
79
80 InputStream is = servletContext.getResourceAsStream(
81 "/META-INF/MANIFEST.MF");
82
83 if (is != null) {
84 Manifest manifest = new Manifest(is);
85
86 attributes = manifest.getMainAttributes();
87 }
88 else {
89 attributes = new Attributes();
90 }
91
92 String artifactGroupId = attributes.getValue(
93 "Implementation-Vendor-Id");
94
95 if (Validator.isNull(artifactGroupId)) {
96 artifactGroupId = attributes.getValue("Implementation-Vendor");
97 }
98
99 if (Validator.isNull(artifactGroupId)) {
100 artifactGroupId = GetterUtil.getString(
101 attributes.getValue("Bundle-Vendor"), servletContextName);
102 }
103
104 String artifactId = attributes.getValue("Implementation-Title");
105
106 if (Validator.isNull(artifactId)) {
107 artifactId = GetterUtil.getString(
108 attributes.getValue("Bundle-Name"), servletContextName);
109 }
110
111 String version = attributes.getValue("Implementation-Version");
112
113 if (Validator.isNull(version)) {
114 version = GetterUtil.getString(
115 attributes.getValue("Bundle-Version"), Version.UNKNOWN);
116 }
117
118 if (version.equals(Version.UNKNOWN) && _log.isWarnEnabled()) {
119 _log.warn(
120 "Plugin package on context " + servletContextName +
121 " cannot be tracked because this WAR does not " +
122 "contain a liferay-plugin-package.xml file");
123 }
124
125 pluginPackage =
126 new PluginPackageImpl(
127 artifactGroupId + StringPool.SLASH + artifactId +
128 StringPool.SLASH + version + StringPool.SLASH +
129 "war");
130
131 pluginPackage.setName(artifactId);
132
133 String shortDescription = attributes.getValue("Bundle-Description");
134
135 if (Validator.isNotNull(shortDescription)) {
136 pluginPackage.setShortDescription(shortDescription);
137 }
138
139 String pageURL = attributes.getValue("Bundle-DocURL");
140
141 if (Validator.isNotNull(pageURL)) {
142 pluginPackage.setPageURL(pageURL);
143 }
144 }
145 else {
146 if (_log.isDebugEnabled()) {
147 _log.debug(
148 "Reading plugin package from liferay-plugin-package.xml");
149 }
150
151 pluginPackage = PluginPackageUtil.readPluginPackageXml(xml);
152 }
153
154 pluginPackage.setContext(servletContextName);
155
156 return pluginPackage;
157 }
158
159 public void invokeDeploy(HotDeployEvent event) throws HotDeployException {
160 try {
161 doInvokeDeploy(event);
162 }
163 catch (Throwable t) {
164 throwHotDeployException(event, "Error registering plugins for ", t);
165 }
166 }
167
168 public void invokeUndeploy(HotDeployEvent event) throws HotDeployException {
169 try {
170 doInvokeUndeploy(event);
171 }
172 catch (Throwable t) {
173 throwHotDeployException(
174 event, "Error unregistering plugins for ", t);
175 }
176 }
177
178 protected void destroyServiceComponent(
179 ServletContext servletContext, ClassLoader classLoader)
180 throws Exception {
181
182 ServiceComponentLocalServiceUtil.destroyServiceComponent(
183 servletContext, classLoader);
184 }
185
186 protected void doInvokeDeploy(HotDeployEvent event) throws Exception {
187 ServletContext servletContext = event.getServletContext();
188
189 String servletContextName = servletContext.getServletContextName();
190
191 if (_log.isDebugEnabled()) {
192 _log.debug("Invoking deploy for " + servletContextName);
193 }
194
195 if (servletContext.getResource(
196 "/WEB-INF/liferay-theme-loader.xml") != null) {
197
198 return;
199 }
200
201 PluginPackage pluginPackage = readPluginPackage(servletContext);
202
203 if (pluginPackage == null) {
204 return;
205 }
206
207 pluginPackage.setContext(servletContextName);
208
209 event.setPluginPackage(pluginPackage);
210
211 PluginPackageUtil.registerInstalledPluginPackage(pluginPackage);
212
213 ClassLoader portletClassLoader = event.getContextClassLoader();
214
215 servletContext.setAttribute(
216 PortletServlet.PORTLET_CLASS_LOADER, portletClassLoader);
217
218 ServletContextPool.put(servletContextName, servletContext);
219
220 initServiceComponent(servletContext, portletClassLoader);
221
222 registerClpMessageListeners(servletContext, portletClassLoader);
223
224 if (_log.isInfoEnabled()) {
225 _log.info(
226 "Plugin package " + pluginPackage.getModuleId() +
227 " registered successfully. It's now ready to be used.");
228 }
229 }
230
231 protected void doInvokeUndeploy(HotDeployEvent event) throws Exception {
232 ServletContext servletContext = event.getServletContext();
233
234 String servletContextName = servletContext.getServletContextName();
235
236 if (_log.isDebugEnabled()) {
237 _log.debug("Invoking deploy for " + servletContextName);
238 }
239
240 PluginPackage pluginPackage = readPluginPackage(servletContext);
241
242 if (pluginPackage == null) {
243 return;
244 }
245
246 event.setPluginPackage(pluginPackage);
247
248 PluginPackageUtil.unregisterInstalledPluginPackage(pluginPackage);
249
250 ServletContextPool.remove(servletContextName);
251
252 destroyServiceComponent(servletContext, event.getContextClassLoader());
253
254 unregisterClpMessageListeners(servletContext);
255
256 if (_log.isInfoEnabled()) {
257 _log.info(
258 "Plugin package " + pluginPackage.getModuleId() +
259 " unregistered successfully");
260 }
261 }
262
263 protected void initServiceComponent(
264 ServletContext servletContext, ClassLoader classLoader)
265 throws Exception {
266
267 Configuration serviceBuilderPropertiesConfiguration = null;
268
269 try {
270 serviceBuilderPropertiesConfiguration =
271 ConfigurationFactoryUtil.getConfiguration(
272 classLoader, "service");
273 }
274 catch (Exception e) {
275 if (_log.isDebugEnabled()) {
276 _log.debug("Unable to read service.properties");
277 }
278
279 return;
280 }
281
282 Properties serviceBuilderProperties =
283 serviceBuilderPropertiesConfiguration.getProperties();
284
285 if (serviceBuilderProperties.size() == 0) {
286 return;
287 }
288
289 String buildNamespace = GetterUtil.getString(
290 serviceBuilderProperties.getProperty("build.namespace"));
291 long buildNumber = GetterUtil.getLong(
292 serviceBuilderProperties.getProperty("build.number"));
293 long buildDate = GetterUtil.getLong(
294 serviceBuilderProperties.getProperty("build.date"));
295 boolean buildAutoUpgrade = GetterUtil.getBoolean(
296 serviceBuilderProperties.getProperty("build.auto.upgrade"), true);
297
298 if (_log.isDebugEnabled()) {
299 _log.debug("Build namespace " + buildNamespace);
300 _log.debug("Build number " + buildNumber);
301 _log.debug("Build date " + buildDate);
302 _log.debug("Build auto upgrade " + buildAutoUpgrade);
303 }
304
305 if (Validator.isNull(buildNamespace)) {
306 return;
307 }
308
309 ServiceComponentLocalServiceUtil.initServiceComponent(
310 servletContext, classLoader, buildNamespace, buildNumber,
311 buildDate, buildAutoUpgrade);
312 }
313
314 private static Log _log = LogFactoryUtil.getLog(
315 PluginPackageHotDeployListener.class);
316
317 }