0001: /*
0002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
0003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
0004: */
0005: package com.sun.portal.desktop.context;
0006:
0007: import java.util.Iterator;
0008: import java.util.List;
0009: import java.util.ArrayList;
0010: import java.util.Map;
0011: import java.util.HashMap;
0012: import java.util.Set;
0013: import java.util.HashSet;
0014: import java.util.Collections;
0015:
0016: import java.net.URL;
0017: import java.net.MalformedURLException;
0018:
0019: import javax.servlet.http.HttpServletRequest;
0020:
0021: import com.sun.portal.desktop.util.SmartMap;
0022: import com.sun.portal.desktop.util.SmartList;
0023: import com.sun.portal.desktop.util.Integers;
0024:
0025: import com.sun.portal.desktop.dp.DPNode;
0026: import com.sun.portal.desktop.dp.DPRoot;
0027: import com.sun.portal.desktop.dp.DPCollection;
0028: import com.sun.portal.desktop.dp.DPChannel;
0029: import com.sun.portal.desktop.dp.DPContainerChannel;
0030: import com.sun.portal.desktop.dp.DPProvider;
0031: import com.sun.portal.desktop.dp.DPString;
0032: import com.sun.portal.desktop.dp.DPBoolean;
0033: import com.sun.portal.desktop.dp.DPInteger;
0034: import com.sun.portal.desktop.dp.DPProperty;
0035: import com.sun.portal.desktop.dp.DPException;
0036: import com.sun.portal.desktop.dp.DPTypes;
0037:
0038: import com.sun.portal.desktop.context.DesktopContextThreadLocalizer;
0039: import com.sun.portal.desktop.context.DesktopAppContextThreadLocalizer;
0040:
0041: import com.sun.portal.providers.ProviderEditTypes;
0042: import com.sun.portal.providers.ProviderWidths;
0043: import com.sun.portal.providers.context.PropertiesFilter;
0044: import com.sun.portal.providers.context.PropertiesFilterException;
0045:
0046: public class DPPropertiesContext implements PropertiesContext, DPTypes {
0047:
0048: private static final String SELECTED = "_selected";
0049: private static final String AVAILABLE = "_available";
0050:
0051: private static final String CLASSNAME = "_classname";
0052: private static final String PROVIDERNAME = "_providername";
0053: private static final String PROVIDERVERSION = "_providerversion";
0054:
0055: /*
0056: * Initially the critical region where a channel is first created
0057: * from the diplay profile was guarded with dpRoot as the lock. This
0058: * created a problem in a rare case like in a situation when the first
0059: * request is creating an element [Channel/Property] and the second
0060: * request queries for the same element. There is a point in time the
0061: * element is not yet well formed. Since, this lock is not common to
0062: * both the request there is a problem here.
0063: *
0064: * To avoid this, now a static lock common to all the users is used to
0065: * protect the critical region the first time when the element is created.
0066: */
0067: private static final Object dpLock = new Object();
0068:
0069: protected Map dpChannels = new HashMap();
0070: protected Map properties = new HashMap();
0071: protected Map channelLists = new HashMap();
0072:
0073: protected DPRoot dpRoot = null;
0074:
0075: public synchronized void init(HttpServletRequest req) {
0076: dpRoot = getDesktopContext().getDPRoot();
0077: }
0078:
0079: public synchronized void refresh() {
0080: dpRoot = getDesktopContext().getDPRoot();
0081:
0082: dpChannels.clear();
0083: properties.clear();
0084: channelLists.clear();
0085: }
0086:
0087: protected void cloneIfNecessary() {
0088: if (!getDesktopContext().isDPRootCustomized()) {
0089: getDesktopContext().setDPRootCustomized(true);
0090: refresh();
0091: }
0092: }
0093:
0094: public synchronized boolean existsChannel(String channel) {
0095: DPChannel dpc = dpRoot.getChannel(channel);
0096:
0097: if (dpc != null) {
0098: return true;
0099: }
0100:
0101: return false;
0102: }
0103:
0104: public void createChannel(String channelName, String providerName) {
0105: cloneIfNecessary();
0106:
0107: synchronized (dpLock) {
0108: dpRoot.createChannel(channelName, providerName);
0109: }
0110: }
0111:
0112: public void createContainer(String channelName, String providerName) {
0113: cloneIfNecessary();
0114:
0115: synchronized (dpLock) {
0116: dpRoot.createContainerChannel(channelName, providerName);
0117: }
0118: }
0119:
0120: public void removeChannel(String channelName) {
0121: cloneIfNecessary();
0122:
0123: synchronized (dpLock) {
0124: dpRoot.removeChannel(channelName);
0125: }
0126: }
0127:
0128: public void copyChannel(String srcName, String destName) {
0129: cloneIfNecessary();
0130:
0131: synchronized (dpLock) {
0132: dpRoot.copyChannel(srcName, destName);
0133: }
0134: }
0135:
0136: protected DPChannel getDPChannel(String name) {
0137: DPChannel dpc = (DPChannel) dpChannels.get(name);
0138:
0139: if (dpc == null) {
0140: //
0141: // two threads can get in here. that's okay, they
0142: // just end up putting the same dpChannel into
0143: // dpChannels twice
0144: //
0145: synchronized (dpLock) {
0146: dpc = dpRoot.getChannel(name);
0147: }
0148: }
0149:
0150: if (dpc != null) {
0151: synchronized (this ) {
0152: dpChannels.put(name, dpc);
0153: }
0154: } else {
0155: throw new ContextError(
0156: "DPPropertiesContext.getDPChannel(): could not get dp channel="
0157: + name);
0158: }
0159:
0160: return dpc;
0161: }
0162:
0163: protected DPContainerChannel getDPContainerChannel(String name) {
0164: DPChannel dpc = getDPChannel(name);
0165: if (dpc == null) {
0166: throw new ContextError(
0167: "DPPropertiesContext.getDPContainerChannel(): could not get dp chanel for name="
0168: + name);
0169: }
0170: if (dpc.getType() != CONTAINER_DP) {
0171: throw new ContextError(
0172: "DPPropertiesContext.getDPContainerChannel(): was not a container name="
0173: + name);
0174: }
0175: DPContainerChannel dpcc = (DPContainerChannel) dpc;
0176:
0177: return dpcc;
0178: }
0179:
0180: protected DesktopContext getDesktopContext() {
0181: //
0182: // properties context is cached per-uid by the provider
0183: // context impl. therefore, we cannot hang on to a
0184: // reference to any particular desktop context
0185: // object
0186: //
0187: return DesktopContextThreadLocalizer.get();
0188: }
0189:
0190: public Iterator getNames(String channel) {
0191: //
0192: // TBD(jtb): cache the names Iterator?
0193: // this is not called very often ...
0194: //
0195: DPChannel dpc = getDPChannel(channel);
0196: synchronized (dpLock) {
0197: Iterator i = dpc.getProperties().getNames().iterator();
0198: return i;
0199: }
0200: }
0201:
0202: public Map getCollectionProperty(String channel, String key) {
0203: return getCollectionProperty(channel, key, null, null);
0204: }
0205:
0206: public Map getCollectionProperty(String channel, String key,
0207: List pflist) {
0208: return getCollectionProperty(channel, key, null, pflist);
0209: }
0210:
0211: public Map getCollectionProperty(String channel, String key, Map def) {
0212: return getCollectionProperty(channel, key, def, null);
0213: }
0214:
0215: public Map getCollectionProperty(String channel, String key,
0216: Map def, List pflist) {
0217: Map m = getCollectionPropertyNE(channel, key, pflist, false);
0218: if (m == null) {
0219: if (def == null) {
0220: throw new ContextError(
0221: "DPPropertiesContext.getCollectionProperty(): property not found in profile for channel="
0222: + channel + ", key=" + key);
0223: } else {
0224: m = def;
0225: }
0226: }
0227:
0228: return m;
0229: }
0230:
0231: protected Map getCollectionPropertyNE(String channel, String key,
0232: List pflist, boolean exact) {
0233: SmartMap m = null;
0234: if (!exact) {
0235: m = (SmartMap) getCachedProperty(channel, key, pflist);
0236: }
0237: if (m == null) {
0238: DPChannel dpc = getDPChannel(channel);
0239: DPCollection val = null;
0240: synchronized (dpLock) {
0241: val = dpc.getProperties().getCollection(key, pflist,
0242: exact);
0243: if (val != null) {
0244: Map n = val.getCollectionValue();
0245: m = new SmartMap(n);
0246: }
0247: }
0248:
0249: if (!exact) {
0250: synchronized (this ) {
0251: putCachedProperty(channel, key, pflist, m);
0252: }
0253: }
0254: } else {
0255: //
0256: // always revert the cache to the original value if the smart map
0257: // is not copied and if we call this method
0258: //
0259: if (m.isCopied()) {
0260: return m.cloneOriginalMap();
0261: } else {
0262: m.revert();
0263: }
0264: }
0265:
0266: return m;
0267: }
0268:
0269: public void setCollectionProperty(String channel, String key,
0270: Map val) {
0271: setCollectionProperty(channel, key, val, null);
0272: }
0273:
0274: public void setCollectionProperty(String channel, String key,
0275: Map val, List pflist) {
0276: cloneIfNecessary();
0277:
0278: DPChannel dpc = getDPChannel(channel);
0279: synchronized (dpLock) {
0280: dpc.getProperties().setCollection(key, val, pflist);
0281: }
0282:
0283: if (val instanceof SmartMap) {
0284: //
0285: // if it's already a smart map, set the original value to the
0286: // copied value (evolve)
0287: //
0288: Map cached = (Map) getCachedProperty(channel, key, pflist);
0289: if (cached == val) {
0290: // we are setting the previously cached value
0291: // FOR THIS PROPERTY, evolve the smart map
0292: // to the new value
0293: SmartMap m = (SmartMap) val;
0294: m.evolve();
0295: } else {
0296: // we are setting the previously cached value
0297: // FOR ANOTHER PROPERTY. make sure we do not
0298: // cache the same SmartMap for two different
0299: // properties
0300: SmartMap sm = (SmartMap) val;
0301: Map m = sm.getMap();
0302: val = new SmartMap(m);
0303: }
0304:
0305: } else {
0306: //
0307: // it's not a smart map, wrap it with a smart map wrapper
0308: //
0309: val = new SmartMap(val);
0310: }
0311:
0312: //
0313: // re-cache the property
0314: //
0315: synchronized (this ) {
0316: removeCachedProperty(channel, key, pflist);
0317: putCachedProperty(channel, key, pflist, val);
0318: }
0319: }
0320:
0321: public void setCollectionProperty(String channel, String key,
0322: List val) {
0323: setCollectionProperty(channel, key, val, null);
0324: }
0325:
0326: public void setCollectionProperty(String channel, String key,
0327: List val, List pflist) {
0328: cloneIfNecessary();
0329:
0330: DPChannel dpc = getDPChannel(channel);
0331: synchronized (dpLock) {
0332: dpc.getProperties().setCollection(key, val, pflist);
0333: }
0334:
0335: //
0336: // we cannot easily re-cache here, because we can only
0337: // cache Maps because the client will call
0338: // getCollectionProperty() and expect a Map
0339: // back.
0340: //
0341: // we could possibly convert the list to a Map
0342: // and re-cache it.
0343: //
0344: synchronized (this ) {
0345: removeCachedProperty(channel, key, pflist);
0346: }
0347: }
0348:
0349: public boolean getBooleanProperty(String channel, String key) {
0350: return getBooleanProperty(channel, key, null);
0351: }
0352:
0353: public boolean getBooleanProperty(String channel, String key,
0354: List pflist) {
0355: Boolean b = getBooleanPropertyNE(channel, key, pflist, false);
0356: if (b == null) {
0357: throw new ContextError(
0358: "DPPropertiesContext.getBooleanProperty(): property not found in profile for channel="
0359: + channel
0360: + ", key="
0361: + key
0362: + ", pflist="
0363: + pflist);
0364: }
0365:
0366: return b.booleanValue();
0367: }
0368:
0369: public boolean getBooleanProperty(String channel, String key,
0370: boolean def) {
0371: return getBooleanProperty(channel, key, def, null);
0372: }
0373:
0374: public boolean getBooleanProperty(String channel, String key,
0375: boolean def, List pflist) {
0376: Boolean b = getBooleanPropertyNE(channel, key, pflist, false);
0377: boolean c;
0378: if (b == null) {
0379: c = def;
0380: } else {
0381: c = b.booleanValue();
0382: }
0383:
0384: return c;
0385: }
0386:
0387: protected Boolean getBooleanPropertyNE(String channel, String key,
0388: List pflist, boolean exact) {
0389: Boolean b = null;
0390: if (!exact) {
0391: b = (Boolean) getCachedProperty(channel, key, pflist);
0392: }
0393: if (b == null) {
0394: DPChannel dpc = getDPChannel(channel);
0395: synchronized (dpLock) {
0396: DPBoolean val = dpc.getProperties().getBoolean(key,
0397: pflist, exact);
0398: if (val != null) {
0399: boolean c = val.getBooleanValue();
0400: if (c) {
0401: b = Boolean.TRUE;
0402: } else {
0403: b = Boolean.FALSE;
0404: }
0405: }
0406: }
0407:
0408: if (!exact) {
0409: synchronized (this ) {
0410: putCachedProperty(channel, key, pflist, b);
0411: }
0412: }
0413: }
0414:
0415: return b;
0416: }
0417:
0418: public void setBooleanProperty(String channel, String key,
0419: boolean val) {
0420: setBooleanProperty(channel, key, val, null);
0421: }
0422:
0423: public void setBooleanProperty(String channel, String key,
0424: boolean val, List pflist) {
0425: cloneIfNecessary();
0426:
0427: DPChannel dpc = getDPChannel(channel);
0428: Boolean b = null;
0429:
0430: synchronized (dpLock) {
0431: dpc.getProperties().setBoolean(key, val, pflist);
0432: if (val) {
0433: b = Boolean.TRUE;
0434: } else {
0435: b = Boolean.FALSE;
0436: }
0437: }
0438:
0439: synchronized (this ) {
0440: removeCachedProperty(channel, key, pflist);
0441: putCachedProperty(channel, key, pflist, b);
0442: }
0443: }
0444:
0445: public int getIntegerProperty(String channel, String key) {
0446: return getIntegerProperty(channel, key, null);
0447: }
0448:
0449: public int getIntegerProperty(String channel, String key,
0450: List pflist) {
0451: Integer i = getIntegerPropertyNE(channel, key, pflist, false);
0452: if (i == null) {
0453: throw new ContextError(
0454: "DPPropertiesContext.getIntegerProperty(): property not found in profile for channel="
0455: + channel + ", key=" + key);
0456: }
0457:
0458: return i.intValue();
0459: }
0460:
0461: public int getIntegerProperty(String channel, String key, int def) {
0462: return getIntegerProperty(channel, key, def, null);
0463: }
0464:
0465: public int getIntegerProperty(String channel, String key, int def,
0466: List pflist) {
0467: Integer i = getIntegerPropertyNE(channel, key, pflist, false);
0468: int j;
0469: if (i == null) {
0470: j = def;
0471: } else {
0472: j = i.intValue();
0473: }
0474:
0475: return j;
0476: }
0477:
0478: protected Integer getIntegerPropertyNE(String channel, String key,
0479: List pflist, boolean exact) {
0480: Integer j = null;
0481: if (!exact) {
0482: j = (Integer) getCachedProperty(channel, key, pflist);
0483: }
0484: if (j == null) {
0485: DPChannel dpc = getDPChannel(channel);
0486: synchronized (dpLock) {
0487: DPInteger val = dpc.getProperties().getInteger(key,
0488: pflist, exact);
0489: if (val != null) {
0490: j = Integers.get(val.getIntValue());
0491: }
0492: }
0493: if (!exact) {
0494: synchronized (this ) {
0495: putCachedProperty(channel, key, pflist, j);
0496: }
0497: }
0498: }
0499:
0500: return j;
0501: }
0502:
0503: public void setIntegerProperty(String channel, String key, int val) {
0504: setIntegerProperty(channel, key, val, null);
0505: }
0506:
0507: public void setIntegerProperty(String channel, String key, int val,
0508: List pflist) {
0509: cloneIfNecessary();
0510:
0511: DPChannel dpc = getDPChannel(channel);
0512: synchronized (dpLock) {
0513: dpc.getProperties().setInteger(key, val, pflist);
0514: }
0515:
0516: synchronized (this ) {
0517: removeCachedProperty(channel, key, pflist);
0518: putCachedProperty(channel, key, pflist, Integers.get(val));
0519: }
0520: }
0521:
0522: public String getClassName(String channel) {
0523: String classname = (String) getCachedProperty(channel,
0524: CLASSNAME, null);
0525:
0526: if (classname == null) {
0527: DPChannel dpc = getDPChannel(channel);
0528: synchronized (dpLock) {
0529: DPProvider dpp = dpc.getProvider();
0530: if (dpp == null) {
0531: classname = null;
0532: } else {
0533: classname = dpp.getClassName();
0534: }
0535: }
0536:
0537: synchronized (this ) {
0538: putCachedProperty(channel, CLASSNAME, null, classname);
0539: }
0540: }
0541:
0542: return classname;
0543: }
0544:
0545: public String getProviderName(String channel) {
0546: String provider = (String) getCachedProperty(channel,
0547: PROVIDERNAME, null);
0548: if (provider == null) {
0549: DPChannel dpc = getDPChannel(channel);
0550: synchronized (dpLock) {
0551: provider = dpc.getProviderName();
0552: }
0553:
0554: synchronized (this ) {
0555: putCachedProperty(channel, PROVIDERNAME, null, provider);
0556: }
0557: }
0558:
0559: return provider;
0560: }
0561:
0562: public int getProviderVersion(String channel) {
0563: int version = 0;
0564: Integer cachedVersion = (Integer) getCachedProperty(channel,
0565: PROVIDERVERSION, null);
0566: if (cachedVersion == null) {
0567: DPChannel dpc = getDPChannel(channel);
0568: synchronized (dpLock) {
0569: DPProvider dpp = dpc.getProvider();
0570: if (dpp == null) {
0571: throw new ContextError(
0572: "DPPropertiesContext.getProviderVersion(): provider was null or channel="
0573: + channel);
0574: }
0575: version = dpp.getProviderVersion();
0576: }
0577:
0578: synchronized (this ) {
0579: putCachedProperty(channel, PROVIDERVERSION, null,
0580: new Integer(version));
0581: }
0582: } else {
0583: version = cachedVersion.intValue();
0584: }
0585:
0586: return version;
0587: }
0588:
0589: public Object getProperty(String channel, String key) {
0590: return getProperty(channel, key, null);
0591: }
0592:
0593: public Object getProperty(String channel, String key, Object def) {
0594: Object o = getPropertyNE(channel, key);
0595: if (o == null) {
0596: if (def == null) {
0597: throw new ContextError(
0598: "DPPropertiesContext.getProperty(): property not found in profile for channel="
0599: + channel + ", key=" + key);
0600: } else {
0601: o = def;
0602: }
0603: }
0604:
0605: return o;
0606: }
0607:
0608: protected Object getPropertyNE(String channel, String key) {
0609: Object o = getCachedProperty(channel, key, null);
0610: if (o == null) {
0611: DPChannel dpc = getDPChannel(channel);
0612: synchronized (dpLock) {
0613: DPProperty val = dpc.getProperties().get(key);
0614: if (val != null) {
0615: o = val.getValue();
0616: }
0617: }
0618:
0619: if (o instanceof Map) {
0620: o = new SmartMap((Map) o);
0621: }
0622:
0623: synchronized (this ) {
0624: putCachedProperty(channel, key, null, o);
0625: }
0626: } else {
0627: if (o instanceof Map) {
0628: SmartMap sm = (SmartMap) o;
0629: if (sm.isCopied()) {
0630: return sm.cloneOriginalMap();
0631: } else {
0632: sm.revert();
0633: }
0634: }
0635: }
0636:
0637: return o;
0638: }
0639:
0640: public void setProperty(String channel, String key, Object val) {
0641: cloneIfNecessary();
0642:
0643: DPChannel dpc = getDPChannel(channel);
0644: synchronized (dpLock) {
0645: dpc.getProperties().set(key, val, (List) null);
0646: }
0647:
0648: if (val instanceof Map) {
0649: if (val instanceof SmartMap) {
0650: //
0651: // if it's already a smart map, set the original value to the
0652: // copied value (evolve)
0653: //
0654: SmartMap m = (SmartMap) val;
0655: m.evolve();
0656: } else {
0657: //
0658: // it's not a smart map, wrap it with a smart map wrapper
0659: //
0660: val = new SmartMap((Map) val);
0661: }
0662: }
0663:
0664: synchronized (this ) {
0665: putCachedProperty(channel, key, null, val);
0666: }
0667: }
0668:
0669: public String getStringProperty(String channel, String key) {
0670: return getStringProperty(channel, key, null, null);
0671: }
0672:
0673: public String getStringProperty(String channel, String key,
0674: String def) {
0675: return getStringProperty(channel, key, def, null);
0676: }
0677:
0678: public String getStringProperty(String channel, String key,
0679: List pflist) {
0680: return getStringProperty(channel, key, null, pflist);
0681: }
0682:
0683: public String getStringProperty(String channel, String key,
0684: String def, List pflist) {
0685: String s = getStringPropertyNE(channel, key, pflist, false);
0686: if (s == null) {
0687: if (def == null) {
0688: throw new ContextError(
0689: "DPPropertiesContext.getStringProperty(): property not found in profile for channel="
0690: + channel + ", key=" + key);
0691: } else {
0692: s = def;
0693: }
0694: }
0695: return s;
0696: }
0697:
0698: /**
0699: * This method will return value for the property for a given locale
0700: * If the value is not available it will return null. Used for l10n of portlet titles.
0701: * @param channel Channel name
0702: * @param key Property key
0703: * @param pflist Locale filter(s)
0704: * @param exact Boolean flag true - for exact value false - default if exact value is not available.
0705: * @return Property value as a string
0706: */
0707: public String getStringProperty(String channel, String key,
0708: List pflist, boolean exact) {
0709: return getStringPropertyNE(channel, key, pflist, exact);
0710: }
0711:
0712: protected String getStringPropertyNE(String channel, String key,
0713: List pflist, boolean exact) {
0714: String s = null;
0715: if (!exact) {
0716: s = (String) getCachedProperty(channel, key, pflist);
0717: }
0718: if (s == null) {
0719: DPChannel dpc = getDPChannel(channel);
0720:
0721: synchronized (dpLock) {
0722: DPString val = dpc.getProperties().getString(key,
0723: pflist, exact);
0724: if (val != null) {
0725: s = val.getStringValue();
0726: }
0727: }
0728: if (!exact) {
0729: synchronized (this ) {
0730: putCachedProperty(channel, key, pflist, s);
0731: }
0732: }
0733: }
0734:
0735: return s;
0736: }
0737:
0738: public void setStringProperty(String channel, String key, String val) {
0739: cloneIfNecessary();
0740:
0741: DPChannel dpc = getDPChannel(channel);
0742: synchronized (dpLock) {
0743: dpc.getProperties().setString(key, val);
0744: }
0745:
0746: synchronized (this ) {
0747: removeCachedProperty(channel, key, null);
0748: putCachedProperty(channel, key, null, val);
0749: }
0750: }
0751:
0752: public void setStringProperty(String channel, String key,
0753: String val, List pflist) {
0754: cloneIfNecessary();
0755:
0756: DPChannel dpc = getDPChannel(channel);
0757: synchronized (dpLock) {
0758: dpc.getProperties().setString(key, val, pflist);
0759: }
0760:
0761: synchronized (this ) {
0762: removeCachedProperty(channel, key, pflist);
0763: putCachedProperty(channel, key, pflist, val);
0764: }
0765: }
0766:
0767: public List getSelectedChannels(String container) {
0768: SmartList sl = (SmartList) getCachedChannelList(container,
0769: SELECTED);
0770: if (sl == null) {
0771: DPContainerChannel dpc = getDPContainerChannel(container);
0772: synchronized (dpLock) {
0773: sl = new SmartList(new ArrayList(dpc.getSelected()
0774: .getCollectionValue().values()));
0775: }
0776:
0777: synchronized (this ) {
0778: putCachedChannelList(container, SELECTED, sl);
0779: }
0780: } else {
0781: //
0782: // always revert the cache to the original value if we call
0783: // this method
0784: //
0785: if (sl.isCopied()) {
0786: return sl.cloneOriginalList();
0787: } else {
0788: sl.revert();
0789: }
0790: }
0791:
0792: return sl;
0793: }
0794:
0795: public List getAvailableChannels(String container) {
0796: SmartList sl = (SmartList) getCachedChannelList(container,
0797: AVAILABLE);
0798: if (sl == null) {
0799: DPContainerChannel dpc = getDPContainerChannel(container);
0800: synchronized (dpLock) {
0801: sl = new SmartList(new ArrayList(dpc.getAvailable()
0802: .getCollectionValue().values()));
0803: }
0804:
0805: synchronized (this ) {
0806: putCachedChannelList(container, AVAILABLE, sl);
0807: }
0808: } else {
0809: //
0810: // always revert the cache to the original value if we call
0811: // this method
0812: //
0813: if (sl.isCopied()) {
0814: return sl.cloneOriginalList();
0815: } else {
0816: sl.revert();
0817: }
0818: }
0819:
0820: return sl;
0821: }
0822:
0823: public void setSelectedChannels(String container, List sel) {
0824: cloneIfNecessary();
0825:
0826: DPContainerChannel dpc = getDPContainerChannel(container);
0827: synchronized (dpLock) {
0828: dpc.setSelected(sel);
0829: }
0830:
0831: if (sel instanceof SmartList) {
0832: //
0833: // if it's already a smart list in the cache, set the
0834: // original value to the copied value (evolve)
0835: //
0836: List cached = getCachedChannelList(container, SELECTED);
0837: if (cached == sel) {
0838: // we are setting the previously cached value
0839: // FOR THIS PROPERTY, evolve the smart list
0840: // to the new value
0841: SmartList sm = (SmartList) sel;
0842: sm.evolve();
0843: } else {
0844: // we are setting the previously cached value
0845: // FOR ANOTHER PROPERTY. make sure we do not
0846: // cache the same SmartList for two different
0847: // properties
0848: SmartList sl = (SmartList) sel;
0849: List l = sl.getList();
0850: sel = new SmartList(l);
0851: }
0852:
0853: } else {
0854: //
0855: // it's not a smart map, wrap it with a smart map wrapper
0856: //
0857: sel = new SmartList(sel);
0858: }
0859:
0860: synchronized (this ) {
0861: putCachedChannelList(container, SELECTED, sel);
0862: }
0863: }
0864:
0865: public void setAvailableChannels(String container, List avail) {
0866: cloneIfNecessary();
0867:
0868: DPContainerChannel dpc = getDPContainerChannel(container);
0869: synchronized (dpLock) {
0870: dpc.setAvailable(avail);
0871: }
0872:
0873: if (avail instanceof SmartList) {
0874: //
0875: // if it's already a smart list in the cache, set the
0876: // original value to the copied value (evolve)
0877: //
0878: List cached = getCachedChannelList(container, AVAILABLE);
0879: if (cached == avail) {
0880: // we are setting the previously cached value
0881: // FOR THIS PROPERTY, evolve the smart list
0882: // to the new value
0883: SmartList sm = (SmartList) avail;
0884: sm.evolve();
0885: } else {
0886: // we are setting the previously cached value
0887: // FOR ANOTHER PROPERTY. make sure we do not
0888: // cache the same SmartList for two different
0889: // properties
0890: SmartList sl = (SmartList) avail;
0891: List l = sl.getList();
0892: avail = new SmartList(l);
0893: }
0894: } else {
0895: //
0896: // it's not a smart map, wrap it with a smart map wrapper
0897: //
0898: avail = new SmartList(avail);
0899: }
0900:
0901: synchronized (this ) {
0902: putCachedChannelList(container, AVAILABLE, avail);
0903: }
0904: }
0905:
0906: public boolean existsStringProperty(String channel, String name) {
0907: String s = getStringPropertyNE(channel, name, null, false);
0908: if (s == null) {
0909: return false;
0910: }
0911: return true;
0912: }
0913:
0914: public boolean existsStringProperty(String channel, String name,
0915: List pflist) {
0916: String s = getStringPropertyNE(channel, name, pflist, false);
0917: if (s == null) {
0918: return false;
0919: }
0920: return true;
0921:
0922: }
0923:
0924: public boolean existsBooleanProperty(String channel, String name) {
0925: Boolean b = getBooleanPropertyNE(channel, name, null, false);
0926: if (b == null) {
0927: return false;
0928: }
0929: return true;
0930: }
0931:
0932: public boolean existsBooleanProperty(String channel, String name,
0933: List pflist) {
0934: Boolean b = getBooleanPropertyNE(channel, name, pflist, false);
0935: if (b == null) {
0936: return false;
0937: }
0938: return true;
0939: }
0940:
0941: public boolean existsIntegerProperty(String channel, String name) {
0942: Integer i = getIntegerPropertyNE(channel, name, null, false);
0943: if (i == null) {
0944: return false;
0945: }
0946: return true;
0947: }
0948:
0949: public boolean existsIntegerProperty(String channel, String name,
0950: List pflist) {
0951: Integer i = getIntegerPropertyNE(channel, name, pflist, false);
0952: if (i == null) {
0953: return false;
0954: }
0955: return true;
0956: }
0957:
0958: public boolean existsCollectionProperty(String channel, String name) {
0959: Map m = getCollectionPropertyNE(channel, name, null, false);
0960: if (m == null) {
0961: return false;
0962: }
0963: return true;
0964: }
0965:
0966: public boolean existsCollectionProperty(String channel,
0967: String name, List pflist) {
0968: Map m = getCollectionPropertyNE(channel, name, pflist, false);
0969: if (m == null) {
0970: return false;
0971: }
0972: return true;
0973: }
0974:
0975: ///////////////////////////////////////////////////////
0976:
0977: protected void putCachedProperty(String channel, String key,
0978: List pflist, Object o) {
0979: Map perFilter = null;
0980: boolean filtered = (pflist != null && pflist.size() > 0);
0981: if (filtered) {
0982: perFilter = (Map) properties.get(Boolean.TRUE);
0983: } else {
0984: perFilter = (Map) properties.get(Boolean.FALSE);
0985: }
0986: if (perFilter == null) {
0987: perFilter = new HashMap();
0988: if (filtered) {
0989: properties.put(Boolean.TRUE, perFilter);
0990: } else {
0991: properties.put(Boolean.FALSE, perFilter);
0992: }
0993: }
0994:
0995: Map perKey = (Map) perFilter.get(key);
0996: if (perKey == null) {
0997: perKey = new HashMap();
0998: perFilter.put(key, perKey);
0999: }
1000:
1001: Map perChannel = null;
1002: if (filtered) {
1003: String filterKey = getFilterKey(pflist);
1004: Map perPF = (Map) perKey.get(filterKey);
1005: if (perPF == null) {
1006: perPF = new HashMap();
1007: perKey.put(filterKey, perPF);
1008: }
1009: perChannel = (Map) perPF.get(channel);
1010: if (perChannel == null) {
1011: perChannel = new HashMap();
1012: perPF.put(channel, perChannel);
1013: }
1014: } else {
1015: perChannel = (Map) perKey.get(channel);
1016: if (perChannel == null) {
1017: perChannel = new HashMap();
1018: perKey.put(channel, perChannel);
1019: }
1020: }
1021:
1022: perChannel.put(channel, o);
1023: }
1024:
1025: protected Object removeCachedProperty(String channel, String key,
1026: List pflist) {
1027: Map perFilter = null;
1028:
1029: perFilter = (Map) properties.get(Boolean.FALSE); //non-filtered
1030: removeCachedPropertyInternal(channel, key, pflist, perFilter);
1031:
1032: perFilter = (Map) properties.get(Boolean.TRUE); //filtered
1033: return removeCachedPropertyInternal(channel, key, pflist,
1034: perFilter);
1035: }
1036:
1037: private Object removeCachedPropertyInternal(String channel,
1038: String key, List pflist, Map perFilter) {
1039: if (perFilter == null) {
1040: return null;
1041: }
1042:
1043: Map perKey = (Map) perFilter.remove(key);
1044: if (perKey == null) {
1045: return null;
1046: }
1047:
1048: boolean filtered = (pflist != null && pflist.size() > 0);
1049: Map perChannel = null;
1050: if (filtered) {
1051: Map perPF = (Map) perKey.remove(getFilterKey(pflist));
1052: if (perPF == null) {
1053: return null;
1054: }
1055: perChannel = (Map) perPF.remove(channel);
1056: } else {
1057: perChannel = (Map) perKey.remove(channel);
1058: }
1059:
1060: if (perChannel == null) {
1061: return null;
1062: }
1063:
1064: return perChannel.remove(channel);
1065: }
1066:
1067: protected Object getCachedProperty(String channel, String key,
1068: List pflist) {
1069: Map perFilter = null;
1070: boolean filtered = (pflist != null && pflist.size() > 0);
1071: if (filtered) {
1072: perFilter = (Map) properties.get(Boolean.TRUE);
1073: } else {
1074: perFilter = (Map) properties.get(Boolean.FALSE);
1075: }
1076: if (perFilter == null) {
1077: return null;
1078: }
1079:
1080: Map perKey = (Map) perFilter.get(key);
1081: if (perKey == null) {
1082: return null;
1083: }
1084:
1085: Map perChannel = null;
1086: if (filtered) {
1087: Map perPF = (Map) perKey.get(getFilterKey(pflist));
1088: if (perPF == null) {
1089: return null;
1090: }
1091: perChannel = (Map) perPF.get(channel);
1092: } else {
1093: perChannel = (Map) perKey.get(channel);
1094: }
1095:
1096: if (perChannel == null) {
1097: return null;
1098: }
1099:
1100: return perChannel.get(channel);
1101: }
1102:
1103: protected boolean existsCachedProperty(String channel, String key,
1104: List pflist) {
1105: Map perFilter = null;
1106: boolean filtered = (pflist != null && pflist.size() > 0);
1107: if (filtered) {
1108: perFilter = (Map) properties.get(Boolean.TRUE);
1109: } else {
1110: perFilter = (Map) properties.get(Boolean.FALSE);
1111: }
1112: if (perFilter == null) {
1113: return false;
1114: }
1115:
1116: Map perKey = (Map) perFilter.get(key);
1117: if (perKey == null) {
1118: return false;
1119: }
1120:
1121: Map perChannel = null;
1122: if (filtered) {
1123: Map perPF = (Map) perKey.get(getFilterKey(pflist));
1124: if (perPF == null) {
1125: return false;
1126: }
1127: perChannel = (Map) perPF.get(channel);
1128: } else {
1129: perChannel = (Map) perKey.get(channel);
1130: }
1131:
1132: if (perChannel == null) {
1133: return false;
1134: }
1135:
1136: return perChannel.containsKey(channel);
1137: }
1138:
1139: //////////////////////////////////////////////////////
1140:
1141: protected void putCachedChannelList(String channel, String type,
1142: List l) {
1143: Map perType = (Map) channelLists.get(type);
1144: if (perType == null) {
1145: perType = new HashMap();
1146: channelLists.put(type, perType);
1147: }
1148: Map perChannel = (Map) perType.get(channel);
1149: if (perChannel == null) {
1150: perChannel = new HashMap();
1151: perType.put(channel, perChannel);
1152: }
1153:
1154: perChannel.put(channel, l);
1155: }
1156:
1157: protected List getCachedChannelList(String channel, String type) {
1158: Map perType = (Map) channelLists.get(type);
1159: if (perType == null) {
1160: return null;
1161: }
1162: Map perChannel = (Map) perType.get(channel);
1163: if (perChannel == null) {
1164: return null;
1165: }
1166:
1167: return (List) perChannel.get(channel);
1168: }
1169:
1170: private String getFilterKey(List pflist) {
1171: StringBuffer b = new StringBuffer();
1172: for (int i = 0; i < pflist.size(); i++) {
1173: PropertiesFilter pf = (PropertiesFilter) pflist.get(i);
1174: if (pf == null) {
1175: return "null";
1176: } else {
1177: String condition = null;
1178: String value = null;
1179: try {
1180: condition = pf.getCondition();
1181: value = pf.getValue();
1182: } catch (PropertiesFilterException pfe) {
1183: throw new ContextError(
1184: "DPPropertiesContext.getFilterKey(): "
1185: + pfe);
1186: }
1187: b.append(condition);
1188: b.append("=");
1189: b.append(value);
1190: if (pf.isRequired()) {
1191: b.append("*");
1192: }
1193: }
1194: if (i < pflist.size()) {
1195: b.append("|");
1196: }
1197: }
1198: return b.toString();
1199:
1200: }
1201: }
|