0001: /**
0002: * $Id: DesktopData.java,v 1.28 2007/01/26 03:48:20 portalbld Exp $
0003: * Copyright 2004 Sun Microsystems, Inc. All
0004: * rights reserved. Use of this product is subject
0005: * to license terms. Federal Acquisitions:
0006: * Commercial Software -- Government Users
0007: * Subject to Standard License Terms and
0008: * Conditions.
0009: *
0010: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
0011: * are trademarks or registered trademarks of Sun Microsystems,
0012: * Inc. in the United States and other countries.
0013: */package com.sun.portal.desktop.admin.mbeans.tasks;
0014:
0015: import java.io.ByteArrayOutputStream;
0016: import java.io.InputStream;
0017: import java.io.FileInputStream;
0018: import java.io.FileOutputStream;
0019: import java.io.File;
0020: import java.io.IOException;
0021:
0022: import java.util.Iterator;
0023: import java.util.Vector;
0024: import java.util.Map;
0025: import java.util.HashMap;
0026: import java.util.Set;
0027: import java.util.Properties;
0028: import java.util.Enumeration;
0029: import java.util.logging.Level;
0030: import java.util.logging.Logger;
0031: import java.util.StringTokenizer;
0032: import java.util.List;
0033:
0034: import java.net.URLEncoder;
0035: import java.net.URLDecoder;
0036:
0037: import org.w3c.dom.Document;
0038:
0039: import com.iplanet.sso.SSOToken;
0040:
0041: import com.sun.portal.admin.common.PSConfigConstants;
0042: import com.sun.portal.admin.common.BackupVersion;
0043: import com.sun.portal.admin.common.context.PSConfigContext;
0044:
0045: import com.sun.portal.desktop.deployment.*;
0046: import com.sun.portal.fabric.util.FileUtil;
0047:
0048: import com.sun.portal.util.Platform;
0049:
0050: /**
0051: * This class provide import and export functionality for Portal
0052: * Data on a given Portal site.
0053: */
0054: public class DesktopData {
0055: public static final String TEMPLATE_BASE_DIR_PROP = "templateBaseDir";
0056: public static final String COMMUNITY_TEMPLATE_BASE_DIR_PROP = "communityTemplateBaseDir";
0057: public static final String COMPILED = "compiled";
0058:
0059: public static final String DESKTOP = "desktop";
0060: public static final String PROVIDER = "provider";
0061: public static final String GLOBAL_KEY = "global";
0062: public static final String ORG_KEY = "organization";
0063: public static final String DEFAULT_ORG_KEY = "defaultOrganization";
0064: public static final String UTF8 = "UTF-8";
0065: public static final int SEARCH_LEVEL = 2;
0066:
0067: // File separator.
0068: public static final String FS = Platform.fs;
0069: public static final String DEL = ";";
0070:
0071: // local member variables
0072: private String m_Portal = null;
0073: private String m_Domain = null;
0074: private PSConfigContext m_PCC = null;
0075: private boolean m_Verbose = false;
0076: private SSOToken m_SSOToken = null;
0077: private Logger m_Logger = null;
0078: private ParFile m_Par = null;
0079: private String m_PortalUri = null;
0080:
0081: /**
0082: * Constructor
0083: *
0084: * @param ssoToken The <code>SSOToken</code> that was used to get
0085: * the connection.
0086: * @param pcc The <code>PSConfigContext</code> object for getting
0087: * access to portal configuration data.
0088: * @param domainName The domain name.
0089: * @param portalName The portal site name.
0090: * @param verbose A <code>boolean</code> to allow more verbose
0091: * output.
0092: * @param logger The <code>Logger</code> that is used for adding
0093: * debugging messages.
0094: */
0095: public DesktopData(SSOToken ssoToken, PSConfigContext pcc,
0096: String domainName, String portalName, boolean verbose,
0097: Logger logger, String portalUri) {
0098: m_SSOToken = ssoToken;
0099: m_PCC = pcc;
0100: m_Domain = domainName;
0101: m_Portal = portalName;
0102: m_Verbose = true;
0103: m_Logger = logger;
0104: m_PortalUri = portalUri;
0105: /*
0106: if (m_Verbose) {
0107: m_Logger.setLevel(Level.FINEST);
0108: }
0109: */
0110: }
0111:
0112: /**
0113: * Export the provider/channel data.
0114: * <p>
0115: * The provider/channel data that will be backed in this method includes:
0116: * <UL>
0117: * <LI>Display profiles fragment for this provider/channel at the specified dn.
0118: * <LI>Desktop web-src data
0119: * <LI>Static files,templates for this provider/channel
0120: * </UL>
0121: *
0122: * @param parFilePath The par file name.
0123: * @param dn dn from where provider data needs to be backed up.
0124: * @param expfiles Vector of all the exportfilenames.
0125: * @exception DesktopDataException If the export operation fails.
0126: */
0127: public void exportProvider(String parFilePath, String dn,
0128: boolean global, byte[][] expfiles)
0129: throws DesktopDataException {
0130:
0131: /*
0132: if (m_Verbose) {
0133: m_Logger.setLevel(Level.FINEST);
0134: }
0135: */
0136: if (m_Logger.isLoggable(Level.FINER)) {
0137: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0062");
0138: }
0139: try {
0140: ParFileBuilder pfb = null;
0141: //---Set System Properties -----------------
0142: String dconfFileName = getDesktopConfigFileName();
0143: // set desktopconfig.properties file name in the system
0144: // properties, which is used by the DPBasedPPCtx.
0145: System.setProperty(ProviderPackageContext.DTPROPFILE,
0146: dconfFileName);
0147:
0148: // set system property for web-src dir
0149: String pDataDir = m_PCC.getPSDataDir() + FS
0150: + PSConfigConstants.PORTALS + FS + m_Portal;
0151: String webSrcPath = pDataDir + FS
0152: + PSConfigConstants.WEB_SRC;
0153:
0154: System.setProperty(ProviderPackageContext.STATICDIR,
0155: webSrcPath);
0156:
0157: // set system property for portal war dir
0158: String warDir = pDataDir + FS + ProviderPackageContext.WAR;
0159: System.setProperty(ProviderPackageContext.PSWARDIR, warDir);
0160:
0161: // set system property for portal data dir
0162: System.setProperty(ProviderPackageContext.PSDATADIR,
0163: pDataDir);
0164:
0165: DPRootSpecifier dpr = DPRootSpecifier.makeSpecifier(
0166: m_SSOToken, m_Portal);
0167: if (global) {
0168: dn = GLOBAL_KEY;
0169: }
0170: dpr.setDN(dn);
0171: ProviderPackageContext ppctx = new DPBasedPPCtx(dpr, null);
0172:
0173: DPHelper dpHelper = DPHelper.getDPHelper(m_PCC, m_SSOToken,
0174: m_Portal);
0175:
0176: DPHelper.setLogger(m_Logger);
0177:
0178: // build a backupVersion number, which is:
0179: // <domain name>;<portalName>;<backup type>;<backup
0180: // version>
0181:
0182: String backupVersion = BackupVersion.generateBackupVersion(
0183: m_Domain, m_Portal, PROVIDER);
0184:
0185: pfb = new ParFileBuilder(m_Verbose, m_Logger, backupVersion);
0186:
0187: HashMap namecheck = new HashMap();
0188: //get the export files
0189:
0190: for (int i = 0; i < expfiles.length; ++i) {
0191: File f = File.createTempFile(FileUtil
0192: .getRandomDirName(), null);
0193: FileOutputStream fo = new FileOutputStream(f);
0194: fo.write(expfiles[i]);
0195: ExportFile xpf = ExportFile.makeExportFile(f
0196: .getAbsolutePath(), dn, ppctx);
0197: String nm = xpf.getDPEntryName();
0198: if (namecheck.get(nm) != null) {
0199: Object tok[] = { nm };
0200: throw new ParFileException("errorExportDupEntry",
0201: tok);
0202: }
0203: namecheck.put(nm, nm);
0204: xpf.addEntry(pfb);
0205: f.delete();
0206: }
0207: pfb.makeParFile(parFilePath);
0208:
0209: if (m_Logger.isLoggable(Level.FINER)) {
0210: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0063");
0211: }
0212:
0213: } catch (DesktopDataException pe) {
0214: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0072", pe);
0215: throw pe;
0216: } catch (Exception e) {
0217: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0073", e);
0218: throw new DesktopDataException(
0219: "DesktopData.exportProvider(): " + e.getMessage(),
0220: e);
0221: } catch (Throwable t) {
0222: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0074", t);
0223: throw new DesktopDataException(
0224: "DesktopData.exportProvider(): " + t.getMessage(),
0225: t);
0226: }
0227:
0228: }
0229:
0230: /**
0231: * Import the provider data from the given file.
0232: *
0233: * @param parFile The fully qualified par file
0234: * @param operations used for importing providers
0235: */
0236: public void importProvider(String parFile, List operations,
0237: boolean overwrite, String dpnode, boolean extractDP)
0238: throws DesktopDataException {
0239:
0240: if (m_Logger.isLoggable(Level.FINER)) {
0241: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0062");
0242: }
0243:
0244: boolean error = false;
0245: try {
0246: if (m_Par == null) {
0247: m_Par = ParFile.makeParFile(parFile);
0248: }
0249:
0250: //check if this is correct provider par : MAy be this is not required now.
0251: ParManifest pMan = m_Par.getParManifest();
0252: String backupVersion = pMan.getBackupVersion();
0253: if (backupVersion != null) {
0254: if (BackupVersion.getType(backupVersion)
0255: .equals(DESKTOP)) {
0256: throw new Exception("Not a Provider Par");
0257: }
0258: }
0259: //---Set System Properties -----------------
0260: String dconfFileName = getDesktopConfigFileName();
0261: // set desktopconfig.properties file name in the system
0262: // properties, which is used by the DPBasedPPCtx.
0263: System.setProperty(ProviderPackageContext.DTPROPFILE,
0264: dconfFileName);
0265:
0266: // set system property for web-src dir
0267: String pDataDir = m_PCC.getPSDataDir() + FS
0268: + PSConfigConstants.PORTALS + FS + m_Portal;
0269: String webSrcPath = pDataDir + FS
0270: + PSConfigConstants.WEB_SRC;
0271:
0272: System.setProperty(ProviderPackageContext.STATICDIR,
0273: webSrcPath);
0274:
0275: // set system property for portal war dir
0276: String warDir = pDataDir + FS + ProviderPackageContext.WAR;
0277: System.setProperty(ProviderPackageContext.PSWARDIR, warDir);
0278:
0279: // set system property for portal data dir
0280: System.setProperty(ProviderPackageContext.PSDATADIR,
0281: pDataDir);
0282:
0283: DPHelper dpHelper = DPHelper.getDPHelper(m_PCC, m_SSOToken,
0284: m_Portal);
0285:
0286: DPHelper.setLogger(m_Logger);
0287:
0288: //import the provider data
0289: DPRootSpecifier dpr = DPRootSpecifier.makeSpecifier(
0290: m_SSOToken, m_Portal);
0291: ParExtractionContext pex = new DPBasedExCtx(dpr, m_Verbose,
0292: m_Logger, overwrite);
0293: if (dpnode != null) {
0294: dpr.setDN(dpnode);
0295: }
0296: if (operations.size() == 0) {
0297: // this extracts at the dn specified in each auto extract entry
0298: m_Par
0299: .performAutoExtraction(pex, dpr.getDN(),
0300: extractDP);
0301: } else {
0302: for (int i = 0; i < operations.size(); ++i) {
0303: String opstr = (String) operations.get(i);
0304: //if opstr does not have a dpnode , this uses dpNode as entered at cli
0305: // if entered dn is null and dpnode in operations is null, error .
0306: ExtractOp op = ExtractOp.makeOpFromArgument(dpr
0307: .getDN(), opstr);
0308: m_Par.performExtraction(pex, op, extractDP);
0309: }
0310: }
0311:
0312: } catch (DesktopDataException de) {
0313: throw de;
0314: } catch (Exception fn) {
0315: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0073", fn);
0316: throw new DesktopDataException(
0317: "DesktopData.importDesktop(): " + fn.getMessage(),
0318: fn);
0319: }
0320:
0321: if (m_Logger.isLoggable(Level.FINER)) {
0322: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0063");
0323: }
0324:
0325: }
0326:
0327: /**
0328: * Export up the desktop data, and create a par file in the local system.
0329: *
0330: * @param base the base from where the desktop data is stored. For
0331: * example, if the desktop data is stored in the Identity
0332: * services, then the base is the dn in the LDAP tree where the
0333: * target desktop data is.
0334: * @param fsOnly <code>true</code> if only file system data is
0335: * backed up.
0336: * @param parFilePath The full file name of the par file.
0337: * @param searchLevel The search level is used to set the scope
0338: * when accessing to the display profile and service attribute data.
0339: * @exception DesktopDataException If error occurs when creating
0340: * the desktop export data.
0341: */
0342: public void exportDesktop(String parFilePath, String base,
0343: boolean fsOnly, boolean dpOnly, String searchLevel)
0344: throws DesktopDataException {
0345: /*
0346: if (m_Verbose) {
0347: m_Logger.setLevel(Level.FINEST);
0348: }
0349: */
0350: if (base == null) {
0351: base = GLOBAL_KEY;
0352: }
0353:
0354: if (m_Logger.isLoggable(Level.FINER)) {
0355: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0062");
0356: }
0357:
0358: try {
0359: ParFileBuilder pfb = null;
0360: ProviderPackageContext ppctx = null;
0361: String dconfFileName = getDesktopConfigFileName();
0362: Map docs = null;
0363: Map parDocs = null;
0364: Map properties = null;
0365: Map dpMappings = new HashMap();
0366:
0367: ppctx = new DPBasedPPCtx(null, null);
0368: // set desktopconfig.properties file name in the system
0369: // properties, which is used by the DPBasedPPCtx.
0370: System.setProperty(ProviderPackageContext.DTPROPFILE,
0371: dconfFileName);
0372:
0373: DPHelper dpHelper = DPHelper.getDPHelper(m_PCC, m_SSOToken,
0374: m_Portal);
0375:
0376: DPHelper.setLogger(m_Logger);
0377:
0378: // start extracting display profile and desktop service
0379: // data
0380:
0381: if (!fsOnly) {
0382:
0383: // Get all the dn nodes in a set
0384: int level = getSearchLevel(searchLevel);
0385: Set nodes = dpHelper.getAllNames(level);
0386:
0387: // The docs map contains all the dp documents, it
0388: // uses dn as the key, and the value is the dp
0389: // document stored in that dn.
0390:
0391: parDocs = new HashMap();
0392: docs = dpHelper.getDocuments(nodes, level);
0393: Set keys = docs.keySet();
0394: String baseDn = m_PCC.getDefaultOrganization();
0395: int j = 0;
0396:
0397: for (Iterator i = keys.iterator(); i.hasNext();) {
0398: String key = (String) i.next();
0399:
0400: // Create par entry, and add it in the parDocs map
0401: Document doc = (Document) docs.get(key);
0402: Document parEntry = null;
0403:
0404: parEntry = Par.makeParEntry(key, null, doc
0405: .getDocumentElement());
0406:
0407: if (parEntry != null) {
0408:
0409: if (m_Logger.isLoggable(Level.FINER)) {
0410: Object tokens[] = { key };
0411: m_Logger.log(Level.FINER,
0412: "PSDT_CSPDAMT0064", tokens);
0413: }
0414:
0415: if (dpHelper.isGlobal(key)) {
0416: parDocs.put(GLOBAL_KEY, parEntry);
0417: } else {
0418: //generate node names and autoExtract
0419: //string node name is node1, node2, node3...
0420: //mapping in autoExtract contains the
0421: //relative dn path to the def org dn
0422: j++;
0423: String nodeName = "node"
0424: + Integer.toString(j);
0425: if (key.equals(baseDn)) {
0426: key = ExtractOp.ARG_DPNODE;
0427: } else {
0428: key = key.substring(0, key
0429: .toLowerCase().indexOf(
0430: baseDn.toLowerCase()))
0431: + ExtractOp.ARG_DPNODE;
0432: }
0433:
0434: dpMappings.put(nodeName, key);
0435: if (m_Logger.isLoggable(Level.FINER)) {
0436: Object tokens[] = { key, nodeName };
0437: m_Logger.log(Level.FINER,
0438: "PSDT_CSPDAMT0065", tokens);
0439: }
0440:
0441: parDocs.put(nodeName, parEntry);
0442: }
0443: }
0444: }
0445: if (!dpOnly) {
0446: // The properties map contains all attributes properties,
0447: // it uses dn as the key. The properties map
0448: // contains one Properties object per dn, and the
0449: // Properties object contains the desktop service
0450: // attribute name and value pairs.
0451:
0452: properties = new HashMap();
0453: Properties prop = null;
0454:
0455: for (Iterator i = nodes.iterator(); i.hasNext();) {
0456: //Adding properties in the properties map
0457: String node = (String) i.next();
0458:
0459: //Get the attributes, and save in the properties
0460: prop = new Properties();
0461: boolean hasProperty = dpHelper
0462: .getServiceAttributes(node, prop);
0463:
0464: if (hasProperty) {
0465: if (m_Logger.isLoggable(Level.FINER)) {
0466: Object tokens[] = { node };
0467: m_Logger.log(Level.FINER,
0468: "PSDT_CSPDAMT0066", tokens);
0469: }
0470:
0471: if (dpHelper.isGlobal(node)) {
0472: properties.put(GLOBAL_KEY, prop);
0473: } else {
0474: if (node.equals(baseDn)) {
0475: node = ExtractOp.ARG_DPNODE;
0476: } else {
0477: node = node
0478: .substring(
0479: 0,
0480: node
0481: .toLowerCase()
0482: .indexOf(
0483: baseDn
0484: .toLowerCase()))
0485: + ExtractOp.ARG_DPNODE;
0486: }
0487:
0488: //if node is already in dpMappings, find
0489: //the node key
0490: Set nodeKeys = dpMappings.keySet();
0491: if (dpMappings.containsValue(node)) {
0492: for (Iterator k = nodeKeys
0493: .iterator(); k.hasNext();) {
0494: String nodeKey = (String) k
0495: .next();
0496: if (((String) dpMappings
0497: .get(nodeKey))
0498: .equals(node)) {
0499: properties.put(nodeKey,
0500: prop);
0501: }
0502: }
0503: } else {
0504: //else add a new node in dpMappings
0505: j++;
0506: String nodeName = "node"
0507: + Integer.toString(j);
0508: dpMappings.put(nodeName, node);
0509: properties.put(nodeName, prop);
0510: }
0511: }
0512: }
0513: } //for
0514: }
0515: }
0516:
0517: Vector files = new Vector();
0518:
0519: if (!dpOnly) {
0520:
0521: // set system property for portal data dir
0522: String pDataDir = m_PCC.getPSDataDir() + FS
0523: + PSConfigConstants.PORTALS + FS + m_Portal;
0524: System.setProperty(ProviderPackageContext.PSDATADIR,
0525: pDataDir);
0526:
0527: //TODO: dn bassed export does not include the
0528: //corresponding class files or portlet/portal war file.
0529:
0530: // add provider/channel related template files
0531: // using DPBasedPPCtx.addDirectory() method to generate list
0532: // of files which is under the templateBaseDir. For global
0533: // export, this will archive ALL files under the
0534: // templateBaseDir. For dn based export, this will archive
0535: // the files base on the corresponding desktop type.
0536: if (m_Logger.isLoggable(Level.FINER)) {
0537: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0067");
0538: }
0539:
0540: ppctx.addDirectory(TEMPLATE_BASE_DIR_PROP, null, true,
0541: false, null, ExtractOp.TYPE_OTHER, COMPILED,
0542: files);
0543: ppctx.addDirectory(COMMUNITY_TEMPLATE_BASE_DIR_PROP,
0544: null, true, true, null, ExtractOp.TYPE_OTHER,
0545: COMPILED, files);
0546:
0547: // add files from web-src
0548: String webSrcPath = pDataDir + FS
0549: + PSConfigConstants.WEB_SRC;
0550:
0551: System.setProperty(ProviderPackageContext.STATICDIR,
0552: webSrcPath);
0553:
0554: if (m_Logger.isLoggable(Level.FINER)) {
0555: Object tokens[] = { webSrcPath };
0556: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0068",
0557: tokens);
0558: }
0559:
0560: ppctx.addDirectory(null, null, true, true, null,
0561: ExtractOp.TYPE_OTHER, null, files);
0562:
0563: // add portlet war files
0564: String warDir = pDataDir + FS
0565: + ProviderPackageContext.WAR;
0566: String portalWarFile = m_PortalUri + ".war";
0567:
0568: System.setProperty(ProviderPackageContext.PSWARDIR,
0569: warDir);
0570: System.setProperty(ProviderPackageContext.PSWARFILE,
0571: portalWarFile.substring(1));
0572: if (m_Logger.isLoggable(Level.FINER)) {
0573: Object tokens[] = { warDir };
0574: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0069",
0575: tokens);
0576: }
0577:
0578: ppctx.addDirectory(ProviderPackageContext.PSWARDIR,
0579: null, false, true, null, ExtractOp.TYPE_OTHER,
0580: null, files);
0581:
0582: //
0583: //TODO: for PS7.0 don't save configuration
0584: //files. For import/export purpose, customer needs to
0585: //manually copy over config files if needed. For create
0586: //portal, desktopconfig.properties is generated with the
0587: //right token-replacement so we don't want to overwrite
0588: //it.
0589: // add portal data config files
0590: //System.setProperty(ProviderPackageContext.PSDATADIR, pDataDir);
0591:
0592: //if (m_Logger.isLoggable(Level.FINER)) {
0593: // m_Logger.logp(Level.FINER,"DesktopData",
0594: // "exportDesktop()", "backing up portal data config files from: " + pDataDir);
0595: //}
0596:
0597: //
0598: //ppctx.addDirectory(ProviderPackageContext.PSDATADIR,null,true,ProviderPackageContext.CONFIG,ExtractOp.TYPE_OTHER,null,files);
0599:
0600: }
0601:
0602: // build a backupVersion number, which is:
0603: // <domain name>;<portalName>;<backup type>;<backup
0604: // version>
0605:
0606: String backupVersion = BackupVersion.generateBackupVersion(
0607: m_Domain, m_Portal, DESKTOP);
0608:
0609: pfb = new ParFileBuilder(m_Verbose, m_Logger, backupVersion);
0610:
0611: // add the dp entry in par file, then make the par file
0612: ExtractOp op = ExtractOp.makeOpWithDPMapping(
0613: DEFAULT_ORG_KEY, dpMappings);
0614: if (m_Logger.isLoggable(Level.FINER) && op != null) {
0615: Object tokens[] = { op.toArg() };
0616: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0070", tokens);
0617: }
0618:
0619: pfb.addDPEntry(base, parDocs, files, properties, op);
0620:
0621: if (m_Logger.isLoggable(Level.FINER)) {
0622: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0071");
0623: }
0624:
0625: pfb.makeParFile(parFilePath);
0626:
0627: if (m_Logger.isLoggable(Level.FINER)) {
0628: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0063");
0629: }
0630:
0631: } catch (DesktopDataException pe) {
0632: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0072", pe);
0633: throw pe;
0634: } catch (Exception e) {
0635: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0073", e);
0636: throw new DesktopDataException(
0637: "DesktopData.exportDesktop(): " + e.getMessage(), e);
0638: } catch (Throwable t) {
0639: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0074", t);
0640: throw new DesktopDataException(
0641: "DesktopData.exportDesktop(): " + t.getMessage(), t);
0642: }
0643:
0644: }
0645:
0646: /**
0647: * Import the desktop data using the given file.
0648: *
0649: * @param backupFile The fully qualified par file
0650: * @param fsOnly <code>true</code> if only file system data is
0651: * imported.
0652: * @param cont Specify if the operation should continue executing,
0653: * for example, if some orgs/roles are missing from the target
0654: * system, continue on the operation or not.
0655: * @param searchLevel The search level is used to set the scope
0656: * when accessing to the display profile and service attribute data.
0657: */
0658: public boolean importDesktop(String parFile, boolean fsOnly,
0659: boolean dpOnly, boolean cont, String searchLevel,
0660: boolean overwrite, String dpnode, boolean skipValidation)
0661: throws DesktopDataException {
0662:
0663: if (m_Logger.isLoggable(Level.FINER)) {
0664: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0062");
0665: }
0666:
0667: boolean error = false;
0668: try {
0669: if (m_Par == null) {
0670: m_Par = ParFile.makeParFile(parFile);
0671: }
0672: error = importPar(m_Par, fsOnly, dpOnly, cont, searchLevel,
0673: overwrite, dpnode, skipValidation);
0674: } catch (DesktopDataException de) {
0675: throw de;
0676: } catch (Exception fn) {
0677: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0073", fn);
0678: throw new DesktopDataException(
0679: "DesktopData.importDesktop(): " + fn.getMessage(),
0680: fn);
0681: }
0682:
0683: if (m_Logger.isLoggable(Level.FINER)) {
0684: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0063");
0685: }
0686: return error;
0687: }
0688:
0689: /**
0690: * Internal call for restoring the desktop data from the par file.
0691: *
0692: * @param par The <code>Par</code> object.
0693: * @param fsOnly <code>true</code> if only file system data is
0694: * imported.
0695: * @param cont Specify if the operation should continue executing,
0696: * for example, if some orgs/roles are missing from the target
0697: * system, continue on the operation or not.
0698: * @param searchLevel The search level is used to set the scope
0699: * when accessing to the display profile and service attribute data.
0700: */
0701: private boolean importPar(ParFile par, boolean fsOnly,
0702: boolean dpOnly, boolean cont, String searchLevel,
0703: boolean overwrite, String dpnode, boolean skipValidation)
0704: throws DesktopDataException {
0705:
0706: // error is true if there's an error happen in
0707: // processing the import operation, AND the cont is false.
0708: // One of the error condition is that a org/role been removed and
0709: // the data can not be imported.
0710: boolean error = false;
0711:
0712: // set desktopconfig.properties file name in the system
0713: // properties, which is used by the DPBasedPPCtx.
0714: String dconfFileName = getDesktopConfigFileName();
0715: System.setProperty(ProviderPackageContext.DTPROPFILE,
0716: dconfFileName);
0717:
0718: DPHelper dpHelper = null;
0719: ParManifest pMan = par.getParManifest();
0720: String entryName = getParEntryName(pMan);
0721:
0722: try {
0723:
0724: // Import dp documents, and services
0725: if (!fsOnly) {
0726:
0727: //setup DPHelper
0728: dpHelper = DPHelper.getDPHelper(m_PCC, m_SSOToken,
0729: m_Portal);
0730:
0731: DPHelper.setLogger(m_Logger);
0732:
0733: int level = getSearchLevel(searchLevel);
0734: Vector docs = pMan.getDPEntryDPDocList(entryName);
0735: ExtractOp op = pMan.getDPEntryAutoExtract(entryName);
0736:
0737: // dpMappings contains name to dn mapping
0738: Map dpMappings = op == null ? null : op.getDPMappings();
0739:
0740: if (docs != null && (op == null || dpMappings == null)) {
0741: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0075");
0742: throw new DesktopDataException(
0743: "DesktopData.importDesktop(): Can not get AutoExtract string from par, exit");
0744: }
0745:
0746: if (m_Logger.isLoggable(Level.FINEST) && op != null) {
0747: Object tokens[] = { op.toArg() };
0748: m_Logger.log(Level.FINEST, "PSDT_CSPDAMT0070",
0749: tokens);
0750: }
0751:
0752: // if dpnode is not input from command, then take the
0753: // dpnode defined in the Manifest
0754: if (dpnode == null) {
0755: dpnode = getDPNode(op);
0756: }
0757:
0758: // Compare nodes to be imported and nodes from
0759: // the system. If any node has been removed from
0760: // the system, then the dp document will not be
0761: // imported for that node, and a warning message
0762: // will be logged.
0763: Map docsMap = null;
0764: if (docs != null) {
0765: docsMap = checkDocs(entryName, docs, dpMappings,
0766: dpnode, dpHelper, cont, level,
0767: skipValidation);
0768:
0769: if (docsMap == null) {
0770: error = true;
0771: }
0772: }
0773:
0774: Map propsMap = null;
0775: if (!dpOnly) {
0776: Vector props = pMan
0777: .getDPEntryAttrPropList(entryName);
0778: if (props != null && error == false) {
0779: propsMap = checkProps(entryName, props,
0780: dpMappings, dpnode, dpHelper, cont,
0781: level, skipValidation);
0782:
0783: if (props == null) {
0784: error = true;
0785: }
0786: }
0787: }
0788:
0789: if (!error) {
0790:
0791: String defaultOrg = m_PCC.getDefaultOrganization();
0792: if (m_Logger.isLoggable(Level.FINEST)) {
0793: Object tokens[] = { defaultOrg };
0794: m_Logger.log(Level.FINEST, "PSDT_CSPDAMT0076",
0795: tokens);
0796: }
0797:
0798: // Store dp documents into system
0799: if (docsMap != null) {
0800: Set docsKeySet = docsMap.keySet();
0801: for (Iterator i = docsKeySet.iterator(); i
0802: .hasNext();) {
0803: String nextDocKey = (String) i.next();
0804: String base = (String) docsMap
0805: .get(nextDocKey);
0806:
0807: if (m_Logger.isLoggable(Level.FINER)) {
0808: Object tokens[] = { base };
0809: m_Logger.log(Level.FINER,
0810: "PSDT_CSPDAMT0077", tokens);
0811: }
0812:
0813: Document doc = Par.streamToDom(par
0814: .getInputStream(pMan
0815: .getDPDocZip(nextDocKey)));
0816: String dp = dpHelper
0817: .generateDPDocument(doc);
0818:
0819: if (nextDocKey.equals(GLOBAL_KEY)) {
0820: if (overwrite) {
0821: dpHelper.storeGlobalDPDocument(dp);
0822: } else {
0823: dpHelper.storeCombinedDPDocument(
0824: true, base, dp);
0825: }
0826: } else {
0827: if (overwrite) {
0828: dpHelper.storeDPDocument(base, dp);
0829: } else {
0830: dpHelper.storeCombinedDPDocument(
0831: false, base, dp);
0832: }
0833: }
0834: }
0835: }
0836:
0837: // Get service attribute properties
0838: // Compare nodes to be imported and nodes from
0839: // the system. If any node has been removed from
0840: // the system, then the service attributes will not be
0841: // importd for that node, and a warning message will
0842: // be logged.
0843:
0844: if (propsMap != null && !dpOnly) {
0845: Set propsKeySet = propsMap.keySet();
0846: for (Iterator i = propsKeySet.iterator(); i
0847: .hasNext();) {
0848: String nextPropKey = (String) i.next();
0849: String base = (String) propsMap
0850: .get(nextPropKey);
0851:
0852: if (m_Logger.isLoggable(Level.FINER)) {
0853: Object tokens[] = { base };
0854: m_Logger.log(Level.FINER,
0855: "PSDT_CSPDAMT0078", tokens);
0856: }
0857:
0858: InputStream is = par.getInputStream(pMan
0859: .getPropertiesZip(nextPropKey));
0860: Properties prop = new Properties();
0861: prop.load(is);
0862: is.close();
0863:
0864: // Store service attribute values back
0865: for (Enumeration e = prop.propertyNames(); e
0866: .hasMoreElements();) {
0867: String key = (String) e.nextElement();
0868: String val = prop.getProperty(key);
0869: if (m_Logger.isLoggable(Level.FINEST)) {
0870: Object tokens[] = { key, val };
0871: m_Logger.log(Level.FINEST,
0872: "PSDT_CSPDAMT0079", tokens);
0873: }
0874: dpHelper.setServiceAttribute(base, key,
0875: val, base.equals(GLOBAL_KEY));
0876: /*
0877: if (base.equals(GLOBAL_KEY)) {
0878: dpHelper.setGlobalServiceAttribute(key, val);
0879: } else {
0880: dpHelper.setServiceAttribute(base, key, val);
0881: }
0882: */
0883: }
0884: }
0885: }
0886: }
0887: }
0888:
0889: // First delete the sub directory of templateBaseDir
0890: ParExtractionContext pex = new DPBasedExCtx(m_Verbose,
0891: m_Logger, overwrite);
0892:
0893: if (!error && !dpOnly) {
0894: // TODO: if the par only have dp and overwrite is set
0895: // to true, then templateBaseDir/communityTemplateBaseDir will be
0896: // deleted. Should we add another option for this?
0897: // Delete template files if overwrite is true
0898: /*
0899: if (overwrite) {
0900: pex.delDirectory(TEMPLATE_BASE_DIR_PROP,
0901: null, null, false);
0902: pex.delDirectory(COMMUNITY_TEMPLATE_BASE_DIR_PROP,
0903: null, null, false);
0904: }
0905: */
0906: if (m_Logger.isLoggable(Level.FINER)) {
0907: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0080");
0908: }
0909:
0910: // set system property for web-src dir
0911: String pDataDir = m_PCC.getPSDataDir() + FS
0912: + PSConfigConstants.PORTALS + FS + m_Portal;
0913: String webSrcPath = pDataDir + FS
0914: + PSConfigConstants.WEB_SRC;
0915:
0916: System.setProperty(ProviderPackageContext.STATICDIR,
0917: webSrcPath);
0918:
0919: // set system property for portal war dir
0920: String warDir = pDataDir + FS
0921: + ProviderPackageContext.WAR;
0922: System.setProperty(ProviderPackageContext.PSWARDIR,
0923: warDir);
0924:
0925: // set system property for portal data dir
0926: System.setProperty(ProviderPackageContext.PSDATADIR,
0927: pDataDir);
0928:
0929: // Store files back to templateBaseDir
0930: par.performFileExtraction(pex, entryName,
0931: ExtractOp.TYPE_OTHER);
0932: }
0933: } catch (DesktopDataException pe) {
0934: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0072", pe);
0935: throw pe;
0936: } catch (Throwable t) {
0937: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0074", t);
0938: throw new DesktopDataException(
0939: "DesktopData.importDesktop(): " + t.getMessage(), t);
0940: } finally {
0941: try {
0942: par.close();
0943: } catch (IOException ioe) {
0944: m_Logger.log(Level.SEVERE, "PSDT_CSPDAMT0081", ioe);
0945: }
0946: }
0947: return error;
0948: }
0949:
0950: /*
0951: * Gets the desktopconfig.properties file name based on the portal
0952: * name.
0953: */
0954: private String getDesktopConfigFileName() {
0955:
0956: String dtConfDir = m_PCC.getPSDataDir() + FS
0957: + PSConfigConstants.PORTALS + FS + m_Portal + FS
0958: + PSConfigConstants.CONFIG;
0959: String dtConf = dtConfDir + FS
0960: + PSConfigConstants.PS_DESKTOP_CONFIG_FILE;
0961: if (m_Logger.isLoggable(Level.FINEST)) {
0962: Object tokens[] = { dtConf };
0963: m_Logger.log(Level.FINEST, "PSDT_CSPDAMT0082", tokens);
0964: }
0965:
0966: return dtConf;
0967: }
0968:
0969: /*
0970: * Gets the par entry name from the manifest.
0971: */
0972: private String getParEntryName(ParManifest pMan)
0973: throws DesktopDataException {
0974: String entryName = null;
0975:
0976: try {
0977: Vector entries = pMan.getDPEntryList();
0978:
0979: if (entries.size() > 1) {
0980: throw new DesktopDataException(
0981: "DesktopData.getParEntryName(): wrong backup file format.");
0982: }
0983:
0984: entryName = (String) entries.iterator().next();
0985: if (m_Logger.isLoggable(Level.FINER)) {
0986: Object tokens[] = { entryName };
0987: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0083", tokens);
0988: }
0989: } catch (Exception e) {
0990: throw new DesktopDataException(
0991: "DesktopData.getParEntryName():" + e.getMessage());
0992: }
0993:
0994: return entryName;
0995: }
0996:
0997: private String getDPNode(ExtractOp op) {
0998: if (op == null) {
0999: return null;
1000: }
1001:
1002: String dpNode = op.getDPNode();
1003: if (dpNode.equals("") || dpNode.equals(DEFAULT_ORG_KEY)) {
1004: dpNode = m_PCC.getDefaultOrganization();
1005: }
1006: if (m_Logger.isLoggable(Level.FINER)) {
1007: Object tokens[] = { dpNode };
1008: m_Logger.log(Level.FINER, "PSDT_CSPDAMT0084", tokens);
1009: }
1010:
1011: return dpNode;
1012: }
1013:
1014: /*
1015: * Check if all display profile documents can be imported. Generate
1016: * a document name to dn map and return.
1017: */
1018: private Map checkDocs(String base, Vector restoreV, Map dpMappings,
1019: String dpnode, DPHelper dpHelper, boolean cont, int level,
1020: boolean skipValidation) throws DesktopDataException {
1021:
1022: Map docsMap = new HashMap();
1023: Set dpMapKeys = dpMappings.keySet();
1024: Set current = null;
1025:
1026: if (base != null && base.equals(GLOBAL_KEY)) {
1027: current = dpHelper.getAllNames(level);
1028: } else {
1029: current = dpHelper.getAllNamesFromBase(base, level, false);
1030: }
1031:
1032: try {
1033: for (Iterator i = restoreV.iterator(); i.hasNext();) {
1034: String docName = (String) i.next();
1035: String dn = null;
1036:
1037: docName = docName.substring(0, docName.indexOf("."));
1038: if (m_Logger.isLoggable(Level.FINEST)) {
1039: Object tokens[] = { docName };
1040: m_Logger.log(Level.FINEST, "PSDT_CSPDAMT0085",
1041: tokens);
1042: }
1043:
1044: if (dpMapKeys.contains(docName)) {
1045: dn = (String) dpMappings.get(docName);
1046: dn = dn.replaceFirst(ExtractOp.ARG_DPNODE, dpnode);
1047: }
1048:
1049: docName = URLDecoder.decode(docName, UTF8);
1050: if (m_Logger.isLoggable(Level.FINEST)) {
1051: Object tokens[] = { dn };
1052: m_Logger.log(Level.FINEST, "PSDT_CSPDAMT0086",
1053: tokens);
1054: }
1055:
1056: // if skipValidation is true, don't compare with the
1057: // current node, just put the docName into the map
1058: if (skipValidation) {
1059: if (docName.equals(GLOBAL_KEY)) {
1060: docsMap.put(GLOBAL_KEY, GLOBAL_KEY);
1061: } else if (dn != null) {
1062: docsMap.put(docName, dn);
1063: }
1064: } else if (!current.contains(dn)
1065: && !(docName.equals(GLOBAL_KEY))
1066: && !(docName.equals(DEFAULT_ORG_KEY))) {
1067: if (m_Logger.isLoggable(Level.WARNING)) {
1068: Object tokens[] = { dn };
1069: m_Logger.log(Level.WARNING, "PSDT_CSPDAMT0087",
1070: tokens);
1071: }
1072: if (cont == false) {
1073: if (m_Logger.isLoggable(Level.WARNING)) {
1074: m_Logger.log(Level.WARNING,
1075: "PSDT_CSPDAMT0088");
1076: }
1077: return null;
1078: }
1079: } else {
1080: if (docName.equals(GLOBAL_KEY)) {
1081: docsMap.put(GLOBAL_KEY, GLOBAL_KEY);
1082: } else if (dn != null) {
1083: docsMap.put(docName, dn);
1084: }
1085: }
1086: }
1087: } catch (Exception e) {
1088: throw new DesktopDataException(e.getMessage(), e);
1089: }
1090:
1091: return docsMap;
1092:
1093: }
1094:
1095: /*
1096: * Check if all service attributes can be imported. Generate
1097: * a property name to dn map and return.
1098: */
1099: private Map checkProps(String base, Vector restoreV,
1100: Map dpMappings, String dpnode, DPHelper dpHelper,
1101: boolean cont, int level, boolean skipValidation)
1102: throws DesktopDataException {
1103:
1104: Map propsMap = new HashMap();
1105: Set dpMapKeys = dpMappings.keySet();
1106: Set current = null;
1107:
1108: if (base != null && base.equals(GLOBAL_KEY)) {
1109: current = dpHelper.getAllNames(level);
1110: } else {
1111: current = dpHelper.getAllNamesFromBase(base, level, false);
1112: }
1113:
1114: try {
1115: for (Iterator i = restoreV.iterator(); i.hasNext();) {
1116: String key = (String) i.next();
1117: String dn = null;
1118:
1119: key = key.substring(0, key.indexOf("."));
1120: if (m_Logger.isLoggable(Level.FINEST)) {
1121: Object tokens[] = { key };
1122: m_Logger.log(Level.FINEST, "PSDT_CSPDAMT0089",
1123: tokens);
1124: }
1125:
1126: if (dpMapKeys.contains(key)) {
1127: dn = (String) dpMappings.get(key);
1128: dn = dn.replaceFirst(ExtractOp.ARG_DPNODE, dpnode);
1129: if (m_Logger.isLoggable(Level.FINEST)) {
1130: Object tokens[] = { dn };
1131: m_Logger.log(Level.FINEST, "PSDT_CSPDAMT0090",
1132: tokens);
1133: }
1134: }
1135:
1136: key = (URLDecoder.decode(key, UTF8));
1137: // if skipValidation is true, don't compare with the
1138: // current node, just put the key into the map
1139: if (skipValidation) {
1140: if (key.equals(GLOBAL_KEY)) {
1141: propsMap.put(GLOBAL_KEY, GLOBAL_KEY);
1142: } else if (dn != null) {
1143: propsMap.put(key, dn);
1144: }
1145: } else if (!current.contains(dn)
1146: && !(key.equals(GLOBAL_KEY))
1147: && !(key.equals(DEFAULT_ORG_KEY))) {
1148: if (m_Logger.isLoggable(Level.WARNING)) {
1149: Object tokens[] = { dn };
1150: m_Logger.log(Level.WARNING, "PSDT_CSPDAMT0091",
1151: tokens);
1152: }
1153: if (cont == false) {
1154: if (m_Logger.isLoggable(Level.WARNING)) {
1155: m_Logger.log(Level.WARNING,
1156: "PSDT_CSPDAMT0088");
1157: }
1158: return null;
1159: }
1160: } else {
1161: if (key.equals(GLOBAL_KEY)) {
1162: propsMap.put(GLOBAL_KEY, GLOBAL_KEY);
1163: } else if (dn != null) {
1164: propsMap.put(key, dn);
1165: }
1166: }
1167: }
1168: } catch (Exception e) {
1169: throw new DesktopDataException(e.getMessage(), e);
1170: }
1171:
1172: return propsMap;
1173: }
1174:
1175: private int getSearchLevel(String searchLevel) {
1176: int level = SEARCH_LEVEL;
1177:
1178: try {
1179: if (searchLevel != null) {
1180: level = Integer.parseInt(searchLevel);
1181: if (level < 0) {
1182: level = SEARCH_LEVEL;
1183: }
1184: }
1185: } catch (NumberFormatException ne) {
1186: //use default value
1187: }
1188: return level;
1189: }
1190:
1191: }
|