001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.userinfo.impl;
018:
019: import java.security.Principal;
020: import java.util.Collection;
021: import java.util.Collections;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.Map;
025: import java.util.prefs.BackingStoreException;
026: import java.util.prefs.Preferences;
027:
028: import javax.portlet.PortletRequest;
029: import javax.security.auth.Subject;
030:
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033: import org.apache.jetspeed.components.portletregistry.PortletRegistry;
034: import org.apache.jetspeed.om.common.UserAttributeRef;
035: import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
036: import org.apache.jetspeed.request.RequestContext;
037: import org.apache.jetspeed.security.SecurityException;
038: import org.apache.jetspeed.security.SecurityHelper;
039: import org.apache.jetspeed.security.User;
040: import org.apache.jetspeed.security.UserManager;
041: import org.apache.jetspeed.security.UserPrincipal;
042: import org.apache.jetspeed.userinfo.UserInfoManager;
043: import org.apache.pluto.om.common.ObjectID;
044:
045: /**
046: * <p>
047: * Implements the {@link org.apache.jetspeed.userinfo.UserInfoManager}
048: * interface.
049: * </p>
050: *
051: * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
052: * @version $Id: UserInfoManagerImpl.java 516448 2007-03-09 16:25:47Z ate $
053: */
054: public class UserInfoManagerImpl extends AbstractUserInfoManagerImpl
055: implements UserInfoManager {
056:
057: /** Logger */
058: private static final Log log = LogFactory
059: .getLog(UserInfoManagerImpl.class);
060:
061: // TODO Same caching issue as usual. We should look into JCS. That wil do
062: // for now.
063: /** Map used to cache user info maps for each mapped portlet application. */
064: private static Map userInfoMapCache;
065:
066: /** The user information property set. */
067: String userInfoPropertySet;
068:
069: /** The user manager */
070: UserManager userMgr;
071:
072: /** The portlet registry. */
073: PortletRegistry registry;
074:
075: /** The object id of the portlet application being processed. */
076: String oid;
077:
078: /**
079: * <p>
080: * Constructor providing access to the {@link UserManager}.
081: * </p>
082: *
083: * @param userMgr The user manager.
084: * @param registry The portlet registry component.
085: */
086: public UserInfoManagerImpl(UserManager userMgr,
087: PortletRegistry registry) {
088: this .userMgr = userMgr;
089: this .registry = registry;
090: this .userInfoPropertySet = User.USER_INFO_PROPERTY_SET;
091: initUserInfoMapCache();
092: }
093:
094: /**
095: * <p>
096: * Constructor providing access to the {@link UserManager}and specifying
097: * which property set to use for user information.
098: * </p>
099: *
100: * @param userMgr The user manager.
101: * @param registry The portlet registry component.
102: * @param userInfoPropertySet The user information property set.
103: *
104: */
105: public UserInfoManagerImpl(UserManager userMgr,
106: PortletRegistry registry, String userInfoPropertySet) {
107: this .userMgr = userMgr;
108: this .registry = registry;
109: this .userInfoPropertySet = userInfoPropertySet;
110: initUserInfoMapCache();
111: }
112:
113: /**
114: * @see org.apache.jetspeed.userinfo.UserInfoManager#setUserInfoMap(org.apache.jetspeed.om.page.Fragment,
115: * org.apache.jetspeed.request.RequestContext)
116: */
117: public Map getUserInfoMap(ObjectID oid, RequestContext context) {
118: if (log.isDebugEnabled())
119: log.debug("Getting user info for portlet application: "
120: + oid.toString());
121:
122: // Check if user info map is in cache.
123: if (userInfoMapCache.containsKey(oid)) {
124: return (Map) userInfoMapCache.get(oid);
125: }
126: // Not in cache, map user info.
127: Preferences userPrefs = getUserPreferences(context);
128: if (null == userPrefs) {
129: log.debug(PortletRequest.USER_INFO + " is set to null");
130: return null;
131: }
132:
133: MutablePortletApplication pa = registry
134: .getPortletApplication(oid);
135: if (null == pa) {
136: log.debug(PortletRequest.USER_INFO + " is set to null");
137: return null;
138: }
139: Preferences userInfoPrefs = userPrefs.node(userInfoPropertySet);
140: Collection userAttributes = pa.getUserAttributes();
141: Collection userAttributeRefs = pa.getUserAttributeRefs();
142: Map userInfoMap = mapUserInfo(userInfoPrefs, userAttributes,
143: userAttributeRefs);
144:
145: return userInfoMap;
146: }
147:
148: /**
149: * <p>
150: * Maps the user info properties retrieved from the user preferences to the
151: * user info attribute declared in the portlet.xml descriptor.
152: * </p>
153: *
154: * @param userInfoPrefs The user info preferences.
155: * @param userAttributes The declarative portlet user attributes.
156: * @param userAttributeRefs The declarative jetspeed portlet extension user
157: * attributes reference.
158: * @return The user info map.
159: */
160: private Map mapUserInfo(Preferences userInfoPrefs,
161: Collection userAttributes, Collection userAttributeRefs) {
162: if ((null == userAttributes) || (userAttributes.size() == 0)) {
163: return null;
164: }
165:
166: Map userInfoMap = new HashMap();
167: String[] propertyKeys = null;
168: try {
169: propertyKeys = userInfoPrefs.keys();
170: if ((null != propertyKeys) && log.isDebugEnabled())
171: log.debug("Found " + propertyKeys.length
172: + " children for "
173: + userInfoPrefs.absolutePath());
174: } catch (BackingStoreException bse) {
175: log.error("BackingStoreException: " + bse.toString());
176: }
177: if (null == propertyKeys) {
178: return null;
179: }
180:
181: Collection linkedUserAttributes = mapLinkedUserAttributes(
182: userAttributes, userAttributeRefs);
183: Iterator iter = linkedUserAttributes.iterator();
184: while (iter.hasNext()) {
185: UserAttributeRef currentAttributeRef = (UserAttributeRef) iter
186: .next();
187: if (null != currentAttributeRef) {
188: for (int i = 0; i < propertyKeys.length; i++) {
189: if (null != currentAttributeRef.getNameLink()) {
190: if ((currentAttributeRef.getNameLink())
191: .equals(propertyKeys[i])) {
192: userInfoMap.put(currentAttributeRef
193: .getName(), userInfoPrefs.get(
194: propertyKeys[i], null));
195: }
196: } else {
197: if ((currentAttributeRef.getName())
198: .equals(propertyKeys[i])) {
199: userInfoMap.put(currentAttributeRef
200: .getName(), userInfoPrefs.get(
201: propertyKeys[i], null));
202: }
203: }
204: }
205: }
206: }
207:
208: userInfoMapCache.put(oid, userInfoMap);
209:
210: return userInfoMap;
211: }
212:
213: /**
214: * <p>
215: * Gets the user preferences from the user's request.
216: * </p>
217: * <p>
218: * If no user is logged in, return null.
219: * </p>
220: *
221: * @param context The request context.
222: * @return The user preferences.
223: */
224: private Preferences getUserPreferences(RequestContext context) {
225: Preferences userPrefs = null;
226: Subject subject = context.getSubject();
227: if (null != subject) {
228: Principal userPrincipal = SecurityHelper.getPrincipal(
229: subject, UserPrincipal.class);
230: if (null != userPrincipal) {
231: log.debug("Got user principal: "
232: + userPrincipal.getName());
233: try {
234: if (userMgr.userExists(userPrincipal.getName())) {
235: User user = userMgr.getUser(userPrincipal
236: .getName());
237: userPrefs = user.getPreferences();
238: }
239: } catch (SecurityException sex) {
240: log
241: .warn(
242: "Unexpected SecurityException in UserInfoManager",
243: sex);
244: }
245: }
246: }
247: return userPrefs;
248: }
249:
250: private void initUserInfoMapCache() {
251: if (null == userInfoMapCache) {
252: userInfoMapCache = Collections
253: .synchronizedMap(new HashMap());
254: }
255: }
256:
257: }
|