/**************************************************************************
* Copyright (c) 2001 by Punch Telematix. All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* 3. Neither the name of Punch Telematix nor the names of *
* other contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission.*
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
* IN NO EVENT SHALL PUNCH TELEMATIX OR OTHER CONTRIBUTORS BE LIABLE *
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, *
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE *
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN *
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
**************************************************************************/
/**
* $Id: FilePermission.java,v 1.2 2006/02/23 12:32:12 cvs Exp $
*/
package java.io;
import java.security.Permission;
import java.security.PermissionCollection;
public final class FilePermission extends Permission {
private static final long serialVersionUID = 7930732926638008763L;
private static final String CURRENTDIR = new File("").getAbsolutePath();
private String actions;
private boolean read;
private boolean write;
private boolean execute;
private boolean delete;
static final String SEP = File.separator;
static final String SEP_STAR = SEP + "*";
static final String SEP_DASH = SEP + "-";
private static final int SEPLENGTH = SEP.length();
private static final char SEP_CHAR = SEP.charAt(0);
private void parseActions(String s) {
String sx = s.toLowerCase();
while (sx != "") {
int i = sx.indexOf(',');
String s0;
if (i<0) {
s0 = sx.trim();
sx = "";
}
else {
s0 = sx.substring(0,i).trim();
sx = sx.substring(i+1);
}
if (s0.equals("read")) {
read = true;
}
else if (s0.equals("write")) {
write = true;
}
else if (s0.equals("execute")) {
execute = true;
}
else if (s0.equals("delete")) {
delete = true;
}
else { throw new IllegalArgumentException(s0+" is no valid action"); }
}
StringBuffer buf = new StringBuffer(26);
if(read) {
buf.append("read,");
}
if(write) {
buf.append("write,");
}
if(execute) {
buf.append("execute,");
}
if(delete) {
buf.append("delete,");
}
if(!(execute || delete || read || write)) {
throw new IllegalArgumentException("no actions specified");
}
else {
actions = buf.substring(0,buf.length()-1); //-1 to lose the trailing ','
}
}
private static String toAbsolutePath(String path){
if(path.startsWith(SEP)){
return path;
}
if(path.startsWith(".")){
String newPath = CURRENTDIR;
int dotCount = 1;
int i = 1;
int path_length = path.length();
for(; i < path_length ; i++){
char ch = path.charAt(i);
if(ch != '.'){
if(path.indexOf(SEP,i) != i){
break;
}
if(dotCount == 2){
int slash = newPath.lastIndexOf(SEP,newPath.length());
if(slash >= SEPLENGTH){
newPath = newPath.substring(0,slash+SEPLENGTH);
}
}
i += SEPLENGTH-1;
}
else{
if(dotCount > 1){
i -= dotCount;
break;
}
dotCount++;
}
}
if(newPath == CURRENTDIR){
return path.substring(i);
}
return newPath+path.substring(i);
}
return path;
}
public FilePermission(String path, String actions) {
// Note: if we were to support relative pathnames, we would do so
// by prefixing the current directory right here.
super(toAbsolutePath(path));
parseActions(actions);
}
public boolean implies (Permission p) {
if (!( p instanceof FilePermission)) {
return false;
}
FilePermission fp = (FilePermission)p;
if ((fp.read && !this.read) || (fp.write && !this.write) || (fp.execute && !this.execute) || (fp.delete && !this.delete)) {
return false;
}
String thisname = super.getName();
String othername = p.getName();
if (thisname.equals("<<ALL FILES>>")) {
return true;
}
if (thisname.endsWith(SEP_DASH)) {
int l = thisname.length()-1;
boolean b = othername.startsWith(thisname.substring(0,l));// this still includes the path itself
b &= (othername.length() != l);
return b;
}
else if (thisname.endsWith(SEP_STAR)) {
int i = thisname.lastIndexOf(SEP_CHAR)+1;
int pos = othername.indexOf(SEP_CHAR,i+1);
int l = othername.length();
return othername.startsWith(thisname.substring(0,i)) //the name should startwith path/
&& (pos < 0 || pos == l-1) // but it may not contain a / unless it is the last one
&& ( l != i); // thtis case means the othername is path/ (is not included in path/*)
}
else {
return othername.equals(thisname);
}
}
public boolean equals (Object o) {
if (!(o instanceof FilePermission)) {
return false;
}
FilePermission fp = (FilePermission) o;
if ((fp.read != this.read) || (fp.write != this.write) || (fp.execute != this.execute) || (fp.delete != this.delete)) {
return false;
}
return fp.getName().equals(super.getName());
}
public int hashCode() {
int h = super.getName().hashCode();
if (this.read) {
h ^= 0x80402010;
}
if (this.write) {
h ^= 0x20408010;
}
if (this.execute) {
h ^= 0x80102040;
}
if (this.delete) {
h ^= 0x08040201;
}
return h;
}
public String getActions() {
return actions;
}
public PermissionCollection newPermissionCollection() {
return new wonka.security.FilePermissionCollection();
}
}