blob: 233061eb9352915e1d271eed77ad69aa05a2ceed [file] [log] [blame]
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed 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 com.google.enterprise.adaptor.fs;
import static java.nio.file.attribute.AclEntryPermission.*;
import java.nio.file.attribute.AclEntry;
import java.nio.file.attribute.AclEntryFlag;
import java.nio.file.attribute.AclEntryPermission;
import java.nio.file.attribute.AclEntryType;
import java.nio.file.attribute.AclFileAttributeView;
import java.nio.file.attribute.GroupPrincipal;
import java.nio.file.attribute.UserPrincipal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
/**
* This convenience class allows creation of an {@link AclFileAttributeView}
* containing a list of {@link AclEntry AclEntries} that is far less verbose
* than using {@link AclEntry.Builder} multiple times.
* </p>
* The static methods {@link user(String)} and {@link group(String} return
* builders for an AclEntry containing a {@link UserPrincipal} or a
* {@link GroupPrincipal}, accordingly. The remaining AclEntry fields may
* then be set using the returned builder.
* </p>
* If using the {@code AclView} constructor that takes {@link AclEntryBuilder}
* parameters, you need not call the {@code build()} method on those builders,
* as the constructor will do that for you.
* </p>
* An example construction of an AclView using this model would look like:<br>
* <code><pre>
* import static com.google.enterprise.adaptor.fs.AclView.*;
* import static java.nio.file.attribute.AclEntryFlag.*;
* import static java.nio.file.attribute.AclEntryPermission.*;
* import static java.nio.file.attribute.AclEntryType.*;
* ...
* AclFileAttributeView aclView = new AclView(
* user("joe").type(ALLOW).perms(READ_DATA, READ_ATTRIBUTES)
* .flags(FILE_INHERIT, DIRECTORY_INHERIT),
* group("EVERYONE").type(ALLOW).perms(READ_DATA)
* .flags(FILE_INHERIT, DIRECTORY_INHERIT),
* user("mary").type(DENY).perms:(READ_DATA));
* </pre></code>
*/
class AclView extends SimpleAclFileAttributeView {
/** Compound permissions for easier specification. */
static enum GenericPermission {
GENERIC_READ(SYNCHRONIZE, READ_ACL, READ_DATA, READ_ATTRIBUTES,
READ_NAMED_ATTRS),
GENERIC_WRITE(SYNCHRONIZE, READ_ACL, WRITE_DATA, APPEND_DATA,
WRITE_ATTRIBUTES, WRITE_NAMED_ATTRS),
GENERIC_EXECUTE(SYNCHRONIZE, READ_ACL, READ_ATTRIBUTES, EXECUTE),
GENERIC_ALL(AclEntryPermission.values());
private final Set<AclEntryPermission> permissions;
GenericPermission(AclEntryPermission... permissions) {
this.permissions = Collections.unmodifiableSet(
EnumSet.copyOf(Arrays.asList(permissions)));
}
Set<AclEntryPermission> getPermissions() {
return permissions;
}
}
AclView() {
super(Collections.<AclEntry>emptyList());
}
AclView(AclEntry... entries) {
super(Arrays.asList(entries));
}
AclView(AclEntryBuilder... entryBuilders) {
super(buildEntries(entryBuilders));
}
/** Return a new AclEntryBuilder for a user entry. */
static AclEntryBuilder user(String name) {
return new AclEntryBuilder().user(name);
}
/** Return a new AclEntryBuilder for a group entry. */
static AclEntryBuilder group(String name) {
return new AclEntryBuilder().group(name);
}
/** Build the a List of AclEntries from the accumulated entry builders. */
private static List<AclEntry> buildEntries(AclEntryBuilder... entryBuilders) {
ArrayList<AclEntry> entries = new ArrayList<AclEntry>(entryBuilders.length);
for (AclEntryBuilder builder : entryBuilders) {
entries.add(builder.build());
}
return entries;
}
/** An AclEntry builder that is less verbose than AclEntry.Builder. */
static class AclEntryBuilder {
private final AclEntry.Builder builder = AclEntry.newBuilder();
AclEntryBuilder user(String name) {
builder.setPrincipal(new User(name));
return this;
}
AclEntryBuilder group(String name) {
builder.setPrincipal(new Group(name));
return this;
}
AclEntryBuilder type(AclEntryType type) {
builder.setType(type);
return this;
}
AclEntryBuilder perms(AclEntryPermission... permissions) {
builder.setPermissions(permissions);
return this;
}
AclEntryBuilder perms(GenericPermission... permissions) {
Set<AclEntryPermission> perms = EnumSet.noneOf(AclEntryPermission.class);
for (GenericPermission genericPerm : permissions) {
perms.addAll(genericPerm.getPermissions());
}
builder.setPermissions(perms);
return this;
}
AclEntryBuilder flags(AclEntryFlag... flags) {
builder.setFlags(flags);
return this;
}
AclEntry build() {
return builder.build();
}
}
private static class User implements UserPrincipal {
private final String name;
User(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return name.equals(obj.toString());
}
}
private static class Group extends User implements GroupPrincipal {
Group(String name) {
super(name);
}
}
}