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