001: /*
002: * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005: package com.sun.portal.portlet.admin.mbeans.tasks;
006:
007: import java.io.IOException;
008: import java.io.File;
009: import java.io.FileInputStream;
010: import java.io.FileOutputStream;
011: import java.io.InputStream;
012: import java.io.FileNotFoundException;
013:
014: import java.util.List;
015: import java.util.ArrayList;
016: import java.util.Map;
017: import java.util.HashMap;
018: import java.util.Properties;
019:
020: import java.util.jar.JarFile;
021: import java.util.jar.JarEntry;
022:
023: import java.util.zip.ZipEntry;
024:
025: import com.sun.portal.desktop.context.AdminDPContext;
026: import java.util.logging.Level;
027: import java.util.logging.Logger;
028:
029: /**
030: * PDDeploy is responsible for processing the command line options
031: * associated with the deploy subcommand by calling the PDWarUpdater
032: * for updating the war file and PDDPUpdater for updating the
033: * Display Profile with the provider entries created from portlet.xml
034: */
035: public class PDDeploy {
036:
037: //private static final String CONFIG_LOCATION_PROPERTY = "deployer.propertiesFile";
038: private static final String WEB_XML = "web.xml";
039: private static final String PORTLET_XML = "portlet.xml";
040: private static final String EXT_XML = "sun-portlet.xml";
041: private static final String WEB_INF_PREFIX = "WEB-INF" + "/";
042: private static final String DD_LOCATION = "DDFileLocation";
043: private static final String DD_SUFFIX = "_portlet.xml";
044: private static final String WAR_SUFFIX = ".war";
045:
046: private Properties configProps = null;
047:
048: public PDDeploy(Properties pdconfigProp)
049: throws PortletDeployerException {
050: this .configProps = pdconfigProp;
051: }
052:
053: public String[] process(AdminDPContext dadc, String dn,
054: boolean global, File warFile, Properties rolesProperties,
055: Properties userinfoProperties, boolean verbose,
056: Logger logger) throws PortletDeployerException {
057:
058: //initialize PDWarUpdate
059: PDWarUpdater pdwr = null;
060: JarFile jar = null;
061: String warName = warFile.getName();
062: String portletAppName = warName.substring(0, warName
063: .indexOf('.'));
064: String ddLocation = configProps.getProperty(DD_LOCATION);
065: String[] filesModified = new String[2];
066:
067: if (verbose) {
068: Object[] tokens = { warName };
069: logger.log(Level.INFO, "PSPL_CSPPAMT0002", tokens);
070:
071: }
072:
073: String portletddName = portletAppName + DD_SUFFIX;
074: File portletDDFile = new File(ddLocation + File.separatorChar
075: + portletddName);
076: if (portletDDFile.exists()) {
077: Object[] tokens = { warName };
078: throw new PortletDeployerException(
079: "errorPortletAlreadyDeployed", tokens);
080: }
081:
082: try {
083: pdwr = new PDWarUpdater(warFile, configProps);
084: jar = pdwr.getJarFile();
085: } catch (IOException ioe) {
086:
087: Object[] tokens = { warName };
088: throw new PortletDeployerException("errorGettingJarFile",
089: ioe, tokens);
090: }
091:
092: if (verbose) {
093: logger.info("PSPL_CSPPAMT0003");
094: }
095: // get the portlet.xml as InputStream
096: InputStream in = null;
097: try {
098: ZipEntry portletXMLEntry = jar.getEntry(WEB_INF_PREFIX
099: + PORTLET_XML);
100: in = jar.getInputStream(portletXMLEntry);
101: } catch (IOException ioe) {
102: Object[] tokens = { portletAppName + DD_SUFFIX };
103: throw new PortletDeployerException("errorStreamRead", ioe,
104: tokens);
105: } catch (Exception ex) {
106: String[] tokens = { WEB_INF_PREFIX + PORTLET_XML };
107: throw new PortletDeployerException("invalidWar", ex, tokens);
108: }
109: if (verbose) {
110: logger.info("PSPL_CSPPAMT0004");
111: }
112:
113: InputStream webXMLStream1 = null;
114: List roles = new ArrayList();
115: try {
116: ZipEntry webXMLEntry = jar.getEntry(WEB_INF_PREFIX
117: + WEB_XML);
118: webXMLStream1 = (InputStream) jar
119: .getInputStream(webXMLEntry);
120: roles = PDWebAppUpdater.getRoles(webXMLStream1);
121: } catch (IOException ioe) {
122: throw new PortletDeployerException("errorGettingRoles", ioe);
123: } catch (PortletDeployerException pde) {
124: throw new PortletDeployerException("errorGettingRoles", pde);
125: } catch (Exception ex) {
126: String[] tokens = { WEB_INF_PREFIX + WEB_XML };
127: throw new PortletDeployerException("invalidWar", ex, tokens);
128: }
129:
130: InputStream extStream = null;
131: try {
132: ZipEntry extXMLEntry = jar.getEntry(WEB_INF_PREFIX
133: + EXT_XML);
134: if (extXMLEntry != null) {
135: extStream = (InputStream) jar
136: .getInputStream(extXMLEntry);
137: }
138: } catch (IOException ioe) {
139: throw new PortletDeployerException("errorGettingExtension",
140: ioe);
141: } catch (Exception ex) {
142: String[] tokens = { WEB_INF_PREFIX + EXT_XML };
143: throw new PortletDeployerException("invalidWar", ex, tokens);
144: }
145:
146: // Call deployment descriptor parser with portlet.xml and create provider elements.
147: PDProviderEntryGenerator providerGen = new PDProviderEntryGenerator(
148: in, extStream, configProps, portletAppName);
149: List providerElements = providerGen.createProviderElements(
150: rolesProperties, userinfoProperties, roles);
151:
152: if (verbose) {
153: logger.info("PSPL_CSPPAMT0006");
154: }
155: // add provider definition using DPAPI.
156: PDDPUpdater dpUpdater = new PDDPUpdater(dadc, dn, global,
157: verbose, logger);
158: dpUpdater.addProviders(providerElements);
159:
160: // copy portlet.xml file to ddlocation directory
161: // to be used later for undeployment.
162: FileOutputStream fos = null;
163: InputStream portletIn = null;
164: try {
165: ZipEntry portletXMLEntry = jar.getEntry(WEB_INF_PREFIX
166: + PORTLET_XML);
167: portletIn = jar.getInputStream(portletXMLEntry);
168: String ddName = portletAppName + DD_SUFFIX;
169: filesModified[0] = ddLocation + File.separatorChar + ddName; //location of dd
170: File portletFile = new File(ddLocation, ddName);
171: portletFile.createNewFile();
172: fos = new FileOutputStream(portletFile);
173:
174: // Allocate a buffer for reading entry data.
175: byte[] buffer = new byte[1024];
176: int bytesRead;
177: if (portletIn != null) {
178: // Read the stream and write it to the file.
179: while ((bytesRead = portletIn.read(buffer)) != -1) {
180: fos.write(buffer, 0, bytesRead);
181: }
182: }
183:
184: } catch (IOException ioe) {
185: Object[] tokens = { portletAppName + DD_SUFFIX };
186: throw new PortletDeployerException("errorStreamRead", ioe,
187: tokens);
188: } catch (Exception ex) {
189: String[] tokens = { WEB_INF_PREFIX + PORTLET_XML };
190: throw new PortletDeployerException("invalidWar", ex, tokens);
191: }
192:
193: if (verbose) {
194: logger
195: .log(Level.INFO, "PSPL_CSPPAMT0037",
196: filesModified[0]);
197: }
198:
199: if (verbose) {
200: logger.info("PSPL_CSPPAMT0005");
201: }
202:
203: File newWebXMLFile = null;
204: // update web.xml.
205: InputStream webXMLStream2 = null;
206: try {
207: ZipEntry webXMLEntry = jar.getEntry(WEB_INF_PREFIX
208: + WEB_XML);
209: webXMLStream2 = (InputStream) jar
210: .getInputStream(webXMLEntry);
211: //pdwr.updateWebApp(webXMLStream, portletAppName);
212: newWebXMLFile = PDWebAppUpdater.addWebAppParam(
213: webXMLStream2, configProps, portletAppName);
214: } catch (IOException ioe) {
215: Object[] tokens = { portletAppName };
216: throw new PortletDeployerException("errorUpdatingWebApp",
217: ioe, tokens);
218: } catch (Exception ex) {
219: Object[] tokens = { portletAppName };
220: throw new PortletDeployerException("errorUpdatingWebApp",
221: ex, tokens);
222: }
223:
224: try {
225: webXMLStream1.close();
226: webXMLStream2.close();
227: in.close();
228: portletIn.close();
229: fos.close();
230: if (extStream != null) {
231: extStream.close();
232: }
233: } catch (IOException ioe) {
234: throw new PortletDeployerException("errorStreamClose", ioe);
235: }
236:
237: //in case of remote deploy, war file gets renamed to abc.war_timestamp ,
238: // so, recreate the destination war : "abc" + ".war"
239: String warFileName = portletAppName + WAR_SUFFIX;
240: //get updated war file
241: try {
242: File newWarFile = pdwr.getUpdatedWarFile(newWebXMLFile);
243: if (newWarFile != null) {
244: File destFile = new File(ddLocation, warFileName);
245: copyFile(newWarFile, destFile, true, false);
246: //delete the temporary war file.
247: newWarFile.delete();
248: warFileName = destFile.getAbsolutePath();
249: } else {
250: Object[] tokens = { warFileName };
251: throw new PortletDeployerException("errorJarUpdate",
252: tokens);
253: }
254: } catch (IOException ioe) {
255: Object[] tokens = { warFileName };
256: throw new PortletDeployerException("errorJarUpdate", ioe,
257: tokens);
258: } catch (Exception ex) {
259: Object[] tokens = { warFileName };
260: throw new PortletDeployerException("errorJarUpdate", ex,
261: tokens);
262: }
263:
264: filesModified[1] = warFileName;
265: return filesModified;
266:
267: }
268:
269: /**
270: * Convienence method to copy a file from a source to a destination.
271: * Overwrite is prevented, and the last modified is kept.
272: *
273: * @throws IOException
274: */
275: public static void copyFile(String sourceFile, String destFile)
276: throws IOException {
277: copyFile(new File(sourceFile), new File(destFile), false, true);
278: }
279:
280: /**
281: * Method to copy a file from a source to a
282: * destination specifying if
283: * source files may overwrite newer destination files and the
284: * last modified time of <code>destFile</code> file should be made equal
285: * to the last modified time of <code>sourceFile</code>.
286: *
287: * @throws IOException
288: */
289: public static void copyFile(File sourceFile, File destFile,
290: boolean overwrite, boolean preserveLastModified)
291: throws IOException {
292:
293: if (overwrite || !destFile.exists()
294: || destFile.lastModified() < sourceFile.lastModified()) {
295:
296: if (destFile.exists() && destFile.isFile()) {
297: destFile.delete();
298: }
299:
300: // ensure that parent dir of dest file exists!
301: File parent = new File(destFile.getParent());
302: if (!parent.exists()) {
303: parent.mkdirs();
304: }
305:
306: FileInputStream in = new FileInputStream(sourceFile);
307: FileOutputStream out = new FileOutputStream(destFile);
308:
309: byte[] buffer = new byte[8 * 1024];
310: int count = 0;
311: do {
312: out.write(buffer, 0, count);
313: count = in.read(buffer, 0, buffer.length);
314: } while (count != -1);
315:
316: in.close();
317: out.close();
318:
319: if (preserveLastModified) {
320: destFile.setLastModified(sourceFile.lastModified());
321: }
322: }
323: }
324: }
|