001: /* Copyright 2004 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.container.deploy;
007:
008: import java.io.File;
009: import java.io.FileInputStream;
010: import java.io.FileOutputStream;
011: import java.io.IOException;
012: import java.io.InputStream;
013: import java.io.OutputStream;
014: import java.io.OutputStreamWriter;
015: import java.io.Writer;
016: import java.util.Enumeration;
017: import java.util.Iterator;
018: import java.util.Locale;
019: import java.util.jar.JarEntry;
020: import java.util.jar.JarFile;
021:
022: import org.apache.pluto.om.ControllerFactory;
023: import org.apache.pluto.om.common.DescriptionSet;
024: import org.apache.pluto.om.common.DisplayNameSet;
025: import org.apache.pluto.om.common.Parameter;
026: import org.apache.pluto.om.common.ParameterCtrl;
027: import org.apache.pluto.om.common.ParameterSet;
028: import org.apache.pluto.om.common.ParameterSetCtrl;
029: import org.apache.pluto.om.common.SecurityRoleRef;
030: import org.apache.pluto.om.common.SecurityRoleRefSet;
031: import org.apache.pluto.om.common.SecurityRoleRefSetCtrl;
032: import org.apache.pluto.om.common.SecurityRoleSet;
033: import org.apache.pluto.om.portlet.PortletApplicationDefinition;
034: import org.apache.pluto.om.portlet.PortletDefinition;
035: import org.apache.pluto.om.servlet.ServletDefinition;
036: import org.apache.pluto.om.servlet.ServletDefinitionCtrl;
037: import org.apache.pluto.om.servlet.ServletDefinitionListCtrl;
038: import org.jasig.portal.container.binding.PortletApplicationUnmarshaller;
039: import org.jasig.portal.container.binding.WebApplicationMarshaller;
040: import org.jasig.portal.container.binding.WebApplicationUnmarshaller;
041: import org.jasig.portal.container.factory.ControllerFactoryImpl;
042: import org.jasig.portal.container.om.common.DescriptionImpl;
043: import org.jasig.portal.container.om.common.DescriptionSetImpl;
044: import org.jasig.portal.container.om.common.DisplayNameImpl;
045: import org.jasig.portal.container.om.common.DisplayNameSetImpl;
046: import org.jasig.portal.container.om.servlet.ServletDefinitionImpl;
047: import org.jasig.portal.container.om.servlet.ServletMappingImpl;
048: import org.jasig.portal.container.om.servlet.ServletMappingListImpl;
049: import org.jasig.portal.container.om.servlet.TagLibImpl;
050: import org.jasig.portal.container.om.servlet.WebApplicationDefinitionImpl;
051: import org.jasig.portal.serialize.OutputFormat;
052: import org.jasig.portal.serialize.Serializer;
053: import org.jasig.portal.serialize.XMLSerializer;
054:
055: /**
056: * A tool that deploys a portlet application into the servlet container.
057: * In the process, this tool adds the necessary portlet-wrapping servlets
058: * into the portlet application deployment descriptor (web.xml file).
059: * This code was borrowed from Pluto's Deploy tool and then modified to
060: * fit the uPortal environment. Pluto used Castor to marshall and unmarshall
061: * XML files. We are doing this work ourselves. This tool is intended to be
062: * launched from a command line tool such as Apache Ant and the buid.xml for
063: * uPortal includes a corresponding ant target called.
064: * @author Ken Weiner, kweiner@unicon.net
065: * @version $Revision: 36785 $
066: */
067: public class Deployer {
068:
069: public static final String WEB_PORTLET_PUBLIC_ID = "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN";
070: public static final String WEB_PORTLET_DTD = "http://java.sun.com/dtd/web-app_2_3.dtd";
071: public static final String WEB_PORTLET_TAGLIB_URI = "http://java.sun.com/portlet";
072: public static final String WEB_PORTLET_TAGLIB_LOCATION = "/WEB-INF/tld/portlet.tld";
073:
074: private static boolean debug = false;
075: private static String dirDelim = File.separator;
076: private static String webInfDir = dirDelim + "WEB-INF" + dirDelim;
077: private static String webAppsDir;
078: private static final String portletAppDir = "lib" + dirDelim
079: + "portlets";
080:
081: public static void deployArchive(String webAppsDir, String warFile)
082: throws IOException {
083: String warFileName = warFile;
084: if (warFileName.indexOf("/") != -1)
085: warFileName = warFileName.substring(warFileName
086: .lastIndexOf("/") + 1);
087: if (warFileName.indexOf(dirDelim) != -1)
088: warFileName = warFileName.substring(warFileName
089: .lastIndexOf(dirDelim) + 1);
090: if (warFileName.endsWith(".war"))
091: warFileName = warFileName.substring(0, warFileName
092: .lastIndexOf("."));
093:
094: System.out.print("Deploying '" + warFileName + "' ... ");
095:
096: String destination = webAppsDir + warFileName;
097:
098: JarFile jarFile = new JarFile(warFile);
099: Enumeration files = jarFile.entries();
100: while (files.hasMoreElements()) {
101: JarEntry entry = (JarEntry) files.nextElement();
102:
103: File file = new File(destination, entry.getName());
104: File dirF = new File(file.getParent());
105: dirF.mkdirs();
106: if (entry.isDirectory()) {
107: file.mkdirs();
108: } else {
109: byte[] buffer = new byte[1024];
110: int length = 0;
111: InputStream fis = jarFile.getInputStream(entry);
112: FileOutputStream fos = new FileOutputStream(file);
113: while ((length = fis.read(buffer)) >= 0) {
114: fos.write(buffer, 0, length);
115: }
116: fos.close();
117: fis.close();
118: }
119:
120: }
121:
122: System.out.println("Finished!");
123: }
124:
125: public static void prepareWebArchive(String webAppsDir,
126: String warFile) throws Exception, IOException {
127: String webModule = warFile;
128: if (webModule.indexOf("/") != -1)
129: webModule = webModule
130: .substring(webModule.lastIndexOf("/") + 1);
131: if (webModule.indexOf(dirDelim) != -1)
132: webModule = webModule.substring(webModule
133: .lastIndexOf(dirDelim) + 1);
134: if (webModule.endsWith(".war"))
135: webModule = webModule.substring(0, webModule
136: .lastIndexOf("."));
137:
138: System.out.print("Preparing web archive '" + webModule
139: + "' ... ");
140:
141: File portletXml = new File(webAppsDir + webModule + webInfDir
142: + "portlet.xml");
143: File webXml = new File(webAppsDir + webModule + webInfDir
144: + "web.xml");
145:
146: try {
147: // Generate the web application definition out of web.xml
148: // If one doesn't exist, create it
149: WebApplicationDefinitionImpl webApplicationDefinition = null;
150: if (webXml.exists()) {
151: WebApplicationUnmarshaller wau = new WebApplicationUnmarshaller();
152: wau.init(new FileInputStream(webXml), webModule);
153: webApplicationDefinition = (WebApplicationDefinitionImpl) wau
154: .getWebApplicationDefinition();
155: } else {
156: webApplicationDefinition = new WebApplicationDefinitionImpl();
157: DisplayNameImpl dispName = new DisplayNameImpl();
158: dispName.setDisplayName(webModule);
159: dispName.setLocale(Locale.getDefault());
160: DisplayNameSetImpl dispSet = new DisplayNameSetImpl();
161: dispSet.add(dispName);
162: webApplicationDefinition
163: .setDisplayNames((DisplayNameSet) dispSet);
164: DescriptionImpl desc = new DescriptionImpl();
165: desc
166: .setDescription("Automated generated Application Wrapper");
167: desc.setLocale(Locale.getDefault());
168: DescriptionSetImpl descSet = new DescriptionSetImpl();
169: descSet.add(desc);
170: webApplicationDefinition
171: .setDescriptions((DescriptionSet) descSet);
172: }
173:
174: // Now get the portlet application definition out of portlet.xml
175: PortletApplicationUnmarshaller pau = new PortletApplicationUnmarshaller();
176: pau.init(new FileInputStream(portletXml), webModule);
177: PortletApplicationDefinition portletApplicationDefinition = pau
178: .getPortletApplicationDefinition(webApplicationDefinition);
179:
180: ControllerFactory controllerFactory = new ControllerFactoryImpl();
181:
182: ServletDefinitionListCtrl servletDefinitionSetCtrl = (ServletDefinitionListCtrl) controllerFactory
183: .get(webApplicationDefinition
184: .getServletDefinitionList());
185: ServletMappingListImpl servletMappings = webApplicationDefinition
186: .getServletMappings();
187:
188: Iterator portlets = portletApplicationDefinition
189: .getPortletDefinitionList().iterator();
190: while (portlets.hasNext()) {
191:
192: PortletDefinition portlet = (PortletDefinition) portlets
193: .next();
194:
195: // Check if already exists
196: ServletDefinition servlet = webApplicationDefinition
197: .getServletDefinitionList().get(
198: portlet.getName());
199: if (servlet != null) {
200: if (!servlet
201: .getServletClass()
202: .equals(
203: "org.jasig.portal.container.PortletServlet")) {
204: System.out
205: .println("Note: Replaced already existing the servlet with the name '"
206: + portlet.getName()
207: + "' with the wrapper servlet.");
208: }
209: ServletDefinitionCtrl _servletCtrl = (ServletDefinitionCtrl) controllerFactory
210: .get(servlet);
211: _servletCtrl
212: .setServletClass("org.jasig.portal.container.PortletServlet");
213: } else {
214: servlet = servletDefinitionSetCtrl
215: .add(portlet.getName(),
216: "org.jasig.portal.container.PortletServlet");
217: }
218:
219: ServletDefinitionCtrl servletCtrl = (ServletDefinitionCtrl) controllerFactory
220: .get(servlet);
221:
222: DisplayNameImpl dispName = new DisplayNameImpl();
223: dispName.setDisplayName(portlet.getName() + " Wrapper");
224: dispName.setLocale(Locale.getDefault());
225: DisplayNameSetImpl dispSet = new DisplayNameSetImpl();
226: dispSet.add(dispName);
227: servletCtrl.setDisplayNames((DisplayNameSet) dispSet);
228: DescriptionImpl desc = new DescriptionImpl();
229: desc
230: .setDescription("Automated generated Portlet Wrapper");
231: desc.setLocale(Locale.getDefault());
232: DescriptionSetImpl descSet = new DescriptionSetImpl();
233: descSet.add(desc);
234: servletCtrl.setDescriptions(descSet);
235: ParameterSet parameters = servlet.getInitParameterSet();
236:
237: ParameterSetCtrl parameterSetCtrl = (ParameterSetCtrl) controllerFactory
238: .get(parameters);
239:
240: Parameter parameter1 = parameters.get("portlet-class");
241: if (parameter1 == null) {
242: parameterSetCtrl.add("portlet-class", portlet
243: .getClassName());
244: } else {
245: ParameterCtrl parameterCtrl = (ParameterCtrl) controllerFactory
246: .get(parameter1);
247: parameterCtrl.setValue(portlet.getClassName());
248:
249: }
250: Parameter parameter2 = parameters.get("portlet-guid");
251: if (parameter2 == null) {
252: parameterSetCtrl.add("portlet-guid", portlet
253: .getId().toString());
254: } else {
255: ParameterCtrl parameterCtrl = (ParameterCtrl) controllerFactory
256: .get(parameter2);
257: parameterCtrl.setValue(portlet.getId().toString());
258:
259: }
260:
261: boolean found = false;
262: Iterator mappings = servletMappings.iterator();
263: while (mappings.hasNext()) {
264: ServletMappingImpl servletMapping = (ServletMappingImpl) mappings
265: .next();
266: if (servletMapping.getServletName().equals(
267: portlet.getName())) {
268: found = true;
269: servletMapping.setUrlPattern("/"
270: + portlet.getName().replace(' ', '_')
271: + "/*");
272: }
273: }
274: if (!found) {
275: ServletMappingImpl servletMapping = new ServletMappingImpl();
276: servletMapping.setServletName(portlet.getName());
277: servletMapping.setUrlPattern("/"
278: + portlet.getName().replace(' ', '_')
279: + "/*");
280: servletMappings.add(servletMapping);
281: }
282:
283: // Add in portlet taglib
284: TagLibImpl tagLib = new TagLibImpl();
285: tagLib.setTaglibUri(WEB_PORTLET_TAGLIB_URI);
286: tagLib.setTaglibLocation(WEB_PORTLET_TAGLIB_LOCATION);
287: webApplicationDefinition.getTagLibs().add(tagLib);
288:
289: SecurityRoleRefSet servletSecurityRoleRefs = ((ServletDefinitionImpl) servlet)
290: .getSecurityRoleRefs();
291:
292: SecurityRoleRefSetCtrl servletSecurityRoleRefSetCtrl = (SecurityRoleRefSetCtrl) controllerFactory
293: .get(servletSecurityRoleRefs);
294:
295: SecurityRoleSet webAppSecurityRoles = webApplicationDefinition
296: .getSecurityRoles();
297:
298: SecurityRoleRefSet portletSecurityRoleRefs = portlet
299: .getInitSecurityRoleRefSet();
300:
301: //SecurityRoleRefSetCtrl portletSecurityRoleRefSetCtrl = (SecurityRoleRefSetCtrl)controllerFactory.get(portletSecurityRoleRefs);
302:
303: Iterator p = portletSecurityRoleRefs.iterator();
304:
305: while (p.hasNext()) {
306: SecurityRoleRef portletSecurityRoleRef = (SecurityRoleRef) p
307: .next();
308:
309: if (portletSecurityRoleRef.getRoleLink() == null
310: && webAppSecurityRoles
311: .get(portletSecurityRoleRef
312: .getRoleName()) == null) {
313: System.out
314: .println("Note: The web application has no security role defined which matches the role name \""
315: + portletSecurityRoleRef
316: .getRoleName()
317: + "\" of the security-role-ref element defined for the wrapper-servlet with the name '"
318: + portlet.getName() + "'.");
319: break;
320: }
321: SecurityRoleRef servletSecurityRoleRef = servletSecurityRoleRefs
322: .get(portletSecurityRoleRef.getRoleName());
323: if (null != servletSecurityRoleRef) {
324: System.out
325: .println("Note: Replaced already existing element of type <security-role-ref> with value \""
326: + portletSecurityRoleRef
327: .getRoleName()
328: + "\" for subelement of type <role-name> for the wrapper-servlet with the name '"
329: + portlet.getName() + "'.");
330: servletSecurityRoleRefSetCtrl
331: .remove(servletSecurityRoleRef);
332: }
333: servletSecurityRoleRefSetCtrl
334: .add(portletSecurityRoleRef);
335: }
336:
337: }
338:
339: if (debug) {
340: System.out.println(webApplicationDefinition);
341: }
342:
343: OutputFormat of = new OutputFormat();
344: of.setIndenting(true);
345: of.setIndent(4); // 2-space indention
346: of.setLineWidth(16384);
347: // As large as needed to prevent linebreaks in text nodes
348: of.setDoctype(WEB_PORTLET_PUBLIC_ID, WEB_PORTLET_DTD);
349:
350: OutputStream outputStream = new FileOutputStream(webAppsDir
351: + webModule + File.separator + "WEB-INF"
352: + File.separator + "web.xml");
353: Writer writer = new OutputStreamWriter(outputStream,
354: "utf-8");
355:
356: Serializer serializer = new XMLSerializer(writer, of);
357: try {
358: WebApplicationMarshaller wam = new WebApplicationMarshaller();
359: wam.init(webApplicationDefinition, serializer);
360: wam.marshall();
361: } catch (Exception e) {
362: writer.close();
363: e.printStackTrace(System.out);
364: throw new Exception();
365: }
366: String strTo = dirDelim + "WEB-INF" + dirDelim + "tld"
367: + dirDelim + "portlet.tld";
368: String strFrom = "webpages" + strTo;
369:
370: copy(strFrom, webAppsDir + webModule + strTo);
371: } catch (Exception e) {
372: System.out.println();
373: e.printStackTrace(System.out);
374: throw new Exception();
375: }
376:
377: System.out.println("Finished!");
378: }
379:
380: public static void copy(String from, String to) throws IOException {
381: File f = new File(to);
382: f.getParentFile().mkdirs();
383:
384: byte[] buffer = new byte[1024];
385: int length = 0;
386: InputStream fis = new FileInputStream(from);
387: FileOutputStream fos = new FileOutputStream(f);
388:
389: while ((length = fis.read(buffer)) >= 0) {
390: fos.write(buffer, 0, length);
391: }
392: fos.close();
393: fis.close();
394: }
395:
396: public static void main(String args[]) {
397: String warFile;
398:
399: if (args.length < 2) {
400: System.out
401: .println("No argument specified. This command hast to be issued as:");
402: System.out
403: .println("deploy <TOMCAT-webapps-directory> <web-archive> [-debug]");
404: return;
405: }
406:
407: if (args.length > 2) {
408: if ((args[2].equals("-debug"))
409: || (args[4].equals("/debug"))) {
410: debug = true;
411: }
412: }
413:
414: if (debug) {
415: for (int i = 0; i < args.length; i++) {
416: System.out.println("args[" + i + "]:" + args[i]);
417: }
418: }
419:
420: webAppsDir = args[0];
421: if (!webAppsDir.endsWith(dirDelim))
422: webAppsDir += dirDelim;
423:
424: warFile = args[1];
425:
426: if (args.length > 2) {
427: if ((args[2].equals("-debug"))
428: || (args[4].equals("/debug"))) {
429: debug = true;
430: }
431: }
432:
433: try {
434: if (warFile.equals("all")) {
435: // In the case of "all", we loop through all the portlet
436: // application archives and deploy each one
437: File portletDir = new File(portletAppDir);
438: if (portletDir.exists()) {
439: File[] portletApps = portletDir.listFiles();
440: for (int i = 0; i < portletApps.length; i++) {
441: String portletApp = portletApps[i].getPath();
442: if (portletApp.endsWith(".war")) {
443: deployArchive(webAppsDir, portletApp);
444: prepareWebArchive(webAppsDir, portletApp);
445: }
446: }
447: }
448:
449: } else {
450: // A specific portlet application was specified, so deploy it
451: deployArchive(webAppsDir, warFile);
452: prepareWebArchive(webAppsDir, warFile);
453: }
454: } catch (Exception e) {
455: e.printStackTrace(System.out);
456: }
457:
458: }
459:
460: }
|