0001: /*
0002: * Copyright 2004 Sun Microsystems, Inc. All
0003: * rights reserved. Use of this product is subject
0004: * to license terms. Federal Acquisitions:
0005: * Commercial Software -- Government Users
0006: * Subject to Standard License Terms and
0007: * Conditions.
0008: *
0009: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
0010: * are trademarks or registered trademarks of Sun Microsystems,
0011: * Inc. in the United States and other countries.
0012: */
0013: package com.sun.portal.taskadmin;
0014:
0015: import java.util.Collections;
0016: import java.util.Collection;
0017: import java.util.List;
0018: import java.util.Arrays;
0019: import java.util.ArrayList;
0020: import java.util.Iterator;
0021: import java.util.Map;
0022: import java.util.HashMap;
0023: import java.util.Set;
0024: import java.util.HashSet;
0025: import java.util.TreeSet;
0026: import java.util.StringTokenizer;
0027: import java.util.regex.Matcher;
0028: import java.util.regex.Pattern;
0029: import java.util.regex.PatternSyntaxException;
0030: import java.util.Locale;
0031: import java.util.ResourceBundle;
0032: import java.util.logging.Logger;
0033: import java.util.logging.Level;
0034: import java.util.logging.LogRecord;
0035:
0036: import java.net.URL;
0037: import java.net.MalformedURLException;
0038: import java.io.BufferedReader;
0039: import java.io.InputStreamReader;
0040:
0041: import javax.servlet.http.HttpServletRequest;
0042: import javax.servlet.http.HttpServletResponse;
0043:
0044: import com.iplanet.sso.SSOToken;
0045:
0046: import com.sun.portal.taskadmin.TaskAdminException;
0047: import com.sun.portal.taskadmin.TaskAdminConstants;
0048: import com.sun.portal.taskadmin.context.ChannelTaskAdminContext;
0049: import com.sun.portal.taskadmin.context.TaskAdminContextFactoryManager;
0050: import com.sun.portal.taskadmin.context.DPRootCacheManager;
0051:
0052: import com.sun.portal.desktop.context.ContextError;
0053: import com.sun.portal.desktop.context.AdminDPContext;
0054: import com.sun.portal.desktop.dp.DPTypes;
0055: import com.sun.portal.desktop.dp.DPRoot;
0056: import com.sun.portal.desktop.dp.DPNode;
0057: import com.sun.portal.desktop.dp.DPChannel;
0058: import com.sun.portal.desktop.dp.DPContainerChannel;
0059: import com.sun.portal.desktop.dp.DPProvider;
0060: import com.sun.portal.desktop.dp.DPProperties;
0061: import com.sun.portal.desktop.dp.DPProperty;
0062: import com.sun.portal.desktop.dp.DPCollection;
0063: import com.sun.portal.desktop.dp.DPString;
0064: import com.sun.portal.desktop.dp.DPInteger;
0065: import com.sun.portal.desktop.dp.DPBoolean;
0066: import com.sun.portal.desktop.dp.DPError;
0067: import com.sun.portal.desktop.dp.xml.XMLDPFactory;
0068: import com.sun.portal.desktop.dp.xml.XMLDPRoot;
0069:
0070: import com.sun.portal.providers.containers.ContainerProvider;
0071: import com.sun.portal.providers.containers.jsp.tab.JSPTabContainerProvider;
0072: import com.sun.portal.log.common.PortalLogger;
0073:
0074: import com.sun.portal.admin.common.DesktopConstants;
0075:
0076: import com.sun.portal.util.ResourceLoader;
0077:
0078: import com.sun.portal.providers.context.PropertiesFilter;
0079: import com.sun.portal.providers.context.ClientPropertiesFilter;
0080: import com.sun.portal.providers.context.LocalePropertiesFilter;
0081: import com.sun.portal.providers.context.PropertiesFilterException;
0082: import com.sun.portal.providers.context.PropertiesFilterFactory;
0083:
0084: /**
0085: * This class implements the APIs that can be used
0086: * to achieve a set of administrative tasks associated
0087: * with channels/containers.
0088: */
0089: public class ChannelTaskAdmin implements TaskAdminConstants {
0090: protected static String PORTLET_CLASS = "PortletWindowProvider";
0091: protected static String REMOTE_PORTLET_CLASS = "WSRPWindowProvider";
0092: private static final String WILD_CARD = "*";
0093: private static final String REPLACEMENT_STRING = ".*";
0094: private static final String DP_PRIORITY_USER = "user";
0095: private static final String DP_PRIORITY_NOT_SET = "Not Yet Set";
0096:
0097: private Map dpRoots = null;
0098:
0099: private boolean canViewDTAttributes = true;
0100: private static Logger logger = PortalLogger
0101: .getLogger(ChannelTaskAdmin.class);
0102: protected ChannelTaskAdminContext context = null;
0103: protected AdminDPContext dpContext = null;
0104: protected boolean dpRootMerged = true;
0105: protected boolean dpDocExists = false;
0106:
0107: protected DPRoot dpRoot = null;
0108: protected String baseDN = null;
0109: /**
0110: * Channel Name Seaparator used for nested channel names.
0111: */
0112: public static String CHANNEL_NAME_SEPARATOR = String
0113: .valueOf(DPNode.CHANNEL_NAME_SEPARATOR);
0114: public static String COLLECTION_NAME_SEPARATOR = "|";
0115: public static String CLIENT_SEPARATOR = "/";
0116: public static short STRING_DP = DPTypes.STRING_DP;
0117: public static short INTEGER_DP = DPTypes.INTEGER_DP;
0118: public static short BOOLEAN_DP = DPTypes.BOOLEAN_DP;
0119: public static short COLLECTION_DP = DPTypes.COLLECTION_DP;
0120: public static short CONDITIONAL_DP = DPTypes.CONDITIONALPROPERTIES_DP;
0121: public static short LOCALE_DP = DPTypes.LOCALE_DP;
0122: public static short UNKNOWN_DP = DPTypes.UNKNOWN_DP;
0123:
0124: /**
0125: * Name of a conditional property is derived by DPAPI from its condition
0126: * and value and is prefixed by this string.
0127: */
0128: String CONDITIONAL_PREFIX = "_conditional_";
0129:
0130: private String portalId = null;
0131:
0132: private Set mergers = null;
0133:
0134: protected static final Object dpLock = new Object();
0135:
0136: public ChannelTaskAdmin(HttpServletRequest req, String baseDN)
0137: throws TaskAdminException {
0138: try {
0139: context = TaskAdminContextFactoryManager
0140: .getChannelTaskAdminFactory()
0141: .getChannelTaskAdminContext(req);
0142: dpContext = context.getDPContext();
0143: if (!dpContext.isGlobal(baseDN)) {
0144: mergers = dpContext.getDPDocumentNames(baseDN);
0145: }
0146: //set canViewDTAttributes flag
0147: canViewDTAttributes = context.canViewDTAttributes();
0148: portalId = ResourceLoader.getInstance(
0149: System.getProperties()).getPortalId();
0150: dpRoots = DPRootCacheManager
0151: .getDPRootMapFromCache(portalId);
0152: dpRoot = getDPRootByDN(baseDN);
0153: this .baseDN = baseDN;
0154: } catch (ContextError ce) {
0155: throw new TaskAdminException(
0156: "ChannelTaskAdmin():Unable to intialize taskadmincontext",
0157: ce);
0158: }
0159: }
0160:
0161: //This constructor can be called from inside an MBean.
0162: public ChannelTaskAdmin(SSOToken ssoToken, String baseDN,
0163: String portalId) throws TaskAdminException {
0164: init(ssoToken, baseDN, portalId, true, true);
0165: }
0166:
0167: public ChannelTaskAdmin(SSOToken ssoToken, String baseDN,
0168: String portalId, boolean resetData)
0169: throws TaskAdminException {
0170: init(ssoToken, baseDN, portalId, true, resetData);
0171: }
0172:
0173: /**
0174: * This constructor can be called from inside an MBean and it constructs
0175: * dpRoot without mergers. It is useful for removeCustomization kind of
0176: * operations
0177: */
0178: public ChannelTaskAdmin(SSOToken ssoToken, String baseDN,
0179: String portalId, boolean merge, boolean resetData)
0180: throws TaskAdminException {
0181: init(ssoToken, baseDN, portalId, merge, resetData);
0182: }
0183:
0184: public void init(SSOToken ssoToken, String baseDN, String portalId,
0185: boolean merge, boolean resetData) throws TaskAdminException {
0186: try {
0187: context = TaskAdminContextFactoryManager
0188: .getChannelTaskAdminFactory()
0189: .getChannelTaskAdminContext(ssoToken, portalId);
0190: dpContext = context.getDPContext();
0191: if (!dpContext.isGlobal(baseDN)) {
0192: mergers = dpContext.getDPDocumentNames(baseDN);
0193: }
0194: //set canViewDTAttributes flag
0195: canViewDTAttributes = context.canViewDTAttributes();
0196: this .portalId = portalId;
0197: dpRoots = DPRootCacheManager
0198: .getDPRootMapFromCache(portalId);
0199: dpRoot = getDPRootByDN(baseDN, merge, resetData);
0200: this .baseDN = baseDN;
0201: logger.log(Level.FINEST, "portalId=" + portalId);
0202: logger.log(Level.FINEST, "baseDN=" + baseDN);
0203: } catch (ContextError ce) {
0204: throw new TaskAdminException(
0205: "ChannelTaskAdmin():Unable to intialize taskadmincontext",
0206: ce);
0207: }
0208:
0209: }
0210:
0211: /*
0212: * warning: any method that reads/write to the persistent store wont work
0213: * for instance that is created through this constructor.
0214: * This is added to do the in-memory manipulation of the DPRoot content.
0215: * that is passed here in as an argument.
0216: */
0217: public ChannelTaskAdmin(HttpServletRequest req, DPRoot someDPRoot)
0218: throws TaskAdminException {
0219: try {
0220: //set canViewDTAttributes flag
0221: dpRoot = someDPRoot;
0222: //hardcoded for community for use in debug messages.
0223: this .portalId = "notset";
0224: this .baseDN = "notset";
0225: context = null;
0226: dpContext = null;
0227: } catch (ContextError ce) {
0228: throw new TaskAdminException(
0229: "ChannelTaskAdmin():Unable to intialize taskadmincontext",
0230: ce);
0231: }
0232: }
0233:
0234: /*
0235: * warning: any method that reads/write to the persistent store wont work
0236: * for instance that is created through this constructor.
0237: * This is added to do the in-memory manipulation of the DPRoot content.
0238: * that is passed here in as an argument.
0239: */
0240: public ChannelTaskAdmin(SSOToken token, DPRoot someDPRoot)
0241: throws TaskAdminException {
0242: try {
0243: //set canViewDTAttributes flag
0244: dpRoot = someDPRoot;
0245: //hardcoded for community for use in debug messages.
0246: this .portalId = "notset";
0247: this .baseDN = "notset";
0248: context = null;
0249: dpContext = null;
0250: } catch (ContextError ce) {
0251: throw new TaskAdminException(
0252: "ChannelTaskAdmin():Unable to intialize taskadmincontext",
0253: ce);
0254: }
0255: }
0256:
0257: private void resetModified(boolean clear) {
0258: dpRoots = DPRootCacheManager.getDPRootMapFromCache(portalId);
0259: if (clear) {
0260: dpRoots.clear();
0261: DPRootCacheManager.updateDPRootCache(portalId, dpRoots);
0262: }
0263: for (Iterator i = dpRoots.keySet().iterator(); i.hasNext();) {
0264: String name = (String) i.next();
0265: long lastRead = dpContext.getDPDocumentLastRead(name);
0266: long lastModified = dpContext
0267: .getDPDocumentLastModified(name);
0268: logger.log(Level.FINEST, "PSDT_CSPT0001", new Object[] {
0269: name, lastRead + "" });
0270: logger.log(Level.FINEST, "PSDT_CSPT0002", new Object[] {
0271: name, lastModified + "" });
0272: if (lastRead == -1 || lastModified > lastRead) {
0273: logger.log(Level.FINEST, "PSDT_CSPT0003",
0274: new Object[] { name });
0275: clear = true;
0276: break;
0277: }
0278: }
0279: if (clear) {
0280: dpRoots.clear();
0281: DPRootCacheManager.updateDPRootCache(portalId, dpRoots);
0282: }
0283: }
0284:
0285: protected DPRoot getDPRootByDN(String baseDN)
0286: throws TaskAdminException {
0287: return getDPRootByDN(baseDN, true, true);
0288: }
0289:
0290: protected DPRoot getDPRootByDN(String baseDN, boolean merge,
0291: boolean resetData) throws TaskAdminException {
0292: //logger.log(Level.FINEST, "Getting dproot for portalId " + portalId + " and baseDN " + baseDN);
0293: DPRoot dpRoot = null;
0294: try {
0295: synchronized (dpLock) {
0296: boolean clearDPRoots = false;
0297: long lastRead = dpContext.getDPDocumentLastRead(baseDN);
0298: long lastModified = dpContext
0299: .getDPDocumentLastModified(baseDN);
0300: logger.log(Level.FINEST, "PSDT_CSPT0001", new Object[] {
0301: baseDN, lastRead + "" });
0302: logger.log(Level.FINEST, "PSDT_CSPT0002", new Object[] {
0303: baseDN, lastModified + "" });
0304: if (lastRead != -1 && lastModified > lastRead) {
0305: if (!resetData) {
0306: logger.log(Level.FINEST, "PSDT_CSPT0003",
0307: new Object[] { baseDN });
0308: Object[] tokens = { baseDN };
0309: throw new TaskAdminException(
0310: DP_MODIFIED_BEFORE_STORE,
0311: "DisplayProfile was modified by another user",
0312: tokens);
0313: } else {
0314: clearDPRoots = true;
0315: }
0316: } else if (lastRead == -1) {
0317: clearDPRoots = true;
0318: }
0319: // check if the key is "_!global!_"
0320: if (dpContext.isGlobal(baseDN)) {
0321: resetModified(clearDPRoots);
0322: String doc = dpContext.getGlobalDPDocument();
0323: if (doc != null && doc.length() > 0) {
0324: dpDocExists = true;
0325: }
0326: if (dpRoots.containsKey(baseDN)) {
0327: dpRoot = (DPRoot) dpRoots.get(baseDN);
0328: } else {
0329: dpRoot = XMLDPFactory.getInstance().createRoot(
0330: dpContext, doc);
0331: dpRoots.put(baseDN, dpRoot);
0332: DPRootCacheManager.updateDPRootCache(portalId,
0333: dpRoots);
0334: }
0335: } else if (!merge) {
0336: dpRootMerged = false;
0337: resetModified(clearDPRoots);
0338: String doc = dpContext.getDPDocument(baseDN);
0339: if (doc != null && doc.length() > 0) {
0340: dpDocExists = true;
0341: }
0342: dpRoot = XMLDPFactory.getInstance().createRoot(
0343: dpContext, doc);
0344: } else {
0345: resetModified(clearDPRoots);
0346: String doc = dpContext.getDPDocument(baseDN);
0347: if (doc != null && doc.length() > 0) {
0348: dpDocExists = true;
0349: }
0350: dpRoot = XMLDPFactory.getInstance().createRoot(
0351: dpContext, baseDN, dpRoots);
0352: DPRootCacheManager.updateDPRootCache(portalId,
0353: dpRoots);
0354: }
0355: Set DNs = new HashSet();
0356: if (mergers != null) {
0357: DNs.addAll(mergers);
0358: }
0359: DNs.add(baseDN);
0360: DPRootCacheManager.markDNAsRecentlyAccessed(portalId,
0361: DNs, context.getSessionID());
0362: }
0363: } catch (DPError dpe) {
0364: // error key for invalid baseDN
0365: if (logger.isLoggable(Level.INFO)) {
0366: LogRecord record = new LogRecord(Level.INFO,
0367: "PSDT_CSPT0004");
0368: record.setLoggerName(logger.getName());
0369: record.setParameters(new Object[] { baseDN });
0370: record.setThrown(dpe);
0371: logger.log(record);
0372: }
0373: Object[] tokens = { baseDN, dpe.getMessage() };
0374: throw new TaskAdminException(INVALID_BASEDN, dpe
0375: .getMessage(), tokens);
0376: }
0377:
0378: //logger.log(Level.FINEST, "returning dproot " + dpRoot);
0379: return dpRoot;
0380: }
0381:
0382: public String getRoleName(String roleDN) {
0383: return context.DNToName(roleDN);
0384: }
0385:
0386: /**
0387: * This method returns the list of baseDNs that
0388: * the user in session can administer.
0389: */
0390: public Set getBaseDNs() {
0391: return context.getBaseDNs();
0392: }
0393:
0394: public ResourceBundle getResourceBundle() {
0395: Locale locale = context.getLocale();
0396: return ResourceBundle.getBundle(
0397: TaskAdminConstants.RESOURCE_BUNDLE_FILE, locale,
0398: getClass().getClassLoader());
0399: }
0400:
0401: /**
0402: * Creates a new channel.
0403: * A new channel is created based on the named provider.
0404: * To create a nested channel, supply a hierarchical channel
0405: * name. For example, to create channel A inside of container X, based on
0406: * provider P:<br><br>
0407: * <code>createChannel("X" + "/" + "A", "P");</code>
0408: */
0409: public void createChannel(String channelName, String providerName)
0410: throws TaskAdminException {
0411: if (channelName == null || channelName.trim().length() == 0) {
0412: Object[] tokens = {};
0413: throw new TaskAdminException(NULL_CHANNEL_NAME,
0414: "channelName passed in is null", tokens);
0415: }
0416: logger.log(Level.FINEST, "PSDT_CSPT0005",
0417: new Object[] { channelName });
0418: synchronized (dpLock) {
0419: if (existsChannel(channelName)) {
0420: //error key for already existent channel
0421: logger.log(Level.FINE, "PSDT_CSPT0006",
0422: new Object[] { channelName });
0423: Object[] tokens = { channelName };
0424: throw new TaskAdminException(CHANNEL_EXISTS,
0425: "Channel already exists", tokens);
0426: }
0427: if (!existsProvider(providerName)) {
0428: // error key for non-existent provider.
0429: logger.log(Level.FINE, "PSDT_CSPT0007",
0430: new Object[] { providerName });
0431: Object[] tokens = { providerName };
0432: throw new TaskAdminException(INVALID_PROVIDER,
0433: "Provider does not exist", tokens);
0434: }
0435: DPChannel newChannel = dpRoot.createChannel(channelName,
0436: providerName);
0437: // make the merge type "replace" instead of the default "fuse"
0438: newChannel.setMergeType(DPTypes.MERGE_REPLACE);
0439: }
0440:
0441: }
0442:
0443: /**
0444: * Creates a new container.
0445: * A new container is created based on the named provider.
0446: * To create a nested container, supply a hierarchical container
0447: * name. For example, to create container A inside of container X, based on
0448: * provider P :<br><br>
0449: * <code>createContainer("X" + "/" + "A", "P");</code>
0450: */
0451: public void createContainer(String channelName, String providerName)
0452: throws TaskAdminException {
0453: if (channelName == null || channelName.trim().length() == 0) {
0454: Object[] tokens = {};
0455: throw new TaskAdminException(NULL_CHANNEL_NAME,
0456: "ChannelName passed in is null", tokens);
0457: }
0458: logger.log(Level.FINEST, "PSDT_CSPT0011", channelName);
0459: synchronized (dpLock) {
0460: if (existsChannel(channelName)) {
0461: // error key for already existent channel
0462: logger.log(Level.FINE, "PSDT_CSPT0012", channelName);
0463: Object[] tokens = { channelName };
0464: throw new TaskAdminException(CHANNEL_EXISTS,
0465: "Container already exists: " + channelName,
0466: tokens);
0467: }
0468: if (!existsProvider(providerName)) {
0469: logger.log(Level.FINE, "PSDT_CSPT0013", providerName);
0470: Object[] tokens = { providerName };
0471: throw new TaskAdminException(INVALID_PROVIDER,
0472: "Provider does not exist: " + providerName,
0473: tokens);
0474: }
0475: logger.log(Level.FINEST, "PSDT_CSPT0014", providerName);
0476: DPContainerChannel newChannel = dpRoot
0477: .createContainerChannel(channelName, providerName);
0478: // make the merge type "replace" instead of the default "fuse"
0479: newChannel.setMergeType(DPTypes.MERGE_REPLACE);
0480: }
0481: }
0482:
0483: /**
0484: * Deletes a channel/container.
0485: * To delete a nested channel/container, supply parent name.
0486: * For example, to delete channel A inside
0487: * of container X:<br><br>
0488: * <code>deleteChannel("A", "X");</code>
0489: */
0490: public void deleteChannel(String channelName, String parentcontainer)
0491: throws TaskAdminException {
0492: DPNode dpNode = null;
0493: String fQCN = null;
0494: logger.log(Level.FINEST, "PSDT_CSPT0015", channelName);
0495: if (parentcontainer != null && parentcontainer.length() != 0) {
0496:
0497: logger.log(Level.FINEST, "PSDT_CSPT0016", new Object[] {
0498: channelName, parentcontainer });
0499: dpNode = getDPContainerChannel(parentcontainer);
0500: fQCN = toFullyQualifiedName(dpNode, channelName);
0501: } else {
0502: dpNode = dpRoot;
0503: fQCN = channelName;
0504: }
0505: synchronized (dpLock) {
0506: //check if channel exists at this baseDN
0507: if (!existsChannel(fQCN)) {
0508: // error key for non-existent channel
0509: logger.log(Level.FINE, "PSDT_CSPT0017", channelName);
0510: Object[] tokens = { fQCN };
0511: throw new TaskAdminException(INVALID_CHANNEL,
0512: "Channel does not exists: " + channelName,
0513: tokens);
0514: }
0515: try {
0516: DPChannel channel = dpNode.removeChannel(channelName);
0517: } catch (DPError dpe) {
0518: if (logger.isLoggable(Level.FINE)) {
0519: LogRecord record = new LogRecord(Level.FINE,
0520: "PSDT_CSPT0018");
0521: record.setLoggerName(logger.getName());
0522: record.setParameters(new Object[] { channelName });
0523: record.setThrown(dpe);
0524: logger.log(record);
0525: }
0526: Object[] tokens = { fQCN };
0527: throw new TaskAdminException(DELETE_CHANNEL_ERROR, dpe
0528: .getMessage(), tokens);
0529: }
0530: // remove channel references from DP documents.
0531: }
0532: removeReferences(dpRoot, fQCN);
0533: }
0534:
0535: private void removeReferences(DPNode node, String channelName)
0536: throws TaskAdminException {
0537: Set channelNames = null;
0538: synchronized (dpLock) {
0539: channelNames = node.getChannelNames();
0540: }
0541: Iterator iterator = channelNames.iterator();
0542: while (iterator.hasNext()) {
0543: String channel = (String) iterator.next();
0544: DPChannel dpChannel = null;
0545: synchronized (dpLock) {
0546: dpChannel = node.getChannel(channel);
0547: }
0548: if (dpChannel instanceof DPContainerChannel) {
0549: DPContainerChannel container = (DPContainerChannel) dpChannel;
0550: removeReferences(container, channelName);
0551: Set available = null;
0552: synchronized (dpLock) {
0553: available = container.getAvailable().getNames();
0554: }
0555: if (available.contains(channelName)) {
0556: available.remove(channelName);
0557: synchronized (dpLock) {
0558: container
0559: .setAvailable(new ArrayList(available));
0560: }
0561: }
0562: Set selected = null;
0563: synchronized (dpLock) {
0564: selected = container.getSelected().getNames();
0565: }
0566: if (selected.contains(channelName)) {
0567: selected.remove(channelName);
0568: synchronized (dpLock) {
0569: container.setSelected(new ArrayList(selected));
0570: }
0571: }
0572: }
0573: }
0574:
0575: }
0576:
0577: /**
0578: * This method returns the list of channels that are existing
0579: * at the baseDN. The channels in this list
0580: * can be modifiable or deleted by the user that can administer
0581: * the baseDN.
0582: * This method returns the list of channels which includes
0583: * the channels defined at the baseDN that is passed in, channels
0584: * defined inside the containers that are defined at the baseDN.
0585: * if specified all, all the channels from the merged list is returned.
0586: * @param all all the channels from mergers
0587: * @return Set of channels that are available at this baseDN.
0588: */
0589: public Set getExistingChannels(boolean all)
0590: throws TaskAdminException {
0591: DPNode currentNode = dpRoot;
0592: Set result = new TreeSet();
0593: Set channelNames = getChannelNames(currentNode);
0594: Iterator iterator = channelNames.iterator();
0595:
0596: while (iterator.hasNext()) {
0597: String channelName = (String) iterator.next();
0598: logger.log(Level.FINEST, "PSDT_CSPT0019", channelName);
0599: if (!isDisplayable(channelName)) {
0600: continue;
0601: }
0602: // if all channels requested returns everything.
0603: // else evaluate the ones defined at this baseDN.
0604: if (!all) {
0605: //check if the ones defined at this baseDN are in mergers
0606: //or the flag is false.
0607: if (!canAccess(channelName)) {
0608: continue;
0609: }
0610: }
0611: DPChannel channel = getDPChannel(channelName);
0612: //check if this channel is a container and if it is get
0613: // the list of channels defined in the container
0614: if (channel instanceof DPContainerChannel) {
0615: // get the list for this container baseDN.
0616: result.addAll(getChannelsInContainer(channel, all,
0617: false));
0618: } else {
0619: result.add(channelName);
0620: }
0621: }
0622: return result;
0623:
0624: }
0625:
0626: /**
0627: * This method returns the list of channels that match the
0628: * search string. The search is done on the list of channels
0629: * that is returned from the getExistingChannels.
0630: * at the baseDN that is passed in. The channels in this list
0631: * can be modifiable or deleted by the user that can administer
0632: * the baseDN that is passed in.
0633: * This method returns the list of channels which includes
0634: * the channels defined at the baseDN that is passed in, channels
0635: * defined inside the containers that are defined at the baseDN.
0636: * @param all flag that specifies take mergers into account.
0637: * @return Set of channels that are available at this baseDN.
0638: */
0639: public Set getExistingChannels(boolean all, String regExp)
0640: throws TaskAdminException {
0641: Set allChannels = getExistingChannels(all);
0642: logger.log(Level.FINEST, "PSDT_CSPT0020", regExp);
0643: if (regExp != null && regExp.equals(WILD_CARD)) {
0644: return allChannels;
0645: }
0646: Set filteredChannels = searchString(regExp, allChannels);
0647: return filteredChannels;
0648: }
0649:
0650: /**
0651: * This method returns the list of containers that are existing
0652: * at the baseDN that is passed in. The containers in this list
0653: * can be modifiable or deleted by the user that can administer
0654: * the baseDN that is passed in.
0655: * This method returns the list of containers which includes
0656: * the containers defined at the baseDN that is passed in, containers
0657: * defined inside the containers that are defined at the baseDN.
0658: * if specified all, all the containers from the merged list is returned.
0659: * @param all all the channels from mergers
0660: * @return Set of channels that are available at this baseDN.
0661: */
0662: public Set getExistingContainers(boolean all)
0663: throws TaskAdminException {
0664: DPNode currentNode = dpRoot;
0665: Set result = new TreeSet();
0666: Set containerNames = getChannelNames(currentNode);
0667: Iterator iterator = containerNames.iterator();
0668:
0669: while (iterator.hasNext()) {
0670: String channelName = (String) iterator.next();
0671: logger.log(Level.FINEST, "PSDT_CSPT0021", channelName);
0672: if (!isDisplayable(channelName)) {
0673: continue;
0674: }
0675: // if all channels requested returns everything.
0676: // else evaluate the ones defined at this baseDN.
0677: if (!all) {
0678: //check if the ones defined at this baseDN are in mergers
0679: //or the flag is false.
0680: if (!canAccess(channelName)) {
0681: continue;
0682: }
0683: }
0684: DPChannel channel = getDPChannel(channelName);
0685: //check if this channel is a container and if it is get
0686: // the list of channels defined in the container
0687: if (channel instanceof DPContainerChannel) {
0688: result.add(channelName);
0689: // get the list for this container baseDN.
0690: result
0691: .addAll(getChannelsInContainer(channel, all,
0692: true));
0693: }
0694: }
0695: return result;
0696:
0697: }
0698:
0699: /**
0700: * This method returns the list of containers that match the
0701: * search string. The search is done on the list of containers
0702: * that is returned from the getExistingContainers.
0703: * at the baseDN that is passed in. The containerls in this list
0704: * can be modifiable or deleted by the user that can administer
0705: * the baseDN that is passed in.
0706: * This method returns the list of containers which includes
0707: * the containers defined at the baseDN that is passed in, containers
0708: * defined inside the containers that are defined at the baseDN.
0709: * @param all flag that specifies take mergers into account.
0710: * @return Set of channels that are available at this baseDN.
0711: */
0712: public Set getExistingContainers(boolean all, String regExp)
0713: throws TaskAdminException {
0714: Set allContainers = getExistingContainers(all);
0715: logger.log(Level.FINEST, "PSDT_CSPT0022", regExp);
0716: if (regExp != null && regExp.equals(WILD_CARD)) {
0717: return allContainers;
0718: }
0719: Set filteredChannels = searchString(regExp, allContainers);
0720: return filteredChannels;
0721: }
0722:
0723: /**
0724: * This method returns the recursive list of channels defined in a container.
0725: */
0726: private Set getChannelsInContainer(DPChannel container,
0727: boolean all, boolean onlyContainers)
0728: throws TaskAdminException {
0729: DPNode currentNode = container;
0730: Set result = new TreeSet();
0731: Set channelNames = getChannelNames(currentNode);
0732: Iterator iterator = channelNames.iterator();
0733:
0734: while (iterator.hasNext()) {
0735: String channelName = (String) iterator.next();
0736: logger.log(Level.FINEST, "PSDT_CSPT0023", channelName);
0737: String fQCN = toFullyQualifiedName(currentNode, channelName);
0738:
0739: if (!isDisplayable(fQCN)) {
0740: continue;
0741: }
0742: // if all channels requested returns everything.
0743: // else evaluate the ones defined at this baseDN.
0744: if (!all) {
0745: //check if the ones defined at this baseDN are in mergers
0746: //or the flag is false.
0747: if (!canAccess(fQCN)) {
0748: continue;
0749: }
0750: }
0751: DPChannel channel = null;
0752: synchronized (dpLock) {
0753: channel = currentNode.getChannel(channelName);
0754: }
0755: //check if this channel is a container and if it is get
0756: // the list of channels defined in the container
0757: if (channel instanceof DPContainerChannel) {
0758: if (onlyContainers) {
0759: result.add(fQCN);
0760: }
0761: // get the list for this container baseDN.
0762: result.addAll(getChannelsInContainer(channel, all,
0763: onlyContainers));
0764: } else if (!onlyContainers) {
0765: result.add(fQCN);
0766: }
0767: }
0768: return result;
0769:
0770: }
0771:
0772: /**
0773: * This method returns the list of providers that are existing
0774: * at the baseDN that is passed in. The providers in this list
0775: * can be used to create channels by the user that can administer
0776: * the baseDN that is passed in. Always takes mergers into account.
0777: * @return Set of providers that are available at this baseDN.
0778: */
0779: public Set getExistingProviders() throws TaskAdminException {
0780: return getProviders(false);
0781: }
0782:
0783: /**
0784: * This method returns the list of containerproviders that are existing
0785: * at the baseDN that is passed in. The containerproviders in this list
0786: * can be used to create container channels by the user that can administer
0787: * the baseDN that is passed in. Always takes mergers into account.
0788: * @return Set of containerproviders that are available at this baseDN.
0789: */
0790: public Set getExistingContainerProviders()
0791: throws TaskAdminException {
0792: return getProviders(true);
0793: }
0794:
0795: private Set getProviders(boolean containerproviders)
0796: throws TaskAdminException {
0797: DPNode currentNode = dpRoot;
0798: Set result = new TreeSet();
0799: Set providerNames = getProviderNames(currentNode);
0800: Iterator iterator = providerNames.iterator();
0801:
0802: while (iterator.hasNext()) {
0803: String providerName = (String) iterator.next();
0804: logger.log(Level.FINEST, "PSDT_CSPT0024", providerName);
0805: DPProvider provider = null;
0806: synchronized (dpLock) {
0807: provider = currentNode.getProvider(providerName);
0808: }
0809: if (!providerName.startsWith("_") && provider != null) {
0810: String className = null;
0811: synchronized (dpLock) {
0812: className = provider.getClassName();
0813: }
0814: boolean isContainerProvider = false;
0815: if (context.getProviderClassLoader() != null) {
0816: try {
0817: Class providerClass = context
0818: .getProviderClassLoader().loadClass(
0819: className);
0820: isContainerProvider = ContainerProvider.class
0821: .isAssignableFrom(providerClass);
0822: } catch (ClassNotFoundException cne) {
0823: if (logger.isLoggable(Level.INFO)) {
0824: LogRecord record = new LogRecord(
0825: Level.INFO, "PSDT_CSPT0025");
0826: record.setLoggerName(logger.getName());
0827: record.setThrown(cne);
0828: record
0829: .setParameters(new Object[] { providerName });
0830: logger.log(record);
0831: }
0832: if (provider.isContainer()) {
0833: isContainerProvider = true;
0834: }
0835: }
0836: } else if (provider.isContainer()) {
0837: isContainerProvider = true;
0838: }
0839: if ((containerproviders && isContainerProvider)
0840: || (!containerproviders && !isContainerProvider)) {
0841: result.add(providerName);
0842: }
0843: }
0844: }
0845: return result;
0846: }
0847:
0848: /**
0849: * This method returns the classname of the provider
0850: * that this channel is based on. It returns null if the provider
0851: * for the given channel name doesn't exists.
0852: */
0853: public String getClassName(String channelname)
0854: throws TaskAdminException {
0855: DPChannel channel = getDPChannel(channelname);
0856: String classname = null;
0857: synchronized (dpLock) {
0858: DPProvider provider = channel.getProvider();
0859: if (provider != null) {
0860: classname = provider.getClassName();
0861: }
0862: }
0863: return classname;
0864: }
0865:
0866: public boolean isContainer(String channelName)
0867: throws TaskAdminException {
0868: DPChannel channel = getDPChannel(channelName);
0869: if (channel instanceof DPContainerChannel) {
0870: return true;
0871: } else {
0872: return false;
0873: }
0874: }
0875:
0876: public boolean isTabContainer(String channelName)
0877: throws TaskAdminException {
0878: boolean isTabContainer = false;
0879: //try {
0880: String className = getClassName(channelName);
0881: if (className != null
0882: && className
0883: .equals("com.sun.portal.providers.containers.jsp.tab.JSPTabContainerProvider")) {
0884: isTabContainer = true;
0885: }
0886: return isTabContainer;
0887: }
0888:
0889: /**
0890: * This method returns the list of channels/containers that are assignable
0891: * to the available and selected list of a container.
0892: * This method returns the list of channels which includes
0893: * the container's children and the container's parent's
0894: * children, parent's parent's children and traverses recursively
0895: * until it reaches the Display Profile root.
0896: * Mergers are taken into account when the channels are traversed.
0897: * @param container container name for which channels has to be assigned.
0898: * @return Set of channels that can be assignable.
0899: */
0900: public Set getAssignableChannels(String container)
0901: throws TaskAdminException {
0902: DPNode currentNode = getDPChannel(container);
0903: Set result = new TreeSet();
0904: Set channelNames = getChannelNames(currentNode);
0905: Iterator iterator = channelNames.iterator();
0906:
0907: while (iterator.hasNext()) {
0908: String channelName = (String) iterator.next();
0909: logger.log(Level.FINEST, "PSDT_CSPT0026", channelName);
0910: String fQCN = toFullyQualifiedName(currentNode, channelName);
0911: if (isDisplayable(fQCN)) {
0912: result.add(fQCN);
0913: }
0914: }
0915:
0916: DPNode parentNode = currentNode.getParentNode();
0917:
0918: while (parentNode != null) {
0919: channelNames = getChannelNames(parentNode);
0920: iterator = channelNames.iterator();
0921:
0922: while (iterator.hasNext()) {
0923: String channelName = (String) iterator.next();
0924: logger.log(Level.FINEST, "PSDT_CSPT0026", channelName);
0925: String fQCN = toFullyQualifiedName(parentNode,
0926: channelName);
0927: if (isDisplayable(fQCN)) {
0928: result.add(fQCN);
0929: }
0930: }
0931:
0932: parentNode = parentNode.getParentNode();
0933: }
0934:
0935: result.remove(currentNode.getName());
0936: return result;
0937: }
0938:
0939: private Set searchString(String regExp, Set names)
0940: throws TaskAdminException {
0941: Set filteredNames = new TreeSet();
0942: try {
0943: String modified_regExp = regExp.replaceAll("\\*",
0944: REPLACEMENT_STRING);
0945: logger.log(Level.FINEST, "PSDT_CSPT0020", modified_regExp);
0946: Pattern p = Pattern.compile(modified_regExp);
0947: Iterator iterator = names.iterator();
0948: while (iterator.hasNext()) {
0949: String name = (String) iterator.next();
0950: logger.log(Level.FINEST, "PSDT_CSPT0027", name);
0951: Matcher m = p.matcher(name);
0952: if (m.matches()) {
0953: filteredNames.add(name);
0954: logger.log(Level.FINEST, "PSDT_CSPT0028", name);
0955: }
0956: }
0957: } catch (PatternSyntaxException pse) {
0958: logger.log(Level.FINE, "PSDT_CSPT0029", pse);
0959: Object[] tokens = { regExp };
0960: throw new TaskAdminException(INVALID_PATTERN, pse
0961: .getMessage(), tokens);
0962: }
0963: return filteredNames;
0964: }
0965:
0966: /**
0967: * Gets the available channels for the container channel at a
0968: * particular baseDN.
0969: */
0970: public List getAvailableChannels(String containerName)
0971: throws TaskAdminException {
0972: DPContainerChannel channel = getDPContainerChannel(containerName);
0973: List availableChannels = null;
0974: synchronized (dpLock) {
0975: availableChannels = new ArrayList(channel.getAvailable()
0976: .getCollectionValue().values());
0977: }
0978: return availableChannels;
0979: }
0980:
0981: /**
0982: * Gets the selected channels for the container channel at a
0983: * particular baseDN.
0984: */
0985: public List getSelectedChannels(String containerName)
0986: throws TaskAdminException {
0987: DPContainerChannel channel = getDPContainerChannel(containerName);
0988: List selectedChannels = null;
0989: synchronized (dpLock) {
0990: selectedChannels = new ArrayList(channel.getSelected()
0991: .getCollectionValue().values());
0992: }
0993: return selectedChannels;
0994: }
0995:
0996: /**
0997: * Sets the available channels for the container channel at a
0998: * particular baseDN.
0999: */
1000: public void setAvailableChannels(List available,
1001: String containerName) throws TaskAdminException {
1002: DPContainerChannel channel = getDPContainerChannel(containerName);
1003: synchronized (dpLock) {
1004: channel.setAvailable(available);
1005: }
1006: }
1007:
1008: /**
1009: * Sets the selected channels for the container channel at a
1010: * particular baseDN.
1011: */
1012: public void setSelectedChannels(List selected, String containerName)
1013: throws TaskAdminException {
1014: DPContainerChannel channel = getDPContainerChannel(containerName);
1015: synchronized (dpLock) {
1016: channel.setSelected(selected);
1017: }
1018: // Persist changes in DP to the backend
1019: }
1020:
1021: private DPContainerChannel getDPContainerChannel(
1022: String containerName) throws TaskAdminException {
1023: DPChannel channel = getDPChannel(containerName);
1024: if (channel == null) {
1025: logger.log(Level.FINE, "PSDT_CSPT0030", containerName);
1026: Object[] tokens = { containerName };
1027: throw new TaskAdminException(INVALID_CHANNEL,
1028: "Container is null: " + containerName, tokens);
1029: }
1030: if (channel.getType() != DPTypes.CONTAINER_DP) {
1031: // error key not a container channel.
1032: logger.log(Level.FINE, "PSDT_CSPT0031", containerName);
1033: Object[] tokens = { containerName };
1034: throw new TaskAdminException(NOT_CONTAINER,
1035: "Not a container: " + containerName, tokens);
1036: }
1037: return (DPContainerChannel) channel;
1038:
1039: }
1040:
1041: public void setStringProperty(String channelName, String key,
1042: String value, List pflist) throws TaskAdminException {
1043: DPChannel channel = null;
1044: if (channelName != null) {
1045: channel = getDPChannel(channelName);
1046: }
1047: try {
1048: synchronized (dpLock) {
1049: DPProperties props = null;
1050: if (channel == null) {
1051: props = dpRoot.getProperties();
1052: } else {
1053: props = channel.getProperties();
1054: }
1055: DPString property = props.getString(key, pflist, false);
1056: if (property != null) {
1057: //workaround for bug 4909695
1058: boolean advanced = property.isAdvanced();
1059: //props.setString(key, value, pflist);
1060: //set exact for given filter
1061: props.setString(key, value, pflist, true);
1062: if (advanced) {
1063: //again set exact so get exact
1064: props.getString(key, pflist, true).setAdvanced(
1065: true);
1066: }
1067: } else {
1068: Object[] tokens = { key };
1069: throw new TaskAdminException(INVALID_PROPERTY,
1070: "Property doesn't exist", tokens);
1071: }
1072: }
1073: } catch (DPError dpe) {
1074: Object[] tokens = { key };
1075: throw new TaskAdminException(INVALID_PROPERTY, dpe
1076: .getMessage(), tokens);
1077: }
1078: }
1079:
1080: public void setListProperty(String channelName, String key,
1081: List value, List pflist) throws TaskAdminException {
1082: DPChannel channel = null;
1083: if (channelName != null) {
1084: channel = getDPChannel(channelName);
1085: }
1086: try {
1087: synchronized (dpLock) {
1088: DPProperties props = null;
1089: if (channel == null) {
1090: props = dpRoot.getProperties();
1091: } else {
1092: props = channel.getProperties();
1093: }
1094: DPCollection property = props.getCollection(key,
1095: pflist, false);
1096: if (property != null) {
1097: //workaround for bug 4909695
1098: boolean advanced = property.isAdvanced();
1099: props.setCollection(key, value, pflist, true);
1100: if (advanced) {
1101: props.getCollection(key, pflist, true)
1102: .setAdvanced(true);
1103: }
1104: } else {
1105: Object[] tokens = { key };
1106: throw new TaskAdminException(INVALID_PROPERTY,
1107: "Property doesn't exist", tokens);
1108: }
1109: }
1110: } catch (DPError dpe) {
1111: Object[] tokens = { key };
1112: throw new TaskAdminException(INVALID_PROPERTY, dpe
1113: .getMessage(), tokens);
1114: }
1115: }
1116:
1117: public void setMapProperty(String channelName, String key,
1118: Map value, List pflist) throws TaskAdminException {
1119: DPChannel channel = null;
1120: if (channelName != null) {
1121: channel = getDPChannel(channelName);
1122: }
1123: try {
1124: synchronized (dpLock) {
1125: DPProperties props = null;
1126: if (channel == null) {
1127: props = dpRoot.getProperties();
1128: } else {
1129: props = channel.getProperties();
1130: }
1131: DPCollection property = props.getCollection(key,
1132: pflist, false);
1133: if (property != null) {
1134: //workaround for bug 4909695
1135: boolean advanced = property.isAdvanced();
1136: props.setCollection(key, value, pflist, true);
1137: if (advanced) {
1138: props.getCollection(key, pflist, true)
1139: .setAdvanced(true);
1140: }
1141: } else {
1142: Object[] tokens = { key };
1143: throw new TaskAdminException(INVALID_PROPERTY,
1144: "Property doesn't exist", tokens);
1145: }
1146: }
1147: } catch (DPError dpe) {
1148: Object[] tokens = { key };
1149: throw new TaskAdminException(INVALID_PROPERTY, dpe
1150: .getMessage(), tokens);
1151: }
1152: }
1153:
1154: public void setIntegerProperty(String channelName, String key,
1155: int value, List pflist) throws TaskAdminException {
1156: DPChannel channel = null;
1157: if (channelName != null) {
1158: channel = getDPChannel(channelName);
1159: }
1160: try {
1161: synchronized (dpLock) {
1162: DPProperties props = null;
1163: if (channel == null) {
1164: props = dpRoot.getProperties();
1165: } else {
1166: props = channel.getProperties();
1167: }
1168: DPInteger property = props.getInteger(key, pflist,
1169: false);
1170: if (property != null) {
1171: //workaround for bug 4909695
1172: boolean advanced = property.isAdvanced();
1173: props.setInteger(key, value, pflist, true);
1174: if (advanced) {
1175: props.getInteger(key, pflist, true)
1176: .setAdvanced(true);
1177: }
1178: } else {
1179: Object[] tokens = { key };
1180: throw new TaskAdminException(INVALID_PROPERTY,
1181: "Property doesn't exist", tokens);
1182: }
1183: }
1184: } catch (DPError dpe) {
1185: Object[] tokens = { key };
1186: throw new TaskAdminException(INVALID_PROPERTY, dpe
1187: .getMessage(), tokens);
1188: }
1189: }
1190:
1191: public void setBooleanProperty(String channelName, String key,
1192: boolean value, List pflist) throws TaskAdminException {
1193: DPChannel channel = null;
1194: if (channelName != null) {
1195: channel = getDPChannel(channelName);
1196: }
1197: try {
1198: synchronized (dpLock) {
1199: DPProperties props = null;
1200: if (channel == null) {
1201: props = dpRoot.getProperties();
1202: } else {
1203: props = channel.getProperties();
1204: }
1205: DPBoolean property = props.getBoolean(key, pflist,
1206: false);
1207: if (property != null) {
1208: //workaround for bug 4909695
1209: boolean advanced = property.isAdvanced();
1210: props.setBoolean(key, value, pflist, true);
1211: if (advanced) {
1212: props.getBoolean(key, pflist, true)
1213: .setAdvanced(true);
1214: }
1215: } else {
1216: Object[] tokens = { key };
1217: throw new TaskAdminException(INVALID_PROPERTY,
1218: "Property doesn't exist", tokens);
1219: }
1220: }
1221: } catch (DPError dpe) {
1222: Object[] tokens = { key };
1223: throw new TaskAdminException(INVALID_PROPERTY, dpe
1224: .getMessage(), tokens);
1225: }
1226: }
1227:
1228: /**
1229: * Return the value for channel String property.
1230: * @param channelName channel name.
1231: * @param key property name
1232: * @param pflist properties filter list
1233: * @return Value of the string property.
1234: * @throws TaskAdminException
1235: */
1236: public String getStringProperty(String channelName, String key,
1237: List pflist) throws TaskAdminException {
1238: DPString val = null;
1239: if (channelName == null || channelName.trim().length() == 0) {
1240: // get key from global properties.
1241: synchronized (dpLock) {
1242: val = dpRoot.getProperties().getString(key, pflist,
1243: false);
1244: }
1245: } else {
1246: DPChannel channel = getDPChannel(channelName);
1247: synchronized (dpLock) {
1248: val = channel.getProperties().getString(key, pflist,
1249: false);
1250: }
1251: }
1252: if (val == null) {
1253: //property doesn't exist for the given pflist.
1254: Object[] tokens = { key };
1255: throw new TaskAdminException(INVALID_PROPERTY,
1256: "property doesn't exist", tokens);
1257: }
1258: return val.getStringValue();
1259: }
1260:
1261: /**
1262: * Return the value for channel integer property.
1263: * @param channelName channel name.
1264: * @param key property name
1265: * @param pflist properties filter list
1266: * @return value of the integer property.
1267: * @throws TaskAdminException
1268: */
1269: public int getIntegerProperty(String channelName, String key,
1270: List pflist) throws TaskAdminException {
1271: DPInteger val = null;
1272: if (channelName == null || channelName.trim().length() == 0) {
1273: // get key from global properties.
1274: synchronized (dpLock) {
1275: val = dpRoot.getProperties().getInteger(key, pflist,
1276: false);
1277: }
1278: } else {
1279: DPChannel channel = getDPChannel(channelName);
1280: synchronized (dpLock) {
1281: val = channel.getProperties().getInteger(key, pflist,
1282: false);
1283: }
1284: }
1285: if (val == null) {
1286: //property doesn't exist for the given pflist.
1287: Object[] tokens = { key };
1288: throw new TaskAdminException(INVALID_PROPERTY,
1289: "property doesn't exist", tokens);
1290: }
1291: return val.getIntValue();
1292: }
1293:
1294: /**
1295: * Return the value for channel's boolean property.
1296: * @param channelName channel name.
1297: * @param key property name
1298: * @param pflist properties filter list
1299: * @return value of the boolean property.
1300: * @throws TaskAdminException
1301: */
1302: public boolean getBooleanProperty(String channelName, String key,
1303: List pflist) throws TaskAdminException {
1304: DPBoolean val = null;
1305: if (channelName == null || channelName.trim().length() == 0) {
1306: // get key from global properties.
1307: synchronized (dpLock) {
1308: val = dpRoot.getProperties().getBoolean(key, pflist,
1309: false);
1310: }
1311: } else {
1312: DPChannel channel = getDPChannel(channelName);
1313: synchronized (dpLock) {
1314: val = channel.getProperties().getBoolean(key, pflist,
1315: false);
1316: }
1317: }
1318: if (val == null) {
1319: //property doesn't exist for the given pflist.
1320: Object[] tokens = { key };
1321: throw new TaskAdminException(INVALID_PROPERTY,
1322: "property doesn't exist", tokens);
1323: }
1324: return val.getBooleanValue();
1325: }
1326:
1327: /**
1328: * This method returns the Map collection object for the given
1329: * collection property.
1330: * @param channelName channel name.
1331: * @param key property name
1332: * @param pflist
1333: * @return
1334: * @throws TaskAdminException
1335: */
1336: public Map getMapProperty(String channelName, String key,
1337: List pflist) throws TaskAdminException {
1338: DPCollection val = null;
1339: if (channelName == null || channelName.trim().length() == 0) {
1340: // get key from global properties.
1341: synchronized (dpLock) {
1342: val = dpRoot.getProperties().getCollection(key, pflist,
1343: false);
1344: }
1345: } else {
1346: DPChannel channel = getDPChannel(channelName);
1347: synchronized (dpLock) {
1348: val = channel.getProperties().getCollection(key,
1349: pflist, false);
1350: }
1351: }
1352: if (val == null) {
1353: //property doesn't exist for the given pflist.
1354: Object[] tokens = { key };
1355: throw new TaskAdminException(INVALID_PROPERTY,
1356: "property doesn't exist", tokens);
1357: }
1358: return val.getCollectionValue();
1359: }
1360:
1361: /**
1362: * This method returns the List collection object for the given
1363: * collection property.
1364: * @param channelName channel name.
1365: * @param key property name
1366: * @param pflist
1367: * @return
1368: * @throws TaskAdminException
1369: */
1370: public List getListProperty(String channelName, String key,
1371: List pflist) throws TaskAdminException {
1372: DPCollection val = null;
1373: if (channelName == null || channelName.trim().length() == 0) {
1374: // get key from global properties.
1375: synchronized (dpLock) {
1376: val = dpRoot.getProperties().getCollection(key, pflist,
1377: false);
1378: }
1379: } else {
1380: DPChannel channel = getDPChannel(channelName);
1381: synchronized (dpLock) {
1382: val = channel.getProperties().getCollection(key,
1383: pflist, false);
1384: }
1385: }
1386: if (val == null) {
1387: //property doesn't exist for the given pflist.
1388: Object[] tokens = { key };
1389: throw new TaskAdminException(INVALID_PROPERTY,
1390: "property doesn't exist", tokens);
1391: }
1392: return new ArrayList(val.getNames());
1393: }
1394:
1395: /**
1396: * This method returns the list of property names that are existing
1397: * at the baseDN and at the given channel name that is passed in. This method
1398: * returns only the default property names and filters out all the conditional
1399: * properties.
1400: *
1401: * @param channelName the channel name for which property names list to be returned.
1402: * @param advanced advanced flag to specify whether to return basic/advanced propertynames.
1403: * @return Set Contaning property name list.
1404: */
1405: public Set getPropertyNames(String channelName, boolean advanced)
1406: throws TaskAdminException {
1407: Map propertyMap = getPropertyMap(channelName, null, advanced);
1408: return propertyMap.keySet();
1409: }
1410:
1411: /**
1412: * Return the Set contaning property names that matches the given regular expression.
1413: * @param channelName channel name.
1414: * @param regExp string which needs to be searched.
1415: * @param advanced advanced flag to specify whether to return basic/advanced propertynames.
1416: * @return
1417: * @throws TaskAdminException
1418: */
1419: public Set getPropertyNames(String channelName, String regExp,
1420: boolean advanced) throws TaskAdminException {
1421: Set filteredPropertySet = searchString(regExp, this
1422: .getPropertyNames(channelName, advanced));
1423: return filteredPropertySet;
1424: }
1425:
1426: /**
1427: * This method returns the list of property names that are existing
1428: * at the baseDN and at the given channel name that is passed in. This method
1429: * returns only the conditional property names and filters out all the default
1430: * properties which are not defined as conditional properties.
1431: * This method assumes that any property that is defined as conditional will
1432: * have an entry for the default.
1433: *
1434: * @param channelName the channel name for which property names list to be returned.
1435: * @param advanced advanced flag to specify whether to return basic/advanced propertynames.
1436: * @return Set Contaning property name list.
1437: */
1438: public Set getPropertyNames(String channelName, List pflist,
1439: boolean advanced) throws TaskAdminException {
1440: logger.log(Level.FINEST, "PSDT_CSPT0032", pflist);
1441: Map propertyMap = getPropertyMap(channelName, pflist, advanced);
1442: return propertyMap.keySet();
1443: }
1444:
1445: private Map getPropertyMap(String channelName, List pflist,
1446: boolean advanced) throws TaskAdminException {
1447: DPChannel channel = getDPChannel(channelName);
1448: logger.log(Level.FINEST, "PSDT_CSPT0033", channelName);
1449: Map propertyMap = new HashMap();
1450: Map advancedMap = new HashMap();
1451: DPProvider provider = null;
1452: synchronized (dpLock) {
1453: provider = channel.getProvider();
1454: }
1455: if (provider == null) {
1456: logger.log(Level.FINE, "PSDT_CSPT0034", channelName);
1457: Object[] tokens = { channelName };
1458: throw new TaskAdminException(INVALID_PROVIDER,
1459: "Provider for the Channel passed in is invalid",
1460: tokens);
1461: }
1462:
1463: DPProperties channelProperties = null;
1464: DPProperties providerProperties = null;
1465: Set channelProps = null;
1466: Set providerProps = null;
1467: Iterator channelIter = null;
1468: Iterator providerIter = null;
1469: synchronized (dpLock) {
1470: channelProperties = channel.getProperties();
1471: providerProperties = provider.getProperties();
1472: // filter out advanced properties and names starting with "_"..
1473: channelProps = channelProperties.getNames(false);
1474: providerProps = providerProperties.getNames(false);
1475: channelIter = channelProps.iterator();
1476: providerIter = providerProps.iterator();
1477: }
1478: while (channelIter.hasNext()) {
1479: String name = (String) channelIter.next();
1480: DPProperty property = null;
1481: if (pflist != null && pflist.size() != 0) {
1482: property = (DPProperty) channelProperties.get(name,
1483: pflist, false);
1484: } else {
1485: property = (DPProperty) channelProperties.get(name);
1486: }
1487: if ((property != null) && (!name.startsWith("_"))) {
1488: if (property.isAdvanced()) {
1489: advancedMap.put(name, property);
1490: } else {
1491: propertyMap.put(name, property);
1492: }
1493: }
1494: }
1495:
1496: while (providerIter.hasNext()) {
1497: String name = (String) providerIter.next();
1498: DPProperty property = null;
1499: if (pflist != null && pflist.size() != 0) {
1500: property = (DPProperty) providerProperties.get(name,
1501: pflist, false);
1502: } else {
1503: property = (DPProperty) providerProperties.get(name);
1504: }
1505: if ((property != null) && (!name.startsWith("_"))
1506: && (!propertyMap.containsKey(name))) {
1507: if (property.isAdvanced()) {
1508: advancedMap.put(name, property);
1509: } else {
1510: propertyMap.put(name, property);
1511: }
1512: }
1513: }
1514: if (advanced) {
1515: return advancedMap;
1516: }
1517: return propertyMap;
1518: }
1519:
1520: /**
1521: * This method returns the list of global property names that are existing
1522: * at the baseDN that is passed in. *
1523: * @return Set Contaning property name list.
1524: */
1525: public Set getGlobalPropertyNames() throws TaskAdminException {
1526: Set globalProperties = new TreeSet();
1527: DPProperties dpProperties = null;
1528: Set props = null;
1529: Iterator iter = null;
1530: synchronized (dpLock) {
1531: dpProperties = dpRoot.getProperties();
1532: props = dpProperties.getNames(false);
1533: iter = props.iterator();
1534: }
1535: while (iter.hasNext()) {
1536: String name = (String) iter.next();
1537: DPProperty property = (DPProperty) dpProperties.get(name);
1538: if ((property == null) || (property.isAdvanced())
1539: || (name.startsWith("_"))) {
1540: continue;
1541: } else {
1542: globalProperties.add(name);
1543: }
1544: }
1545:
1546: return globalProperties;
1547: }
1548:
1549: protected DPChannel getDPChannel(String channelName)
1550: throws TaskAdminException {
1551: DPChannel channel = null;
1552: synchronized (dpLock) {
1553: if (!existsChannel(channelName)) {
1554: // error key non-existent channel.
1555: logger.log(Level.FINE, "PSDT_CSPT0035", new Object[] {
1556: channelName, dpRoot.getName() });
1557: Object[] tokens = { channelName };
1558: throw new TaskAdminException(INVALID_CHANNEL,
1559: "Channel does not exists: " + channelName,
1560: tokens);
1561: }
1562: channel = dpRoot.getChannel(channelName);
1563: }
1564: return channel;
1565: }
1566:
1567: /**
1568: * This method returns the property type for the given property name.
1569: * @param channelName channel name.
1570: * @return short value indicating property type.
1571: * @throws TaskAdminException
1572: */
1573: public short getPropertyType(String channelName, String propertyName)
1574: throws TaskAdminException {
1575: synchronized (dpLock) {
1576: if (!existsChannel(channelName)) {
1577: //error key non-existent channel.
1578: logger.log(Level.FINE, "PSDT_CSPT0035", new Object[] {
1579: channelName, baseDN });
1580: Object[] tokens = { channelName };
1581: throw new TaskAdminException(INVALID_CHANNEL,
1582: "Channel doesn't exist", tokens);
1583: }
1584: }
1585: if (propertyName.startsWith("_")) {
1586: logger.log(Level.FINE, "PSDT_CSPT0036", propertyName);
1587: Object[] tokens = { propertyName };
1588: throw new TaskAdminException(INVALID_PROPERTY_TYPE,
1589: "Invalid Property", tokens);
1590: }
1591: DPChannel channel = getDPChannel(channelName);
1592: DPProperty p = null;
1593: synchronized (dpLock) {
1594: p = channel.getProperties().get(propertyName);
1595: }
1596: return p.getType();
1597: }
1598:
1599: public List getMergedDNs() {
1600: List mergedDNs = null;
1601: if (mergers != null) {
1602: mergedDNs = new ArrayList(mergers);
1603: } else {
1604: mergedDNs = new ArrayList();
1605: }
1606: return mergedDNs;
1607: }
1608:
1609: protected boolean existsChannel(String channel) {
1610: boolean exists = dpRoot.channelExists(channel);
1611: return exists;
1612: }
1613:
1614: protected boolean existsProvider(String provider) {
1615: boolean exists = dpRoot.providerExists(provider);
1616: return exists;
1617: }
1618:
1619: protected Set getChannelNames(DPNode node) {
1620: Set channelNames = null;
1621: synchronized (dpLock) {
1622: channelNames = node.getChannelNames();
1623: }
1624: return channelNames;
1625: }
1626:
1627: protected Set getProviderNames(DPNode node) {
1628: Set providerNames = null;
1629: synchronized (dpLock) {
1630: providerNames = node.getProviderNames();
1631: }
1632: return providerNames;
1633: }
1634:
1635: private String toFullyQualifiedName(DPNode container,
1636: String shortName) {
1637: return ((container instanceof DPRoot) ? "" : container
1638: .getName()
1639: + DPNode.CHANNEL_NAME_SEPARATOR)
1640: + shortName;
1641: }
1642:
1643: /**
1644: * Checks if the channel/container should be displayed to the user
1645: */
1646: protected boolean isDisplayable(String fqcn) {
1647:
1648: boolean isDisplayable = true;
1649: if (fqcn == null || fqcn.length() == 0) {
1650: isDisplayable = false;
1651: return isDisplayable;
1652: }
1653: //context.debugError("isDisplayable: " + fqcn);
1654: DPChannel channel = null;
1655: try {
1656: channel = getDPChannel(fqcn);
1657: } catch (TaskAdminException tae) {
1658: isDisplayable = false;
1659: return isDisplayable;
1660: }
1661: String shortName = getTail(fqcn, CHANNEL_NAME_SEPARATOR);
1662:
1663: // Filter out all channels/containers that are defined advanced or
1664: // if the name starts with "_"
1665: if (channel == null || channel.isAdvanced()
1666: || shortName.startsWith("_")) {
1667:
1668: isDisplayable = false;
1669: }
1670:
1671: return isDisplayable;
1672: }
1673:
1674: /**
1675: * Checks if the current user can access a given channel
1676: * @param channel Fully qualified name of the channel as a String
1677: * @return <B>true</B> if the use can access.
1678: */
1679: protected boolean canAccess(String channel) {
1680:
1681: boolean canAccess = true;
1682: boolean existChannel = false;
1683: synchronized (dpLock) {
1684: existChannel = existsChannel(channel);
1685: }
1686: if (!canViewDTAttributes) {
1687: boolean isInMergers = false;
1688: List mergers = null;
1689: synchronized (dpLock) {
1690: mergers = dpRoot.getMergers();
1691: }
1692: if (mergers != null) {
1693: Iterator iterator = mergers.iterator();
1694:
1695: while (iterator.hasNext()) {
1696: DPRoot merger = (DPRoot) iterator.next();
1697: boolean exists = false;
1698: synchronized (dpLock) {
1699: exists = merger.channelExists(channel);
1700: }
1701: if (exists) {
1702: isInMergers = true;
1703: break;
1704: }
1705: }
1706: }
1707:
1708: canAccess = existChannel && !isInMergers;
1709: }
1710:
1711: return canAccess;
1712: }
1713:
1714: public void store() throws TaskAdminException {
1715: if (!dpRoot.isDirty()) {
1716: // don't bother to store it if the display profile hasn't changed
1717: logger.log(Level.FINE, "PSDT_CSPT0037",
1718: new Object[] { baseDN });
1719: return;
1720: }
1721:
1722: dpRoot.setDirty(false);
1723: StringBuffer buff = new StringBuffer(100);
1724: dpRoot.toXML(buff, 0);
1725: String dpText = buff.toString();
1726: logger.log(Level.FINEST, "PSDT_CSPT0038", dpText);
1727: try {
1728: synchronized (dpLock) {
1729: context.store(baseDN, dpText);
1730: }
1731: } catch (ContextError e) {
1732: logger.log(Level.FINEST, "PSDT_CSPT0039", e);
1733: // error key for store error
1734: Object[] tokens = { baseDN };
1735: throw new TaskAdminException(STORE_ERROR, e.getMessage(),
1736: tokens);
1737: }
1738: }
1739:
1740: /////////////Begin rpn manipulation helpers ////////////////////////
1741:
1742: /**
1743: * Relative Path Name (RPN) is similar to
1744: * FQCN(fully qualified channel name) and is in the form
1745: * "c1/c2/c3/c4". This method returns c1.
1746: *
1747: * @param rpn Relative path name
1748: * @returns first element in the relative path name. If the string is
1749: * not delimited with '/', then rpn is returned as is.
1750: */
1751: protected String getHead(String rpn, String nameSeparator) {
1752: String head = null;
1753: if (rpn != null && rpn.length() != 0) {
1754: int index = rpn.indexOf(nameSeparator);
1755: if (index == -1) {
1756: head = rpn;
1757: } else {
1758: head = rpn.substring(0, index);
1759: }
1760: }
1761: return head;
1762: }
1763:
1764: /**
1765: * Relative Path Name (RPN) is similar to
1766: * FQCN(fully qualified channel name) and is in the form
1767: * "c1/c2/c3/c4". This method returns c4.
1768: *
1769: * @param rpn Relative path name
1770: * @returns last element in the relative path name. If the string is
1771: * not delimited with '/', then rpn is returned as is.
1772: */
1773: private String getTail(String rpn, String nameSeparator) {
1774: String tail = null;
1775: if (rpn != null && rpn.length() != 0) {
1776: int index = rpn.lastIndexOf(nameSeparator);
1777: if (index == -1) {
1778: tail = rpn;
1779: } else {
1780: tail = rpn.substring(index + 1, rpn.length());
1781: }
1782: }
1783: return tail;
1784: }
1785:
1786: /**
1787: * If source is c1/c2/c3/c4 and substring is c4, then this method
1788: * returns c1/c2/c3. It returns null if there is no string preceding
1789: * the substring or if substring is not found in the source.
1790: *
1791: */
1792: protected String getPreceding(String source, String substring,
1793: String nameSeparator) {
1794: String preceeding = null;
1795: int index = -1;
1796: if (source != null && substring != null) {
1797: index = source.indexOf(substring);
1798: if (index != -1) {
1799: preceeding = source.substring(0, index);
1800: if (preceeding.endsWith(nameSeparator)) {
1801: preceeding = preceeding.substring(0, preceeding
1802: .length() - 1);
1803: }
1804: preceeding = preceeding.length() == 0 ? null
1805: : preceeding;
1806: }
1807: }
1808: return preceeding;
1809: }
1810:
1811: /**
1812: * If source is c1/c2/c3/c4 and substring is c2, then this method
1813: * returns c3/c4. It returns null if there is no string following
1814: * the substring or if substring is not found in the source.
1815: *
1816: */
1817: protected String getFollowing(String source, String substring,
1818: String nameSeparator) {
1819: String following = null;
1820: int index = -1;
1821: if (source != null && substring != null) {
1822: index = source.indexOf(substring);
1823: if (index != -1) {
1824: following = source
1825: .substring(index + substring.length());
1826: if (following.startsWith(nameSeparator)) {
1827: following = following.substring(1);
1828: }
1829: following = following.length() == 0 ? null : following;
1830: }
1831: }
1832: return following;
1833: }
1834:
1835: /////////////End rpn manipulation helpers ////////////////////////
1836:
1837: public String getDPPriority() throws TaskAdminException {
1838: String priority = null;
1839: if (!dpDocExists) {
1840: priority = DP_PRIORITY_NOT_SET;
1841: } else {
1842: synchronized (dpLock) {
1843: int p = dpRoot.getPriority();
1844: if (p == -1) {
1845: priority = DP_PRIORITY_NOT_SET;
1846: }
1847: if (p == Integer.MAX_VALUE) {
1848: priority = DP_PRIORITY_USER;
1849: } else {
1850: priority = String.valueOf(p);
1851: }
1852: }
1853: }
1854: return priority;
1855: }
1856:
1857: public void setDPPriority(String priority)
1858: throws TaskAdminException {
1859: if (!dpDocExists) {
1860: Object[] tokens = { baseDN };
1861: throw new TaskAdminException(
1862: EMPTY_DP_DOC,
1863: "Priority cannot be set. DP Document Doesn't exist",
1864: tokens);
1865: }
1866: int p = -1;
1867: if (priority != null && dpDocExists) {
1868: if (priority.equals(DP_PRIORITY_USER)) {
1869: p = Integer.MAX_VALUE;
1870: } else {
1871: p = (new Integer(priority)).intValue();
1872: }
1873: synchronized (dpLock) {
1874: dpRoot.setPriority(p);
1875: dpRoot.setDirty(true);
1876: store();
1877: }
1878: dpRoot = getDPRootByDN(baseDN, true, true);
1879: }
1880: }
1881:
1882: public Map getNodeProperties(String fqcn, String rpn,
1883: String client, String locale) throws TaskAdminException {
1884: Map propInfoMap = new HashMap(5);
1885:
1886: //build a properties filter list for client and locale
1887: List pfList = getFilterList(client, locale);
1888:
1889: if (fqcn != null && fqcn.equals(DesktopConstants.DP_ROOT_NODE)) {
1890: //request is for dproot properties
1891: DPProperties dpProperties = dpRoot.getProperties();
1892:
1893: Map dpPropertyMap = getNestedProperties(dpProperties, rpn,
1894: pfList);
1895: //add the list of DNs that contributed to this merger
1896: propInfoMap.put(DesktopConstants.KEY_MERGED_DNS,
1897: getMergedDNs());
1898: buildPropertyInfo(propInfoMap, dpPropertyMap, false);
1899: } else {
1900: DPChannel channel = null;
1901: if (existsChannel(fqcn)) {
1902: channel = getDPChannel(fqcn);
1903: }
1904:
1905: if (channel == null) {
1906: logger.log(Level.SEVERE, "Channel " + fqcn
1907: + " does not exist");
1908: Object[] tokens = { fqcn };
1909: throw new TaskAdminException(INVALID_CHANNEL,
1910: "Channel is null", tokens);
1911: }
1912:
1913: DPProperties channelProperties = channel.getProperties();
1914:
1915: DPProvider provider = channel.getProvider();
1916: if (provider == null) {
1917: logger.log(Level.SEVERE, "Provider is null for " + fqcn
1918: + "channel");
1919: Object[] tokens = { fqcn };
1920: throw new TaskAdminException(INVALID_PROVIDER,
1921: "Provider does not exist for channel " + fqcn,
1922: tokens);
1923: }
1924:
1925: String providerName = provider.getName();
1926: DPProperties providerProperties = provider.getProperties();
1927:
1928: Map channelPropertyMap = getNestedProperties(
1929: channelProperties, rpn, pfList);
1930: Map providerPropertyMap = getNestedProperties(
1931: providerProperties, rpn, pfList);
1932:
1933: Set channelPropertyNames = channelPropertyMap.keySet();
1934: Set providerPropertyNames = providerPropertyMap.keySet();
1935:
1936: Iterator iter = providerPropertyNames.iterator();
1937: while (iter.hasNext()) {
1938: String name = (String) iter.next();
1939: if (channelPropertyNames.contains(name)) {
1940: /* remove the property name from the provider property names
1941: * and from the provider property map
1942: * for a property which exists in the channel.*/
1943: iter.remove();
1944: }
1945: }
1946:
1947: /*
1948: * See bug 4847287:
1949: * The PAPI will return provider collection as long as the
1950: * collection is not defined in channel. If it is defined
1951: * in the channel, it will not merge the channel and
1952: * provider collections. So we need to remove all the provider
1953: * properties if any one property is customized inside a collection
1954: * This makes the behaviour consistent with the PAPI.
1955: */
1956: if (rpn != null) {
1957: if (!channelPropertyNames.isEmpty()
1958: || isCustomizedCollection(channelProperties,
1959: getHead(rpn, COLLECTION_NAME_SEPARATOR))) {
1960: //if the collection is defined in the channel
1961: //then do not show provider properties
1962: providerPropertyMap.clear();
1963: }
1964: }
1965:
1966: /**
1967: * Holds the name-info pairs for all properties (custom + default).
1968: * The keyset has names of the properties and the values are
1969: * info map
1970: */
1971: buildPropertyInfo(propInfoMap, channelPropertyMap, false);
1972: buildPropertyInfo(propInfoMap, providerPropertyMap, true);
1973: addExtraNodeInfo(propInfoMap, provider, channel);
1974:
1975: logger.log(Level.FINEST, "Number of channel properties = "
1976: + channelPropertyMap.size());
1977: logger.log(Level.FINEST, "Number of provider properties = "
1978: + providerPropertyMap.size());
1979: logger.log(Level.FINEST, "Total properties in info map = "
1980: + propInfoMap.size());
1981: }
1982: return propInfoMap;
1983: }
1984:
1985: /**
1986: * Returns true if the collectionName is defined in the channel at
1987: * top level
1988: * If a collection is customized, no matter where in the collection
1989: * hierarchy it may be, the whole collection tree is written out
1990: * in the channel. For example, there may be c1/c2/c3, and c3 is
1991: * customized, then c1/c2/c3 is written to the channel dp.
1992: * So if we check if the first one is coming from a channel,
1993: * i.e. if c1 is in the channel, then all of the hierarchy is
1994: * customized. This method checks if the collectionName is in the
1995: * channel.
1996: *
1997: * @param properties The channel top level properties object
1998: * @param collectionName The first collection in the hierarchy which is
1999: * at the channel top level
2000: * @returns true if the collectionName exists at the channel top level
2001: */
2002: private boolean isCustomizedCollection(DPProperties properties,
2003: String collectionName) {
2004: DPProperty dpp = properties.getCollection(collectionName);
2005: boolean customized = false;
2006: short type = dpp.getProperties().getPropertyHolder().getType();
2007: if (type == DPTypes.CHANNEL_DP || type == DPTypes.CONTAINER_DP) {
2008: customized = true;
2009: }
2010: return customized;
2011: }
2012:
2013: /**
2014: * adds this additional information about the node being processed
2015: * to the infoMap
2016: *
2017: * KEY_PROVIDER_NAME = provider name
2018: * KEY_IS_CONTAINER = true/false
2019: * KEY_IS_TAB_CONTAINER = true/false
2020: * KEY_IS_PORTLET_CHANNEL = true/false
2021: */
2022: private void addExtraNodeInfo(Map infoMap, DPProvider provider,
2023: DPChannel channel) {
2024: //add provider name to infoMap
2025: infoMap.put(DesktopConstants.KEY_PROVIDER_NAME, provider
2026: .getName());
2027:
2028: boolean container = channel instanceof DPContainerChannel;
2029: //add whether channel is a container
2030: infoMap.put(DesktopConstants.KEY_IS_CONTAINER, new Boolean(
2031: container));
2032:
2033: String cName = channel.getName();
2034:
2035: //add whether channel is a tab container or not
2036: if (container) {
2037: boolean tc = false;
2038: try {
2039: tc = isTabContainer(cName);
2040: } catch (TaskAdminException tae) {
2041: //nothing, assume its not a tab container
2042: }
2043: infoMap.put(DesktopConstants.KEY_IS_TAB_CONTAINER,
2044: new Boolean(tc));
2045: } else {
2046: infoMap.put(DesktopConstants.KEY_IS_TAB_CONTAINER,
2047: new Boolean(false));
2048: }
2049: //add whether channel is a portlet channel
2050: if (container) {
2051: infoMap.put(DesktopConstants.KEY_IS_PORTLET_CHANNEL,
2052: new Boolean(false));
2053: } else {
2054: String classname = null;
2055: try {
2056: classname = getClassName(cName);
2057: } catch (TaskAdminException tae) {
2058: //nothing, assume its not a portlet channel
2059: }
2060: if (classname != null && classname.endsWith(PORTLET_CLASS)) {
2061: infoMap.put(DesktopConstants.KEY_IS_PORTLET_CHANNEL,
2062: new Boolean(true));
2063: } else {
2064: infoMap.put(DesktopConstants.KEY_IS_PORTLET_CHANNEL,
2065: new Boolean(false));
2066: }
2067: }
2068: //add the list of DNs that contributed to this merger
2069: infoMap.put(DesktopConstants.KEY_MERGED_DNS, getMergedDNs());
2070: }
2071:
2072: /**
2073: * Constructs the info map for each property and adds it to propInfoMap
2074: * The data/information is in the following format
2075: * name - infoMap {
2076: * KEY_NAMED = <Boolean - true/false>
2077: * KEY_VALUE = <Object - value>
2078: * KEY_TYPE = <short - com.sun.portal.admin.common.DesktopConstants.TYPE_
2079: * STRING_PROPERTY/INTEGER_PROPERTY/BOOLEAN_PROPERTY/
2080: * COLLECTION_PROPERTY/CONDITIONAL_PROPERTY>
2081: * KEY_STATE = <String - com.sun.portal.admin.common.DesktopConstants.STATE_
2082: * DEFAULT/INHERITED/CUSTOMIZED>
2083: * KEY_IS_ADVANCED = <Boolean - advanced:true/false>
2084: * }
2085: */
2086: private void buildPropertyInfo(Map infoMap, Map channelPropertyMap,
2087: boolean provider) {
2088: Iterator iter = channelPropertyMap.keySet().iterator();
2089: while (iter.hasNext()) {
2090: String name = (String) iter.next();
2091: DPProperty dpProp = (DPProperty) channelPropertyMap
2092: .get(name);
2093: Map info = new HashMap(5);
2094: info.put(DesktopConstants.KEY_NAMED, new Boolean(dpProp
2095: .isNamed()));
2096: short type = dpProp.getType();
2097: info.put(DesktopConstants.KEY_TYPE, new Short(type));
2098: if (type == COLLECTION_DP) {
2099: Set names = ((DPCollection) dpProp).getNames();
2100: List valueList = getList((DPCollection) dpProp);
2101: //if collection contains only unnamed props, then list is
2102: //not empty, otherwise empty
2103: //But if the collection does not contain anything, then
2104: //it is also treated as a list (empty list of unnamed props)
2105: boolean empty = valueList.isEmpty();
2106: if (!empty || names.isEmpty()) {
2107: info.put(DesktopConstants.KEY_VALUE, valueList);
2108: //change the type to list type
2109: info
2110: .put(
2111: DesktopConstants.KEY_TYPE,
2112: new Short(
2113: DesktopConstants.TYPE_STRING_LIST_PROPERTY));
2114: } else {
2115: //not a list type, so the value is null string
2116: info.put(DesktopConstants.KEY_VALUE, "");
2117: }
2118: } else {
2119: info.put(DesktopConstants.KEY_VALUE, dpProp.getValue());
2120: }
2121: info.put(DesktopConstants.KEY_IS_ADVANCED, new Boolean(
2122: dpProp.isAdvanced()));
2123: if (provider) {
2124: info.put(DesktopConstants.KEY_STATE,
2125: DesktopConstants.STATE_DEFAULT);
2126: } else if (dpProp.isDummy()) {
2127: info.put(DesktopConstants.KEY_STATE,
2128: DesktopConstants.STATE_INHERITED);
2129: } else {
2130: info.put(DesktopConstants.KEY_STATE,
2131: DesktopConstants.STATE_CUSTOMIZED);
2132: }
2133: infoMap.put(name, info);
2134: }
2135: }
2136:
2137: /**
2138: * Returns a list of strings if this collection contains only
2139: * unnamed strings, otherwise returns an empty List
2140: * A list is a list of Strings althought DP does not prevent
2141: * making a list of any type. In other words, only unnamed
2142: * Strings are allowed.
2143: */
2144: private List getList(DPCollection collection) {
2145: List unnamedList = new ArrayList();
2146: //DPProperties properties = collection.getProperties();
2147: //Iterator namesIter = properties.getNames().iterator();
2148: Iterator namesIter = collection.getNames().iterator();
2149: while (namesIter.hasNext()) {
2150: String name = (String) namesIter.next();
2151: DPProperty prop = collection.get(name);
2152: //if named property exists, then this is a map and not a list
2153: //so return empty list
2154: if (prop.isNamed()) {
2155: unnamedList.clear();
2156: logger.log(Level.FINEST, "Collection "
2157: + collection.getName()
2158: + " is not a List, it contains named property "
2159: + prop.getName());
2160: break;
2161: }
2162: //check the type and if there is any type other than String
2163: //then this is not a valid list type, so return empty list
2164: short type = prop.getType();
2165: if (type != STRING_DP) {
2166: unnamedList.clear();
2167: logger
2168: .log(
2169: Level.FINEST,
2170: "Collection "
2171: + collection.getName()
2172: + " is not a List, it contains types other than Strings");
2173: break;
2174: }
2175: unnamedList.add(prop.getValue());
2176: }
2177: logger.log(Level.FINEST, "Collection " + collection.getName()
2178: + " is a List containing " + unnamedList.size()
2179: + " Strings");
2180: return unnamedList;
2181: }
2182:
2183: /**
2184: * Recursively reaches the end of the relative property path and returns
2185: * the property map for the last property name in the
2186: * relative property name(rpn) string.
2187: */
2188: private Map getNestedProperties(DPCollection collection,
2189: String rpn, List pfList) {
2190:
2191: //should never happen if called properly, but...
2192: if (collection == null) {
2193: return Collections.EMPTY_MAP;
2194: }
2195:
2196: if (rpn == null) {
2197: logger.log(Level.FINEST, "Building property map for "
2198: + collection.getName());
2199: return buildPropertyMap(collection, pfList);
2200: }
2201:
2202: String name = getHead(rpn, COLLECTION_NAME_SEPARATOR);
2203: if (collection instanceof DPProperties) {
2204: collection = (DPCollection) ((DPProperties) collection)
2205: .get(name, pfList, false, false);
2206: } else {
2207: collection = (DPCollection) collection.get(name);
2208: }
2209:
2210: return getNestedProperties(collection, getFollowing(rpn, name,
2211: COLLECTION_NAME_SEPARATOR), pfList);
2212: }
2213:
2214: /**
2215: * @param collection The DPCollection object from which to extract the
2216: * properties and build a map.
2217: * @returns Map containing name=DPProperty pairs.
2218: */
2219: private Map buildPropertyMap(DPCollection collection, List pfList) {
2220: Set names = null;
2221: boolean dpPropertiesObject = collection instanceof DPProperties;
2222: if (dpPropertiesObject) {
2223: /**
2224: * get all names with scoped=true to fix 6338036.
2225: * The properties from parent prop holder will get filtered
2226: * in the while loop below.
2227: */
2228: names = ((DPProperties) collection).getNames(true);
2229: } else {
2230: names = collection.getNames();
2231: }
2232: names = (names == null) ? Collections.EMPTY_SET : names;
2233: Map map = new HashMap(names.size());
2234: Iterator iter = names.iterator();
2235: while (iter.hasNext()) {
2236: String name = (String) iter.next();
2237: DPProperty prop = null;
2238: if (dpPropertiesObject) {
2239: /* if the collection is an instance of either DPProperties (channel
2240: * properties at top level) or DPConditionalProperties, then
2241: * a scoped lookup needs to be done with scope=false to filter
2242: * out the proeprties from the parent property holder.
2243: */
2244: prop = ((DPProperties) collection).get(name, pfList,
2245: false, false);
2246: } else {
2247: prop = collection.get(name);
2248: }
2249: if (prop != null && !hideProperty(name, prop)) {
2250: map.put(name, prop);
2251: }
2252: }
2253:
2254: logger.log(Level.FINEST, "Map contains " + map.size()
2255: + " properties.");
2256:
2257: return map;
2258: }
2259:
2260: /**
2261: * A property is hidden if
2262: * - it is a conditional property
2263: * - name starts with underscore
2264: * - is of type Locale
2265: * @returns true if property should be hidden
2266: */
2267: private boolean hideProperty(String name, DPProperty property) {
2268: boolean hide = false;
2269: short type = property.getType();
2270:
2271: if (type == UNKNOWN_DP) {
2272: /* filter unknown type*/
2273: hide = true;
2274: } else if (type == LOCALE_DP || type == CONDITIONAL_DP
2275: || name.startsWith("_")) {
2276: /* filter any property starting with underscore
2277: * or conditional or of type LOCALE.*/
2278: hide = true;
2279: }
2280:
2281: if (hide) {
2282: logger.log(Level.FINEST, "Property " + name + " is hidden");
2283: }
2284: return hide;
2285: }
2286:
2287: /**
2288: * Returns the list of client and locale filters
2289: *
2290: * if client=WML,Nokia, then it will add 2 client filters to the list
2291: * as client=WML and client=Nokia
2292: * if locale = en_US_POSIX
2293: * then it will add 3 locale filters
2294: * locale=en
2295: * locale-US
2296: * locale=POSIX
2297: * so the returning list should now have 5 filters
2298: *
2299: * if locale is en_US, then it adds 2 filters to the list
2300: * if locale is en, then it adds one filter
2301: * if locale is US_WIN, then also it will add 2 filters although it is
2302: * not known if this is of any use
2303: *
2304: */
2305: private List getFilterList(String client, String locale) {
2306: List pfList = new ArrayList();
2307: try {
2308: PropertiesFilter filter = null;
2309:
2310: //if client = WML,Nokia
2311: //then it will add 2 client filters
2312: //client=WML
2313: //client=Nokia
2314: if (client != null && client.length() != 0) {
2315: String[] clientFragments = client
2316: .split(CLIENT_SEPARATOR);
2317: for (int i = 0; i < clientFragments.length; i++) {
2318: if (clientFragments[i] != null) {
2319: //remove leading and trailing spaces
2320: clientFragments[i] = clientFragments[i].trim();
2321: }
2322: if (clientFragments[i] != null
2323: && clientFragments[i].length() != 0
2324: && !clientFragments[i].equals("null")) {
2325: filter = PropertiesFilterFactory
2326: .get(
2327: PropertiesFilterFactory.CLIENT_PROPERTIESFILTER_CLASSNAME,
2328: clientFragments[i]);
2329: pfList.add(filter);
2330: logger.log(Level.FINEST, "Added client="
2331: + clientFragments[i] + " filter");
2332: }
2333: }
2334: }
2335:
2336: //if locale = en_US_POSIX
2337: //then it will add 3 filters
2338: //locale=en
2339: //locale-US
2340: //locale=POSIX
2341: if (locale != null && locale.length() != 0) {
2342: String[] localeFragments = locale.split("_");
2343: for (int i = 0; i < localeFragments.length; i++) {
2344: if (localeFragments[i] != null
2345: && localeFragments[i].length() != 0
2346: && !localeFragments[i].equals("null")) {
2347: filter = PropertiesFilterFactory
2348: .get(
2349: PropertiesFilterFactory.LOCALE_PROPERTIESFILTER_CLASSNAME,
2350: localeFragments[i]);
2351: pfList.add(filter);
2352: logger.log(Level.FINEST, "Added locale="
2353: + localeFragments[i] + " filter");
2354: }
2355: }
2356: }
2357: } catch (PropertiesFilterException pfe) {
2358: logger.log(Level.SEVERE,
2359: "Unable to create properties filter: "
2360: + pfe.getMessage());
2361: pfList = Collections.EMPTY_LIST;
2362: }
2363: return pfList;
2364: }
2365:
2366: public void setNodeProperties(String fqcn, String rpn,
2367: String client, String locale, Object values)
2368: throws TaskAdminException {
2369: if (fqcn == null || values == null) {
2370: logger.log(Level.SEVERE, "fqcn or values can not be null");
2371: throw new TaskAdminException(
2372: "fqcn or values can not be null");
2373: }
2374:
2375: logger.log(Level.FINEST, "Setting properties " + values
2376: + " for " + fqcn);
2377:
2378: //build a properties filter list for client and locale
2379: List pfList = getFilterList(client, locale);
2380:
2381: logger.log(Level.FINEST, "Set properties using "
2382: + pfList.size() + " filters");
2383:
2384: if (rpn == null && values instanceof List) {
2385: logger
2386: .log(
2387: Level.SEVERE,
2388: "Can not set name-value pairs as values is a List"
2389: + " and channel top level can not contain un-named properties");
2390: throw new TaskAdminException("Can not set name-value pairs"
2391: + " for " + fqcn + "due to incorrect arguments");
2392: }
2393:
2394: if (rpn == null && values instanceof Map) { //set channel level properties
2395: Map modifiedMap = (Map) values;
2396: Iterator iter = modifiedMap.keySet().iterator();
2397: while (iter.hasNext()) {
2398: String name = (String) iter.next();
2399: Object value = modifiedMap.get(name);
2400: if (fqcn != null
2401: && fqcn.equals(DesktopConstants.DP_ROOT_NODE)) {
2402: //pass null to set*Property() methods to set global props.
2403: fqcn = null;
2404: }
2405: if (value instanceof Boolean) {
2406: setBooleanProperty(fqcn, name, ((Boolean) value)
2407: .booleanValue(), pfList);
2408: } else if (value instanceof Integer) {
2409: setIntegerProperty(fqcn, name, ((Integer) value)
2410: .intValue(), pfList);
2411: } else if (value instanceof String) {
2412: setStringProperty(fqcn, name, (String) value,
2413: pfList);
2414: }
2415: }
2416: } else { //set collection properties - this can be nested
2417: //get the channel to begin with
2418: boolean isDPRoot = fqcn != null
2419: && fqcn.equals(DesktopConstants.DP_ROOT_NODE);
2420: DPProperties channelProperties = null;
2421: DPCollection c4 = null;
2422: List collectionList = new ArrayList();
2423: if (isDPRoot) {
2424: channelProperties = dpRoot.getProperties();
2425: c4 = getNestedCollection(channelProperties, rpn,
2426: pfList, null);
2427: } else {
2428: DPChannel channel = getDPChannel(fqcn);
2429:
2430: if (channel == null) {
2431: logger.log(Level.SEVERE, "Channel " + fqcn
2432: + " does not exist");
2433: Object[] tokens = { fqcn };
2434: throw new TaskAdminException(INVALID_CHANNEL,
2435: "Channel is null", tokens);
2436: }
2437:
2438: //get all props at channel level
2439: channelProperties = channel.getProperties();
2440: if (channelProperties == null) {
2441: logger.log(Level.SEVERE, "Channel " + fqcn
2442: + " properties does not exist");
2443: Object[] tokens = { fqcn };
2444: throw new TaskAdminException(INVALID_CHANNEL,
2445: "Channel properties null", tokens);
2446: }
2447:
2448: //get provider properties for collection information
2449: DPProvider provider = channel.getProvider();
2450: if (provider == null) {
2451: logger.log(Level.SEVERE, "Provider is null for "
2452: + fqcn + "channel");
2453: Object[] tokens = { fqcn };
2454: throw new TaskAdminException(INVALID_PROVIDER,
2455: "Provider does not exist for channel "
2456: + fqcn, tokens);
2457: }
2458:
2459: //get all the collections in the rpn from the provider
2460: //so if any collection needs to be customized at the channel
2461: //then we can find out if it is advanced or basic
2462: DPProperties providerProperties = provider
2463: .getProperties();
2464: collectionList = getNestedCollectionList(
2465: providerProperties, rpn, new ArrayList());
2466:
2467: //build a categories map - name = advanced(t/f)
2468: Map collectionCategories = new HashMap();
2469: Iterator collsIter = collectionList.iterator();
2470: while (collsIter.hasNext()) {
2471: DPCollection pc = (DPCollection) collsIter.next();
2472: collectionCategories.put(pc.getName(), new Boolean(
2473: pc.isAdvanced()));
2474: }
2475:
2476: //if the rpn is c1/c2/c3/c4, then get the collection c4
2477: //if hierarchy does not exist at the channel, then create it
2478: c4 = getNestedCollection(channelProperties, rpn,
2479: pfList, collectionCategories);
2480: }
2481: if (values instanceof Map) { //set name-value pairs in a collection
2482: Map modifiedMap = (Map) values;
2483: Iterator iter = modifiedMap.keySet().iterator();
2484: while (iter.hasNext()) {
2485: String name = (String) iter.next();
2486: Object value = modifiedMap.get(name);
2487: DPProperty property = c4.get(name);
2488: //if it is a customized/created collection, then it will
2489: //not have this property, so create it
2490: // for dproot property can never be null.
2491: if (property == null && !isDPRoot) {
2492: property = XMLDPFactory.getInstance()
2493: .createProperty(
2494: dpContext,
2495: dpRoot,
2496: ((XMLDPRoot) dpRoot)
2497: .getDocument(), name,
2498: value);
2499: property = c4.add(property);
2500: //set category - advanced/basic
2501: //for this, look up the category from provider
2502: //this proeprty is expected to be at the last index of
2503: //provider collections list
2504: int index = collectionList.size() - 1;
2505: if (index >= 0) { //if there exists any collection
2506: DPCollection pc = (DPCollection) collectionList
2507: .get(index); //get the last in the list
2508: DPProperty pProp = null;
2509: //if its the same provider collection
2510: if (pc.getName().equals(
2511: getTail(rpn,
2512: COLLECTION_NAME_SEPARATOR))) {
2513: pProp = pc.get(name);
2514: }
2515: if (pProp != null
2516: && pProp.getName().equals(name)
2517: && pProp.isAdvanced()) {
2518: property.setAdvanced(true);
2519: logger.log(Level.FINEST,
2520: "Setting property " + name
2521: + " as advanced");
2522: }
2523: }
2524: logger
2525: .log(
2526: Level.FINEST,
2527: "Property "
2528: + name
2529: + " added at channel inside collection "
2530: + rpn);
2531: }
2532: property.setValue(value);
2533: logger.log(Level.FINEST, "Property value set for "
2534: + name);
2535: }
2536: } else if (values instanceof List) { //set un-named properties
2537: List list = (List) values;
2538: //first add whatever is new
2539: //i.e. exists in the list but does not exist in the collection
2540: Collection jc = c4.getCollectionValue().values();
2541: Iterator iter = list.iterator();
2542: while (iter.hasNext()) {
2543: String value = (String) iter.next();
2544:
2545: //if it is a customized/created collection, then it will
2546: //not have this property, so create it
2547: if (!jc.contains(value)) {
2548: DPProperty property = XMLDPFactory
2549: .getInstance().createProperty(
2550: dpContext,
2551: dpRoot,
2552: ((XMLDPRoot) dpRoot)
2553: .getDocument(), value);
2554: property = c4.add(property);
2555: logger.log(Level.FINEST, "Property " + value
2556: + " added to " + c4.getName());
2557: }
2558: }
2559: //second remove whatever is removed
2560: //i.e. if it exists in collection but does not exist in the list
2561: iter = c4.getCollectionValue().values().iterator();
2562: while (iter.hasNext()) {
2563: String value = (String) iter.next();
2564: if (!list.contains(value)) {
2565: c4.remove(value);
2566: logger.log(Level.FINEST, "Property " + value
2567: + " removed from " + c4.getName());
2568: }
2569: }
2570: }
2571: }
2572:
2573: //finally, do not forget to write out the dp
2574: store();
2575: }
2576:
2577: /**
2578: * Returns a hierarchical list of all collections in the relative path name
2579: * So for c1/c2/c3, it will return a list of 3 DPCollection objects
2580: * If the full hierarchy does not exist, then whatever is there is
2581: * returned. So if there is only c1/c2, then 2 elements will be in the list
2582: */
2583: private List getNestedCollectionList(DPCollection collection,
2584: String rpn, List hierarchy) {
2585:
2586: if (collection == null) {
2587: //if the hierarchy does not exist, then return
2588: return hierarchy;
2589: } else {
2590: hierarchy.add(collection);
2591: }
2592:
2593: if (rpn == null) {
2594: return hierarchy;
2595: }
2596:
2597: String name = getHead(rpn, COLLECTION_NAME_SEPARATOR);
2598: if (collection instanceof DPProperties) {
2599: collection = (DPCollection) ((DPProperties) collection)
2600: .get(name, false);
2601: } else {
2602: collection = (DPCollection) collection.get(name);
2603: }
2604:
2605: return getNestedCollectionList(collection, getFollowing(rpn,
2606: name, COLLECTION_NAME_SEPARATOR), hierarchy);
2607: }
2608:
2609: /**
2610: * Recursively reaches the end of the relative property path and returns
2611: * the last collection in the relative property name(rpn) string.
2612: * If the collection does not exist, then it creates a new collection.
2613: * What this means is, if the collection hierarchy does not exist, then
2614: * it customizes it at the channel
2615: * To customize a collection, if it needs to be created then
2616: * it also needs a category as basic/adv. So all the provider
2617: * collections categories are sent in the map which contains
2618: * collection name and its Boolean object which tells whether it is
2619: * advanced or basic.
2620: */
2621: private DPCollection getNestedCollection(DPCollection collection,
2622: String rpn, List pfList, Map collectionCategories)
2623: throws TaskAdminException {
2624:
2625: //caller should not pass null, but...
2626: if (collection == null) {
2627: return null;
2628: }
2629:
2630: if (rpn == null) {
2631: logger.log(Level.FINEST,
2632: "Got the last collection in hierarchy: "
2633: + collection.getName());
2634: return collection;
2635: }
2636:
2637: String name = getHead(rpn, COLLECTION_NAME_SEPARATOR);
2638: DPCollection c = null;
2639: if (collection instanceof DPProperties) { //at channel top level
2640: c = (DPCollection) ((DPProperties) collection).get(name,
2641: pfList, true, false);
2642: //get with pfList should be with exact=true
2643: //and if fails then it needs to be created for that pfList
2644: if (c == null) {
2645: logger
2646: .log(
2647: Level.FINEST,
2648: "Collection "
2649: + name
2650: + " does not exist at the channel for given filter");
2651: //collection for given filter does not exist, so create it
2652: //set should be able to create it and set it if does
2653: //not already exist
2654: ((DPProperties) collection).setCollection(name,
2655: Collections.EMPTY_MAP, pfList, true);
2656: //get it again and this time it should succeed
2657: c = (DPCollection) ((DPProperties) collection).get(
2658: name, pfList, true, false);
2659: }
2660: } else { //inside a collection
2661: c = (DPCollection) collection.get(name);
2662: if (c == null) { //collection does not exist, so create
2663: c = (DPCollection) XMLDPFactory.getInstance()
2664: .createProperty(dpContext, dpRoot,
2665: ((XMLDPRoot) dpRoot).getDocument(),
2666: name, Collections.EMPTY_MAP);
2667: c = (DPCollection) collection.add(c);
2668:
2669: //if it is advanced in provider, set it advanced
2670: Boolean advanced = (Boolean) collectionCategories
2671: .get(name);
2672: if (advanced != null && advanced.booleanValue()) {
2673: c.setAdvanced(true);
2674: }
2675: logger
2676: .log(
2677: Level.FINEST,
2678: "Collection "
2679: + name
2680: + " does not exist at the channel, so creating it");
2681: }
2682: }
2683: if (c == null) {
2684: //if c is still null, then its hopeless situation
2685: //throw an exception
2686: throw new TaskAdminException(
2687: "Unable to customize collection hierarchy at the channel");
2688: }
2689: collection = c;
2690: return getNestedCollection(collection, getFollowing(rpn, name,
2691: COLLECTION_NAME_SEPARATOR), pfList,
2692: collectionCategories);
2693: }
2694:
2695: public void removeCustomization(String fqcn, String rpn,
2696: String client, String locale, List names)
2697: throws TaskAdminException {
2698: if (fqcn == null || names == null) {
2699: logger.log(Level.SEVERE, "fqcn or names can not be null");
2700: throw new TaskAdminException(
2701: "fqcn or names can not be null");
2702: }
2703:
2704: if (dpRootMerged) {
2705: logger.log(Level.SEVERE,
2706: "Can not remove customization on a merged dpRoot");
2707: throw new TaskAdminException(
2708: "Can not remove customization on a merged dpRoot");
2709: }
2710:
2711: if (names.isEmpty()) {
2712: logger.log(Level.FINEST,
2713: "The list for removing customization was empty");
2714: return;
2715: }
2716:
2717: //build a properties filter list for client and locale
2718: List pfList = getFilterList(client, locale);
2719:
2720: DPProperties channelProperties = null;
2721: if (fqcn != null && fqcn.equals(DesktopConstants.DP_ROOT_NODE)) {
2722: channelProperties = dpRoot.getProperties();
2723: } else {
2724: //get the channel to begin with
2725: DPChannel channel = getDPChannel(fqcn);
2726:
2727: if (channel == null) {
2728: logger.log(Level.SEVERE, "Channel " + fqcn
2729: + " does not exist");
2730: Object[] tokens = { fqcn };
2731: throw new TaskAdminException(INVALID_CHANNEL,
2732: "Channel is null", tokens);
2733: }
2734:
2735: //get all props at channel level
2736: channelProperties = channel.getProperties();
2737: }
2738:
2739: if (channelProperties == null) {
2740: logger.log(Level.SEVERE, "Channel " + fqcn
2741: + " properties does not exist");
2742: Object[] tokens = { fqcn };
2743: throw new TaskAdminException(INVALID_CHANNEL,
2744: "Channel properties null", tokens);
2745: }
2746:
2747: //if the rpn is c1/c2/c3/c4, then get the collection c4
2748: //if hierarchy does not exist at the channel, then create it.
2749: //Although the creation of the hierarchy is not required here, the
2750: //method getNestedCollection does it for setting the node props. This
2751: //does not hurt because even if the hierarchy gets created, it will be
2752: //empty and then the call to get(name) will not return anything.
2753: DPCollection c4 = getNestedCollection(channelProperties, rpn,
2754: pfList, null);
2755:
2756: Iterator iter = names.iterator();
2757: while (iter.hasNext()) {
2758: String name = (String) iter.next();
2759: DPProperty prop = c4.get(name);
2760: if (prop == null) {
2761: logger.log(Level.SEVERE,
2762: "Property is not customized here");
2763: //since we throw an exception here, none of the properties in
2764: //the list will be removed even if one fails. So this is all
2765: //or nothing operation
2766: throw new TaskAdminException(
2767: "Property is not customized here");
2768: } else {
2769: //if the property being removed is at the channel top level
2770: //then use the filter to remove the correct property
2771: //for a particular client_locale
2772: if (c4 instanceof DPProperties) {
2773: ((DPProperties) c4).remove(name, pfList);
2774: } else {
2775: //if the property being removed is inside a collection
2776: //then we already have a collection from a specific exact
2777: //client_locale returned by getNestedCollection
2778: c4.remove(name);
2779: }
2780: logger.log(Level.FINEST,
2781: "Property removed from this dp doc");
2782: store();
2783: //current dproot is non-merged.remove the dproot from map
2784: //so that merged dproot for the current dn is updated.
2785: dpRoots.remove(baseDN);
2786: DPRootCacheManager.updateDPRootCache(portalId, dpRoots);
2787: }
2788: }
2789: }
2790:
2791: public void createNodeProperty(String fqcn, String rpn,
2792: String client, String locale, String name, Object value,
2793: Boolean advanced) throws TaskAdminException {
2794: if (fqcn == null || name == null) {
2795: logger.log(Level.SEVERE, "fqcn or name can not be null");
2796: throw new TaskAdminException("fqcn or name can not be null");
2797: }
2798:
2799: //build a properties filter list for client and locale
2800: List pfList = getFilterList(client, locale);
2801:
2802: DPProperties channelProperties = null;
2803: if (fqcn != null && fqcn.equals(DesktopConstants.DP_ROOT_NODE)) {
2804: channelProperties = dpRoot.getProperties();
2805: } else {
2806:
2807: //get the channel to begin with
2808: DPChannel channel = getDPChannel(fqcn);
2809:
2810: if (channel == null) {
2811: logger.log(Level.SEVERE, "Channel " + fqcn
2812: + " does not exist");
2813: Object[] tokens = { fqcn };
2814: throw new TaskAdminException(INVALID_CHANNEL,
2815: "Channel is null", tokens);
2816: }
2817:
2818: //get all props at channel level
2819: channelProperties = channel.getProperties();
2820: }
2821: if (channelProperties == null) {
2822: logger.log(Level.SEVERE, "Channel " + fqcn
2823: + " properties does not exist");
2824: Object[] tokens = { fqcn };
2825: throw new TaskAdminException(INVALID_CHANNEL,
2826: "Channel properties null", tokens);
2827: }
2828:
2829: //if the rpn is c1/c2/c3/c4, then get the collection c4
2830: //if hierarchy does not exist at the channel, then create it.
2831: DPCollection c4 = getNestedCollection(channelProperties, rpn,
2832: pfList, null);
2833:
2834: DPProperty property = XMLDPFactory
2835: .getInstance()
2836: .createProperty(dpContext, dpRoot,
2837: ((XMLDPRoot) dpRoot).getDocument(), name, value);
2838:
2839: if (advanced.booleanValue()) {
2840: property.setAdvanced(true);
2841: }
2842:
2843: c4.add(property);
2844: store();
2845: }
2846:
2847: }
|