View Javadoc

1   /* 
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.userinfo.impl;
18  
19  import java.security.Principal;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  import java.util.prefs.BackingStoreException;
26  import java.util.prefs.Preferences;
27  
28  import javax.portlet.PortletRequest;
29  import javax.security.auth.Subject;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.apache.jetspeed.components.portletregistry.PortletRegistry;
34  import org.apache.jetspeed.om.common.UserAttributeRef;
35  import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
36  import org.apache.jetspeed.request.RequestContext;
37  import org.apache.jetspeed.security.SecurityException;
38  import org.apache.jetspeed.security.SecurityHelper;
39  import org.apache.jetspeed.security.User;
40  import org.apache.jetspeed.security.UserManager;
41  import org.apache.jetspeed.security.UserPrincipal;
42  import org.apache.jetspeed.userinfo.UserInfoManager;
43  import org.apache.pluto.om.common.ObjectID;
44  
45  /***
46   * <p>
47   * Implements the {@link org.apache.jetspeed.userinfo.UserInfoManager}
48   * interface.
49   * </p>
50   * 
51   * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
52   * @version $Id: UserInfoManagerImpl.java 516448 2007-03-09 16:25:47Z ate $
53   */
54  public class UserInfoManagerImpl extends AbstractUserInfoManagerImpl implements UserInfoManager
55  {
56  
57      /*** Logger */
58      private static final Log log = LogFactory.getLog(UserInfoManagerImpl.class);
59  
60      // TODO Same caching issue as usual. We should look into JCS. That wil do
61      // for now.
62      /*** Map used to cache user info maps for each mapped portlet application. */
63      private static Map userInfoMapCache;
64  
65      /*** The user information property set. */
66      String userInfoPropertySet;
67  
68      /*** The user manager */
69      UserManager userMgr;
70  
71      /*** The portlet registry. */
72      PortletRegistry registry;
73  
74      /*** The object id of the portlet application being processed. */
75      String oid;
76  
77      /***
78       * <p>
79       * Constructor providing access to the {@link UserManager}.
80       * </p>
81       * 
82       * @param userMgr The user manager.
83       * @param registry The portlet registry component.
84       */
85      public UserInfoManagerImpl(UserManager userMgr, PortletRegistry registry)
86      {
87          this.userMgr = userMgr;
88          this.registry = registry;
89          this.userInfoPropertySet = User.USER_INFO_PROPERTY_SET;
90          initUserInfoMapCache();
91      }
92  
93      /***
94       * <p>
95       * Constructor providing access to the {@link UserManager}and specifying
96       * which property set to use for user information.
97       * </p>
98       * 
99       * @param userMgr The user manager.
100      * @param registry The portlet registry component.
101      * @param userInfoPropertySet The user information property set.
102      *  
103      */
104     public UserInfoManagerImpl(UserManager userMgr, PortletRegistry registry, String userInfoPropertySet)
105     {
106         this.userMgr = userMgr;
107         this.registry = registry;
108         this.userInfoPropertySet = userInfoPropertySet;
109         initUserInfoMapCache();
110     }
111 
112     /***
113      * @see org.apache.jetspeed.userinfo.UserInfoManager#setUserInfoMap(org.apache.jetspeed.om.page.Fragment,
114      *      org.apache.jetspeed.request.RequestContext)
115      */
116     public Map getUserInfoMap(ObjectID oid, RequestContext context)
117     {
118         if (log.isDebugEnabled())
119             log.debug("Getting user info for portlet application: " + oid.toString());
120 
121         // Check if user info map is in cache.
122         if (userInfoMapCache.containsKey(oid))
123         {
124             return (Map) userInfoMapCache.get(oid);
125         }
126         // Not in cache, map user info.
127         Preferences userPrefs = getUserPreferences(context);
128         if (null == userPrefs)
129         {
130             log.debug(PortletRequest.USER_INFO + " is set to null");
131             return null;
132         }
133 
134         MutablePortletApplication pa = registry.getPortletApplication(oid);
135         if (null == pa)
136         {
137             log.debug(PortletRequest.USER_INFO + " is set to null");
138             return null;
139         }
140         Preferences userInfoPrefs = userPrefs.node(userInfoPropertySet);
141         Collection userAttributes = pa.getUserAttributes();
142         Collection userAttributeRefs = pa.getUserAttributeRefs();
143         Map userInfoMap = mapUserInfo(userInfoPrefs, userAttributes, 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, Collection userAttributes, Collection userAttributeRefs)
161     {
162         if ((null == userAttributes) || (userAttributes.size() == 0))
163         {
164             return null;
165         }
166 
167         Map userInfoMap = new HashMap();
168         String[] propertyKeys = null;
169         try
170         {
171             propertyKeys = userInfoPrefs.keys();
172             if ((null != propertyKeys) && log.isDebugEnabled())
173                 log.debug("Found " + propertyKeys.length + " children for " + userInfoPrefs.absolutePath());
174         }
175         catch (BackingStoreException bse)
176         {
177             log.error("BackingStoreException: " + bse.toString());
178         }
179         if (null == propertyKeys)
180         {
181             return null;
182         }
183 
184         Collection linkedUserAttributes = mapLinkedUserAttributes(userAttributes, userAttributeRefs);
185         Iterator iter = linkedUserAttributes.iterator();
186         while (iter.hasNext())
187         {
188             UserAttributeRef currentAttributeRef = (UserAttributeRef) iter.next();
189             if (null != currentAttributeRef)
190             {
191                 for (int i = 0; i < propertyKeys.length; i++)
192                 {
193                     if (null != currentAttributeRef.getNameLink())
194                     {
195                         if ((currentAttributeRef.getNameLink()).equals(propertyKeys[i]))
196                         {
197                             userInfoMap.put(currentAttributeRef.getName(), userInfoPrefs.get(propertyKeys[i], null));
198                         }
199                     }
200                     else
201                     {
202                         if ((currentAttributeRef.getName()).equals(propertyKeys[i]))
203                         {
204                             userInfoMap.put(currentAttributeRef.getName(), userInfoPrefs.get(propertyKeys[i], null));
205                         }
206                     }
207                 }
208             }
209         }
210 
211         userInfoMapCache.put(oid, userInfoMap);
212 
213         return userInfoMap;
214     }
215 
216     /***
217      * <p>
218      * Gets the user preferences from the user's request.
219      * </p>
220      * <p>
221      * If no user is logged in, return null.
222      * </p>
223      * 
224      * @param context The request context.
225      * @return The user preferences.
226      */
227     private Preferences getUserPreferences(RequestContext context)
228     {
229         Preferences userPrefs = null;
230         Subject subject = context.getSubject();
231         if (null != subject)
232         {
233             Principal userPrincipal = SecurityHelper.getPrincipal(subject, UserPrincipal.class);
234             if (null != userPrincipal)
235             {
236                 log.debug("Got user principal: " + userPrincipal.getName());
237                 try
238                 {
239                     if (userMgr.userExists(userPrincipal.getName()))
240                     {
241                         User user = userMgr.getUser(userPrincipal.getName());
242                         userPrefs = user.getPreferences();
243                     }
244                 }
245                 catch (SecurityException sex)
246                 {
247                     log.warn("Unexpected SecurityException in UserInfoManager", sex);
248                 }
249             }
250         }
251         return userPrefs;
252     }
253 
254     private void initUserInfoMapCache()
255     {
256         if (null == userInfoMapCache)
257         {
258             userInfoMapCache = Collections.synchronizedMap(new HashMap());
259         }
260     }
261 
262 }