1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.hdfs; 19 20 import java.util.List; 21 import java.util.Map; 22 23 import org.apache.hadoop.HadoopIllegalArgumentException; 24 import org.apache.hadoop.classification.InterfaceAudience; 25 import org.apache.hadoop.fs.XAttr; 26 import org.apache.hadoop.fs.XAttr.NameSpace; 27 import org.apache.hadoop.util.StringUtils; 28 29 import com.google.common.base.Preconditions; 30 import com.google.common.collect.Lists; 31 import com.google.common.collect.Maps; 32 33 @InterfaceAudience.Private 34 public class XAttrHelper { 35 36 /** 37 * Build <code>XAttr</code> from xattr name with prefix. 38 */ buildXAttr(String name)39 public static XAttr buildXAttr(String name) { 40 return buildXAttr(name, null); 41 } 42 43 /** 44 * Build <code>XAttr</code> from name with prefix and value. 45 * Name can not be null. Value can be null. The name and prefix 46 * are validated. 47 * Both name and namespace are case sensitive. 48 */ buildXAttr(String name, byte[] value)49 public static XAttr buildXAttr(String name, byte[] value) { 50 Preconditions.checkNotNull(name, "XAttr name cannot be null."); 51 52 final int prefixIndex = name.indexOf("."); 53 if (prefixIndex < 3) {// Prefix length is at least 3. 54 throw new HadoopIllegalArgumentException("An XAttr name must be " + 55 "prefixed with user/trusted/security/system/raw, followed by a '.'"); 56 } else if (prefixIndex == name.length() - 1) { 57 throw new HadoopIllegalArgumentException("XAttr name cannot be empty."); 58 } 59 60 NameSpace ns; 61 final String prefix = name.substring(0, prefixIndex); 62 if (StringUtils.equalsIgnoreCase(prefix, NameSpace.USER.toString())) { 63 ns = NameSpace.USER; 64 } else if ( 65 StringUtils.equalsIgnoreCase(prefix, NameSpace.TRUSTED.toString())) { 66 ns = NameSpace.TRUSTED; 67 } else if ( 68 StringUtils.equalsIgnoreCase(prefix, NameSpace.SYSTEM.toString())) { 69 ns = NameSpace.SYSTEM; 70 } else if ( 71 StringUtils.equalsIgnoreCase(prefix, NameSpace.SECURITY.toString())) { 72 ns = NameSpace.SECURITY; 73 } else if ( 74 StringUtils.equalsIgnoreCase(prefix, NameSpace.RAW.toString())) { 75 ns = NameSpace.RAW; 76 } else { 77 throw new HadoopIllegalArgumentException("An XAttr name must be " + 78 "prefixed with user/trusted/security/system/raw, followed by a '.'"); 79 } 80 XAttr xAttr = (new XAttr.Builder()).setNameSpace(ns).setName(name. 81 substring(prefixIndex + 1)).setValue(value).build(); 82 83 return xAttr; 84 } 85 86 /** 87 * Build xattr name with prefix as <code>XAttr</code> list. 88 */ buildXAttrAsList(String name)89 public static List<XAttr> buildXAttrAsList(String name) { 90 XAttr xAttr = buildXAttr(name); 91 List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1); 92 xAttrs.add(xAttr); 93 94 return xAttrs; 95 } 96 97 /** 98 * Get value of first xattr from <code>XAttr</code> list 99 */ getFirstXAttrValue(List<XAttr> xAttrs)100 public static byte[] getFirstXAttrValue(List<XAttr> xAttrs) { 101 byte[] value = null; 102 XAttr xAttr = getFirstXAttr(xAttrs); 103 if (xAttr != null) { 104 value = xAttr.getValue(); 105 if (value == null) { 106 value = new byte[0]; // xattr exists, but no value. 107 } 108 } 109 return value; 110 } 111 112 /** 113 * Get first xattr from <code>XAttr</code> list 114 */ getFirstXAttr(List<XAttr> xAttrs)115 public static XAttr getFirstXAttr(List<XAttr> xAttrs) { 116 if (xAttrs != null && !xAttrs.isEmpty()) { 117 return xAttrs.get(0); 118 } 119 120 return null; 121 } 122 123 /** 124 * Build xattr map from <code>XAttr</code> list, the key is 125 * xattr name with prefix, and value is xattr value. 126 */ buildXAttrMap(List<XAttr> xAttrs)127 public static Map<String, byte[]> buildXAttrMap(List<XAttr> xAttrs) { 128 if (xAttrs == null) { 129 return null; 130 } 131 Map<String, byte[]> xAttrMap = Maps.newHashMap(); 132 for (XAttr xAttr : xAttrs) { 133 String name = getPrefixName(xAttr); 134 byte[] value = xAttr.getValue(); 135 if (value == null) { 136 value = new byte[0]; 137 } 138 xAttrMap.put(name, value); 139 } 140 141 return xAttrMap; 142 } 143 144 /** 145 * Get name with prefix from <code>XAttr</code> 146 */ getPrefixName(XAttr xAttr)147 public static String getPrefixName(XAttr xAttr) { 148 if (xAttr == null) { 149 return null; 150 } 151 152 String namespace = xAttr.getNameSpace().toString(); 153 return StringUtils.toLowerCase(namespace) + "." + xAttr.getName(); 154 } 155 156 /** 157 * Build <code>XAttr</code> list from xattr name list. 158 */ buildXAttrs(List<String> names)159 public static List<XAttr> buildXAttrs(List<String> names) { 160 if (names == null || names.isEmpty()) { 161 throw new HadoopIllegalArgumentException("XAttr names can not be " + 162 "null or empty."); 163 } 164 165 List<XAttr> xAttrs = Lists.newArrayListWithCapacity(names.size()); 166 for (String name : names) { 167 xAttrs.add(buildXAttr(name, null)); 168 } 169 return xAttrs; 170 } 171 } 172