001
014
015 package com.liferay.portal.deploy.hot;
016
017 import aQute.bnd.annotation.ProviderType;
018
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.servlet.WebDirDetector;
025 import com.liferay.portal.kernel.util.FileUtil;
026 import com.liferay.portal.kernel.util.HttpUtil;
027 import com.liferay.portal.kernel.util.PortalUtil;
028 import com.liferay.portal.kernel.util.StreamUtil;
029 import com.liferay.portal.kernel.util.StringBundler;
030 import com.liferay.portal.kernel.util.StringPool;
031 import com.liferay.portal.kernel.util.SystemProperties;
032 import com.liferay.portal.tools.WebXMLBuilder;
033 import com.liferay.portal.util.ExtRegistry;
034 import com.liferay.taglib.FileAvailabilityUtil;
035 import com.liferay.util.ant.CopyTask;
036
037 import java.io.File;
038 import java.io.FileOutputStream;
039 import java.io.IOException;
040 import java.io.InputStream;
041
042 import java.nio.file.Files;
043 import java.nio.file.Path;
044 import java.nio.file.Paths;
045
046 import java.util.Map;
047 import java.util.Set;
048
049 import javax.servlet.ServletContext;
050
051
054 @ProviderType
055 public class ExtHotDeployListener extends BaseHotDeployListener {
056
057 @Override
058 public void invokeDeploy(HotDeployEvent hotDeployEvent)
059 throws HotDeployException {
060
061 try {
062 doInvokeDeploy(hotDeployEvent);
063 }
064 catch (Throwable t) {
065 throwHotDeployException(
066 hotDeployEvent, "Error registering extension environment for ",
067 t);
068 }
069 }
070
071 @Override
072 public void invokeUndeploy(HotDeployEvent hotDeployEvent)
073 throws HotDeployException {
074
075 try {
076 doInvokeUndeploy(hotDeployEvent);
077 }
078 catch (Throwable t) {
079 throwHotDeployException(
080 hotDeployEvent,
081 "Error unregistering extension environment for ", t);
082 }
083 }
084
085 protected void copyJar(
086 ServletContext servletContext, String dir, String jarName)
087 throws Exception {
088
089 String servletContextName = servletContext.getServletContextName();
090
091 String jarFullName = "/WEB-INF/" + jarName + "/" + jarName + ".jar";
092
093 InputStream is = servletContext.getResourceAsStream(jarFullName);
094
095 if (is == null) {
096 throw new HotDeployException(jarFullName + " does not exist");
097 }
098
099 String newJarFullName =
100 dir + "ext-" + servletContextName + jarName.substring(3) + ".jar";
101
102 StreamUtil.transfer(is, new FileOutputStream(new File(newJarFullName)));
103 }
104
105 protected void doInvokeDeploy(HotDeployEvent hotDeployEvent)
106 throws Exception {
107
108 ServletContext servletContext = hotDeployEvent.getServletContext();
109
110 String servletContextName = servletContext.getServletContextName();
111
112 if (_log.isDebugEnabled()) {
113 _log.debug("Invoking deploy for " + servletContextName);
114 }
115
116 String xml = HttpUtil.URLtoString(
117 servletContext.getResource(
118 "/WEB-INF/ext-" + servletContextName + ".xml"));
119
120 if (xml == null) {
121 return;
122 }
123
124 if (_log.isInfoEnabled()) {
125 _log.info(
126 "Registering extension environment for " + servletContextName);
127 }
128
129 if (ExtRegistry.isRegistered(servletContextName)) {
130 if (_log.isInfoEnabled()) {
131 _log.info(
132 "Extension environment for " + servletContextName +
133 " has been applied.");
134 }
135
136 return;
137 }
138
139 Map<String, Set<String>> conflicts = ExtRegistry.getConflicts(
140 servletContext);
141
142 if (!conflicts.isEmpty()) {
143 StringBundler sb = new StringBundler();
144
145 sb.append("Extension environment for ");
146 sb.append(servletContextName);
147 sb.append(" cannot be applied because of detected conflicts:");
148
149 for (Map.Entry<String, Set<String>> entry : conflicts.entrySet()) {
150 String conflictServletContextName = entry.getKey();
151 Set<String> conflictFiles = entry.getValue();
152
153 sb.append("\n\t");
154 sb.append(conflictServletContextName);
155 sb.append(":");
156
157 for (String conflictFile : conflictFiles) {
158 sb.append("\n\t\t");
159 sb.append(conflictFile);
160 }
161 }
162
163 _log.error(sb.toString());
164
165 return;
166 }
167
168 installExt(servletContext, hotDeployEvent.getContextClassLoader());
169
170 FileAvailabilityUtil.clearAvailabilities();
171
172 if (_log.isInfoEnabled()) {
173 _log.info(
174 "Extension environment for " + servletContextName +
175 " has been applied. You must reboot the server and " +
176 "redeploy all other plugins.");
177 }
178 }
179
180 protected void doInvokeUndeploy(HotDeployEvent hotDeployEvent)
181 throws Exception {
182
183 ServletContext servletContext = hotDeployEvent.getServletContext();
184
185 String servletContextName = servletContext.getServletContextName();
186
187 if (_log.isDebugEnabled()) {
188 _log.debug("Invoking undeploy for " + servletContextName);
189 }
190
191 String xml = HttpUtil.URLtoString(
192 servletContext.getResource(
193 "/WEB-INF/ext-" + servletContextName + ".xml"));
194
195 if (xml == null) {
196 return;
197 }
198
199 if (_log.isInfoEnabled()) {
200 _log.info(
201 "Extension environment for " + servletContextName +
202 " will not be undeployed");
203 }
204 }
205
206 @Deprecated
207 protected void installExt(ServletContext servletContext) throws Exception {
208 installExt(servletContext, servletContext.getClassLoader());
209 }
210
211 protected void installExt(
212 ServletContext servletContext, ClassLoader portletClassLoader)
213 throws Exception {
214
215 String servletContextName = servletContext.getServletContextName();
216
217 String globalLibDir = PortalUtil.getGlobalLibDir();
218 String portalWebDir = PortalUtil.getPortalWebDir();
219 String portalLibDir = PortalUtil.getPortalLibDir();
220 String pluginWebDir = WebDirDetector.getRootDir(portletClassLoader);
221
222 copyJar(servletContext, globalLibDir, "ext-service");
223 copyJar(servletContext, portalLibDir, "ext-impl");
224 copyJar(servletContext, portalLibDir, "ext-util-bridges");
225 copyJar(servletContext, portalLibDir, "ext-util-java");
226 copyJar(servletContext, portalLibDir, "ext-util-taglib");
227
228 mergeWebXml(portalWebDir, pluginWebDir);
229
230 CopyTask.copyDirectory(
231 pluginWebDir + "WEB-INF/ext-web/docroot", portalWebDir,
232 StringPool.BLANK, "**/WEB-INF/web.xml", true, false);
233
234 FileUtil.copyFile(
235 pluginWebDir + "WEB-INF/ext-" + servletContextName + ".xml",
236 portalWebDir + "WEB-INF/ext-" + servletContextName + ".xml");
237
238 ExtRegistry.registerExt(servletContext);
239 }
240
241 protected void mergeWebXml(String portalWebDir, String pluginWebDir)
242 throws IOException {
243
244 if (!FileUtil.exists(
245 pluginWebDir + "WEB-INF/ext-web/docroot/WEB-INF/web.xml")) {
246
247 return;
248 }
249
250 Path tempDirPath = Files.createTempDirectory(
251 Paths.get(SystemProperties.get(SystemProperties.TMP_DIR)), null);
252
253 File tempDir = tempDirPath.toFile();
254
255 WebXMLBuilder.main(
256 new String[] {
257 portalWebDir + "WEB-INF/web.xml",
258 pluginWebDir + "WEB-INF/ext-web/docroot/WEB-INF/web.xml",
259 tempDir.getAbsolutePath() + "/web.xml"
260 });
261
262 File portalWebXml = new File(portalWebDir + "WEB-INF/web.xml");
263 File tmpWebXml = new File(tempDir + "/web.xml");
264
265 tmpWebXml.setLastModified(portalWebXml.lastModified());
266
267 CopyTask.copyFile(
268 tmpWebXml, new File(portalWebDir + "WEB-INF"), true, true);
269
270 FileUtil.deltree(tempDir);
271 }
272
273 private static final Log _log = LogFactoryUtil.getLog(
274 ExtHotDeployListener.class);
275
276 }