001: /*
002: * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005: package com.sun.portal.desktop.deployment;
006:
007: import java.util.StringTokenizer;
008:
009: import java.io.PrintStream;
010: import java.io.InputStream;
011: import java.io.FileOutputStream;
012: import java.io.FileInputStream;
013: import java.io.File;
014:
015: import java.util.logging.Level;
016: import java.util.logging.Logger;
017:
018: import org.w3c.dom.Document;
019: import org.w3c.dom.Element;
020:
021: import com.sun.portal.desktop.dp.DPRoot;
022: import com.sun.portal.desktop.dp.DPNode;
023: import com.sun.portal.desktop.dp.DPChannel;
024: import com.sun.portal.desktop.dp.DPProvider;
025: import com.sun.portal.desktop.dp.DPContainerChannel;
026: import com.sun.portal.desktop.dp.DPReferenceList;
027: import com.sun.portal.desktop.dp.DPProperty;
028: import com.sun.portal.desktop.dp.DPPropertyHolder;
029: import com.sun.portal.desktop.dp.DPReference;
030:
031: import com.sun.portal.desktop.dp.xml.XMLDPNode;
032: import com.sun.portal.desktop.dp.xml.XMLDPObject;
033:
034: import com.sun.portal.util.Platform;
035:
036: public class DPBasedExCtx extends DPBasedContext implements
037: ParExtractionContext {
038:
039: // This is called from the MBean, a logger is passed in and
040: // it is used for debugging statements, in this case m_Out is not used.
041: public DPBasedExCtx(boolean verbose, Logger logger,
042: boolean overwrite) {
043: m_Verbose = verbose;
044: m_Logger = logger;
045: m_Overwrite = overwrite;
046: }
047:
048: public DPBasedExCtx(DPRootSpecifier droot, boolean overwrite,
049: boolean verbose, PrintStream out, String ss) {
050: m_DPRSpec = droot;
051: m_Overwrite = overwrite;
052: m_Verbose = verbose;
053: m_Out = out;
054: setStaticSub(ss);
055: }
056:
057: public DPBasedExCtx(DPRootSpecifier droot, boolean verbose,
058: Logger logger, boolean overwrite) {
059: m_DPRSpec = droot;
060: m_Overwrite = overwrite;
061: m_Verbose = verbose;
062: m_Logger = logger;
063: }
064:
065: public void putParEntryXMLFile(InputStream in, int types)
066: throws ParFileException {
067:
068: if (!deployDynamic()) {
069: return;
070: }
071:
072: Document doc = Par.streamToDom(in);
073: DPRoot dr = m_DPRSpec.getRoot();
074:
075: // if we don't actually install a provider, we have to use the name contained in
076: // the document. If we install a provider, this will be replaced. This may be null
077: // if there's no channel in the document.
078:
079: String pvname = Par.getProviderNameFromChannel(doc);
080: String objname = pvname;
081: m_PathXFrom = null;
082: m_PathXTo = null;
083: m_PropFileXFrom = null;
084: m_PropFileXTo = null;
085:
086: if ((types & ExtractOp.TYPE_PROVIDER) != 0) {
087:
088: // provider name on operation is an override. If null,
089: // the provider name is taken from the document. If we
090: // change the provider name, not that we have to translate
091: // property file names corresponding to its resource bundle.
092:
093: pvname = m_Op.getProviderName();
094: if (pvname == null) {
095: pvname = Par.getProviderName(doc);
096: } else {
097: m_PropFileXFrom = Par.getProviderName(doc);
098: m_PropFileXTo = pvname;
099: }
100: objname = pvname;
101: String cls = Par.getProviderClass(doc);
102:
103: int providerVersion = Par.getProviderVersion(doc);
104:
105: try {
106: if (dr.getProvider(pvname) != null) {
107: if (!m_Overwrite) {
108: Object tok[] = { pvname };
109: throw new ParFileException(
110: "errorProviderExists", tok);
111: }
112: dr.removeProvider(pvname);
113: }
114:
115: Object tok[] = { "provider", pvname + ", " + cls };
116: if (m_Logger != null) {
117: if (m_Verbose) {
118: if (m_Logger.isLoggable(Level.INFO)) {
119: m_Logger.log(Level.INFO, "PSDT_CSPDD0001",
120: tok);
121: }
122: }
123: } else {
124: message(Par.getLocalizedString("msgImportAdd", tok));
125: }
126: DPProvider pr = m_DPRSpec.createProvider(pvname, cls,
127: providerVersion);
128: pr = dr.addProvider(pr);
129: setProperties(pr, Par.getProviderProperties(doc));
130: } catch (Exception ex) {
131: throw new ParFileException("errorImporting", ex);
132: }
133:
134: }
135:
136: if ((types & ExtractOp.TYPE_CHANNEL) != 0) {
137: try {
138: DPNode container = dr;
139: String containerName = m_Op.getChannelContainer();
140:
141: if (containerName != null) {
142: container = dr.getChannel(containerName);
143: if (container == null) {
144: Object tok[] = { containerName };
145: throw new ParFileException("errorNoContainer",
146: tok);
147: }
148: }
149:
150: // Set up channel name. If operation specifies a channel name, we also
151: // note that we have to change directory components from the old name.
152:
153: String channelName = m_Op.getChannelName();
154: if (channelName == null) {
155: channelName = Par.getChannelName(doc);
156: } else {
157: m_PathXFrom = Par.getChannelName(doc);
158: m_PathXTo = channelName;
159: }
160: objname = containerName != null ? containerName
161: + DPNode.CHANNEL_NAME_SEPARATOR + channelName
162: : channelName;
163:
164: if (dr.getChannel(objname) != null) {
165: if (!m_Overwrite) {
166: Object tok[] = { objname };
167: throw new ParFileException(
168: "errorChannelExists", tok);
169: }
170: dr.removeChannel(objname);
171: }
172:
173: Object tok[] = { "channel", objname + ", " + pvname };
174: if (m_Logger != null) {
175: if (m_Verbose) {
176: if (m_Logger.isLoggable(Level.INFO)) {
177: m_Logger.log(Level.INFO, "PSDT_CSPDD0001",
178: tok);
179: }
180: }
181: } else {
182: message(Par.getLocalizedString("msgImportAdd", tok));
183: }
184: DPChannel chan = m_DPRSpec.createChannel(channelName,
185: pvname); // the one place we don't use full name.
186: chan = container.addChannel(chan);
187: setProperties(chan, Par.getChannelProperties(doc));
188:
189: String aname = m_Op.getAvailContainer();
190: if (aname != null) {
191: DPChannel avchan = dr.getChannel(aname);
192: addReference(((DPContainerChannel) avchan)
193: .getAvailable(), objname);
194: if (m_Op.getMakeSelected()) {
195: addReference(((DPContainerChannel) avchan)
196: .getSelected(), objname);
197: }
198: }
199: } catch (Exception ex) {
200: throw new ParFileException("errorImporting", ex);
201: }
202: }
203:
204: m_DPRSpec.flush();
205: setPropertyHolder(dr, objname, types);
206: }
207:
208: public void putClassFile(String fullname, InputStream in)
209: throws ParFileException {
210:
211: if (!deployDynamic()) {
212: return;
213: }
214:
215: String cdir = (String) getClassPath().elementAt(0);
216: streamOut(cdir + FS + Par.classToFile(fullname), in);
217: }
218:
219: public void initializeForOperation(ExtractOp op)
220: throws ParFileException {
221: Object tok[] = { op.toArg() };
222: if (m_Logger != null) {
223: if (m_Verbose) {
224: if (m_Logger.isLoggable(Level.INFO)) {
225: m_Logger.log(Level.INFO, "PSDT_CSPDD0002", tok);
226: }
227: }
228: } else {
229: message(Par.getLocalizedString("msgImportInitOp", tok));
230: }
231: m_DPRSpec.setDN(op.getDPNode());
232: m_Op = op;
233: }
234:
235: public void putPropLocFile(String rootproperty, String path,
236: InputStream in) throws ParFileException {
237: String realPath = getPBFProperty(rootproperty, false) + FS
238: + translatePath(path);
239:
240: if (deployDynamic()) {
241: streamOut(getPBFProperty(rootproperty, false) + FS
242: + translatePath(path), in);
243: }
244: }
245:
246: public void putWarFile(String path, InputStream in)
247: throws ParFileException {
248: if (deployStatic()) {
249: streamOut(getPortalWarDirectory() + FS + path, in);
250: }
251: }
252:
253: public void putConfigFile(String path, InputStream in)
254: throws ParFileException {
255: if (deployStatic()) {
256: streamOut(getPSDataDirectory() + FS + path, in);
257: }
258: }
259:
260: public void putStaticFile(String path, InputStream in)
261: throws ParFileException {
262: if (deployStatic()) {
263: for (int idx = 0; idx < getStaticDirectoryCount(); ++idx) {
264:
265: String outpath = getStaticDirectory() + FS
266: + translatePath(path);
267: streamOut(outpath, in);
268:
269: // Since we can't rewind streams, just open a new stream to
270: // the stuff we just copied.
271:
272: try {
273: in = new FileInputStream(outpath);
274: } catch (Exception ex) {
275: throw new ParFileException("errorImporting", ex);
276: }
277: }
278: }
279: }
280:
281: public void terminateOperation(boolean success)
282: throws ParFileException {
283: if (success) {
284:
285: // NOTE - static content deployment done by the script,
286: // rather than this java code.
287:
288: if (deployStatic()) {
289: }
290: if (m_Logger != null) {
291: if (m_Verbose) {
292: if (m_Logger.isLoggable(Level.INFO)) {
293: m_Logger.log(Level.INFO, "PSDT_CSPDD0003");
294: }
295: }
296: } else {
297: message(Par.getLocalizedString("msgImportOpComplete"));
298: }
299:
300: } else {
301: if (m_Logger != null) {
302: if (m_Verbose) {
303: if (m_Logger.isLoggable(Level.INFO)) {
304: m_Logger.log(Level.INFO, "PSDT_CSPDD0004");
305: }
306: }
307: } else {
308: message(Par.getLocalizedString("msgImportOpFailed"));
309: }
310:
311: }
312: m_Op = null;
313: }
314:
315: // translate relies on assumptions about the way files
316: // are used. Its purpose is to massage file names to
317: // reflect changes of provider / channel name. Our current rules
318: // are that if a channel is renamed, we change directories
319: // which match that name (current usage in template directories),
320: // and if a provider is renamed, we rename property files beginning
321: // with the provider name to handle getResourceBundle().
322:
323: private String translatePath(String path) {
324:
325: if (m_PathXFrom == null && m_PropFileXFrom == null) {
326: return path;
327: }
328:
329: StringBuffer buf = new StringBuffer();
330: StringTokenizer toks = new StringTokenizer(path, "/");
331: String pfx = "";
332: while (toks.hasMoreTokens()) {
333: String comp = toks.nextToken();
334: if (m_PathXFrom != null && comp.equals(m_PathXFrom)) {
335: comp = m_PathXTo;
336: }
337: if (m_PropFileXFrom != null && comp.endsWith(".properties")
338: && comp.startsWith(m_PropFileXFrom)) {
339: comp = m_PropFileXTo
340: + comp.substring(m_PropFileXFrom.length());
341: }
342: buf.append(pfx);
343: buf.append(comp);
344: pfx = "/";
345: }
346:
347: return buf.toString();
348: }
349:
350: private void setProperties(DPPropertyHolder nd, Element props)
351: throws ParFileException {
352:
353: // FIXME - we shouldn't be coercing to implementation class
354:
355: XMLDPObject xnd = (XMLDPObject) nd;
356: Element elt = xnd.getElement();
357: Par.replaceProps(elt, props);
358: }
359:
360: private void addReference(DPReferenceList rl, String nm)
361: throws ParFileException {
362: try {
363: DPReference ref = m_DPRSpec.createReference(nm);
364: rl.add(ref);
365: } catch (Exception ex) {
366: throw new ParFileException("errorImporting", ex);
367: }
368: }
369:
370: private void message(String mess) {
371: if (m_Verbose) {
372: if (m_Out != null) {
373: m_Out.println(mess);
374: }
375: }
376: }
377:
378: private void streamOut(String filename, InputStream in)
379: throws ParFileException {
380: try {
381: byte buf[] = new byte[4000];
382:
383: File f = new File(filename);
384: if (!m_Overwrite) {
385: if (f.exists() && !f.isDirectory()) {
386: return;
387: }
388: }
389:
390: f.getParentFile().mkdirs();
391: FileOutputStream os = new FileOutputStream(f);
392:
393: int len;
394: while ((len = in.read(buf)) > 0) {
395: os.write(buf, 0, len);
396: }
397: os.close();
398: } catch (Exception ex) {
399: throw new ParFileException("errorImporting", ex);
400: }
401: }
402:
403: public void putJarFile(String path, InputStream in)
404: throws ParFileException {
405: }
406:
407: public void delDirectory(String prop, String subdir,
408: String dfilter, boolean delTopChildren)
409: throws ParFileException {
410:
411: String rdir = prop != null ? getPBFProperty(prop, false)
412: : getStaticDirectory();
413: if (rdir.endsWith(FS)) {
414: int len = rdir.length();
415: rdir = rdir.substring(0, len - 1);
416: }
417:
418: if (m_Verbose) {
419: String[] token = { rdir };
420: if (m_Logger.isLoggable(Level.INFO)) {
421: m_Logger.log(Level.INFO, "PSDT_CSPDD0005", token);
422: }
423: }
424:
425: delSubDir(rdir, subdir, dfilter, delTopChildren);
426:
427: }
428:
429: private void delSubDir(String rdir, String subdir, String dfilter,
430: boolean delTopChildren) {
431:
432: File f = new File(
433: (subdir == null ? rdir : (rdir + FS + subdir)));
434: File children[] = f.listFiles();
435: if (children == null) {
436: return;
437: }
438:
439: for (int i = 0; i < children.length; ++i) {
440: File child = children[i];
441: if (child.isDirectory()) {
442: String nm = child.getName();
443: String nmplus = subdir == null ? nm
444: : (subdir + FS + nm);
445: if (dfilter == null || dfilter.equals(nm)) {
446: delSubDir(rdir, nmplus, null, true);
447: } else {
448: delSubDir(rdir, nmplus, dfilter, true);
449: }
450: child.delete();
451: } else if (child.exists()) {
452: if (delTopChildren) {
453: if (m_Verbose) {
454: if (m_Logger.isLoggable(Level.INFO)) {
455: String[] token = { child.getName() };
456: m_Logger.log(Level.INFO, "PSDT_CSPDD0006",
457: token);
458: }
459: }
460: child.delete();
461: }
462: }
463: }
464: }
465:
466: public void setChannelPath(InputStream in, int types)
467: throws ParFileException {
468:
469: if ((types & ExtractOp.TYPE_CHANNEL) != 0) {
470: Document doc = Par.streamToDom(in);
471: String channelName = m_Op.getChannelName();
472: if (channelName == null) {
473: channelName = Par.getChannelName(doc);
474: } else {
475: m_PathXFrom = Par.getChannelName(doc);
476: m_PathXTo = channelName;
477: }
478: }
479: }
480:
481: private boolean m_Overwrite = false;
482: private boolean m_Verbose = false;
483: private Logger m_Logger = null;
484: private PrintStream m_Out = null;
485: private ExtractOp m_Op = null;
486: private DPRootSpecifier m_DPRSpec;
487: private String m_PathXFrom = null;
488: private String m_PathXTo = null;
489: private String m_PropFileXFrom = null;
490: private String m_PropFileXTo = null;
491: private static final String FS = Platform.fs;
492: }
|