blob: 7433c14ab93f30e42117b22a04f5b84eef4990d4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package org.apache.clerezza.dataset.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.PushbackReader;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.Permission;
/**
* Provides a utility method to instantiate a permission given its string
* representation as returned by <code>java security.Permission.toString</code>.
*
* @author reto
*/
public class PermissionParser {
final static Logger logger = LoggerFactory.getLogger(PermissionParser.class);
/**
* Parsers permissionDescription and instantiates the permission using
* the ClassLoader of this class.
*
* @param permissionDescription
* @return Permission
*/
public static Permission getPermission(String permissionDescription) {
return getPermission(permissionDescription, PermissionParser.class.getClassLoader());
}
/**
* Parsers permissionDescription and instantiates the permission using
* classLoader.
*
* @param permissionDescription
* @param classLoader
* @return Permission
*/
public static Permission getPermission(String permissionDescription, ClassLoader classLoader) {
PermissionInfo permissionInfo = parse(permissionDescription);
try {
Class clazz = classLoader.loadClass(permissionInfo.className);
Constructor<?> constructor = clazz.getConstructor(
String.class, String.class);
return (Permission) constructor.newInstance(
permissionInfo.name, permissionInfo.actions);
} catch (InstantiationException ie) {
logger.warn("{}", ie);
throw new RuntimeException(ie);
} catch (ClassNotFoundException cnfe) {
logger.warn("{}", cnfe);
throw new RuntimeException(cnfe);
} catch (NoSuchMethodException nsme) {
logger.warn("{}", nsme);
throw new RuntimeException(nsme);
} catch (InvocationTargetException ite) {
logger.warn("{}", ite);
throw new RuntimeException(ite);
} catch (IllegalAccessException iae) {
logger.warn("{}", iae);
throw new RuntimeException(iae);
}
}
private static PermissionInfo parse(String permissionDescription) {
StringReader reader = new StringReader(permissionDescription);
try {
return parse(reader);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
private static PermissionInfo parse(StringReader reader) throws IOException {
PermissionInfo result = new PermissionInfo();
for (int ch = reader.read(); ch != -1; ch = reader.read()) {
if (ch == ' ') {
continue;
}
if (ch =='(') {
parseFromClassName(reader, result);
break;
} else {
throw new IllegalArgumentException("Permission description does not start with '('");
}
}
for (int ch = reader.read(); ch != -1; ch = reader.read()) {
if (ch != ' ') {
throw new IllegalArgumentException("Unparsable characters after closing ')'");
}
}
return result;
}
private static void parseFromClassName(StringReader StringReader, PermissionInfo result) throws IOException {
PushbackReader reader = new PushbackReader(StringReader, 1);
result.className = readSection(reader);
result.name = readSection(reader);
result.actions = readSection(reader);
byte closingBracketsCount = 0;
for (int ch = reader.read(); ch != -1; ch = reader.read()) {
if (ch == ' ') {
continue;
}
if (ch == ')') {
closingBracketsCount++;
if (closingBracketsCount > 1) {
throw new IllegalArgumentException("more than 1 closing bracket");
}
continue;
}
else {
throw new IllegalArgumentException("illegal character at this position: "+ch);
}
}
}
private static String readSection(PushbackReader reader) throws IOException {
for (int ch = reader.read(); ch != -1; ch = reader.read()) {
if (ch == ' ') {
continue;
} else {
reader.unread(ch);
return readSectionWithNoHeadingSpace(reader);
}
}
return null;
}
private static String readSectionWithNoHeadingSpace(PushbackReader reader) throws IOException {
StringBuilder sectionWriter = new StringBuilder();
for (int ch = reader.read(); ch != -1; ch = reader.read()) {
if (ch == '"') {
if (sectionWriter.length() > 0) {
throw new IllegalArgumentException("Quote at wrong position, characters before quote: "+sectionWriter.toString());
}
sectionWriter = null;
return readTillQuote(reader);
}
if (ch == ' ') {
return sectionWriter.toString();
}
if (ch == ')') {
reader.unread(ch);
return sectionWriter.toString();
}
sectionWriter.append((char)ch);
}
throw new IllegalArgumentException("missing closing bracket (')')");
}
private static String readTillQuote(PushbackReader reader) throws IOException {
StringBuilder sectionWriter = new StringBuilder();
for (int ch = reader.read(); ch != -1; ch = reader.read()) {
if (ch == '"') {
return sectionWriter.toString();
}
sectionWriter.append((char)ch);
}
throw new IllegalArgumentException("missing closing quote ('=')");
}
private static class PermissionInfo {
String className, name, actions;
}
}