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