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