001
014
015 package com.liferay.portal.deploy.hot;
016
017 import com.liferay.portal.kernel.configuration.Configuration;
018 import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
019 import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
020 import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
021 import com.liferay.portal.kernel.deploy.hot.HotDeployException;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.plugin.PluginPackage;
025 import com.liferay.portal.kernel.plugin.Version;
026 import com.liferay.portal.kernel.servlet.PortletServlet;
027 import com.liferay.portal.kernel.servlet.ServletContextPool;
028 import com.liferay.portal.kernel.util.GetterUtil;
029 import com.liferay.portal.kernel.util.HttpUtil;
030 import com.liferay.portal.kernel.util.StringPool;
031 import com.liferay.portal.kernel.util.Validator;
032 import com.liferay.portal.kernel.xml.DocumentException;
033 import com.liferay.portal.plugin.PluginPackageImpl;
034 import com.liferay.portal.plugin.PluginPackageUtil;
035 import com.liferay.portal.service.ServiceComponentLocalServiceUtil;
036
037 import java.io.IOException;
038 import java.io.InputStream;
039
040 import java.util.Properties;
041 import java.util.jar.Attributes;
042 import java.util.jar.Manifest;
043
044 import javax.servlet.ServletContext;
045
046
049 public class PluginPackageHotDeployListener extends BaseHotDeployListener {
050
051 public static PluginPackage readPluginPackage(ServletContext servletContext)
052 throws DocumentException, IOException {
053
054 PluginPackage pluginPackage = null;
055
056 String servletContextName = servletContext.getServletContextName();
057
058 String xml = HttpUtil.URLtoString(
059 servletContext.getResource("/WEB-INF/liferay-plugin-package.xml"));
060
061 if (_log.isInfoEnabled()) {
062 if (servletContextName == null) {
063 _log.info("Reading plugin package for the root context");
064 }
065 else {
066 _log.info("Reading plugin package for " + servletContextName);
067 }
068 }
069
070 if (xml == null) {
071 if (_log.isDebugEnabled()) {
072 _log.debug("Reading plugin package from MANIFEST.MF");
073 }
074
075 Attributes attributes = null;
076
077 InputStream is = servletContext.getResourceAsStream(
078 "/META-INF/MANIFEST.MF");
079
080 if (is != null) {
081 Manifest manifest = new Manifest(is);
082
083 attributes = manifest.getMainAttributes();
084 }
085 else {
086 attributes = new Attributes();
087 }
088
089 String artifactGroupId = attributes.getValue(
090 "Implementation-Vendor-Id");
091
092 if (Validator.isNull(artifactGroupId)) {
093 artifactGroupId = attributes.getValue("Implementation-Vendor");
094 }
095
096 if (Validator.isNull(artifactGroupId)) {
097 artifactGroupId = GetterUtil.getString(
098 attributes.getValue("Bundle-Vendor"), servletContextName);
099 }
100
101 String artifactId = attributes.getValue("Implementation-Title");
102
103 if (Validator.isNull(artifactId)) {
104 artifactId = GetterUtil.getString(
105 attributes.getValue("Bundle-Name"), servletContextName);
106 }
107
108 String version = attributes.getValue("Implementation-Version");
109
110 if (Validator.isNull(version)) {
111 version = GetterUtil.getString(
112 attributes.getValue("Bundle-Version"), Version.UNKNOWN);
113 }
114
115 if (version.equals(Version.UNKNOWN) && _log.isWarnEnabled()) {
116 _log.warn(
117 "Plugin package on context " + servletContextName +
118 " cannot be tracked because this WAR does not " +
119 "contain a liferay-plugin-package.xml file");
120 }
121
122 pluginPackage =
123 new PluginPackageImpl(
124 artifactGroupId + StringPool.SLASH + artifactId +
125 StringPool.SLASH + version + StringPool.SLASH +
126 "war");
127
128 pluginPackage.setName(artifactId);
129
130 String shortDescription = attributes.getValue("Bundle-Description");
131
132 if (Validator.isNotNull(shortDescription)) {
133 pluginPackage.setShortDescription(shortDescription);
134 }
135
136 String pageURL = attributes.getValue("Bundle-DocURL");
137
138 if (Validator.isNotNull(pageURL)) {
139 pluginPackage.setPageURL(pageURL);
140 }
141 }
142 else {
143 if (_log.isDebugEnabled()) {
144 _log.debug(
145 "Reading plugin package from liferay-plugin-package.xml");
146 }
147
148 pluginPackage = PluginPackageUtil.readPluginPackageXml(xml);
149 }
150
151 pluginPackage.setContext(servletContextName);
152
153 return pluginPackage;
154 }
155
156 public void invokeDeploy(HotDeployEvent event) throws HotDeployException {
157 try {
158 doInvokeDeploy(event);
159 }
160 catch (Throwable t) {
161 throwHotDeployException(event, "Error registering plugins for ", t);
162 }
163 }
164
165 public void invokeUndeploy(HotDeployEvent event) throws HotDeployException {
166 try {
167 doInvokeUndeploy(event);
168 }
169 catch (Throwable t) {
170 throwHotDeployException(
171 event, "Error unregistering plugins for ", t);
172 }
173 }
174
175 protected void destroyServiceComponent(
176 ServletContext servletContext, ClassLoader classLoader)
177 throws Exception {
178
179 ServiceComponentLocalServiceUtil.destroyServiceComponent(
180 servletContext, classLoader);
181 }
182
183 protected void doInvokeDeploy(HotDeployEvent event) throws Exception {
184 ServletContext servletContext = event.getServletContext();
185
186 String servletContextName = servletContext.getServletContextName();
187
188 if (_log.isDebugEnabled()) {
189 _log.debug("Invoking deploy for " + servletContextName);
190 }
191
192 if (servletContext.getResource(
193 "/WEB-INF/liferay-theme-loader.xml") != null) {
194
195 return;
196 }
197
198 PluginPackage pluginPackage = readPluginPackage(servletContext);
199
200 if (pluginPackage == null) {
201 return;
202 }
203
204 pluginPackage.setContext(servletContextName);
205
206 event.setPluginPackage(pluginPackage);
207
208 PluginPackageUtil.registerInstalledPluginPackage(pluginPackage);
209
210 ClassLoader portletClassLoader = event.getContextClassLoader();
211
212 servletContext.setAttribute(
213 PortletServlet.PORTLET_CLASS_LOADER, portletClassLoader);
214
215 ServletContextPool.put(servletContextName, servletContext);
216
217 initServiceComponent(servletContext, portletClassLoader);
218
219 registerClpMessageListeners(servletContext, portletClassLoader);
220
221 if (_log.isInfoEnabled()) {
222 _log.info(
223 "Plugin package " + pluginPackage.getModuleId() +
224 " registered successfully. It's now ready to be used.");
225 }
226 }
227
228 protected void doInvokeUndeploy(HotDeployEvent event) throws Exception {
229 ServletContext servletContext = event.getServletContext();
230
231 String servletContextName = servletContext.getServletContextName();
232
233 if (_log.isDebugEnabled()) {
234 _log.debug("Invoking deploy for " + servletContextName);
235 }
236
237 PluginPackage pluginPackage = readPluginPackage(servletContext);
238
239 if (pluginPackage == null) {
240 return;
241 }
242
243 event.setPluginPackage(pluginPackage);
244
245 PluginPackageUtil.unregisterInstalledPluginPackage(pluginPackage);
246
247 ServletContextPool.remove(servletContextName);
248
249 destroyServiceComponent(servletContext, event.getContextClassLoader());
250
251 unregisterClpMessageListeners(servletContext);
252
253 if (_log.isInfoEnabled()) {
254 _log.info(
255 "Plugin package " + pluginPackage.getModuleId() +
256 " unregistered successfully");
257 }
258 }
259
260 protected void initServiceComponent(
261 ServletContext servletContext, ClassLoader classLoader)
262 throws Exception {
263
264 Configuration serviceBuilderPropertiesConfiguration = null;
265
266 try {
267 serviceBuilderPropertiesConfiguration =
268 ConfigurationFactoryUtil.getConfiguration(
269 classLoader, "service");
270 }
271 catch (Exception e) {
272 if (_log.isDebugEnabled()) {
273 _log.debug("Unable to read service.properties");
274 }
275
276 return;
277 }
278
279 Properties serviceBuilderProperties =
280 serviceBuilderPropertiesConfiguration.getProperties();
281
282 if (serviceBuilderProperties.size() == 0) {
283 return;
284 }
285
286 String buildNamespace = GetterUtil.getString(
287 serviceBuilderProperties.getProperty("build.namespace"));
288 long buildNumber = GetterUtil.getLong(
289 serviceBuilderProperties.getProperty("build.number"));
290 long buildDate = GetterUtil.getLong(
291 serviceBuilderProperties.getProperty("build.date"));
292 boolean buildAutoUpgrade = GetterUtil.getBoolean(
293 serviceBuilderProperties.getProperty("build.auto.upgrade"), true);
294
295 if (_log.isDebugEnabled()) {
296 _log.debug("Build namespace " + buildNamespace);
297 _log.debug("Build number " + buildNumber);
298 _log.debug("Build date " + buildDate);
299 _log.debug("Build auto upgrade " + buildAutoUpgrade);
300 }
301
302 if (Validator.isNull(buildNamespace)) {
303 return;
304 }
305
306 ServiceComponentLocalServiceUtil.initServiceComponent(
307 servletContext, classLoader, buildNamespace, buildNumber,
308 buildDate, buildAutoUpgrade);
309 }
310
311 private static Log _log = LogFactoryUtil.getLog(
312 PluginPackageHotDeployListener.class);
313
314 }