Source Code Cross Referenced for Subject.java in  » 6.0-JDK-Core » security » javax » security » auth » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » security » javax.security.auth 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.security.auth;
0027
0028        import java.util.*;
0029        import java.io.*;
0030        import java.lang.reflect.*;
0031        import java.text.MessageFormat;
0032        import java.security.AccessController;
0033        import java.security.AccessControlContext;
0034        import java.security.DomainCombiner;
0035        import java.security.Permission;
0036        import java.security.PermissionCollection;
0037        import java.security.Principal;
0038        import java.security.PrivilegedAction;
0039        import java.security.PrivilegedExceptionAction;
0040        import java.security.PrivilegedActionException;
0041        import java.security.ProtectionDomain;
0042        import sun.security.util.ResourcesMgr;
0043        import sun.security.util.SecurityConstants;
0044
0045        /**
0046         * <p> A <code>Subject</code> represents a grouping of related information
0047         * for a single entity, such as a person.
0048         * Such information includes the Subject's identities as well as
0049         * its security-related attributes
0050         * (passwords and cryptographic keys, for example).
0051         *
0052         * <p> Subjects may potentially have multiple identities.
0053         * Each identity is represented as a <code>Principal</code>
0054         * within the <code>Subject</code>.  Principals simply bind names to a
0055         * <code>Subject</code>.  For example, a <code>Subject</code> that happens
0056         * to be a person, Alice, might have two Principals:
0057         * one which binds "Alice Bar", the name on her driver license,
0058         * to the <code>Subject</code>, and another which binds,
0059         * "999-99-9999", the number on her student identification card,
0060         * to the <code>Subject</code>.  Both Principals refer to the same
0061         * <code>Subject</code> even though each has a different name.
0062         *
0063         * <p> A <code>Subject</code> may also own security-related attributes,
0064         * which are referred to as credentials.
0065         * Sensitive credentials that require special protection, such as
0066         * private cryptographic keys, are stored within a private credential
0067         * <code>Set</code>.  Credentials intended to be shared, such as
0068         * public key certificates or Kerberos server tickets are stored
0069         * within a public credential <code>Set</code>.  Different permissions
0070         * are required to access and modify the different credential Sets.
0071         *
0072         * <p> To retrieve all the Principals associated with a <code>Subject</code>,
0073         * invoke the <code>getPrincipals</code> method.  To retrieve
0074         * all the public or private credentials belonging to a <code>Subject</code>,
0075         * invoke the <code>getPublicCredentials</code> method or
0076         * <code>getPrivateCredentials</code> method, respectively.
0077         * To modify the returned <code>Set</code> of Principals and credentials,
0078         * use the methods defined in the <code>Set</code> class.
0079         * For example:
0080         * <pre>
0081         *	Subject subject;
0082         *	Principal principal;
0083         *	Object credential;
0084         *
0085         *	// add a Principal and credential to the Subject
0086         *	subject.getPrincipals().add(principal);
0087         *	subject.getPublicCredentials().add(credential);
0088         * </pre>
0089         *
0090         * <p> This <code>Subject</code> class implements <code>Serializable</code>.
0091         * While the Principals associated with the <code>Subject</code> are serialized,
0092         * the credentials associated with the <code>Subject</code> are not.
0093         * Note that the <code>java.security.Principal</code> class
0094         * does not implement <code>Serializable</code>.  Therefore all concrete
0095         * <code>Principal</code> implementations associated with Subjects
0096         * must implement <code>Serializable</code>.
0097         *
0098         * @version 1.135, 06/29/07
0099         * @see java.security.Principal
0100         * @see java.security.DomainCombiner
0101         */
0102        public final class Subject implements  java.io.Serializable {
0103
0104            private static final long serialVersionUID = -8308522755600156056L;
0105
0106            /**
0107             * A <code>Set</code> that provides a view of all of this
0108             * Subject's Principals
0109             *
0110             * <p>
0111             *
0112             * @serial Each element in this set is a
0113             *		<code>java.security.Principal</code>.
0114             *		The set is a <code>Subject.SecureSet</code>.
0115             */
0116            Set<Principal> principals;
0117
0118            /**
0119             * Sets that provide a view of all of this
0120             * Subject's Credentials
0121             */
0122            transient Set<Object> pubCredentials;
0123            transient Set<Object> privCredentials;
0124
0125            /**
0126             * Whether this Subject is read-only
0127             *
0128             * @serial
0129             */
0130            private volatile boolean readOnly = false;
0131
0132            private static final int PRINCIPAL_SET = 1;
0133            private static final int PUB_CREDENTIAL_SET = 2;
0134            private static final int PRIV_CREDENTIAL_SET = 3;
0135
0136            private static final ProtectionDomain[] NULL_PD_ARRAY = new ProtectionDomain[0];
0137
0138            /**
0139             * Create an instance of a <code>Subject</code>
0140             * with an empty <code>Set</code> of Principals and empty
0141             * Sets of public and private credentials.
0142             *
0143             * <p> The newly constructed Sets check whether this <code>Subject</code>
0144             * has been set read-only before permitting subsequent modifications.
0145             * The newly created Sets also prevent illegal modifications
0146             * by ensuring that callers have sufficient permissions.
0147             *
0148             * <p> To modify the Principals Set, the caller must have
0149             * <code>AuthPermission("modifyPrincipals")</code>.
0150             * To modify the public credential Set, the caller must have
0151             * <code>AuthPermission("modifyPublicCredentials")</code>.
0152             * To modify the private credential Set, the caller must have
0153             * <code>AuthPermission("modifyPrivateCredentials")</code>.
0154             */
0155            public Subject() {
0156
0157                this .principals = Collections
0158                        .synchronizedSet(new SecureSet<Principal>(this ,
0159                                PRINCIPAL_SET));
0160                this .pubCredentials = Collections
0161                        .synchronizedSet(new SecureSet<Object>(this ,
0162                                PUB_CREDENTIAL_SET));
0163                this .privCredentials = Collections
0164                        .synchronizedSet(new SecureSet<Object>(this ,
0165                                PRIV_CREDENTIAL_SET));
0166            }
0167
0168            /**
0169             * Create an instance of a <code>Subject</code> with
0170             * Principals and credentials.
0171             *
0172             * <p> The Principals and credentials from the specified Sets
0173             * are copied into newly constructed Sets.
0174             * These newly created Sets check whether this <code>Subject</code>
0175             * has been set read-only before permitting subsequent modifications.
0176             * The newly created Sets also prevent illegal modifications
0177             * by ensuring that callers have sufficient permissions.
0178             *
0179             * <p> To modify the Principals Set, the caller must have
0180             * <code>AuthPermission("modifyPrincipals")</code>.
0181             * To modify the public credential Set, the caller must have
0182             * <code>AuthPermission("modifyPublicCredentials")</code>.
0183             * To modify the private credential Set, the caller must have
0184             * <code>AuthPermission("modifyPrivateCredentials")</code>.
0185             * <p>
0186             *
0187             * @param readOnly true if the <code>Subject</code> is to be read-only,
0188             *		and false otherwise. <p>
0189             *
0190             * @param principals the <code>Set</code> of Principals
0191             *		to be associated with this <code>Subject</code>. <p>
0192             *
0193             * @param pubCredentials the <code>Set</code> of public credentials
0194             *		to be associated with this <code>Subject</code>. <p>
0195             *
0196             * @param privCredentials the <code>Set</code> of private credentials
0197             *		to be associated with this <code>Subject</code>.
0198             *
0199             * @exception NullPointerException if the specified
0200             *		<code>principals</code>, <code>pubCredentials</code>,
0201             *		or <code>privCredentials</code> are <code>null</code>.
0202             */
0203            public Subject(boolean readOnly,
0204                    Set<? extends Principal> principals, Set<?> pubCredentials,
0205                    Set<?> privCredentials) {
0206
0207                if (principals == null || pubCredentials == null
0208                        || privCredentials == null)
0209                    throw new NullPointerException(ResourcesMgr
0210                            .getString("invalid null input(s)"));
0211
0212                this .principals = Collections
0213                        .synchronizedSet(new SecureSet<Principal>(this ,
0214                                PRINCIPAL_SET, principals));
0215                this .pubCredentials = Collections
0216                        .synchronizedSet(new SecureSet<Object>(this ,
0217                                PUB_CREDENTIAL_SET, pubCredentials));
0218                this .privCredentials = Collections
0219                        .synchronizedSet(new SecureSet<Object>(this ,
0220                                PRIV_CREDENTIAL_SET, privCredentials));
0221                this .readOnly = readOnly;
0222            }
0223
0224            /**
0225             * Set this <code>Subject</code> to be read-only.
0226             *
0227             * <p> Modifications (additions and removals) to this Subject's
0228             * <code>Principal</code> <code>Set</code> and
0229             * credential Sets will be disallowed.
0230             * The <code>destroy</code> operation on this Subject's credentials will
0231             * still be permitted.
0232             *
0233             * <p> Subsequent attempts to modify the Subject's <code>Principal</code>
0234             * and credential Sets will result in an
0235             * <code>IllegalStateException</code> being thrown.
0236             * Also, once a <code>Subject</code> is read-only,
0237             * it can not be reset to being writable again.
0238             *
0239             * <p>
0240             *
0241             * @exception SecurityException if the caller does not have permission
0242             *		to set this <code>Subject</code> to be read-only.
0243             */
0244            public void setReadOnly() {
0245                java.lang.SecurityManager sm = System.getSecurityManager();
0246                if (sm != null) {
0247                    sm.checkPermission(new AuthPermission("setReadOnly"));
0248                }
0249
0250                this .readOnly = true;
0251            }
0252
0253            /**
0254             * Query whether this <code>Subject</code> is read-only.
0255             *
0256             * <p>
0257             *
0258             * @return true if this <code>Subject</code> is read-only, false otherwise.
0259             */
0260            public boolean isReadOnly() {
0261                return this .readOnly;
0262            }
0263
0264            /**
0265             * Get the <code>Subject</code> associated with the provided
0266             * <code>AccessControlContext</code>.
0267             *
0268             * <p> The <code>AccessControlContext</code> may contain many
0269             * Subjects (from nested <code>doAs</code> calls).
0270             * In this situation, the most recent <code>Subject</code> associated
0271             * with the <code>AccessControlContext</code> is returned.
0272             *
0273             * <p>
0274             *
0275             * @param  acc the <code>AccessControlContext</code> from which to retrieve
0276             *		the <code>Subject</code>.
0277             *
0278             * @return  the <code>Subject</code> associated with the provided
0279             *		<code>AccessControlContext</code>, or <code>null</code>
0280             *		if no <code>Subject</code> is associated
0281             *		with the provided <code>AccessControlContext</code>.
0282             *
0283             * @exception SecurityException if the caller does not have permission
0284             *		to get the <code>Subject</code>. <p>
0285             *
0286             * @exception NullPointerException if the provided
0287             *		<code>AccessControlContext</code> is <code>null</code>.
0288             */
0289            public static Subject getSubject(final AccessControlContext acc) {
0290
0291                java.lang.SecurityManager sm = System.getSecurityManager();
0292                if (sm != null) {
0293                    sm.checkPermission(new AuthPermission("getSubject"));
0294                }
0295
0296                if (acc == null) {
0297                    throw new NullPointerException(
0298                            ResourcesMgr
0299                                    .getString("invalid null AccessControlContext provided"));
0300                }
0301
0302                // return the Subject from the DomainCombiner of the provided context
0303                return AccessController
0304                        .doPrivileged(new java.security.PrivilegedAction<Subject>() {
0305                            public Subject run() {
0306                                DomainCombiner dc = acc.getDomainCombiner();
0307                                if (!(dc instanceof  SubjectDomainCombiner))
0308                                    return null;
0309                                SubjectDomainCombiner sdc = (SubjectDomainCombiner) dc;
0310                                return sdc.getSubject();
0311                            }
0312                        });
0313            }
0314
0315            /**
0316             * Perform work as a particular <code>Subject</code>.
0317             *
0318             * <p> This method first retrieves the current Thread's
0319             * <code>AccessControlContext</code> via
0320             * <code>AccessController.getContext</code>,
0321             * and then instantiates a new <code>AccessControlContext</code>
0322             * using the retrieved context along with a new
0323             * <code>SubjectDomainCombiner</code> (constructed using
0324             * the provided <code>Subject</code>).
0325             * Finally, this method invokes <code>AccessController.doPrivileged</code>,
0326             * passing it the provided <code>PrivilegedAction</code>,
0327             * as well as the newly constructed <code>AccessControlContext</code>.
0328             *
0329             * <p>
0330             *
0331             * @param subject the <code>Subject</code> that the specified
0332             *			<code>action</code> will run as.  This parameter
0333             *			may be <code>null</code>. <p>
0334             *
0335             * @param action the code to be run as the specified
0336             *			<code>Subject</code>. <p>
0337             *
0338             * @return the value returned by the PrivilegedAction's
0339             *			<code>run</code> method.
0340             *
0341             * @exception NullPointerException if the <code>PrivilegedAction</code>
0342             *			is <code>null</code>. <p>
0343             *
0344             * @exception SecurityException if the caller does not have permission
0345             *			to invoke this method.
0346             */
0347            public static <T> T doAs(final Subject subject,
0348                    final java.security.PrivilegedAction<T> action) {
0349
0350                java.lang.SecurityManager sm = System.getSecurityManager();
0351                if (sm != null) {
0352                    sm.checkPermission(SecurityConstants.DO_AS_PERMISSION);
0353                }
0354                if (action == null)
0355                    throw new NullPointerException(ResourcesMgr
0356                            .getString("invalid null action provided"));
0357
0358                // set up the new Subject-based AccessControlContext
0359                // for doPrivileged
0360                final AccessControlContext currentAcc = AccessController
0361                        .getContext();
0362
0363                // call doPrivileged and push this new context on the stack
0364                return java.security.AccessController.doPrivileged(action,
0365                        createContext(subject, currentAcc));
0366            }
0367
0368            /**
0369             * Perform work as a particular <code>Subject</code>.
0370             *
0371             * <p> This method first retrieves the current Thread's
0372             * <code>AccessControlContext</code> via
0373             * <code>AccessController.getContext</code>,
0374             * and then instantiates a new <code>AccessControlContext</code>
0375             * using the retrieved context along with a new
0376             * <code>SubjectDomainCombiner</code> (constructed using
0377             * the provided <code>Subject</code>).
0378             * Finally, this method invokes <code>AccessController.doPrivileged</code>,
0379             * passing it the provided <code>PrivilegedExceptionAction</code>,
0380             * as well as the newly constructed <code>AccessControlContext</code>.
0381             *
0382             * <p>
0383             *
0384             * @param subject the <code>Subject</code> that the specified
0385             *			<code>action</code> will run as.  This parameter
0386             *			may be <code>null</code>. <p>
0387             *
0388             * @param action the code to be run as the specified
0389             *			<code>Subject</code>. <p>
0390             *
0391             * @return the value returned by the
0392             *			PrivilegedExceptionAction's <code>run</code> method.
0393             *
0394             * @exception PrivilegedActionException if the
0395             *			<code>PrivilegedExceptionAction.run</code>
0396             *			method throws a checked exception. <p>
0397             *
0398             * @exception NullPointerException if the specified
0399             *			<code>PrivilegedExceptionAction</code> is
0400             *			<code>null</code>. <p>
0401             *
0402             * @exception SecurityException if the caller does not have permission
0403             *			to invoke this method.
0404             */
0405            public static <T> T doAs(final Subject subject,
0406                    final java.security.PrivilegedExceptionAction<T> action)
0407                    throws java.security.PrivilegedActionException {
0408
0409                java.lang.SecurityManager sm = System.getSecurityManager();
0410                if (sm != null) {
0411                    sm.checkPermission(SecurityConstants.DO_AS_PERMISSION);
0412                }
0413
0414                if (action == null)
0415                    throw new NullPointerException(ResourcesMgr
0416                            .getString("invalid null action provided"));
0417
0418                // set up the new Subject-based AccessControlContext for doPrivileged
0419                final AccessControlContext currentAcc = AccessController
0420                        .getContext();
0421
0422                // call doPrivileged and push this new context on the stack
0423                return java.security.AccessController.doPrivileged(action,
0424                        createContext(subject, currentAcc));
0425            }
0426
0427            /**
0428             * Perform privileged work as a particular <code>Subject</code>.
0429             *
0430             * <p> This method behaves exactly as <code>Subject.doAs</code>,
0431             * except that instead of retrieving the current Thread's
0432             * <code>AccessControlContext</code>, it uses the provided
0433             * <code>AccessControlContext</code>.  If the provided
0434             * <code>AccessControlContext</code> is <code>null</code>,
0435             * this method instantiates a new <code>AccessControlContext</code>
0436             * with an empty collection of ProtectionDomains.
0437             *
0438             * <p>
0439             *
0440             * @param subject the <code>Subject</code> that the specified
0441             *			<code>action</code> will run as.  This parameter
0442             *			may be <code>null</code>. <p>
0443             *
0444             * @param action the code to be run as the specified
0445             *			<code>Subject</code>. <p>
0446             *
0447             * @param acc the <code>AccessControlContext</code> to be tied to the
0448             *			specified <i>subject</i> and <i>action</i>. <p>
0449             *
0450             * @return the value returned by the PrivilegedAction's
0451             *			<code>run</code> method.
0452             *
0453             * @exception NullPointerException if the <code>PrivilegedAction</code>
0454             *			is <code>null</code>. <p>
0455             *
0456             * @exception SecurityException if the caller does not have permission
0457             *			to invoke this method.
0458             */
0459            public static <T> T doAsPrivileged(final Subject subject,
0460                    final java.security.PrivilegedAction<T> action,
0461                    final java.security.AccessControlContext acc) {
0462
0463                java.lang.SecurityManager sm = System.getSecurityManager();
0464                if (sm != null) {
0465                    sm
0466                            .checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION);
0467                }
0468
0469                if (action == null)
0470                    throw new NullPointerException(ResourcesMgr
0471                            .getString("invalid null action provided"));
0472
0473                // set up the new Subject-based AccessControlContext
0474                // for doPrivileged
0475                final AccessControlContext callerAcc = (acc == null ? new AccessControlContext(
0476                        NULL_PD_ARRAY)
0477                        : acc);
0478
0479                // call doPrivileged and push this new context on the stack
0480                return java.security.AccessController.doPrivileged(action,
0481                        createContext(subject, callerAcc));
0482            }
0483
0484            /**
0485             * Perform privileged work as a particular <code>Subject</code>.
0486             *
0487             * <p> This method behaves exactly as <code>Subject.doAs</code>,
0488             * except that instead of retrieving the current Thread's
0489             * <code>AccessControlContext</code>, it uses the provided
0490             * <code>AccessControlContext</code>.  If the provided
0491             * <code>AccessControlContext</code> is <code>null</code>,
0492             * this method instantiates a new <code>AccessControlContext</code>
0493             * with an empty collection of ProtectionDomains.
0494             *
0495             * <p>
0496             *
0497             * @param subject the <code>Subject</code> that the specified
0498             *			<code>action</code> will run as.  This parameter
0499             *			may be <code>null</code>. <p>
0500             *
0501             * @param action the code to be run as the specified
0502             *			<code>Subject</code>. <p>
0503             *
0504             * @param acc the <code>AccessControlContext</code> to be tied to the
0505             *			specified <i>subject</i> and <i>action</i>. <p>
0506             *
0507             * @return the value returned by the
0508             *			PrivilegedExceptionAction's <code>run</code> method.
0509             *
0510             * @exception PrivilegedActionException if the
0511             *			<code>PrivilegedExceptionAction.run</code>
0512             *			method throws a checked exception. <p>
0513             *
0514             * @exception NullPointerException if the specified
0515             *			<code>PrivilegedExceptionAction</code> is
0516             *			<code>null</code>. <p>
0517             *
0518             * @exception SecurityException if the caller does not have permission
0519             *			to invoke this method.
0520             */
0521            public static <T> T doAsPrivileged(final Subject subject,
0522                    final java.security.PrivilegedExceptionAction<T> action,
0523                    final java.security.AccessControlContext acc)
0524                    throws java.security.PrivilegedActionException {
0525
0526                java.lang.SecurityManager sm = System.getSecurityManager();
0527                if (sm != null) {
0528                    sm
0529                            .checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION);
0530                }
0531
0532                if (action == null)
0533                    throw new NullPointerException(ResourcesMgr
0534                            .getString("invalid null action provided"));
0535
0536                // set up the new Subject-based AccessControlContext for doPrivileged
0537                final AccessControlContext callerAcc = (acc == null ? new AccessControlContext(
0538                        NULL_PD_ARRAY)
0539                        : acc);
0540
0541                // call doPrivileged and push this new context on the stack
0542                return java.security.AccessController.doPrivileged(action,
0543                        createContext(subject, callerAcc));
0544            }
0545
0546            private static AccessControlContext createContext(
0547                    final Subject subject, final AccessControlContext acc) {
0548
0549                return java.security.AccessController
0550                        .doPrivileged(new java.security.PrivilegedAction<AccessControlContext>() {
0551                            public AccessControlContext run() {
0552                                if (subject == null)
0553                                    return new AccessControlContext(acc, null);
0554                                else
0555                                    return new AccessControlContext(acc,
0556                                            new SubjectDomainCombiner(subject));
0557                            }
0558                        });
0559            }
0560
0561            /**
0562             * Return the <code>Set</code> of Principals associated with this
0563             * <code>Subject</code>.  Each <code>Principal</code> represents
0564             * an identity for this <code>Subject</code>.
0565             *
0566             * <p> The returned <code>Set</code> is backed by this Subject's
0567             * internal <code>Principal</code> <code>Set</code>.  Any modification
0568             * to the returned <code>Set</code> affects the internal
0569             * <code>Principal</code> <code>Set</code> as well.
0570             *
0571             * <p>
0572             *
0573             * @return	The <code>Set</code> of Principals associated with this
0574             *		<code>Subject</code>.
0575             */
0576            public Set<Principal> getPrincipals() {
0577
0578                // always return an empty Set instead of null
0579                // so LoginModules can add to the Set if necessary
0580                return principals;
0581            }
0582
0583            /**
0584             * Return a <code>Set</code> of Principals associated with this
0585             * <code>Subject</code> that are instances or subclasses of the specified
0586             * <code>Class</code>.
0587             *
0588             * <p> The returned <code>Set</code> is not backed by this Subject's
0589             * internal <code>Principal</code> <code>Set</code>.  A new
0590             * <code>Set</code> is created and returned for each method invocation.
0591             * Modifications to the returned <code>Set</code>
0592             * will not affect the internal <code>Principal</code> <code>Set</code>.
0593             *
0594             * <p>
0595             *
0596             * @param c the returned <code>Set</code> of Principals will all be
0597             *		instances of this class.
0598             *
0599             * @return a <code>Set</code> of Principals that are instances of the
0600             *		specified <code>Class</code>.
0601             *
0602             * @exception NullPointerException if the specified <code>Class</code> 
0603             *			is <code>null</code>.
0604             */
0605            public <T extends Principal> Set<T> getPrincipals(Class<T> c) {
0606
0607                if (c == null)
0608                    throw new NullPointerException(ResourcesMgr
0609                            .getString("invalid null Class provided"));
0610
0611                // always return an empty Set instead of null
0612                // so LoginModules can add to the Set if necessary
0613                return new ClassSet<T>(PRINCIPAL_SET, c);
0614            }
0615
0616            /**
0617             * Return the <code>Set</code> of public credentials held by this
0618             * <code>Subject</code>.
0619             *
0620             * <p> The returned <code>Set</code> is backed by this Subject's
0621             * internal public Credential <code>Set</code>.  Any modification
0622             * to the returned <code>Set</code> affects the internal public
0623             * Credential <code>Set</code> as well.
0624             *
0625             * <p>
0626             *
0627             * @return	A <code>Set</code> of public credentials held by this
0628             *		<code>Subject</code>.
0629             */
0630            public Set<Object> getPublicCredentials() {
0631
0632                // always return an empty Set instead of null
0633                // so LoginModules can add to the Set if necessary
0634                return pubCredentials;
0635            }
0636
0637            /**
0638             * Return the <code>Set</code> of private credentials held by this
0639             * <code>Subject</code>.
0640             *
0641             * <p> The returned <code>Set</code> is backed by this Subject's
0642             * internal private Credential <code>Set</code>.  Any modification
0643             * to the returned <code>Set</code> affects the internal private
0644             * Credential <code>Set</code> as well.
0645             *
0646             * <p> A caller requires permissions to access the Credentials
0647             * in the returned <code>Set</code>, or to modify the
0648             * <code>Set</code> itself.  A <code>SecurityException</code>
0649             * is thrown if the caller does not have the proper permissions.
0650             * 
0651             * <p> While iterating through the <code>Set</code>,
0652             * a <code>SecurityException</code> is thrown
0653             * if the caller does not have permission to access a
0654             * particular Credential.  The <code>Iterator</code>
0655             * is nevertheless advanced to next element in the <code>Set</code>.
0656             *
0657             * <p>
0658             *
0659             * @return	A <code>Set</code> of private credentials held by this
0660             *		<code>Subject</code>.
0661             */
0662            public Set<Object> getPrivateCredentials() {
0663
0664                // XXX
0665                // we do not need a security check for
0666                // AuthPermission(getPrivateCredentials)
0667                // because we already restrict access to private credentials
0668                // via the PrivateCredentialPermission.  all the extra AuthPermission
0669                // would do is protect the set operations themselves
0670                // (like size()), which don't seem security-sensitive.
0671
0672                // always return an empty Set instead of null
0673                // so LoginModules can add to the Set if necessary
0674                return privCredentials;
0675            }
0676
0677            /**
0678             * Return a <code>Set</code> of public credentials associated with this
0679             * <code>Subject</code> that are instances or subclasses of the specified
0680             * <code>Class</code>.
0681             *
0682             * <p> The returned <code>Set</code> is not backed by this Subject's
0683             * internal public Credential <code>Set</code>.  A new
0684             * <code>Set</code> is created and returned for each method invocation.
0685             * Modifications to the returned <code>Set</code>
0686             * will not affect the internal public Credential <code>Set</code>.
0687             *
0688             * <p>
0689             *
0690             * @param c the returned <code>Set</code> of public credentials will all be
0691             *		instances of this class.
0692             *
0693             * @return a <code>Set</code> of public credentials that are instances
0694             *		of the	specified <code>Class</code>.
0695             *
0696             * @exception NullPointerException if the specified <code>Class</code>
0697             *		is <code>null</code>.
0698             */
0699            public <T> Set<T> getPublicCredentials(Class<T> c) {
0700
0701                if (c == null)
0702                    throw new NullPointerException(ResourcesMgr
0703                            .getString("invalid null Class provided"));
0704
0705                // always return an empty Set instead of null
0706                // so LoginModules can add to the Set if necessary
0707                return new ClassSet<T>(PUB_CREDENTIAL_SET, c);
0708            }
0709
0710            /**
0711             * Return a <code>Set</code> of private credentials associated with this
0712             * <code>Subject</code> that are instances or subclasses of the specified
0713             * <code>Class</code>. 
0714             *
0715             * <p> The caller must have permission to access all of the
0716             * requested Credentials, or a <code>SecurityException</code>
0717             * will be thrown.
0718             *
0719             * <p> The returned <code>Set</code> is not backed by this Subject's
0720             * internal private Credential <code>Set</code>.  A new
0721             * <code>Set</code> is created and returned for each method invocation.
0722             * Modifications to the returned <code>Set</code>
0723             * will not affect the internal private Credential <code>Set</code>.
0724             *
0725             * <p>
0726             *
0727             * @param c the returned <code>Set</code> of private credentials will all be
0728             *		instances of this class.
0729             *
0730             * @return a <code>Set</code> of private credentials that are instances
0731             *		of the	specified <code>Class</code>.
0732             *
0733             * @exception NullPointerException if the specified <code>Class</code>
0734             *		is <code>null</code>.
0735             */
0736            public <T> Set<T> getPrivateCredentials(Class<T> c) {
0737
0738                // XXX
0739                // we do not need a security check for
0740                // AuthPermission(getPrivateCredentials)
0741                // because we already restrict access to private credentials
0742                // via the PrivateCredentialPermission.  all the extra AuthPermission
0743                // would do is protect the set operations themselves
0744                // (like size()), which don't seem security-sensitive.
0745
0746                if (c == null)
0747                    throw new NullPointerException(ResourcesMgr
0748                            .getString("invalid null Class provided"));
0749
0750                // always return an empty Set instead of null
0751                // so LoginModules can add to the Set if necessary
0752                return new ClassSet<T>(PRIV_CREDENTIAL_SET, c);
0753            }
0754
0755            /**
0756             * Compares the specified Object with this <code>Subject</code>
0757             * for equality.  Returns true if the given object is also a Subject
0758             * and the two <code>Subject</code> instances are equivalent.
0759             * More formally, two <code>Subject</code> instances are
0760             * equal if their <code>Principal</code> and <code>Credential</code>
0761             * Sets are equal.
0762             *
0763             * <p>
0764             *
0765             * @param o Object to be compared for equality with this
0766             *		<code>Subject</code>.
0767             *
0768             * @return true if the specified Object is equal to this
0769             *		<code>Subject</code>.
0770             *
0771             * @exception SecurityException if the caller does not have permission
0772             *		to access the private credentials for this <code>Subject</code>,
0773             *		or if the caller does not have permission to access the
0774             *		private credentials for the provided <code>Subject</code>.
0775             */
0776            public boolean equals(Object o) {
0777
0778                if (o == null)
0779                    return false;
0780
0781                if (this  == o)
0782                    return true;
0783
0784                if (o instanceof  Subject) {
0785
0786                    final Subject that = (Subject) o;
0787
0788                    // check the principal and credential sets
0789                    Set<Principal> thatPrincipals;
0790                    synchronized (that.principals) {
0791                        // avoid deadlock from dual locks
0792                        thatPrincipals = new HashSet<Principal>(that.principals);
0793                    }
0794                    if (!principals.equals(thatPrincipals)) {
0795                        return false;
0796                    }
0797
0798                    Set<Object> thatPubCredentials;
0799                    synchronized (that.pubCredentials) {
0800                        // avoid deadlock from dual locks
0801                        thatPubCredentials = new HashSet<Object>(
0802                                that.pubCredentials);
0803                    }
0804                    if (!pubCredentials.equals(thatPubCredentials)) {
0805                        return false;
0806                    }
0807
0808                    Set<Object> thatPrivCredentials;
0809                    synchronized (that.privCredentials) {
0810                        // avoid deadlock from dual locks
0811                        thatPrivCredentials = new HashSet<Object>(
0812                                that.privCredentials);
0813                    }
0814                    if (!privCredentials.equals(thatPrivCredentials)) {
0815                        return false;
0816                    }
0817                    return true;
0818                }
0819                return false;
0820            }
0821
0822            /**
0823             * Return the String representation of this <code>Subject</code>.
0824             *
0825             * <p>
0826             *
0827             * @return the String representation of this <code>Subject</code>.
0828             */
0829            public String toString() {
0830                return toString(true);
0831            }
0832
0833            /**
0834             * package private convenience method to print out the Subject
0835             * without firing off a security check when trying to access
0836             * the Private Credentials
0837             */
0838            String toString(boolean includePrivateCredentials) {
0839
0840                String s = ResourcesMgr.getString("Subject:\n");
0841                String suffix = "";
0842
0843                synchronized (principals) {
0844                    Iterator<Principal> pI = principals.iterator();
0845                    while (pI.hasNext()) {
0846                        Principal p = pI.next();
0847                        suffix = suffix
0848                                + ResourcesMgr.getString("\tPrincipal: ")
0849                                + p.toString() + ResourcesMgr.getString("\n");
0850                    }
0851                }
0852
0853                synchronized (pubCredentials) {
0854                    Iterator<Object> pI = pubCredentials.iterator();
0855                    while (pI.hasNext()) {
0856                        Object o = pI.next();
0857                        suffix = suffix
0858                                + ResourcesMgr
0859                                        .getString("\tPublic Credential: ")
0860                                + o.toString() + ResourcesMgr.getString("\n");
0861                    }
0862                }
0863
0864                if (includePrivateCredentials) {
0865                    synchronized (privCredentials) {
0866                        Iterator<Object> pI = privCredentials.iterator();
0867                        while (pI.hasNext()) {
0868                            try {
0869                                Object o = pI.next();
0870                                suffix += ResourcesMgr
0871                                        .getString("\tPrivate Credential: ")
0872                                        + o.toString()
0873                                        + ResourcesMgr.getString("\n");
0874                            } catch (SecurityException se) {
0875                                suffix += ResourcesMgr
0876                                        .getString("\tPrivate Credential inaccessible\n");
0877                                break;
0878                            }
0879                        }
0880                    }
0881                }
0882                return s + suffix;
0883            }
0884
0885            /**
0886             * Returns a hashcode for this <code>Subject</code>.
0887             *
0888             * <p>
0889             *
0890             * @return a hashcode for this <code>Subject</code>.
0891             *
0892             * @exception SecurityException if the caller does not have permission
0893             *		to access this Subject's private credentials.
0894             */
0895            public int hashCode() {
0896
0897                /** 
0898                 * The hashcode is derived exclusive or-ing the
0899                 * hashcodes of this Subject's Principals and credentials.
0900                 *
0901                 * If a particular credential was destroyed
0902                 * (<code>credential.hashCode()</code> throws an
0903                 * <code>IllegalStateException</code>),
0904                 * the hashcode for that credential is derived via:
0905                 * <code>credential.getClass().toString().hashCode()</code>.
0906                 */
0907
0908                int hashCode = 0;
0909
0910                synchronized (principals) {
0911                    Iterator<Principal> pIterator = principals.iterator();
0912                    while (pIterator.hasNext()) {
0913                        Principal p = pIterator.next();
0914                        hashCode ^= p.hashCode();
0915                    }
0916                }
0917
0918                synchronized (pubCredentials) {
0919                    Iterator<Object> pubCIterator = pubCredentials.iterator();
0920                    while (pubCIterator.hasNext()) {
0921                        hashCode ^= getCredHashCode(pubCIterator.next());
0922                    }
0923                }
0924                return hashCode;
0925            }
0926
0927            /**
0928             * get a credential's hashcode
0929             */
0930            private int getCredHashCode(Object o) {
0931                try {
0932                    return o.hashCode();
0933                } catch (IllegalStateException ise) {
0934                    return o.getClass().toString().hashCode();
0935                }
0936            }
0937
0938            /**
0939             * Writes this object out to a stream (i.e., serializes it).
0940             */
0941            private void writeObject(java.io.ObjectOutputStream oos)
0942                    throws java.io.IOException {
0943                synchronized (principals) {
0944                    oos.defaultWriteObject();
0945                }
0946            }
0947
0948            /**
0949             * Reads this object from a stream (i.e., deserializes it)
0950             */
0951            private void readObject(java.io.ObjectInputStream s)
0952                    throws java.io.IOException, ClassNotFoundException {
0953
0954                s.defaultReadObject();
0955
0956                // The Credential <code>Set</code> is not serialized, but we do not
0957                // want the default deserialization routine to set it to null.
0958                this .pubCredentials = Collections
0959                        .synchronizedSet(new SecureSet<Object>(this ,
0960                                PUB_CREDENTIAL_SET));
0961                this .privCredentials = Collections
0962                        .synchronizedSet(new SecureSet<Object>(this ,
0963                                PRIV_CREDENTIAL_SET));
0964            }
0965
0966            /**
0967             * Prevent modifications unless caller has permission.
0968             *
0969             * @serial include
0970             */
0971            private static class SecureSet<E> extends AbstractSet<E> implements 
0972                    java.io.Serializable {
0973
0974                private static final long serialVersionUID = 7911754171111800359L;
0975
0976                /**
0977                 * @serialField this$0 Subject The outer Subject instance.
0978                 * @serialField elements LinkedList The elements in this set.
0979                 */
0980                private static final ObjectStreamField[] serialPersistentFields = {
0981                        new ObjectStreamField("this$0", Subject.class),
0982                        new ObjectStreamField("elements", LinkedList.class),
0983                        new ObjectStreamField("which", int.class) };
0984
0985                Subject subject;
0986                LinkedList<E> elements;
0987
0988                /**
0989                 * @serial An integer identifying the type of objects contained
0990                 *	in this set.  If <code>which == 1</code>,
0991                 *	this is a Principal set and all the elements are
0992                 *	of type <code>java.security.Principal</code>.
0993                 *	If <code>which == 2</code>, this is a public credential
0994                 *	set and all the elements are of type <code>Object</code>.
0995                 *	If <code>which == 3</code>, this is a private credential
0996                 *	set and all the elements are of type <code>Object</code>.
0997                 */
0998                private int which;
0999
1000                SecureSet(Subject subject, int which) {
1001                    this .subject = subject;
1002                    this .which = which;
1003                    this .elements = new LinkedList<E>();
1004                }
1005
1006                SecureSet(Subject subject, int which, Set<? extends E> set) {
1007                    this .subject = subject;
1008                    this .which = which;
1009                    this .elements = new LinkedList<E>(set);
1010                }
1011
1012                public int size() {
1013                    return elements.size();
1014                }
1015
1016                public Iterator<E> iterator() {
1017                    final LinkedList<E> list = elements;
1018                    return new Iterator<E>() {
1019                        ListIterator<E> i = list.listIterator(0);
1020
1021                        public boolean hasNext() {
1022                            return i.hasNext();
1023                        }
1024
1025                        public E next() {
1026                            if (which != Subject.PRIV_CREDENTIAL_SET) {
1027                                return i.next();
1028                            }
1029
1030                            SecurityManager sm = System.getSecurityManager();
1031                            if (sm != null) {
1032                                try {
1033                                    sm
1034                                            .checkPermission(new PrivateCredentialPermission(
1035                                                    list.get(i.nextIndex())
1036                                                            .getClass()
1037                                                            .getName(), subject
1038                                                            .getPrincipals()));
1039                                } catch (SecurityException se) {
1040                                    i.next();
1041                                    throw (se);
1042                                }
1043                            }
1044                            return i.next();
1045                        }
1046
1047                        public void remove() {
1048
1049                            if (subject.isReadOnly()) {
1050                                throw new IllegalStateException(ResourcesMgr
1051                                        .getString("Subject is read-only"));
1052                            }
1053
1054                            java.lang.SecurityManager sm = System
1055                                    .getSecurityManager();
1056                            if (sm != null) {
1057                                switch (which) {
1058                                case Subject.PRINCIPAL_SET:
1059                                    sm.checkPermission(new AuthPermission(
1060                                            "modifyPrincipals"));
1061                                    break;
1062                                case Subject.PUB_CREDENTIAL_SET:
1063                                    sm.checkPermission(new AuthPermission(
1064                                            "modifyPublicCredentials"));
1065                                    break;
1066                                default:
1067                                    sm.checkPermission(new AuthPermission(
1068                                            "modifyPrivateCredentials"));
1069                                    break;
1070                                }
1071                            }
1072                            i.remove();
1073                        }
1074                    };
1075                }
1076
1077                public boolean add(E o) {
1078
1079                    if (subject.isReadOnly()) {
1080                        throw new IllegalStateException(ResourcesMgr
1081                                .getString("Subject is read-only"));
1082                    }
1083
1084                    java.lang.SecurityManager sm = System.getSecurityManager();
1085                    if (sm != null) {
1086                        switch (which) {
1087                        case Subject.PRINCIPAL_SET:
1088                            sm.checkPermission(new AuthPermission(
1089                                    "modifyPrincipals"));
1090                            break;
1091                        case Subject.PUB_CREDENTIAL_SET:
1092                            sm.checkPermission(new AuthPermission(
1093                                    "modifyPublicCredentials"));
1094                            break;
1095                        default:
1096                            sm.checkPermission(new AuthPermission(
1097                                    "modifyPrivateCredentials"));
1098                            break;
1099                        }
1100                    }
1101
1102                    switch (which) {
1103                    case Subject.PRINCIPAL_SET:
1104                        if (!(o instanceof  Principal)) {
1105                            throw new SecurityException(
1106                                    ResourcesMgr
1107                                            .getString("attempting to add an object which is not an "
1108                                                    + "instance of java.security.Principal to a "
1109                                                    + "Subject's Principal Set"));
1110                        }
1111                        break;
1112                    default:
1113                        // ok to add Objects of any kind to credential sets
1114                        break;
1115                    }
1116
1117                    // check for duplicates
1118                    if (!elements.contains(o))
1119                        return elements.add(o);
1120                    else
1121                        return false;
1122                }
1123
1124                public boolean remove(Object o) {
1125
1126                    final Iterator<E> e = iterator();
1127                    while (e.hasNext()) {
1128                        E next;
1129                        if (which != Subject.PRIV_CREDENTIAL_SET) {
1130                            next = e.next();
1131                        } else {
1132                            next = java.security.AccessController
1133                                    .doPrivileged(new java.security.PrivilegedAction<E>() {
1134                                        public E run() {
1135                                            return e.next();
1136                                        }
1137                                    });
1138                        }
1139
1140                        if (next == null) {
1141                            if (o == null) {
1142                                e.remove();
1143                                return true;
1144                            }
1145                        } else if (next.equals(o)) {
1146                            e.remove();
1147                            return true;
1148                        }
1149                    }
1150                    return false;
1151                }
1152
1153                public boolean contains(Object o) {
1154                    final Iterator<E> e = iterator();
1155                    while (e.hasNext()) {
1156                        E next;
1157                        if (which != Subject.PRIV_CREDENTIAL_SET) {
1158                            next = e.next();
1159                        } else {
1160
1161                            // For private credentials:
1162                            // If the caller does not have read permission for
1163                            // for o.getClass(), we throw a SecurityException.
1164                            // Otherwise we check the private cred set to see whether
1165                            // it contains the Object
1166
1167                            SecurityManager sm = System.getSecurityManager();
1168                            if (sm != null) {
1169                                sm
1170                                        .checkPermission(new PrivateCredentialPermission(
1171                                                o.getClass().getName(), subject
1172                                                        .getPrincipals()));
1173                            }
1174                            next = java.security.AccessController
1175                                    .doPrivileged(new java.security.PrivilegedAction<E>() {
1176                                        public E run() {
1177                                            return e.next();
1178                                        }
1179                                    });
1180                        }
1181
1182                        if (next == null) {
1183                            if (o == null) {
1184                                return true;
1185                            }
1186                        } else if (next.equals(o)) {
1187                            return true;
1188                        }
1189                    }
1190                    return false;
1191                }
1192
1193                public boolean removeAll(Collection<?> c) {
1194
1195                    boolean modified = false;
1196                    final Iterator<E> e = iterator();
1197                    while (e.hasNext()) {
1198                        E next;
1199                        if (which != Subject.PRIV_CREDENTIAL_SET) {
1200                            next = e.next();
1201                        } else {
1202                            next = java.security.AccessController
1203                                    .doPrivileged(new java.security.PrivilegedAction<E>() {
1204                                        public E run() {
1205                                            return e.next();
1206                                        }
1207                                    });
1208                        }
1209
1210                        Iterator<?> ce = c.iterator();
1211                        while (ce.hasNext()) {
1212                            Object o = ce.next();
1213                            if (next == null) {
1214                                if (o == null) {
1215                                    e.remove();
1216                                    modified = true;
1217                                    break;
1218                                }
1219                            } else if (next.equals(o)) {
1220                                e.remove();
1221                                modified = true;
1222                                break;
1223                            }
1224                        }
1225                    }
1226                    return modified;
1227                }
1228
1229                public boolean retainAll(Collection<?> c) {
1230
1231                    boolean modified = false;
1232                    boolean retain = false;
1233                    final Iterator<E> e = iterator();
1234                    while (e.hasNext()) {
1235                        retain = false;
1236                        E next;
1237                        if (which != Subject.PRIV_CREDENTIAL_SET) {
1238                            next = e.next();
1239                        } else {
1240                            next = java.security.AccessController
1241                                    .doPrivileged(new java.security.PrivilegedAction<E>() {
1242                                        public E run() {
1243                                            return e.next();
1244                                        }
1245                                    });
1246                        }
1247
1248                        Iterator<?> ce = c.iterator();
1249                        while (ce.hasNext()) {
1250                            Object o = ce.next();
1251                            if (next == null) {
1252                                if (o == null) {
1253                                    retain = true;
1254                                    break;
1255                                }
1256                            } else if (next.equals(o)) {
1257                                retain = true;
1258                                break;
1259                            }
1260                        }
1261
1262                        if (!retain) {
1263                            e.remove();
1264                            retain = false;
1265                            modified = true;
1266                        }
1267                    }
1268                    return modified;
1269                }
1270
1271                public void clear() {
1272                    final Iterator<E> e = iterator();
1273                    while (e.hasNext()) {
1274                        E next;
1275                        if (which != Subject.PRIV_CREDENTIAL_SET) {
1276                            next = e.next();
1277                        } else {
1278                            next = java.security.AccessController
1279                                    .doPrivileged(new java.security.PrivilegedAction<E>() {
1280                                        public E run() {
1281                                            return e.next();
1282                                        }
1283                                    });
1284                        }
1285                        e.remove();
1286                    }
1287                }
1288
1289                /**
1290                 * Writes this object out to a stream (i.e., serializes it).
1291                 *
1292                 * <p>
1293                 *
1294                 * @serialData If this is a private credential set,
1295                 *	a security check is performed to ensure that
1296                 *	the caller has permission to access each credential
1297                 *	in the set.  If the security check passes,
1298                 *	the set is serialized.
1299                 */
1300                private void writeObject(java.io.ObjectOutputStream oos)
1301                        throws java.io.IOException {
1302
1303                    if (which == Subject.PRIV_CREDENTIAL_SET) {
1304                        // check permissions before serializing
1305                        Iterator<E> i = iterator();
1306                        while (i.hasNext()) {
1307                            i.next();
1308                        }
1309                    }
1310                    ObjectOutputStream.PutField fields = oos.putFields();
1311                    fields.put("this$0", subject);
1312                    fields.put("elements", elements);
1313                    fields.put("which", which);
1314                    oos.writeFields();
1315                }
1316
1317                private void readObject(ObjectInputStream ois)
1318                        throws IOException, ClassNotFoundException {
1319                    ObjectInputStream.GetField fields = ois.readFields();
1320                    subject = (Subject) fields.get("this$0", null);
1321                    elements = (LinkedList<E>) fields.get("elements", null);
1322                    which = fields.get("which", 0);
1323                }
1324            }
1325
1326            /**
1327             * This class implements a <code>Set</code> which returns only 
1328             * members that are an instance of a specified Class. 
1329             */
1330            private class ClassSet<T> extends AbstractSet<T> {
1331
1332                private int which;
1333                private Class<T> c;
1334                private Set<T> set;
1335
1336                ClassSet(int which, Class<T> c) {
1337                    this .which = which;
1338                    this .c = c;
1339                    set = new HashSet<T>();
1340
1341                    switch (which) {
1342                    case Subject.PRINCIPAL_SET:
1343                        synchronized (principals) {
1344                            populateSet();
1345                        }
1346                        break;
1347                    case Subject.PUB_CREDENTIAL_SET:
1348                        synchronized (pubCredentials) {
1349                            populateSet();
1350                        }
1351                        break;
1352                    default:
1353                        synchronized (privCredentials) {
1354                            populateSet();
1355                        }
1356                        break;
1357                    }
1358                }
1359
1360                private void populateSet() {
1361                    final Iterator<?> iterator;
1362                    switch (which) {
1363                    case Subject.PRINCIPAL_SET:
1364                        iterator = Subject.this .principals.iterator();
1365                        break;
1366                    case Subject.PUB_CREDENTIAL_SET:
1367                        iterator = Subject.this .pubCredentials.iterator();
1368                        break;
1369                    default:
1370                        iterator = Subject.this .privCredentials.iterator();
1371                        break;
1372                    }
1373
1374                    // Check whether the caller has permisson to get
1375                    // credentials of Class c 
1376
1377                    while (iterator.hasNext()) {
1378                        Object next;
1379                        if (which == Subject.PRIV_CREDENTIAL_SET) {
1380                            next = java.security.AccessController
1381                                    .doPrivileged(new java.security.PrivilegedAction<Object>() {
1382                                        public Object run() {
1383                                            return iterator.next();
1384                                        }
1385                                    });
1386                        } else {
1387                            next = iterator.next();
1388                        }
1389                        if (c.isAssignableFrom(next.getClass())) {
1390                            if (which != Subject.PRIV_CREDENTIAL_SET) {
1391                                set.add((T) next);
1392                            } else {
1393                                // Check permission for private creds
1394                                SecurityManager sm = System
1395                                        .getSecurityManager();
1396                                if (sm != null) {
1397                                    sm
1398                                            .checkPermission(new PrivateCredentialPermission(
1399                                                    next.getClass().getName(),
1400                                                    Subject.this 
1401                                                            .getPrincipals()));
1402                                }
1403                                set.add((T) next);
1404                            }
1405                        }
1406                    }
1407                }
1408
1409                public int size() {
1410                    return set.size();
1411                }
1412
1413                public Iterator<T> iterator() {
1414                    return set.iterator();
1415                }
1416
1417                public boolean add(T o) {
1418
1419                    if (!o.getClass().isAssignableFrom(c)) {
1420                        MessageFormat form = new MessageFormat(
1421                                ResourcesMgr
1422                                        .getString("attempting to add an object which is not an "
1423                                                + "instance of class"));
1424                        Object[] source = { c.toString() };
1425                        throw new SecurityException(form.format(source));
1426                    }
1427
1428                    return set.add(o);
1429                }
1430            }
1431        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.