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