001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.core.api.local;
023
024import java.security.Principal;
025import java.util.LinkedList;
026
027import javax.security.auth.Subject;
028
029/**
030 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
031 */
032public class LoginStack {
033
034    public static LoginStack synchronizedStack() {
035        return new Sync();
036    }
037
038    protected final LinkedList<Entry> stack = new LinkedList<Entry>();
039
040    public void clear() {
041        stack.clear();
042    }
043
044    public void push(Principal principal, Object credential, Subject subject) {
045        stack.add(new Entry(principal, credential, subject));
046    }
047
048    public Entry pop() {
049        if (stack.isEmpty()) {
050            return null;
051        }
052        return stack.removeLast();
053    }
054
055    public Entry peek() {
056        if (stack.isEmpty()) {
057            return null;
058        }
059        return stack.getLast();
060    }
061
062    public boolean isEmpty() {
063        return stack.isEmpty();
064    }
065
066    public int size() {
067        return stack.size();
068    }
069
070    public Entry get(int index) {
071        return stack.get(index);
072    }
073
074    public Entry remove(int index) {
075        return stack.remove(index);
076    }
077
078    public Entry[] toArray() {
079        return stack.toArray(new Entry[stack.size()]);
080    }
081
082    public static class Entry {
083        protected final Principal principal;
084
085        protected final Object credential;
086
087        protected final Subject subject;
088
089        public Entry(Principal principal, Object credential, Subject subject) {
090            this.principal = principal;
091            this.credential = credential;
092            this.subject = subject;
093        }
094
095        public Principal getPrincipal() {
096            return principal;
097        }
098
099        public Object getCredential() {
100            return credential;
101        }
102
103        public Subject getSubject() {
104            return subject;
105        }
106    }
107
108    public static class Sync extends LoginStack {
109
110        @Override
111        public synchronized void clear() {
112            stack.clear();
113        }
114
115        @Override
116        public synchronized void push(Principal principal, Object credential, Subject subject) {
117            stack.add(new Entry(principal, credential, subject));
118        }
119
120        @Override
121        public synchronized Entry pop() {
122            if (stack.isEmpty()) {
123                return null;
124            }
125            return stack.removeLast();
126        }
127
128        @Override
129        public synchronized Entry peek() {
130            if (stack.isEmpty()) {
131                return null;
132            }
133            return stack.getLast();
134        }
135
136        @Override
137        public synchronized boolean isEmpty() {
138            return stack.isEmpty();
139        }
140
141        @Override
142        public synchronized int size() {
143            return stack.size();
144        }
145
146        @Override
147        public synchronized Entry get(int index) {
148            return stack.get(index);
149        }
150
151        @Override
152        public synchronized Entry remove(int index) {
153            return stack.remove(index);
154        }
155
156        @Override
157        public synchronized Entry[] toArray() {
158            return stack.toArray(new Entry[stack.size()]);
159        }
160
161    }
162
163}