0001: /**
0002: * Copyright 2002 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 iPlanet
0010: * are trademarks or registered trademarks of Sun Microsystems,
0011: * Inc. in the United States and other countries.
0012: */package com.sun.portal.app.calendarcommon.calendar;
0013:
0014: import com.sun.comclient.calendar.CalendarSession;
0015: import com.sun.comclient.calendar.CalendarStore;
0016: import com.sun.comclient.calendar.ICalendar;
0017: import com.sun.comclient.calendar.socs.SOCSCalendarStore;
0018: import com.sun.portal.app.calendarcommon.common.SharedServicesException;
0019: import com.sun.portal.app.calendarcommon.common.SharedServicesUtils;
0020: import com.sun.portal.app.calendarcommon.common.SharedServicesUtilsFactory;
0021: import com.sun.portal.log.common.PortalLogger;
0022: import com.sun.portal.portlet.impl.PortletRequestConstants;
0023: import com.sun.portal.portlet.service.provision.PortletProvisionPreferences;
0024: import com.sun.portal.portlet.service.provision.PortletProvisionPreferencesException;
0025: import com.sun.portal.search.demo.SearchDatabase;
0026: import com.sun.portal.search.soif.SOIF;
0027: import com.sun.ssoadapter.SSOAdapterException;
0028: import com.sun.ssoadapter.SSOAdapterFactory;
0029: import com.sun.ssoadapter.SSOAdapterSession;
0030: import com.sun.ssoadapter.SSOAdapter;
0031: import com.iplanet.sso.SSOToken;
0032: import java.util.HashMap;
0033: import java.util.Iterator;
0034: import java.util.Map;
0035: import java.util.Properties;
0036: import java.util.TimeZone;
0037: import java.util.logging.Level;
0038: import java.util.logging.Logger;
0039: import java.util.Enumeration;
0040: import java.io.IOException;
0041: import java.net.MalformedURLException;
0042: import javax.faces.context.FacesContext;
0043: import javax.portlet.PortletContext;
0044: import javax.portlet.PortletPreferences;
0045: import javax.portlet.PortletRequest;
0046: import javax.portlet.PortletSession;
0047: import javax.servlet.ServletContext;
0048: import javax.servlet.http.HttpServletRequest;
0049:
0050: /**
0051: * Implementation of SharedCalendarUtils.
0052: *
0053: * @author Nigel Jacobs
0054: * @created May 19, 2005
0055: *
0056: */
0057: public class SharedCalendarUtilsImpl implements SharedCalendarUtils {
0058:
0059: // Prefix that indicates user calendars
0060: private static final String USER_CAL_PREFIX = "USR_";
0061:
0062: // Prefix that indicates proxy calendars
0063: private static final String PROXY_CAL_PREFIX = "PRX_";
0064:
0065: private static final String CAL_ACL_PROP = "acl";
0066: private static final String CAL_DESCRIPTION_PROP = "desc";
0067: // Provide read/write/free-busy/schedule/invite access to to proxy cal by others
0068: private static final String PROXY_CAL_ACL = "@@o^c^wdeic^g;@@o^a^rsf^g;@^a^frs^g;@^c^dw^g;@^p^r^g";
0069: private static final String USER_CAL_ACL = "@@o^a^r^g;@@o^c^wdeic^g;@^a^sf^g;@^c^^g;@^p^r^g";
0070:
0071: private static final String MBR_CAL_DESCRIPTION = "WARNING: Do not delete or change permissions of this calendar, or community calendar applications may fail";
0072:
0073: private static Logger logger = PortalLogger
0074: .getLogger(SharedCalendarUtilsImpl.class);
0075:
0076: private ServletContext _context = null;
0077: private SharedServicesUtils _servicesUtils = null;
0078:
0079: // a cache of da handlers, indexed by community id.
0080: private Map _daHandlers = new HashMap();
0081:
0082: // cache of uid->CalStore for proxy cty calendars
0083: private HashMap _calStoreCache = new HashMap();
0084:
0085: private Map getProxyCalStoreCache() {
0086: return _calStoreCache;
0087: }
0088:
0089: // map of DA business org dn to sunPreferredDomain attr value
0090: private HashMap _sunPreferredDomainMap = new HashMap();
0091:
0092: private Map getSunPrefferedDomainMap() {
0093: return _sunPreferredDomainMap;
0094: }
0095:
0096: protected SharedCalendarUtilsImpl(ServletContext context) {
0097: _context = context;
0098: }
0099:
0100: /*
0101: ************************************************************
0102: *
0103: * BEGIN: Implementations of interface SharedCalendarUtils
0104: *
0105: ************************************************************
0106: */
0107:
0108: /**
0109: * Compute the community proxy users calendar id for this community.
0110: * "Friends" => "CTY_CAL_Friends"
0111: * @param portletRequest
0112: * @return Community proxys calendar id
0113: */
0114: public String getCommunityCalendarID(PortletRequest portletRequest)
0115: throws SharedServicesException {
0116:
0117: PortletPreferences preferences = portletRequest
0118: .getPreferences();
0119: HttpServletRequest servletRequest = (HttpServletRequest) portletRequest
0120: .getAttribute(PortletRequestConstants.HTTP_SERVLET_REQUEST);
0121: Properties configProps = getConfigProperties(preferences,
0122: servletRequest);
0123:
0124: return getCommunityCalendarID(getServicesUtils()
0125: .getCommunityID(portletRequest),
0126: getProxyCalDomainIfHosted(configProps));
0127: }
0128:
0129: /**
0130: * Compute the community proxy users calendar id for this community.
0131: * "Friends" => "CTY_CAL_Friends"
0132: * @param portletRequest
0133: * @return Community proxys calendar id
0134: */
0135: public String getCommunityCalendarID(FacesContext context)
0136: throws SharedServicesException {
0137: Object request = context.getExternalContext().getRequest();
0138: if (request instanceof PortletRequest) {
0139: return getCommunityCalendarID((PortletRequest) request);
0140: } else {
0141: throw new SharedServicesException(
0142: "Can't getCommunityCalendarID: only supporting Portlet environment.");
0143: }
0144: }
0145:
0146: /**
0147: * Compute the proxy user uid from the communityID
0148: * e.g. "Friends" => "CTY_CAL_PRX_JTO__Friends"
0149: */
0150: public String getProxyUser(String communityID) {
0151: return CTY_CAL_PREFIX + PROXY_CAL_PREFIX + communityID;
0152: }
0153:
0154: /**
0155: * Compute the community member's universal calendar id (common across communities). Uses
0156: * the cached organization param, retrieve from the request.
0157: * "joe" in organization "sun.com" => CTY_CAL_joe@sun.com
0158: * @param portletRequest
0159: * @param memberID
0160: * @return
0161: */
0162: public String getMemberCalendarID(PortletRequest portletRequest,
0163: String memberID) throws SharedServicesException {
0164:
0165: PortletPreferences preferences = portletRequest
0166: .getPreferences();
0167: HttpServletRequest servletRequest = (HttpServletRequest) portletRequest
0168: .getAttribute(PortletRequestConstants.HTTP_SERVLET_REQUEST);
0169: Properties configProps = getConfigProperties(preferences,
0170: servletRequest);
0171: String communityID = getServicesUtils().getCommunityID(
0172: portletRequest);
0173: return getUid(memberID)
0174: + ":"
0175: + getMemberCalendarLocalID(servletRequest, configProps,
0176: communityID, memberID);
0177: }
0178:
0179: /**
0180: * Compute the community member's universal calendar id (common across communities). Uses
0181: * the cached organization param, retrieve from the request.
0182: * "joe" in organization "sun.com" => CTY_CAL_joe@sun.com
0183: * @param context
0184: * @param memberID
0185: * @return
0186: */
0187: public String getMemberCalendarID(FacesContext context,
0188: String memberID) throws SharedServicesException {
0189: Object request = context.getExternalContext().getRequest();
0190: if (request instanceof PortletRequest) {
0191: return getMemberCalendarID((PortletRequest) request,
0192: memberID);
0193: } else {
0194: throw new SharedServicesException(
0195: "Can't getMemberCalendarID: only supporting Portlet environment.");
0196: }
0197: }
0198:
0199: /**
0200: * Get the user id, and configuration via the request.
0201: * Generate the calendar id from the user id.
0202: * If the calendar store is cached (indexed by calendar id), return it.
0203: * Otherwise connect to calendar server, get the users calendar store, and create the calendar with id,
0204: * setting default permissions, but allowing the proxy user update access.
0205: * Cache and return the store.
0206: * @param context
0207: * @param memberID
0208: * @return
0209: */
0210: public synchronized CalendarStore getMemberCalendarStore(
0211: FacesContext context, String memberID)
0212: throws SharedServicesException {
0213: Object request = context.getExternalContext().getRequest();
0214: if (request instanceof PortletRequest) {
0215: return getMemberCalendarStore((PortletRequest) request,
0216: memberID);
0217: } else {
0218: throw new SharedServicesException(
0219: "Can't getMemberCalendarStore: only supporting Portlet environment.");
0220: }
0221: }
0222:
0223: /**
0224: * Get the user id, and configuration via the request.
0225: * Generate the calendar id from the user id.
0226: * If the calendar store is cached (indexed by calendar id), return it.
0227: * Otherwise connect to calendar server, get the users calendar store, and create the calendar with id,
0228: * setting default permissions, but allowing the proxy user update access.
0229: * Cache and return the store.
0230: * @param portletRequest
0231: * @param memberID
0232: * @return
0233: */
0234: public synchronized CalendarStore getMemberCalendarStore(
0235: PortletRequest portletRequest, String memberID)
0236: throws SharedServicesException {
0237:
0238: PortletContext context = portletRequest.getPortletSession()
0239: .getPortletContext();
0240: SharedServicesUtils servicesUtils = SharedServicesUtilsFactory
0241: .getSharedServicesUtils(context);
0242: HttpServletRequest servletRequest = (HttpServletRequest) portletRequest
0243: .getAttribute(PortletRequestConstants.HTTP_SERVLET_REQUEST);
0244: String communityID = servicesUtils
0245: .getCommunityID(portletRequest);
0246: Map preferences = portletRequest.getPreferences().getMap();
0247:
0248: return getMemberCalendarStoreViaPrefs(preferences,
0249: servletRequest, communityID, memberID,
0250: getMemberCalStoreCache(portletRequest));
0251:
0252: }
0253:
0254: /**
0255: * Get the user id, and configuration via the request.
0256: * Generate the calendar id from the user id.
0257: * If the calendar store is cached (indexed by calendar id), return it.
0258: * Otherwise connect to calendar server, get the users calendar store, and create the calendar with id,
0259: * setting default permissions, but allowing the proxy user update access.
0260: * Cache and return the store
0261: * @param servletRequest
0262: * @param preferences The PortletPreferences / PortletProvisionPreferences map.
0263: * @param communityID
0264: * @param memberID
0265: * @return calendar store
0266: */
0267: public CalendarStore getMemberCalendarStore(
0268: HttpServletRequest servletRequest, Map preferences,
0269: String communityID, String memberID)
0270: throws SharedServicesException {
0271:
0272: return getMemberCalendarStoreViaPrefs(preferences,
0273: servletRequest, communityID, memberID,
0274: // don't pass a cache: this is only called from the provisioning code to create the
0275: // mbr cal store when mbr joins cty. The portlet apps call via the one of other 2
0276: // getMemberCalendarStore i/f, which will cache the cal store on the portlet session
0277: null);
0278:
0279: }
0280:
0281: /**
0282: * Get the community id, and the configuration via the request.
0283: * Generate the calendar id from the community id.
0284: * If the calendar store is cached (indexed by calendar id), return it.
0285: * Otherwise connect to calendar server, get the proxys calendar store, and create the calendar with id
0286: * Cache and return the store.
0287: * @param context
0288: * @return
0289: */
0290: public synchronized CalendarStore getProxyCalendarStore(
0291: FacesContext context) throws SharedServicesException {
0292: Object request = context.getExternalContext().getRequest();
0293: if (request instanceof PortletRequest) {
0294: return getProxyCalendarStore((PortletRequest) request);
0295: } else {
0296: throw new SharedServicesException(
0297: "Can't getProxyCalendarStore: only supporting Portlet environment.");
0298: }
0299: }
0300:
0301: /**
0302: * Generate the calendar id from the community id.
0303: * If the calendar store is cached (indexed by calendar id), return it.
0304: * Otherwise connect to calendar server, get the proxys calendar store, and create the calendar with id
0305: * Cache and return the store.
0306: * @param communityID
0307: * @return
0308: */
0309: public synchronized CalendarStore getProxyCalendarStore(
0310: PortletRequest portletRequest)
0311: throws SharedServicesException {
0312:
0313: PortletContext context = portletRequest.getPortletSession()
0314: .getPortletContext();
0315: SharedServicesUtils servicesUtils = SharedServicesUtilsFactory
0316: .getSharedServicesUtils(context);
0317: HttpServletRequest servletRequest = (HttpServletRequest) portletRequest
0318: .getAttribute(PortletRequestConstants.HTTP_SERVLET_REQUEST);
0319: String communityID = servicesUtils
0320: .getCommunityID(portletRequest);
0321: Map preferences = portletRequest.getPreferences().getMap();
0322:
0323: return getProxyCalendarStoreViaPrefs(preferences,
0324: servletRequest, communityID);
0325:
0326: }
0327:
0328: /**
0329: * Generate the calendar id from the community id.
0330: * If the calendar store is cached (indexed by calendar id), return it.
0331: * Otherwise connect to calendar server, get the proxys calendar store, and create the calendar with id
0332: * Cache and return the store.
0333: * @param preferences A read-only map of portlet prefs (PortletPreferences or PortletProvisionPreferences)
0334: * @param communityID
0335: * @return
0336: */
0337: public synchronized CalendarStore getProxyCalendarStore(
0338: PortletProvisionPreferences preferences,
0339: HttpServletRequest servletRequest, String communityID)
0340: throws SharedServicesException {
0341:
0342: try {
0343:
0344: Map prefsMap = new HashMap();
0345: Iterator names = preferences.getNames().iterator();
0346: while (names.hasNext()) {
0347: String name = (String) names.next();
0348: prefsMap.put(name, preferences.getValue(name));
0349: }
0350:
0351: return getProxyCalendarStoreViaPrefs(prefsMap,
0352: servletRequest, communityID);
0353:
0354: } catch (PortletProvisionPreferencesException e) {
0355: throw new SharedServicesException(
0356: "Cant get proxy cal store: " + e);
0357: }
0358:
0359: }
0360:
0361: /**
0362: * Delete the proxy calendar store
0363: */
0364: public synchronized void deleteProxyCalendarStore(
0365: String communityID, Properties configProps)
0366: throws SharedServicesException {
0367:
0368: String calID = getCommunityCalendarID(communityID,
0369: getProxyCalDomainIfHosted(configProps));
0370:
0371: Map calStoreCache = getProxyCalStoreCache();
0372: CalendarStore calStore = (CalendarStore) calStoreCache
0373: .get(calID);
0374:
0375: try {
0376:
0377: String fullID = calStore.verifyCalendarId(calID);
0378: calStore.deleteCalendar(fullID);
0379:
0380: if (logger.isLoggable(Level.FINE)) {
0381: logger.fine("Deleted proxy calendar: " + fullID);
0382: }
0383:
0384: // remove the cal store from the cache on servlet context
0385: calStoreCache.remove(calID);
0386:
0387: } catch (Exception e) {
0388: throw new SharedServicesException(
0389: "Can't delete cal store: " + calID, e);
0390: }
0391:
0392: }
0393:
0394: /**
0395: * Perform any clean up operations: close connections and release resources.
0396: */
0397: public void destroy() {
0398: }
0399:
0400: /**
0401: * Get the Shared Calendar configuration properties for this portlet.
0402: * Use the config name stored in the portlet prefs to look up the sso adapter config,
0403: * and return contained properties.
0404: * @param preferences
0405: * @param servletRequest
0406: * @return
0407: */
0408: public Properties getConfigProperties(
0409: PortletPreferences preferences,
0410: HttpServletRequest servletRequest)
0411: throws SharedServicesException {
0412: String configName = preferences.getValue(
0413: SHARED_CAL_CONFIG_ATTR, SHARED_CAL_CONFIG_DEFAULT);
0414: return getConfigProperties(configName, servletRequest);
0415: }
0416:
0417: /**
0418: * Get the Shared Calendar configuration properties for this portlet.
0419: * Use the config name stored in the portlet prefs to look up the sso adapter config,
0420: * and return contained properties.
0421: * @param preferences
0422: * @param servletRequest
0423: * @return
0424: */
0425: public Properties getConfigProperties(Map preferences,
0426: HttpServletRequest servletRequest)
0427: throws SharedServicesException {
0428:
0429: Object names = preferences.get(SHARED_CAL_CONFIG_ATTR);
0430: String configName = null;
0431: if (names instanceof String) {
0432: configName = (String) names;
0433: } else if (names instanceof String[]) {
0434: configName = ((String[]) names)[0];
0435: } else
0436: throw new SharedServicesException(
0437: "Can't get config name from preferences");
0438: if (configName == null)
0439: configName = SHARED_CAL_CONFIG_DEFAULT;
0440: return getConfigProperties(configName, servletRequest);
0441: }
0442:
0443: /**
0444: * Find of create a DelegatedAdministratorHandler for the community.
0445: * @param communityID The community ID.
0446: * @param configProps The SSO adapter configuration properties for the community.
0447: * @return The DelegatedAdministratorHandler for the community.
0448: */
0449: public DelegatedAdministratorHandler getDAHandler(
0450: String communityID, Properties configProps) {
0451: DelegatedAdministratorHandler daHandler = (DelegatedAdministratorHandler) _daHandlers
0452: .get(communityID);
0453: if (daHandler == null) {
0454: // pull through the da handler cache
0455: daHandler = new DelegatedAdministratorHandler(communityID,
0456: configProps, this );
0457: _daHandlers.put(communityID, daHandler);
0458: }
0459: return daHandler;
0460: }
0461:
0462: /**
0463: * Should events be created in the member's community calendar,
0464: * or solely in the proxy community calendar (defined in SSO adapter config param).
0465: * @param The faces context.
0466: * @return Whether to create events in members community calendar
0467: */
0468: public boolean createEventsInMembersCalendar(FacesContext context)
0469: throws SharedServicesException {
0470: Object request = context.getExternalContext().getRequest();
0471: if (request instanceof PortletRequest) {
0472: return createEventsInMembersCalendar((PortletRequest) request);
0473: } else {
0474: throw new SharedServicesException(
0475: "Can't createEventsInMembersCalendar: only supporting Portlet environment.");
0476: }
0477: }
0478:
0479: /**
0480: * Should events be created in the member's community calendar,
0481: * or solely in the proxy community calendar (defined in SSO adapter config param).
0482: * @param The portlet request.
0483: * @return Whether to create events in members community calendar
0484: */
0485: public boolean createEventsInMembersCalendar(
0486: PortletRequest portletRequest)
0487: throws SharedServicesException {
0488: PortletContext context = portletRequest.getPortletSession()
0489: .getPortletContext();
0490: HttpServletRequest servletRequest = (HttpServletRequest) portletRequest
0491: .getAttribute(PortletRequestConstants.HTTP_SERVLET_REQUEST);
0492: PortletPreferences preferences = portletRequest
0493: .getPreferences();
0494: Properties configProps = getConfigProperties(preferences,
0495: servletRequest);
0496: String val = configProps
0497: .getProperty(CONFIG_PROP_createEventsInMembersCal);
0498: // defaults to 'true'
0499: return (val == null) || !(val.equalsIgnoreCase("false"));
0500:
0501: }
0502:
0503: /*
0504: ************************************************************
0505: *
0506: * END: Implementations of interface SharedCalendarUtils
0507: *
0508: ************************************************************
0509: */
0510:
0511: /**
0512: * Compute the community proxy users calendar id for this community.
0513: * e.g. "JTO::Friends" => "CTY_CAL_PRX_JTO__Friends"
0514: * @param communityID
0515: * @param domainIfHosted
0516: * @return Community proxys calendar id
0517: */
0518: private String getCommunityCalendarID(String communityID,
0519: String domainIfHosted) {
0520: String s = getProxyUser(communityID);
0521:
0522: if (domainIfHosted != null) {
0523: s = s + "@" + domainIfHosted;
0524: }
0525: // DEBUG: REMOVE
0526: if (logger.isLoggable(Level.FINER))
0527: logger.finer("ctyID: " + communityID + ", dom: "
0528: + domainIfHosted + " => " + s);
0529: return s;
0530: }
0531:
0532: private CalendarStore getMemberCalendarStoreViaPrefs(
0533: Map preferences, HttpServletRequest servletRequest,
0534: String communityID, String memberID, Map calStoreCache)
0535: throws SharedServicesException {
0536:
0537: Properties configProps = getConfigProperties(preferences,
0538: servletRequest);
0539: String domainIfHosted = getMemberCalDomainIfHosted(configProps,
0540: communityID, memberID);
0541: String calID = getMemberCalendarLocalID(servletRequest,
0542: configProps, communityID, memberID);
0543: String mbrUid = getUid(memberID);
0544:
0545: return getCalendarStore(preferences, servletRequest, calID,
0546: mbrUid, USER_CAL_ACL, domainIfHosted,
0547: MBR_CAL_DESCRIPTION, calStoreCache);
0548:
0549: }
0550:
0551: private CalendarStore getProxyCalendarStoreViaPrefs(
0552: Map preferences, HttpServletRequest servletRequest,
0553: String communityID) throws SharedServicesException {
0554:
0555: Properties configProps = getConfigProperties(preferences,
0556: servletRequest);
0557: String domainIfHosted = getProxyCalDomainIfHosted(configProps);
0558: String calID = getCommunityCalendarID(communityID,
0559: domainIfHosted);
0560: String proxyUid = getProxyUser(communityID);
0561: Map cache = getProxyCalStoreCache();
0562:
0563: return getCalendarStore(preferences, servletRequest, calID,
0564: proxyUid, PROXY_CAL_ACL, domainIfHosted, null, cache);
0565:
0566: }
0567:
0568: /**
0569: *
0570: * Pull the calendar store through the cache. Create if necessary.
0571: */
0572: private CalendarStore getCalendarStore(Map preferences,
0573: HttpServletRequest servletRequest, String calID,
0574: String calUid, String calACL, String domainIfHosted,
0575: String description, Map calStoreCache)
0576: throws SharedServicesException {
0577:
0578: CalendarStore calStore = null;
0579: if (calStoreCache != null) {
0580: calStore = (CalendarStore) calStoreCache.get(calID);
0581: }
0582:
0583: try {
0584:
0585: // TODO: check if calStore is closed
0586: if (calStore == null) {
0587:
0588: Properties configProps = getConfigProperties(
0589: preferences, servletRequest);
0590:
0591: if (logger.isLoggable(Level.FINER)) {
0592: logger.finer("PROP: CONFIG_PROP_daHost, VALUE: "
0593: + configProps
0594: .getProperty(CONFIG_PROP_daHost));
0595: logger.finer("PROP: CONFIG_PROP_daPort, VALUE: "
0596: + configProps
0597: .getProperty(CONFIG_PROP_daPort));
0598: logger
0599: .finer("PROP: CONFIG_PROP_daProxyUid, VALUE: "
0600: + configProps
0601: .getProperty(CONFIG_PROP_daProxyUid));
0602: logger
0603: .finer("PROP: CONFIG_PROP_daProxyPassword, VALUE: "
0604: + configProps
0605: .getProperty(CONFIG_PROP_daProxyPassword));
0606: logger.finer("PROP: CONFIG_PROP_calHost, VALUE: "
0607: + configProps
0608: .getProperty(CONFIG_PROP_calHost));
0609: logger.finer("PROP: CONFIG_PROP_calPort, VALUE: "
0610: + configProps
0611: .getProperty(CONFIG_PROP_calPort));
0612: logger
0613: .finer("PROP: CONFIG_PROP_calProxyUid, VALUE: "
0614: + configProps
0615: .getProperty(CONFIG_PROP_calProxyUid));
0616: logger
0617: .finer("PROP: CONFIG_PROP_calProxyPassword, VALUE: "
0618: + configProps
0619: .getProperty(CONFIG_PROP_calProxyPassword));
0620: logger
0621: .finer("PROP: CONFIG_PROP_configDesc, VALUE: "
0622: + configProps
0623: .getProperty(CONFIG_PROP_configDesc));
0624: logger
0625: .finer("PROP: CONFIG_PROP_autoDeleteProxyUserCal, VALUE: "
0626: + configProps
0627: .getProperty(CONFIG_PROP_autoDeleteProxyUserCal));
0628: logger
0629: .finer("PROP: CONFIG_PROP_isHostedDomain, VALUE: "
0630: + configProps
0631: .getProperty(CONFIG_PROP_isHostedDomain));
0632: logger
0633: .finer("PROP: CONFIG_PROP_ssoClassName, VALUE: "
0634: + configProps
0635: .getProperty(CONFIG_PROP_ssoClassName));
0636: logger.finer("Cal ID:" + calID);
0637: logger.finer("Cal Uid:" + calUid);
0638: logger.finer("Cal ACL:" + calACL);
0639: logger.finer("Domain:" + domainIfHosted);
0640: }
0641:
0642: String host = configProps
0643: .getProperty(CONFIG_PROP_calHost);
0644: String portString = configProps
0645: .getProperty(CONFIG_PROP_calPort);
0646: int port = 0;
0647: try {
0648: port = Integer.parseInt(portString);
0649: } catch (NumberFormatException e) {
0650: throw new SharedServicesException(
0651: "Calendar Host Port: "
0652: + configProps
0653: .getProperty(CONFIG_PROP_calHost)
0654: + " is not an integer");
0655: }
0656:
0657: Properties sessionProps = new Properties();
0658: sessionProps.put("cal.host", host);
0659: sessionProps.put("cal.port", portString);
0660: sessionProps.put("cal.protocol", "http");
0661: // cal.user is actually proxy (priviliged / admin user)
0662: sessionProps.put("cal.user", configProps
0663: .getProperty(CONFIG_PROP_calProxyUid));
0664: sessionProps.put("cal.password", configProps
0665: .getProperty(CONFIG_PROP_calProxyPassword));
0666: // cal.proxyauth is actually the cal user, whose calendar we are trying to gain access
0667: sessionProps.put("cal.proxyauth", calUid);
0668: sessionProps.put("cal.http.usepost", "true");
0669:
0670: if (domainIfHosted != null) {
0671: sessionProps.put("cal.domain", domainIfHosted);
0672: }
0673:
0674: CalendarSession session = CalendarSession
0675: .getInstance(sessionProps);
0676: session.setTimeZone(TimeZone.getDefault());
0677: calStore = session
0678: .getStore("com.sun.comclient.calendar.socs.SOCSCalendarStore");
0679: // should be of type 'com.sun.comclient.calendar.socs.SOCSCalendarStore'
0680: if (!(calStore instanceof SOCSCalendarStore))
0681: throw new SharedServicesException(
0682: "Got a calendar store is not a SOCSCalendarStore");
0683:
0684: calStore.connect(host, port);
0685:
0686: String fullID = calStore.verifyCalendarId(calID);
0687: ICalendar cal = null;
0688: Properties calProps = new Properties();
0689:
0690: calProps.put(CAL_ACL_PROP, calACL);
0691:
0692: if (description != null) {
0693: calProps.put(CAL_DESCRIPTION_PROP, description);
0694: }
0695:
0696: if (fullID != null) {
0697: cal = calStore.openCalendar(fullID);
0698: // if calendar already exists (i.e. auto-prov), then we need to set the permissions
0699: cal.setCalProps(calProps);
0700: if (logger.isLoggable(Level.FINE)) {
0701: logger.fine("Opened calendar: " + calID
0702: + " with props: " + cal.getCalProps());
0703: }
0704: } else {
0705: // The subscribe property can only be set during 'createCalendar' on SOCSCalStore
0706: calProps.put("subscribe", "1");
0707: cal = ((SOCSCalendarStore) calStore)
0708: .createCalendar(calID, calProps);
0709: if (logger.isLoggable(Level.FINE)) {
0710: logger.fine("Created calendar: " + calID
0711: + " with props: " + cal.getCalProps());
0712: }
0713: }
0714:
0715: // cache the cal store
0716: if (calStoreCache != null) {
0717: calStoreCache.put(calID, calStore);
0718: }
0719:
0720: } else {
0721: if (logger.isLoggable(Level.FINER)) {
0722: logger.finer("Found cal store in cache: "
0723: + calStore + " for calID:" + calID);
0724: }
0725: }
0726:
0727: // Reconnect to cal server if store is no longer valid
0728: if (!calStore.isConnected()) {
0729:
0730: Properties configProps = getConfigProperties(
0731: preferences, servletRequest);
0732: CalendarSession session = calStore.getSession();
0733: String host = session.getProperty("cal.host");
0734: String portString = session.getProperty("cal.port");
0735: int port = 0;
0736: try {
0737: port = Integer.parseInt(portString);
0738: } catch (NumberFormatException e) {
0739: throw new SharedServicesException(
0740: "Calendar Host Port: "
0741: + configProps
0742: .getProperty(CONFIG_PROP_calHost)
0743: + " is not an integer");
0744: }
0745: calStore.connect(host, port);
0746: if (logger.isLoggable(Level.FINER)) {
0747: logger.finer("Reconnected to: " + calStore
0748: + " for calID:" + calID);
0749: }
0750:
0751: }
0752:
0753: } catch (Exception e) {
0754: throw new SharedServicesException("Can't open cal store: ",
0755: e);
0756: }
0757:
0758: return calStore;
0759:
0760: }
0761:
0762: /**
0763: * Pull the shared services utils on the ServletContext through the cache.
0764: */
0765: private SharedServicesUtils getServicesUtils()
0766: throws SharedServicesException {
0767: if (_servicesUtils == null) {
0768: Object utils = _context
0769: .getAttribute(SharedServicesUtils.SHARED_SVCS_UTILS_CONTEXT_ATTR);
0770: if ((utils == null)
0771: || (!(utils instanceof SharedServicesUtils))) {
0772: throw new SharedServicesException(
0773: "SharedServicesUtils attr on servlet context is null or of wrong type");
0774: }
0775: _servicesUtils = (SharedServicesUtils) utils;
0776: }
0777: return _servicesUtils;
0778: }
0779:
0780: /**
0781: * Get the Shared Calendar configuration properties for this portlet.
0782: * Use the config name stored in the portlet prefs to look up the sso adapter config,
0783: * and return contained properties.
0784: * @param preferences
0785: * @param servletRequest
0786: * @return
0787: */
0788: private Properties getConfigProperties(String configName,
0789: HttpServletRequest servletRequest)
0790: throws SharedServicesException {
0791:
0792: SSOAdapterFactory adapterFactory = SSOAdapterFactory
0793: .getInstance();
0794:
0795: SSOAdapter ssoAdapter = null;
0796: Properties props = null;
0797:
0798: try {
0799:
0800: ssoAdapter = (SSOAdapter) adapterFactory.getSSOAdapter(
0801: configName, new SSOAdapterSession(servletRequest));
0802: if (ssoAdapter == null)
0803: throw new SharedServicesException(
0804: "SSO adapter for config name: " + configName
0805: + " is null");
0806: Properties configProps = ssoAdapter.getProperties();
0807:
0808: return configProps;
0809:
0810: } catch (SSOAdapterException e) {
0811: throw new SharedServicesException(
0812: "Cant get SSO adapter for config:" + configName, e);
0813: }
0814:
0815: }
0816:
0817: /**
0818: * Converts PS member ID (SSO prinicipal name) to uid for DA / S1CS
0819: * e.g. "uid=x,ou=people,o=developersample,dc=red,dc=iplanet,dc=com"
0820: * => "x"
0821: * - Extracts the value of lowest (leftmost) RDN
0822: * TODO: Generalize this to other character sets, to include String quote etc.
0823: * via a DN library (ldapjdk)
0824: * Returns memberID, on failure.
0825: */
0826: private String getUid(String memberID) {
0827: String ans = memberID;
0828: int equalsPos = memberID.indexOf('=');
0829: if (equalsPos > -1) {
0830: int commaPos = memberID.indexOf(',');
0831: if (commaPos > -1) {
0832: ans = memberID.substring(equalsPos + 1, commaPos);
0833: }
0834: }
0835: if (logger.isLoggable(Level.FINER)) {
0836: logger.fine("getDaUid: " + memberID + " => " + ans);
0837: }
0838: return ans;
0839: }
0840:
0841: /**
0842: * Returns the domain of the proxy users community calendar, if in hosted mode, otherwise null.
0843: */
0844: private String getProxyCalDomainIfHosted(Properties configProps) {
0845:
0846: String domain = null;
0847: // are we in hosted domain mode ?
0848: String isHostedDomain = configProps
0849: .getProperty(CONFIG_PROP_isHostedDomain);
0850: if ((isHostedDomain != null) // default is 'false'
0851: && (isHostedDomain.equalsIgnoreCase("true"))) {
0852: domain = configProps.getProperty(CONFIG_PROP_daDomain);
0853: }
0854: if (logger.isLoggable(Level.FINER)) {
0855: logger.fine("getCtyCalDomIfHosted => " + domain);
0856: }
0857: return domain;
0858:
0859: }
0860:
0861: /**
0862: * Returns the domain of the community calendar, if in hosted mode, otherwise null.
0863: */
0864: private String getMemberCalDomainIfHosted(Properties configProps,
0865: String communityID, String memberID)
0866: throws SharedServicesException {
0867:
0868: String domain = null;
0869: // are we in hosted domain mode ?
0870: String isHostedDomain = configProps
0871: .getProperty(CONFIG_PROP_isHostedDomain);
0872: if ((isHostedDomain != null) // default is 'false'
0873: && (isHostedDomain.equalsIgnoreCase("true"))) {
0874: // Get the domain of the most specific parent org
0875: domain = getDAHandler(communityID, configProps)
0876: .getDomainOfMember(memberID);
0877: }
0878: if (logger.isLoggable(Level.FINER)) {
0879: logger.fine("getCtyCalDomIfHosted => " + domain);
0880: }
0881: return domain;
0882:
0883: }
0884:
0885: /**
0886: * Get the local name of the members calendar (required for creates),
0887: * without the uid prefix:
0888: * e.g. full name = x:CTY_CAL_USR_X,
0889: * local name = CTY_CAL_USR_X
0890: */
0891: private String getMemberCalendarLocalID(
0892: HttpServletRequest servletRequest, Properties configProps,
0893: String communityID, String memberID)
0894: throws SharedServicesException {
0895: String s = CTY_CAL_PREFIX + USER_CAL_PREFIX + getUid(memberID);
0896:
0897: // are we in hosted domain mode ?
0898: String isHostedDomain = configProps
0899: .getProperty(CONFIG_PROP_isHostedDomain);
0900: if ((isHostedDomain != null) // default is 'false'
0901: && (isHostedDomain.equalsIgnoreCase("true"))) {
0902:
0903: String domain = getDAHandler(communityID, configProps)
0904: .getDomainOfMember(memberID);
0905:
0906: s = s + "@" + domain;
0907:
0908: }
0909:
0910: if (logger.isLoggable(Level.FINER)) {
0911: logger.finer("getMbrCalLclID: mbrID:" + memberID + " => "
0912: + s);
0913: }
0914: return s;
0915:
0916: }
0917:
0918: /**
0919: * Cache of member cty calendar stores - cached on the portlet session
0920: */
0921: private Map getMemberCalStoreCache(PortletRequest request) {
0922: PortletSession session = request.getPortletSession();
0923: Map cache = (Map) session
0924: .getAttribute(CAL_STORE_CACHE_SESSION_ATTR);
0925: if (cache == null) {
0926: cache = new HashMap();
0927: session.setAttribute(CAL_STORE_CACHE_SESSION_ATTR, cache);
0928: if (logger.isLoggable(Level.FINE)) {
0929: logger
0930: .finer("Set mbr cal store cache on portlet session");
0931: }
0932: }
0933: return cache;
0934: }
0935:
0936: private String getSessionId(FacesContext context) {
0937: Object obj = context.getExternalContext().getRequest();
0938: if (obj instanceof PortletRequest) {
0939: PortletRequest req = (PortletRequest) obj;
0940: SSOToken ssoToken = (SSOToken) req
0941: .getAttribute("javax.portlet.portletc.ssotoken");
0942: if (ssoToken != null) {
0943: return ssoToken.getTokenID().toString();
0944: }
0945: }
0946: return null;
0947: }
0948:
0949: /**
0950: * Insert a resource description for the calendar item into the search database.
0951: * @param FacesContext The faces context.
0952: * @param appType APP_TYPE_SHAREDEVENTS or APP_TYPE_SHAREDTASKS
0953: * @param memberID The id of the community member
0954: * @param itemID The ID of the event or task
0955: * @param title The title of the event (summary)
0956: * @param description The one line description of the item
0957: * @param displayURL The url that when selected will display the item.
0958: */
0959: public void insertItemIntoSearchDatabase(FacesContext context,
0960: int appType, String memberID, String itemID, String title,
0961: String description, String displayURL)
0962: throws SharedServicesException {
0963:
0964: logger.fine("ENTERING insert");
0965:
0966: Object request = context.getExternalContext().getRequest();
0967: if (!(request instanceof PortletRequest)) {
0968: logger.severe("req ! iof PortletRequest");
0969: throw new SharedServicesException(
0970: "Can't insert resource descriptor into search database: only supporting Portlet environment.");
0971: }
0972: PortletRequest portletRequest = (PortletRequest) request;
0973: PortletPreferences preferences = portletRequest
0974: .getPreferences();
0975:
0976: logger.fine("prefs = " + preferences);
0977: {
0978: Enumeration enumName = preferences.getNames();
0979: while (enumName.hasMoreElements()) {
0980: String key = (String) enumName.nextElement();
0981: logger.fine("Prefs key=" + key + " Value="
0982: + preferences.getValue(key, null));
0983: }
0984:
0985: }
0986:
0987: String communityID = getServicesUtils().getCommunityID(
0988: portletRequest);
0989:
0990: logger.fine("comm ID = " + communityID);
0991:
0992: String serverUrl = (String) preferences.getValue(
0993: SEARCH_SERVER_URL_PREF, null);
0994: String dbName = (String) preferences.getValue(SEARCH_DB_PREF,
0995: null);
0996:
0997: logger
0998: .fine("serverURL = " + serverUrl + ", dbName = "
0999: + dbName);
1000:
1001: if (serverUrl == null || dbName == null)
1002: throw new SharedServicesException(
1003: "Can't open search database: server url or db name are null");
1004:
1005: SearchDatabase searchDb = null;
1006: try {
1007: searchDb = new SearchDatabase(serverUrl, dbName);
1008: } catch (Exception ex) {
1009: throw new SharedServicesException(
1010: "Exception while trying to open search database",
1011: ex);
1012: }
1013:
1014: logger.fine("searchDb = " + searchDb);
1015:
1016: SOIF rd = new SOIF("DOCUMENT", getResourceDescriptionURL(
1017: getAppName(appType), communityID, itemID));
1018:
1019: logger.fine("rd = " + rd);
1020:
1021: rd.insert("rd-display-url", displayURL);
1022: rd.insert("title", getAppItemLabel(appType) + ": " + title);
1023: rd.insert("description", description);
1024: rd.insert("author", memberID);
1025:
1026: logger.fine("about to insert rd");
1027: try {
1028: searchDb.insert(rd);
1029: logger.fine("inserted");
1030:
1031: } catch (IOException ex) {
1032: throw new SharedServicesException(
1033: "Can't insert resource descriptor for item: "
1034: + itemID, ex);
1035: }
1036:
1037: }
1038:
1039: /**
1040: * Delete a resource description for the calendar item from the search database.
1041: * @param appType APP_TYPE_SHAREDEVENTS or APP_TYPE_SHAREDTASKS
1042: * @param itemID The ID of the event or task
1043: */
1044: public void deleteItemFromSearchDatabase(FacesContext context,
1045: int appType, String itemID) throws SharedServicesException {
1046:
1047: Object request = context.getExternalContext().getRequest();
1048: if (!(request instanceof PortletRequest)) {
1049: throw new SharedServicesException(
1050: "Can't delete resource descriptor from search database: only supporting Portlet environment.");
1051: }
1052: PortletRequest portletRequest = (PortletRequest) request;
1053: PortletPreferences preferences = portletRequest
1054: .getPreferences();
1055: String communityID = getServicesUtils().getCommunityID(
1056: portletRequest);
1057:
1058: String serverUrl = (String) preferences.getValue(
1059: SEARCH_SERVER_URL_PREF, null);
1060: String dbName = (String) preferences.getValue(SEARCH_DB_PREF,
1061: null);
1062: if (serverUrl == null || dbName == null)
1063: throw new SharedServicesException(
1064: "Can't open search database: server url or db name are null");
1065:
1066: SearchDatabase searchDb = null;
1067: try {
1068: searchDb = new SearchDatabase(serverUrl, dbName);
1069: } catch (MalformedURLException ex) {
1070: throw new SharedServicesException(
1071: "Exception while trying to open search databse", ex);
1072: }
1073:
1074: try {
1075: searchDb.delete(getResourceDescriptionURL(
1076: getAppName(appType), communityID, itemID));
1077: } catch (IOException ex) {
1078: throw new SharedServicesException(
1079: "Can't delete resource descriptor for item: "
1080: + itemID, ex);
1081: }
1082:
1083: }
1084:
1085: /**
1086: * Connect to a search database for the community.
1087: * @param The faces context.
1088: */
1089: public SearchDatabase getSearchDatabase(FacesContext context)
1090: throws SharedServicesException {
1091:
1092: logger.fine("ENTERING searchDb");
1093:
1094: Object request = context.getExternalContext().getRequest();
1095: if (!(request instanceof PortletRequest)) {
1096: logger.severe("req ! iof PortletRequest");
1097: throw new SharedServicesException(
1098: "Can't insert resource descriptor into search database: only supporting Portlet environment.");
1099: }
1100: PortletRequest portletRequest = (PortletRequest) request;
1101: PortletPreferences preferences = portletRequest
1102: .getPreferences();
1103:
1104: logger.fine("prefs = " + preferences);
1105:
1106: String communityID = getServicesUtils().getCommunityID(
1107: portletRequest);
1108:
1109: logger.fine("comm ID = " + communityID);
1110:
1111: String serverUrl = (String) preferences.getValue(
1112: SEARCH_SERVER_URL_PREF, null);
1113: String dbName = (String) preferences.getValue(SEARCH_DB_PREF,
1114: null);
1115:
1116: logger
1117: .fine("serverURL = " + serverUrl + ", dbName = "
1118: + dbName);
1119:
1120: if (serverUrl == null || dbName == null)
1121: throw new SharedServicesException(
1122: "Can't open search database: server url or db name are null");
1123:
1124: SearchDatabase searchDb = null;
1125: try {
1126: searchDb = new SearchDatabase(serverUrl, dbName);
1127: String sessionId = getSessionId(context);
1128: if (sessionId != null) {
1129: searchDb.setSessionID(sessionId);
1130: }
1131:
1132: } catch (Exception ex) {
1133: logger.fine("EX: " + ex);
1134: throw new SharedServicesException(
1135: "Exception while trying to open search database",
1136: ex);
1137: }
1138:
1139: logger.fine("searchDb = " + searchDb);
1140:
1141: return searchDb;
1142: }
1143:
1144: /**
1145: * Return the app name (i.g. sharedevents, sharedtasks)
1146: */
1147: private String getAppName(int appType) {
1148: if (appType == APP_TYPE_SHAREDEVENTS) {
1149: return "sharedevents";
1150: } else {
1151: return "sharedtasks";
1152: }
1153: }
1154:
1155: /**
1156: * Return the app item label (i.g. Event, Task)
1157: */
1158: private String getAppItemLabel(int appType) {
1159: if (appType == APP_TYPE_SHAREDEVENTS) {
1160: return "Event";
1161: } else {
1162: return "Task";
1163: }
1164: }
1165:
1166: private String getResourceDescriptionURL(String appName,
1167: String communityID, String itemID) {
1168: return appName + "::" + communityID + "::" + itemID;
1169: }
1170:
1171: }
|