Integrated SCT's attribute definition classes.
[java-idp.git] / tests / edu / internet2 / middleware / shibboleth / aa / attrresolv / AttributesFile.java
1 /*
2  * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation for Advanced Internet Development, Inc.
3  * All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted
4  * provided that the following conditions are met: Redistributions of source code must retain the above copyright
5  * notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above
6  * copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials
7  * provided with the distribution, if any, must include the following acknowledgment: "This product includes software
8  * developed by the University Corporation for Advanced Internet Development <http://www.ucaid.edu>Internet2 Project.
9  * Alternately, this acknowledegement may appear in the software itself, if and wherever such third-party
10  * acknowledgments normally appear. Neither the name of Shibboleth nor the names of its contributors, nor Internet2, nor
11  * the University Corporation for Advanced Internet Development, Inc., nor UCAID may be used to endorse or promote
12  * products derived from this software without specific prior written permission. For written permission, please contact
13  * shibboleth@shibboleth.org Products derived from this software may not be called Shibboleth, Internet2, UCAID, or the
14  * University Corporation for Advanced Internet Development, nor may Shibboleth appear in their name, without prior
15  * written permission of the University Corporation for Advanced Internet Development. THIS SOFTWARE IS PROVIDED BY THE
16  * COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE
18  * DISCLAIMED AND THE ENTIRE RISK OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE. IN NO
19  * EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC.
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 /*
27  * Contributed by SungGard SCT.
28  */
29
30 package edu.internet2.middleware.shibboleth.aa.attrresolv;
31
32 import java.io.FileReader;
33 import java.io.IOException;
34 import java.io.LineNumberReader;
35
36 import javax.naming.directory.Attributes;
37 import javax.naming.directory.BasicAttribute;
38 import javax.naming.directory.BasicAttributes;
39
40 import org.apache.log4j.Logger;
41 import org.opensaml.SAMLException;
42
43 import edu.internet2.middleware.shibboleth.aa.AAAttribute;
44 import edu.internet2.middleware.shibboleth.aa.AAAttributeSet;
45
46 /**
47  * The AttributesFile reads attributes specified in a file as name-value pairs separated by an 'equals' sign (=)
48  * Multiple values of an attribute may be specified using multiple pairs with the same attribute name. Multi-valued
49  * attributes can be read as ordered or unordered.
50  * 
51  * @author <a href="mailto:vgoenka@sungardsct.com">Vishal Goenka </a>
52  */
53
54 public class AttributesFile {
55
56         private static Logger log = Logger.getLogger(AttributesFile.class.getName());
57         private String datafile;
58         private FileReader freader = null;
59         private LineNumberReader linereader = null;
60
61         public AttributesFile(String datafile) {
62
63                 this.datafile = datafile;
64         }
65
66         private void open() throws IOException {
67
68                 freader = new FileReader(datafile);
69                 linereader = new LineNumberReader(freader);
70         }
71
72         private void close() {
73
74                 try {
75                         if (freader != null) freader.close();
76                 } catch (Exception e) {
77                         log.warn("Unexpected error when closing file: " + datafile + " -- " + e.getMessage());
78                 }
79         }
80
81         private AVPair readAV() throws IOException {
82
83                 AVPair av = null;
84                 do {
85                         String line = linereader.readLine();
86                         if (line == null) break;
87
88                         line = line.trim();
89                         // Ignore comments and empty lines
90                         if ((line.length() == 0) || (line.charAt(0) == '#')) continue;
91
92                         int index = line.indexOf("=");
93                         if (index == -1)
94                                 throw new IOException("'=' not specified in " + datafile + ":" + linereader.getLineNumber());
95                         String attrib = line.substring(0, index).trim();
96                         String value = line.substring(index + 1).trim();
97                         if ((attrib == null) || (attrib.length() == 0))
98                                 throw new IOException("Empty attribute name in " + datafile + ":" + linereader.getLineNumber());
99
100                         if (value == null) value = "";
101
102                         av = new AVPair(attrib, value);
103                 } while (av == null);
104                 return av;
105         }
106
107         public synchronized Attributes readAttributes(boolean ordered) throws IOException {
108
109                 open();
110                 try {
111                         BasicAttributes attributes = new BasicAttributes();
112                         AVPair av = readAV();
113                         while (av != null) {
114                                 BasicAttribute ba = (BasicAttribute) attributes.get(av.name);
115                                 if (ba == null) {
116                                         ba = new BasicAttribute(av.name, ordered);
117                                         attributes.put(ba);
118                                 }
119                                 ba.add(av.value);
120                                 av = readAV();
121                         }
122                         return attributes;
123                 } finally {
124                         close();
125                 }
126         }
127
128         public synchronized ResolverAttributeSet getResolverAttributes(boolean returnValues) throws IOException,
129                         SAMLException {
130
131                 open();
132                 try {
133                         AAAttributeSet attributes = new AAAttributeSet();
134                         AVPair av = readAV();
135                         while (av != null) {
136                                 AAAttribute attr = (AAAttribute) attributes.getByName(av.name);
137                                 if (attr == null) {
138                                         // The intern() is to work-around the bug in AAAttribute.equals() where the name of the
139                                         // attribute is compared
140                                         // using "==" rather than "equals" ...
141                                         attr = new AAAttribute(av.name.intern());
142                                         attributes.add(attr);
143                                 }
144                                 if (returnValues) {
145                                         attr.addValue(av.value);
146                                 }
147                                 av = readAV();
148                         }
149                         return attributes;
150                 } finally {
151                         close();
152                 }
153         }
154
155         private class AVPair {
156
157                 String name;
158                 String value;
159
160                 public AVPair(String a, String v) {
161
162                         name = a;
163                         value = v;
164                 }
165         }
166
167 }