SDSS WAYF patch for multi-federation support
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / wayf / IdPSiteSet.java
1 /*
2  * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package edu.internet2.middleware.shibboleth.wayf;
17
18 import java.util.Collection;
19 import java.util.Iterator;
20 import java.util.List;
21
22 import org.apache.log4j.Logger;
23 import org.opensaml.XML;
24 import org.w3c.dom.Element;
25
26 import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
27 import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
28 import edu.internet2.middleware.shibboleth.metadata.Metadata;
29 import edu.internet2.middleware.shibboleth.metadata.MetadataException;
30 import edu.internet2.middleware.shibboleth.metadata.MetadataProviderFactory;
31
32
33 /**
34  * 
35  * @author Rod Widdowson
36  *
37  * Represents a collection of related sites - usually a federation.  When the WAYF
38  * looks to see which IdP sites to show, it trims the list so as to not show IdP's 
39  * which do not trust the SP.
40  *
41  * This class is opaque outside this file.  The three static methods getSitesLists,
42  * searchForMatchingOrigins and lookupIdP provide mechansims for accessing 
43  * collections of IdPSiteSets.
44  * 
45  */
46
47 public class IdPSiteSet {
48         
49         private static Logger log = Logger.getLogger(IdPSiteSet.class.getName());
50
51         private final Metadata metadata;
52         private final String identifier;
53         private final String displayName;
54         
55         public IdPSiteSet(Element el) throws ShibbolethConfigurationException {
56                 
57             identifier = el.getAttribute("identifier");
58             displayName = el.getAttribute("displayName");
59             
60             log.info("Loading Metadata for " + displayName);
61
62             try {
63                         metadata = MetadataProviderFactory.loadProvider(el);
64             } catch (MetadataException ex) {
65                 log.error("Could not parse " + displayName, ex);
66                 throw new ShibbolethConfigurationException("Could not parse " + displayName, ex);
67             }
68         }
69         
70         /**
71          * The metadata representing this Set
72          */
73         
74         private Metadata getMetadata()
75         {
76                 return metadata;
77         }
78         
79         protected String getIdentifier() {
80                 return identifier;
81         }
82
83         private String getDisplayName() {
84                 return displayName;
85         }
86
87         /**
88          * We do not need to look at set if it doesn't know about the given SP.  However if
89          * no SP is given (as per 1.1) then we do need to look 
90          */
91
92         private boolean containsSP(String SPName) {
93
94                 //
95                 // Deal with the case where we do *not* want to search by
96                 // SP (also handles the 1.1 case)
97                 //
98                 
99                 if ((SPName == null) || (SPName.length() == 0)) {
100                         return true;
101                 }
102                 
103                 EntityDescriptor e = metadata.lookup(SPName);
104                 
105                 if (e == null) {
106                         return false;
107                 }
108                 
109                 return (e.getSPSSODescriptor(XML.SAML11_PROTOCOL_ENUM) != null);
110         }
111         
112         private EntityDescriptor IdPforName(String IdPName) {
113
114                 if ((IdPName == null) || (IdPName.length() == 0)) {
115                         return null;
116                 }
117                 
118                 return metadata.lookup(IdPName);
119                 
120         }
121         
122         /**
123          * Iterate over all the sitesets and if they know about the SP add them to the 
124          * list and the list of lists.    
125          * 
126          * @param siteSets  All the site sets we know about
127          * 
128          * @param SPName The SP we are looking for (null or empty matches all sitesets)
129          * 
130          * @param siteLists If not null this is is populated with a set of sets of sites
131          *  
132          * @param sites.  If not Null this is populated with a set of sites.
133          */
134         public static void getSiteLists(Collection /*<IdPSiteSet>*/ siteSets,
135                                                                         String SPName,
136                                                                         Collection /*<IdPSiteSetEntry>*/ siteLists,
137                                                                         Collection /*<IdPSite>*/ sites) {
138                 //
139                 // By having siteLists and sites as parameters we only iterate over 
140                 // the metadata arrays once.
141                 //
142                 
143                 Iterator /*<IdPSiteSet>*/ it = siteSets.iterator();
144                 
145                 while (it.hasNext()) {
146                         IdPSiteSet set = (IdPSiteSet) it.next();
147                         
148                         if (set.containsSP(SPName)) {
149                                 Collection c = IdPSite.getIdPSites(set.getMetadata());
150                                 
151                                 if (siteLists != null) {
152                                         siteLists.add(new IdPSiteSetEntry(set.getDisplayName(),c));
153                                 }
154                                 
155                                 if (sites != null) {
156                                         sites.addAll(c);
157                                 }
158                         }
159                 }
160                 
161         }
162         
163
164         
165         /**
166          * Give the set of siteSets, an SP name and a searchString, look for the name in all 
167          * the appropriate siteSets. 
168          *
169          */
170
171         public static Collection /*<IdPSite>*/ seachForMatchingOrigins(Collection/*<IdPSiteSet>*/ siteSets, String SPName, String parameter, HandlerConfig config) {
172
173                 Collection/*<IdPSite>*/ result = null;
174                 Iterator/*<IdPSiteSet>*/ it = siteSets.iterator();
175                 
176                 while (it.hasNext()) {
177                         IdPSiteSet set = (IdPSiteSet) it.next();
178                         
179                         if (set.containsSP(SPName)) {
180                                 Collection/*<IdPSite>*/ c = IdPSite.seachForMatchingOrigins(set.getMetadata(),parameter, config);
181                                 
182                                 if (result == null) {
183                                         result = c;
184                                 } else {
185                                         result.addAll(c);
186                                 }
187                         }
188                 }
189                 
190                 return result;
191         }
192
193         public static IdPSite IdPforSP(List /*<IdPSiteSet>*/ siteSets, String IdPName, String SPName) {
194
195                 Iterator /*<IdPSiteSet>*/ it = siteSets.iterator();
196                 
197                 while (it.hasNext()) {
198                         IdPSiteSet set = (IdPSiteSet) it.next();
199                         
200                         if (set.containsSP(SPName)) {
201                                 EntityDescriptor e = set.IdPforName(IdPName);
202                                 
203                                 if (e != null) {
204                                         return new IdPSite(e);
205                                 }
206                         }
207                 }
208                 
209                 return null;
210         }
211 }
212