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