2 * The Shibboleth License, Version 1.
4 * University Corporation for Advanced Internet Development, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution, if any, must include
17 * the following acknowledgment: "This product includes software developed by
18 * the University Corporation for Advanced Internet Development
19 * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
20 * may appear in the software itself, if and wherever such third-party
21 * acknowledgments normally appear.
23 * Neither the name of Shibboleth nor the names of its contributors, nor
24 * Internet2, nor the University Corporation for Advanced Internet Development,
25 * Inc., nor UCAID may be used to endorse or promote products derived from this
26 * software without specific prior written permission. For written permission,
27 * please contact shibboleth@shibboleth.org
29 * Products derived from this software may not be called Shibboleth, Internet2,
30 * UCAID, or the University Corporation for Advanced Internet Development, nor
31 * may Shibboleth appear in their name, without prior written permission of the
32 * University Corporation for Advanced Internet Development.
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36 * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
38 * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
39 * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
40 * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
41 * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
42 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 package edu.internet2.middleware.shibboleth.aa.arp.provider;
52 import java.io.IOException;
53 import java.security.Principal;
54 import java.util.HashMap;
55 import java.util.HashSet;
57 import java.util.Properties;
60 import org.apache.log4j.Logger;
61 import org.w3c.dom.Element;
62 import org.xml.sax.SAXException;
64 import edu.internet2.middleware.shibboleth.aa.arp.Arp;
65 import edu.internet2.middleware.shibboleth.aa.arp.ArpMarshallingException;
66 import edu.internet2.middleware.shibboleth.aa.arp.ArpRepository;
67 import edu.internet2.middleware.shibboleth.aa.arp.ArpRepositoryException;
70 * Provides marshalling/unmarshalling functionality common among
71 * <code>ArpRepository</code> implementations.
73 * @author Walter Hoehn (wassa@columbia.edu)
76 public abstract class BaseArpRepository implements ArpRepository {
78 private static Logger log = Logger.getLogger(BaseArpRepository.class.getName());
79 private ArpCache arpCache;
81 BaseArpRepository(Properties properties) {
84 "edu.internet2.middleware.shibboleth.aa.arp.BaseArpRepository.ArpTTL",
87 arpCache = ArpCache.instance();
88 arpCache.setCacheLength(
90 properties.getProperty(
91 "edu.internet2.middleware.shibboleth.aa.arp.BaseArpRepository.ArpTTL",
97 * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#getAllPolicies(Principal)
100 public Arp[] getAllPolicies(Principal principal) throws ArpRepositoryException {
102 "Received a query for all policies applicable to principal: ("
103 + principal.getName()
105 Set allPolicies = new HashSet();
106 if (getSitePolicy() != null) {
107 log.debug("Returning site policy.");
108 allPolicies.add(getSitePolicy());
110 if (getUserPolicy(principal) != null) {
111 allPolicies.add(getUserPolicy(principal));
112 log.debug("Returning user policy.");
114 if (allPolicies.isEmpty()) {
115 log.debug("No policies found.");
117 return (Arp[]) allPolicies.toArray(new Arp[0]);
121 * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#getSitePolicy()
123 public Arp getSitePolicy() throws ArpRepositoryException {
126 if (arpCache != null) {
127 Arp cachedArp = arpCache.retrieveSiteArpFromCache();
128 if (cachedArp != null) {
129 log.debug("Using cached site ARP.");
134 Element xml = retrieveSiteArpXml();
139 Arp siteArp = new Arp();
140 siteArp.marshall(xml);
141 if (arpCache != null) {
142 arpCache.cache(siteArp);
145 } catch (ArpMarshallingException ame) {
146 log.error("An error occurred while marshalling an ARP: " + ame);
147 throw new ArpRepositoryException("An error occurred while marshalling an ARP.");
148 } catch (IOException ioe) {
149 log.error("An error occurred while loading an ARP: " + ioe);
150 throw new ArpRepositoryException("An error occurred while loading an ARP.");
151 } catch (SAXException se) {
152 log.error("An error occurred while parsing an ARP: " + se);
153 throw new ArpRepositoryException("An error occurred while parsing an ARP.");
158 * Inheritors must return the site Arp as an xml element.
161 protected abstract Element retrieveSiteArpXml() throws IOException, SAXException;
164 * @see edu.internet2.middleware.shibboleth.aa.arp.ArpRepository#getUserPolicy(Principal)
166 public Arp getUserPolicy(Principal principal) throws ArpRepositoryException {
168 if (arpCache != null) {
169 Arp cachedArp = arpCache.retrieveUserArpFromCache(principal);
170 if (cachedArp != null) {
171 log.debug("Using cached user ARP.");
177 Element xml = retrieveUserArpXml(principal);
182 Arp userArp = new Arp();
183 userArp.setPrincipal(principal);
185 userArp.marshall(xml);
186 if (arpCache != null) {
187 arpCache.cache(userArp);
190 } catch (ArpMarshallingException ame) {
191 log.error("An error occurred while marshalling an ARP: " + ame);
192 throw new ArpRepositoryException("An error occurred while marshalling an ARP.");
193 } catch (IOException ioe) {
194 log.error("An error occurred while loading an ARP: " + ioe);
195 throw new ArpRepositoryException("An error occurred while loading an ARP.");
196 } catch (SAXException se) {
197 log.error("An error occurred while parsing an ARP: " + se);
198 throw new ArpRepositoryException("An error occurred while parsing an ARP.");
203 * Inheritors must return the user Arp as an xml element.
206 protected abstract Element retrieveUserArpXml(Principal principal)
207 throws IOException, SAXException;
213 private static ArpCache instance = null;
214 private long cacheLength;
215 private Map cache = new HashMap();
217 protected ArpCache() {
220 static ArpCache instance() {
221 if (instance == null) {
222 return new ArpCache();
227 void setCacheLength(long cacheLength) {
228 this.cacheLength = cacheLength;
231 void cache(Arp arp) {
232 if (arp.isSitePolicy() == false) {
233 cache.put(arp.getPrincipal(), new CachedArp(arp, System.currentTimeMillis()));
235 cache.put(new SiteCachePrincipal(), new CachedArp(arp, System.currentTimeMillis()));
239 Arp retrieveUserArpFromCache(Principal principal) {
240 return retrieveArpFromCache(principal);
243 Arp retrieveSiteArpFromCache() {
244 return retrieveArpFromCache(new SiteCachePrincipal());
247 private Arp retrieveArpFromCache(Principal principal) {
248 CachedArp cachedArp = (CachedArp) cache.get(principal);
249 if (cachedArp == null) {
253 if ((System.currentTimeMillis() - cachedArp.creationTimeMillis) < cacheLength) {
254 return cachedArp.arp;
256 cache.remove(principal);
262 long creationTimeMillis;
264 CachedArp(Arp arp, long creationTimeMillis) {
266 this.creationTimeMillis = creationTimeMillis;
270 class SiteCachePrincipal implements Principal {
272 public String getName() {
276 public boolean equals(Object object) {
277 if (object instanceof SiteCachePrincipal) {
283 public long hashcode() {
284 return "edu.internet2.middleware.shibboleth.aa.arp.provider.BaseArpRepository.SiteCachePrincipal"