001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019
020
021 package org.apache.geronimo.security.util;
022
023 import java.util.Set;
024 import java.util.HashSet;
025 import java.util.regex.Pattern;
026
027 /**
028 * Tracks sets of HTTP actions for use while computing permissions during web deployment.
029 *
030 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
031 */
032 public class HTTPMethods {
033 private static final Pattern TOKEN_PATTERN = Pattern.compile("[!-~&&[^\\(\\)\\<\\>@,;:\\\\\"/\\[\\]\\?=\\{\\}]]*");
034
035 private final Set<String> methods = new HashSet<String>();
036 private boolean isExcluded = false;
037
038
039 public HTTPMethods() {
040 }
041
042 public HTTPMethods(HTTPMethods httpMethods, boolean complemented) {
043 isExcluded = httpMethods.isExcluded ^ complemented;
044 methods.addAll(httpMethods.methods);
045 }
046
047 public void add(String httpMethod) {
048 if (isExcluded) {
049 checkToken(httpMethod);
050 methods.remove(httpMethod);
051 } else if (httpMethod == null || httpMethod.length() == 0) {
052 isExcluded = true;
053 methods.clear();
054 } else {
055 checkToken(httpMethod);
056 methods.add(httpMethod);
057 }
058 }
059
060 public HTTPMethods add(HTTPMethods httpMethods) {
061 if (isExcluded) {
062 if (httpMethods.isExcluded) {
063 methods.retainAll(httpMethods.methods);
064 } else {
065 methods.removeAll(httpMethods.methods);
066 }
067 } else {
068 if (httpMethods.isExcluded) {
069 isExcluded = true;
070 Set<String> toRemove = new HashSet<String>(methods);
071 methods.clear();
072 methods.addAll(httpMethods.methods);
073 methods.removeAll(toRemove);
074 } else {
075 methods.addAll(httpMethods.methods);
076 }
077 }
078 return this;
079 }
080
081 public String getHttpMethods() {
082 return getHttpMethodsBuffer(isExcluded).toString();
083 }
084
085 public StringBuffer getHttpMethodsBuffer() {
086 return getHttpMethodsBuffer(isExcluded);
087 }
088
089 public String getComplementedHttpMethods() {
090 return getHttpMethodsBuffer(!isExcluded).toString();
091 }
092
093 private StringBuffer getHttpMethodsBuffer( boolean excluded) {
094 StringBuffer buffer = new StringBuffer();
095 if (excluded) {
096 buffer.append("!");
097 }
098 boolean afterFirst = false;
099 for (String method : methods) {
100 if (afterFirst) {
101 buffer.append(",");
102 } else {
103 afterFirst = true;
104 }
105 buffer.append(method);
106 }
107 return buffer;
108 }
109
110 private void checkToken(String method) {
111 if (!TOKEN_PATTERN.matcher(method).matches()) {
112 throw new IllegalArgumentException("Invalid HTTPMethodSpec");
113 }
114 }
115
116
117 public boolean isNone() {
118 return !isExcluded && methods.isEmpty();
119 }
120 }