| /** |
| * 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.hadoop.hdfs; |
| |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.hadoop.HadoopIllegalArgumentException; |
| import org.apache.hadoop.classification.InterfaceAudience; |
| import org.apache.hadoop.fs.XAttr; |
| import org.apache.hadoop.fs.XAttr.NameSpace; |
| import org.apache.hadoop.util.StringUtils; |
| |
| import com.google.common.base.Preconditions; |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Maps; |
| |
| @InterfaceAudience.Private |
| public class XAttrHelper { |
| |
| /** |
| * Build <code>XAttr</code> from xattr name with prefix. |
| */ |
| public static XAttr buildXAttr(String name) { |
| return buildXAttr(name, null); |
| } |
| |
| /** |
| * Build <code>XAttr</code> from name with prefix and value. |
| * Name can not be null. Value can be null. The name and prefix |
| * are validated. |
| * Both name and namespace are case sensitive. |
| */ |
| public static XAttr buildXAttr(String name, byte[] value) { |
| Preconditions.checkNotNull(name, "XAttr name cannot be null."); |
| |
| final int prefixIndex = name.indexOf("."); |
| if (prefixIndex < 3) {// Prefix length is at least 3. |
| throw new HadoopIllegalArgumentException("An XAttr name must be " + |
| "prefixed with user/trusted/security/system/raw, followed by a '.'"); |
| } else if (prefixIndex == name.length() - 1) { |
| throw new HadoopIllegalArgumentException("XAttr name cannot be empty."); |
| } |
| |
| NameSpace ns; |
| final String prefix = name.substring(0, prefixIndex); |
| if (StringUtils.equalsIgnoreCase(prefix, NameSpace.USER.toString())) { |
| ns = NameSpace.USER; |
| } else if ( |
| StringUtils.equalsIgnoreCase(prefix, NameSpace.TRUSTED.toString())) { |
| ns = NameSpace.TRUSTED; |
| } else if ( |
| StringUtils.equalsIgnoreCase(prefix, NameSpace.SYSTEM.toString())) { |
| ns = NameSpace.SYSTEM; |
| } else if ( |
| StringUtils.equalsIgnoreCase(prefix, NameSpace.SECURITY.toString())) { |
| ns = NameSpace.SECURITY; |
| } else if ( |
| StringUtils.equalsIgnoreCase(prefix, NameSpace.RAW.toString())) { |
| ns = NameSpace.RAW; |
| } else { |
| throw new HadoopIllegalArgumentException("An XAttr name must be " + |
| "prefixed with user/trusted/security/system/raw, followed by a '.'"); |
| } |
| |
| return (new XAttr.Builder()).setNameSpace(ns).setName(name. |
| substring(prefixIndex + 1)).setValue(value).build(); |
| } |
| |
| /** |
| * Build xattr name with prefix as <code>XAttr</code> list. |
| */ |
| public static List<XAttr> buildXAttrAsList(String name) { |
| XAttr xAttr = buildXAttr(name); |
| List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1); |
| xAttrs.add(xAttr); |
| |
| return xAttrs; |
| } |
| |
| /** |
| * Get value of first xattr from <code>XAttr</code> list |
| */ |
| public static byte[] getFirstXAttrValue(List<XAttr> xAttrs) { |
| byte[] value = null; |
| XAttr xAttr = getFirstXAttr(xAttrs); |
| if (xAttr != null) { |
| value = xAttr.getValue(); |
| if (value == null) { |
| value = new byte[0]; // xattr exists, but no value. |
| } |
| } |
| return value; |
| } |
| |
| /** |
| * Get first xattr from <code>XAttr</code> list |
| */ |
| public static XAttr getFirstXAttr(List<XAttr> xAttrs) { |
| if (xAttrs != null && !xAttrs.isEmpty()) { |
| return xAttrs.get(0); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Build xattr map from <code>XAttr</code> list, the key is |
| * xattr name with prefix, and value is xattr value. |
| */ |
| public static Map<String, byte[]> buildXAttrMap(List<XAttr> xAttrs) { |
| if (xAttrs == null) { |
| return null; |
| } |
| Map<String, byte[]> xAttrMap = Maps.newHashMap(); |
| for (XAttr xAttr : xAttrs) { |
| String name = getPrefixedName(xAttr); |
| byte[] value = xAttr.getValue(); |
| if (value == null) { |
| value = new byte[0]; |
| } |
| xAttrMap.put(name, value); |
| } |
| |
| return xAttrMap; |
| } |
| |
| /** |
| * Get name with prefix from <code>XAttr</code> |
| */ |
| public static String getPrefixedName(XAttr xAttr) { |
| if (xAttr == null) { |
| return null; |
| } |
| |
| return getPrefixedName(xAttr.getNameSpace(), xAttr.getName()); |
| } |
| |
| public static String getPrefixedName(XAttr.NameSpace ns, String name) { |
| return StringUtils.toLowerCase(ns.toString()) + "." + name; |
| } |
| |
| /** |
| * Build <code>XAttr</code> list from xattr name list. |
| */ |
| public static List<XAttr> buildXAttrs(List<String> names) { |
| if (names == null || names.isEmpty()) { |
| throw new HadoopIllegalArgumentException("XAttr names can not be " + |
| "null or empty."); |
| } |
| |
| List<XAttr> xAttrs = Lists.newArrayListWithCapacity(names.size()); |
| for (String name : names) { |
| xAttrs.add(buildXAttr(name, null)); |
| } |
| return xAttrs; |
| } |
| } |