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