1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.jimfs; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 21 import com.google.common.collect.ImmutableList; 22 import com.google.common.collect.ImmutableMap; 23 import com.google.common.collect.ImmutableSet; 24 import java.io.IOException; 25 import java.nio.file.attribute.AclEntry; 26 import java.nio.file.attribute.AclFileAttributeView; 27 import java.nio.file.attribute.FileAttributeView; 28 import java.nio.file.attribute.FileOwnerAttributeView; 29 import java.nio.file.attribute.UserPrincipal; 30 import java.util.List; 31 import java.util.Map; 32 import org.checkerframework.checker.nullness.compatqual.NullableDecl; 33 34 /** 35 * Attribute provider that provides the {@link AclFileAttributeView} ("acl"). 36 * 37 * @author Colin Decker 38 */ 39 final class AclAttributeProvider extends AttributeProvider { 40 41 private static final ImmutableSet<String> ATTRIBUTES = ImmutableSet.of("acl"); 42 43 private static final ImmutableSet<String> INHERITED_VIEWS = ImmutableSet.of("owner"); 44 45 private static final ImmutableList<AclEntry> DEFAULT_ACL = ImmutableList.of(); 46 47 @Override name()48 public String name() { 49 return "acl"; 50 } 51 52 @Override inherits()53 public ImmutableSet<String> inherits() { 54 return INHERITED_VIEWS; 55 } 56 57 @Override fixedAttributes()58 public ImmutableSet<String> fixedAttributes() { 59 return ATTRIBUTES; 60 } 61 62 @Override defaultValues(Map<String, ?> userProvidedDefaults)63 public ImmutableMap<String, ?> defaultValues(Map<String, ?> userProvidedDefaults) { 64 Object userProvidedAcl = userProvidedDefaults.get("acl:acl"); 65 66 ImmutableList<AclEntry> acl = DEFAULT_ACL; 67 if (userProvidedAcl != null) { 68 acl = toAcl(checkType("acl", "acl", userProvidedAcl, List.class)); 69 } 70 71 return ImmutableMap.of("acl:acl", acl); 72 } 73 74 @NullableDecl 75 @Override get(File file, String attribute)76 public Object get(File file, String attribute) { 77 if (attribute.equals("acl")) { 78 return file.getAttribute("acl", "acl"); 79 } 80 81 return null; 82 } 83 84 @Override set(File file, String view, String attribute, Object value, boolean create)85 public void set(File file, String view, String attribute, Object value, boolean create) { 86 if (attribute.equals("acl")) { 87 checkNotCreate(view, attribute, create); 88 file.setAttribute("acl", "acl", toAcl(checkType(view, attribute, value, List.class))); 89 } 90 } 91 92 @SuppressWarnings("unchecked") // only cast after checking each element's type toAcl(List<?> list)93 private static ImmutableList<AclEntry> toAcl(List<?> list) { 94 ImmutableList<?> copy = ImmutableList.copyOf(list); 95 for (Object obj : copy) { 96 if (!(obj instanceof AclEntry)) { 97 throw new IllegalArgumentException( 98 "invalid element for attribute 'acl:acl': should be List<AclEntry>, " 99 + "found element of type " 100 + obj.getClass()); 101 } 102 } 103 104 return (ImmutableList<AclEntry>) copy; 105 } 106 107 @Override viewType()108 public Class<AclFileAttributeView> viewType() { 109 return AclFileAttributeView.class; 110 } 111 112 @Override view( FileLookup lookup, ImmutableMap<String, FileAttributeView> inheritedViews)113 public AclFileAttributeView view( 114 FileLookup lookup, ImmutableMap<String, FileAttributeView> inheritedViews) { 115 return new View(lookup, (FileOwnerAttributeView) inheritedViews.get("owner")); 116 } 117 118 /** Implementation of {@link AclFileAttributeView}. */ 119 private static final class View extends AbstractAttributeView implements AclFileAttributeView { 120 121 private final FileOwnerAttributeView ownerView; 122 View(FileLookup lookup, FileOwnerAttributeView ownerView)123 public View(FileLookup lookup, FileOwnerAttributeView ownerView) { 124 super(lookup); 125 this.ownerView = checkNotNull(ownerView); 126 } 127 128 @Override name()129 public String name() { 130 return "acl"; 131 } 132 133 @SuppressWarnings("unchecked") 134 @Override getAcl()135 public List<AclEntry> getAcl() throws IOException { 136 return (List<AclEntry>) lookupFile().getAttribute("acl", "acl"); 137 } 138 139 @Override setAcl(List<AclEntry> acl)140 public void setAcl(List<AclEntry> acl) throws IOException { 141 checkNotNull(acl); 142 lookupFile().setAttribute("acl", "acl", ImmutableList.copyOf(acl)); 143 } 144 145 @Override getOwner()146 public UserPrincipal getOwner() throws IOException { 147 return ownerView.getOwner(); 148 } 149 150 @Override setOwner(UserPrincipal owner)151 public void setOwner(UserPrincipal owner) throws IOException { 152 ownerView.setOwner(owner); 153 } 154 } 155 } 156