001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.xbean.naming.context;
018    
019    import javax.naming.Name;
020    import javax.naming.NamingException;
021    import java.util.List;
022    import java.util.Iterator;
023    import java.util.Collections;
024    import java.util.ArrayList;
025    
026    /**
027     * @version $Rev$ $Date$
028     */
029    public class ContextAccessControlList implements ContextAccess {
030        private final boolean defaultAllow;
031        private final List allow;
032        private final List deny;
033    
034        public ContextAccessControlList(boolean defaultAllow, List allow, List deny) {
035            this.defaultAllow = defaultAllow;
036            this.allow = toACL(allow);
037            this.deny = toACL(deny);
038        }
039    
040        private List toACL(List input) {
041            if (input == null) return Collections.EMPTY_LIST;
042            
043            ArrayList list = new ArrayList(input.size());
044            for (Iterator iterator = input.iterator(); iterator.hasNext();) {
045                Object value = iterator.next();
046                if (value instanceof Name) {
047                    list.add(value);
048                } else if (value instanceof String) {
049                    String string = (String) value;
050                    Name name = null;
051                    try {
052                        name = ContextUtil.NAME_PARSER.parse(string);
053                    } catch (NamingException e) {
054                        throw new IllegalArgumentException("error while parsing name: " + value);
055                    }
056                    list.add(name);
057                } else {
058                    throw new IllegalArgumentException("name is not an instance of Name or String: " + value);
059                }
060            }
061            return Collections.unmodifiableList(list);
062        }
063    
064        public boolean isModifiable(Name name) {
065            if (name == null) throw new NullPointerException("name is null");
066            if (defaultAllow) {
067                // allow by default, so allow if it wasn't explicitly denied or was explicitly allowed
068                return !isDenied(name) || isAllowed(name);
069            } else {
070                // deny by default, so allow if it was explicitly allowed or wasn't explicitly denied
071                return isAllowed(name) && !isDenied(name);
072            }
073        }
074    
075        protected boolean isAllowed(Name name) {
076            if (name == null) throw new NullPointerException("name is null");
077            for (Iterator iterator = allow.iterator(); iterator.hasNext();) {
078                Name prefix = (Name) iterator.next();
079                if (name.startsWith(prefix)) {
080                    return true;
081                }
082            }
083    
084            return false;
085        }
086    
087        protected boolean isDenied(Name name) {
088            if (name == null) throw new NullPointerException("name is null");
089            for (Iterator iterator = deny.iterator(); iterator.hasNext();) {
090                Name prefix = (Name) iterator.next();
091                if (name.startsWith(prefix)) {
092                    return true;
093                }
094            }
095    
096            return false;
097        }
098    }