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