001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.hadoop.hdfs.web; 019 020 import org.apache.hadoop.fs.*; 021 import org.apache.hadoop.fs.permission.AclEntry; 022 import org.apache.hadoop.fs.permission.AclStatus; 023 import org.apache.hadoop.fs.permission.FsPermission; 024 import org.apache.hadoop.hdfs.DFSUtil; 025 import org.apache.hadoop.hdfs.protocol.*; 026 import org.apache.hadoop.hdfs.protocol.DatanodeInfo.AdminStates; 027 import org.apache.hadoop.hdfs.security.token.block.BlockTokenIdentifier; 028 import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier; 029 import org.apache.hadoop.hdfs.server.namenode.INodeId; 030 import org.apache.hadoop.ipc.RemoteException; 031 import org.apache.hadoop.security.token.Token; 032 import org.apache.hadoop.security.token.TokenIdentifier; 033 import org.apache.hadoop.util.DataChecksum; 034 import org.apache.hadoop.util.StringUtils; 035 import org.mortbay.util.ajax.JSON; 036 037 import java.io.ByteArrayInputStream; 038 import java.io.DataInputStream; 039 import java.io.IOException; 040 import java.util.*; 041 042 /** JSON Utilities */ 043 public class JsonUtil { 044 private static final Object[] EMPTY_OBJECT_ARRAY = {}; 045 private static final DatanodeInfo[] EMPTY_DATANODE_INFO_ARRAY = {}; 046 047 /** Convert a token object to a Json string. */ 048 public static String toJsonString(final Token<? extends TokenIdentifier> token 049 ) throws IOException { 050 return toJsonString(Token.class, toJsonMap(token)); 051 } 052 053 private static Map<String, Object> toJsonMap( 054 final Token<? extends TokenIdentifier> token) throws IOException { 055 if (token == null) { 056 return null; 057 } 058 059 final Map<String, Object> m = new TreeMap<String, Object>(); 060 m.put("urlString", token.encodeToUrlString()); 061 return m; 062 } 063 064 /** Convert a Json map to a Token. */ 065 public static Token<? extends TokenIdentifier> toToken( 066 final Map<?, ?> m) throws IOException { 067 if (m == null) { 068 return null; 069 } 070 071 final Token<DelegationTokenIdentifier> token 072 = new Token<DelegationTokenIdentifier>(); 073 token.decodeFromUrlString((String)m.get("urlString")); 074 return token; 075 } 076 077 /** Convert a Json map to a Token of DelegationTokenIdentifier. */ 078 @SuppressWarnings("unchecked") 079 public static Token<DelegationTokenIdentifier> toDelegationToken( 080 final Map<?, ?> json) throws IOException { 081 final Map<?, ?> m = (Map<?, ?>)json.get(Token.class.getSimpleName()); 082 return (Token<DelegationTokenIdentifier>)toToken(m); 083 } 084 085 /** Convert a Json map to a Token of BlockTokenIdentifier. */ 086 @SuppressWarnings("unchecked") 087 private static Token<BlockTokenIdentifier> toBlockToken( 088 final Map<?, ?> m) throws IOException { 089 return (Token<BlockTokenIdentifier>)toToken(m); 090 } 091 092 /** Convert a Token[] to a JSON array. */ 093 private static Object[] toJsonArray(final Token<? extends TokenIdentifier>[] array 094 ) throws IOException { 095 if (array == null) { 096 return null; 097 } else if (array.length == 0) { 098 return EMPTY_OBJECT_ARRAY; 099 } else { 100 final Object[] a = new Object[array.length]; 101 for(int i = 0; i < array.length; i++) { 102 a[i] = toJsonMap(array[i]); 103 } 104 return a; 105 } 106 } 107 108 /** Convert a token object to a JSON string. */ 109 public static String toJsonString(final Token<? extends TokenIdentifier>[] tokens 110 ) throws IOException { 111 if (tokens == null) { 112 return null; 113 } 114 115 final Map<String, Object> m = new TreeMap<String, Object>(); 116 m.put(Token.class.getSimpleName(), toJsonArray(tokens)); 117 return toJsonString(Token.class.getSimpleName() + "s", m); 118 } 119 120 /** Convert an Object[] to a List<Token<?>>. */ 121 private static List<Token<?>> toTokenList(final Object[] objects) throws IOException { 122 if (objects == null) { 123 return null; 124 } else if (objects.length == 0) { 125 return Collections.emptyList(); 126 } else { 127 final List<Token<?>> list = new ArrayList<Token<?>>(objects.length); 128 for(int i = 0; i < objects.length; i++) { 129 list.add(toToken((Map<?, ?>)objects[i])); 130 } 131 return list; 132 } 133 } 134 135 /** Convert a JSON map to a List<Token<?>>. */ 136 public static List<Token<?>> toTokenList(final Map<?, ?> json) throws IOException { 137 if (json == null) { 138 return null; 139 } 140 141 final Map<?, ?> m = (Map<?, ?>)json.get(Token.class.getSimpleName() + "s"); 142 return toTokenList((Object[])m.get(Token.class.getSimpleName())); 143 } 144 145 /** Convert an exception object to a Json string. */ 146 public static String toJsonString(final Exception e) { 147 final Map<String, Object> m = new TreeMap<String, Object>(); 148 m.put("exception", e.getClass().getSimpleName()); 149 m.put("message", e.getMessage()); 150 m.put("javaClassName", e.getClass().getName()); 151 return toJsonString(RemoteException.class, m); 152 } 153 154 /** Convert a Json map to a RemoteException. */ 155 public static RemoteException toRemoteException(final Map<?, ?> json) { 156 final Map<?, ?> m = (Map<?, ?>)json.get(RemoteException.class.getSimpleName()); 157 final String message = (String)m.get("message"); 158 final String javaClassName = (String)m.get("javaClassName"); 159 return new RemoteException(javaClassName, message); 160 } 161 162 private static String toJsonString(final Class<?> clazz, final Object value) { 163 return toJsonString(clazz.getSimpleName(), value); 164 } 165 166 /** Convert a key-value pair to a Json string. */ 167 public static String toJsonString(final String key, final Object value) { 168 final Map<String, Object> m = new TreeMap<String, Object>(); 169 m.put(key, value); 170 return JSON.toString(m); 171 } 172 173 /** Convert a FsPermission object to a string. */ 174 private static String toString(final FsPermission permission) { 175 return String.format("%o", permission.toShort()); 176 } 177 178 /** Convert a string to a FsPermission object. */ 179 private static FsPermission toFsPermission(final String s) { 180 return new FsPermission(Short.parseShort(s, 8)); 181 } 182 183 static enum PathType { 184 FILE, DIRECTORY, SYMLINK; 185 186 static PathType valueOf(HdfsFileStatus status) { 187 return status.isDir()? DIRECTORY: status.isSymlink()? SYMLINK: FILE; 188 } 189 } 190 191 /** Convert a HdfsFileStatus object to a Json string. */ 192 public static String toJsonString(final HdfsFileStatus status, 193 boolean includeType) { 194 if (status == null) { 195 return null; 196 } 197 final Map<String, Object> m = new TreeMap<String, Object>(); 198 m.put("pathSuffix", status.getLocalName()); 199 m.put("type", PathType.valueOf(status)); 200 if (status.isSymlink()) { 201 m.put("symlink", status.getSymlink()); 202 } 203 204 m.put("length", status.getLen()); 205 m.put("owner", status.getOwner()); 206 m.put("group", status.getGroup()); 207 m.put("permission", toString(status.getPermission())); 208 m.put("accessTime", status.getAccessTime()); 209 m.put("modificationTime", status.getModificationTime()); 210 m.put("blockSize", status.getBlockSize()); 211 m.put("replication", status.getReplication()); 212 m.put("fileId", status.getFileId()); 213 m.put("childrenNum", status.getChildrenNum()); 214 return includeType ? toJsonString(FileStatus.class, m): JSON.toString(m); 215 } 216 217 /** Convert a Json map to a HdfsFileStatus object. */ 218 public static HdfsFileStatus toFileStatus(final Map<?, ?> json, boolean includesType) { 219 if (json == null) { 220 return null; 221 } 222 223 final Map<?, ?> m = includesType ? 224 (Map<?, ?>)json.get(FileStatus.class.getSimpleName()) : json; 225 final String localName = (String) m.get("pathSuffix"); 226 final PathType type = PathType.valueOf((String) m.get("type")); 227 final byte[] symlink = type != PathType.SYMLINK? null 228 : DFSUtil.string2Bytes((String)m.get("symlink")); 229 230 final long len = (Long) m.get("length"); 231 final String owner = (String) m.get("owner"); 232 final String group = (String) m.get("group"); 233 final FsPermission permission = toFsPermission((String) m.get("permission")); 234 final long aTime = (Long) m.get("accessTime"); 235 final long mTime = (Long) m.get("modificationTime"); 236 final long blockSize = (Long) m.get("blockSize"); 237 final short replication = (short) (long) (Long) m.get("replication"); 238 final long fileId = m.containsKey("fileId") ? (Long) m.get("fileId") 239 : INodeId.GRANDFATHER_INODE_ID; 240 Long childrenNumLong = (Long) m.get("childrenNum"); 241 final int childrenNum = (childrenNumLong == null) ? -1 242 : childrenNumLong.intValue(); 243 return new HdfsFileStatus(len, type == PathType.DIRECTORY, replication, 244 blockSize, mTime, aTime, permission, owner, group, 245 symlink, DFSUtil.string2Bytes(localName), fileId, childrenNum); 246 } 247 248 /** Convert an ExtendedBlock to a Json map. */ 249 private static Map<String, Object> toJsonMap(final ExtendedBlock extendedblock) { 250 if (extendedblock == null) { 251 return null; 252 } 253 254 final Map<String, Object> m = new TreeMap<String, Object>(); 255 m.put("blockPoolId", extendedblock.getBlockPoolId()); 256 m.put("blockId", extendedblock.getBlockId()); 257 m.put("numBytes", extendedblock.getNumBytes()); 258 m.put("generationStamp", extendedblock.getGenerationStamp()); 259 return m; 260 } 261 262 /** Convert a Json map to an ExtendedBlock object. */ 263 private static ExtendedBlock toExtendedBlock(final Map<?, ?> m) { 264 if (m == null) { 265 return null; 266 } 267 268 final String blockPoolId = (String)m.get("blockPoolId"); 269 final long blockId = (Long)m.get("blockId"); 270 final long numBytes = (Long)m.get("numBytes"); 271 final long generationStamp = (Long)m.get("generationStamp"); 272 return new ExtendedBlock(blockPoolId, blockId, numBytes, generationStamp); 273 } 274 275 /** Convert a DatanodeInfo to a Json map. */ 276 static Map<String, Object> toJsonMap(final DatanodeInfo datanodeinfo) { 277 if (datanodeinfo == null) { 278 return null; 279 } 280 281 // TODO: Fix storageID 282 final Map<String, Object> m = new TreeMap<String, Object>(); 283 m.put("ipAddr", datanodeinfo.getIpAddr()); 284 // 'name' is equivalent to ipAddr:xferPort. Older clients (1.x, 0.23.x) 285 // expects this instead of the two fields. 286 m.put("name", datanodeinfo.getXferAddr()); 287 m.put("hostName", datanodeinfo.getHostName()); 288 m.put("storageID", datanodeinfo.getDatanodeUuid()); 289 m.put("xferPort", datanodeinfo.getXferPort()); 290 m.put("infoPort", datanodeinfo.getInfoPort()); 291 m.put("infoSecurePort", datanodeinfo.getInfoSecurePort()); 292 m.put("ipcPort", datanodeinfo.getIpcPort()); 293 294 m.put("capacity", datanodeinfo.getCapacity()); 295 m.put("dfsUsed", datanodeinfo.getDfsUsed()); 296 m.put("remaining", datanodeinfo.getRemaining()); 297 m.put("blockPoolUsed", datanodeinfo.getBlockPoolUsed()); 298 m.put("cacheCapacity", datanodeinfo.getCacheCapacity()); 299 m.put("cacheUsed", datanodeinfo.getCacheUsed()); 300 m.put("lastUpdate", datanodeinfo.getLastUpdate()); 301 m.put("xceiverCount", datanodeinfo.getXceiverCount()); 302 m.put("networkLocation", datanodeinfo.getNetworkLocation()); 303 m.put("adminState", datanodeinfo.getAdminState().name()); 304 return m; 305 } 306 307 private static int getInt(Map<?, ?> m, String key, final int defaultValue) { 308 Object value = m.get(key); 309 if (value == null) { 310 return defaultValue; 311 } 312 return (int) (long) (Long) value; 313 } 314 315 private static long getLong(Map<?, ?> m, String key, final long defaultValue) { 316 Object value = m.get(key); 317 if (value == null) { 318 return defaultValue; 319 } 320 return (long) (Long) value; 321 } 322 323 private static String getString(Map<?, ?> m, String key, 324 final String defaultValue) { 325 Object value = m.get(key); 326 if (value == null) { 327 return defaultValue; 328 } 329 return (String) value; 330 } 331 332 /** Convert a Json map to an DatanodeInfo object. */ 333 static DatanodeInfo toDatanodeInfo(final Map<?, ?> m) 334 throws IOException { 335 if (m == null) { 336 return null; 337 } 338 339 // ipAddr and xferPort are the critical fields for accessing data. 340 // If any one of the two is missing, an exception needs to be thrown. 341 342 // Handle the case of old servers (1.x, 0.23.x) sending 'name' instead 343 // of ipAddr and xferPort. 344 Object tmpValue = m.get("ipAddr"); 345 String ipAddr = (tmpValue == null) ? null : (String)tmpValue; 346 tmpValue = m.get("xferPort"); 347 int xferPort = (tmpValue == null) ? -1 : (int)(long)(Long)tmpValue; 348 if (ipAddr == null) { 349 tmpValue = m.get("name"); 350 if (tmpValue != null) { 351 String name = (String)tmpValue; 352 int colonIdx = name.indexOf(':'); 353 if (colonIdx > 0) { 354 ipAddr = name.substring(0, colonIdx); 355 xferPort = Integer.parseInt(name.substring(colonIdx +1)); 356 } else { 357 throw new IOException( 358 "Invalid value in server response: name=[" + name + "]"); 359 } 360 } else { 361 throw new IOException( 362 "Missing both 'ipAddr' and 'name' in server response."); 363 } 364 // ipAddr is non-null & non-empty string at this point. 365 } 366 367 // Check the validity of xferPort. 368 if (xferPort == -1) { 369 throw new IOException( 370 "Invalid or missing 'xferPort' in server response."); 371 } 372 373 // TODO: Fix storageID 374 return new DatanodeInfo( 375 ipAddr, 376 (String)m.get("hostName"), 377 (String)m.get("storageID"), 378 xferPort, 379 (int)(long)(Long)m.get("infoPort"), 380 getInt(m, "infoSecurePort", 0), 381 (int)(long)(Long)m.get("ipcPort"), 382 383 getLong(m, "capacity", 0l), 384 getLong(m, "dfsUsed", 0l), 385 getLong(m, "remaining", 0l), 386 getLong(m, "blockPoolUsed", 0l), 387 getLong(m, "cacheCapacity", 0l), 388 getLong(m, "cacheUsed", 0l), 389 getLong(m, "lastUpdate", 0l), 390 getInt(m, "xceiverCount", 0), 391 getString(m, "networkLocation", ""), 392 AdminStates.valueOf(getString(m, "adminState", "NORMAL"))); 393 } 394 395 /** Convert a DatanodeInfo[] to a Json array. */ 396 private static Object[] toJsonArray(final DatanodeInfo[] array) { 397 if (array == null) { 398 return null; 399 } else if (array.length == 0) { 400 return EMPTY_OBJECT_ARRAY; 401 } else { 402 final Object[] a = new Object[array.length]; 403 for(int i = 0; i < array.length; i++) { 404 a[i] = toJsonMap(array[i]); 405 } 406 return a; 407 } 408 } 409 410 /** Convert an Object[] to a DatanodeInfo[]. */ 411 private static DatanodeInfo[] toDatanodeInfoArray(final Object[] objects) 412 throws IOException { 413 if (objects == null) { 414 return null; 415 } else if (objects.length == 0) { 416 return EMPTY_DATANODE_INFO_ARRAY; 417 } else { 418 final DatanodeInfo[] array = new DatanodeInfo[objects.length]; 419 for(int i = 0; i < array.length; i++) { 420 array[i] = toDatanodeInfo((Map<?, ?>) objects[i]); 421 } 422 return array; 423 } 424 } 425 426 /** Convert a LocatedBlock to a Json map. */ 427 private static Map<String, Object> toJsonMap(final LocatedBlock locatedblock 428 ) throws IOException { 429 if (locatedblock == null) { 430 return null; 431 } 432 433 final Map<String, Object> m = new TreeMap<String, Object>(); 434 m.put("blockToken", toJsonMap(locatedblock.getBlockToken())); 435 m.put("isCorrupt", locatedblock.isCorrupt()); 436 m.put("startOffset", locatedblock.getStartOffset()); 437 m.put("block", toJsonMap(locatedblock.getBlock())); 438 m.put("locations", toJsonArray(locatedblock.getLocations())); 439 m.put("cachedLocations", toJsonArray(locatedblock.getCachedLocations())); 440 return m; 441 } 442 443 /** Convert a Json map to LocatedBlock. */ 444 private static LocatedBlock toLocatedBlock(final Map<?, ?> m) throws IOException { 445 if (m == null) { 446 return null; 447 } 448 449 final ExtendedBlock b = toExtendedBlock((Map<?, ?>)m.get("block")); 450 final DatanodeInfo[] locations = toDatanodeInfoArray( 451 (Object[])m.get("locations")); 452 final long startOffset = (Long)m.get("startOffset"); 453 final boolean isCorrupt = (Boolean)m.get("isCorrupt"); 454 final DatanodeInfo[] cachedLocations = toDatanodeInfoArray( 455 (Object[])m.get("cachedLocations")); 456 457 final LocatedBlock locatedblock = new LocatedBlock(b, locations, 458 null, null, startOffset, isCorrupt, cachedLocations); 459 locatedblock.setBlockToken(toBlockToken((Map<?, ?>)m.get("blockToken"))); 460 return locatedblock; 461 } 462 463 /** Convert a LocatedBlock[] to a Json array. */ 464 private static Object[] toJsonArray(final List<LocatedBlock> array 465 ) throws IOException { 466 if (array == null) { 467 return null; 468 } else if (array.size() == 0) { 469 return EMPTY_OBJECT_ARRAY; 470 } else { 471 final Object[] a = new Object[array.size()]; 472 for(int i = 0; i < array.size(); i++) { 473 a[i] = toJsonMap(array.get(i)); 474 } 475 return a; 476 } 477 } 478 479 /** Convert an Object[] to a List of LocatedBlock. */ 480 private static List<LocatedBlock> toLocatedBlockList(final Object[] objects 481 ) throws IOException { 482 if (objects == null) { 483 return null; 484 } else if (objects.length == 0) { 485 return Collections.emptyList(); 486 } else { 487 final List<LocatedBlock> list = new ArrayList<LocatedBlock>(objects.length); 488 for(int i = 0; i < objects.length; i++) { 489 list.add(toLocatedBlock((Map<?, ?>)objects[i])); 490 } 491 return list; 492 } 493 } 494 495 /** Convert LocatedBlocks to a Json string. */ 496 public static String toJsonString(final LocatedBlocks locatedblocks 497 ) throws IOException { 498 if (locatedblocks == null) { 499 return null; 500 } 501 502 final Map<String, Object> m = new TreeMap<String, Object>(); 503 m.put("fileLength", locatedblocks.getFileLength()); 504 m.put("isUnderConstruction", locatedblocks.isUnderConstruction()); 505 506 m.put("locatedBlocks", toJsonArray(locatedblocks.getLocatedBlocks())); 507 m.put("lastLocatedBlock", toJsonMap(locatedblocks.getLastLocatedBlock())); 508 m.put("isLastBlockComplete", locatedblocks.isLastBlockComplete()); 509 return toJsonString(LocatedBlocks.class, m); 510 } 511 512 /** Convert a Json map to LocatedBlock. */ 513 public static LocatedBlocks toLocatedBlocks(final Map<?, ?> json 514 ) throws IOException { 515 if (json == null) { 516 return null; 517 } 518 519 final Map<?, ?> m = (Map<?, ?>)json.get(LocatedBlocks.class.getSimpleName()); 520 final long fileLength = (Long)m.get("fileLength"); 521 final boolean isUnderConstruction = (Boolean)m.get("isUnderConstruction"); 522 final List<LocatedBlock> locatedBlocks = toLocatedBlockList( 523 (Object[])m.get("locatedBlocks")); 524 final LocatedBlock lastLocatedBlock = toLocatedBlock( 525 (Map<?, ?>)m.get("lastLocatedBlock")); 526 final boolean isLastBlockComplete = (Boolean)m.get("isLastBlockComplete"); 527 return new LocatedBlocks(fileLength, isUnderConstruction, locatedBlocks, 528 lastLocatedBlock, isLastBlockComplete); 529 } 530 531 /** Convert a ContentSummary to a Json string. */ 532 public static String toJsonString(final ContentSummary contentsummary) { 533 if (contentsummary == null) { 534 return null; 535 } 536 537 final Map<String, Object> m = new TreeMap<String, Object>(); 538 m.put("length", contentsummary.getLength()); 539 m.put("fileCount", contentsummary.getFileCount()); 540 m.put("directoryCount", contentsummary.getDirectoryCount()); 541 m.put("quota", contentsummary.getQuota()); 542 m.put("spaceConsumed", contentsummary.getSpaceConsumed()); 543 m.put("spaceQuota", contentsummary.getSpaceQuota()); 544 return toJsonString(ContentSummary.class, m); 545 } 546 547 /** Convert a Json map to a ContentSummary. */ 548 public static ContentSummary toContentSummary(final Map<?, ?> json) { 549 if (json == null) { 550 return null; 551 } 552 553 final Map<?, ?> m = (Map<?, ?>)json.get(ContentSummary.class.getSimpleName()); 554 final long length = (Long)m.get("length"); 555 final long fileCount = (Long)m.get("fileCount"); 556 final long directoryCount = (Long)m.get("directoryCount"); 557 final long quota = (Long)m.get("quota"); 558 final long spaceConsumed = (Long)m.get("spaceConsumed"); 559 final long spaceQuota = (Long)m.get("spaceQuota"); 560 561 return new ContentSummary(length, fileCount, directoryCount, 562 quota, spaceConsumed, spaceQuota); 563 } 564 565 /** Convert a MD5MD5CRC32FileChecksum to a Json string. */ 566 public static String toJsonString(final MD5MD5CRC32FileChecksum checksum) { 567 if (checksum == null) { 568 return null; 569 } 570 571 final Map<String, Object> m = new TreeMap<String, Object>(); 572 m.put("algorithm", checksum.getAlgorithmName()); 573 m.put("length", checksum.getLength()); 574 m.put("bytes", StringUtils.byteToHexString(checksum.getBytes())); 575 return toJsonString(FileChecksum.class, m); 576 } 577 578 /** Convert a Json map to a MD5MD5CRC32FileChecksum. */ 579 public static MD5MD5CRC32FileChecksum toMD5MD5CRC32FileChecksum( 580 final Map<?, ?> json) throws IOException { 581 if (json == null) { 582 return null; 583 } 584 585 final Map<?, ?> m = (Map<?, ?>)json.get(FileChecksum.class.getSimpleName()); 586 final String algorithm = (String)m.get("algorithm"); 587 final int length = (int)(long)(Long)m.get("length"); 588 final byte[] bytes = StringUtils.hexStringToByte((String)m.get("bytes")); 589 590 final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes)); 591 final DataChecksum.Type crcType = 592 MD5MD5CRC32FileChecksum.getCrcTypeFromAlgorithmName(algorithm); 593 final MD5MD5CRC32FileChecksum checksum; 594 595 // Recreate what DFSClient would have returned. 596 switch(crcType) { 597 case CRC32: 598 checksum = new MD5MD5CRC32GzipFileChecksum(); 599 break; 600 case CRC32C: 601 checksum = new MD5MD5CRC32CastagnoliFileChecksum(); 602 break; 603 default: 604 throw new IOException("Unknown algorithm: " + algorithm); 605 } 606 checksum.readFields(in); 607 608 //check algorithm name 609 if (!checksum.getAlgorithmName().equals(algorithm)) { 610 throw new IOException("Algorithm not matched. Expected " + algorithm 611 + ", Received " + checksum.getAlgorithmName()); 612 } 613 //check length 614 if (length != checksum.getLength()) { 615 throw new IOException("Length not matched: length=" + length 616 + ", checksum.getLength()=" + checksum.getLength()); 617 } 618 619 return checksum; 620 } 621 /** Convert a AclStatus object to a Json string. */ 622 public static String toJsonString(final AclStatus status) { 623 if (status == null) { 624 return null; 625 } 626 627 final Map<String, Object> m = new TreeMap<String, Object>(); 628 m.put("owner", status.getOwner()); 629 m.put("group", status.getGroup()); 630 m.put("stickyBit", status.isStickyBit()); 631 m.put("entries", status.getEntries()); 632 final Map<String, Map<String, Object>> finalMap = 633 new TreeMap<String, Map<String, Object>>(); 634 finalMap.put(AclStatus.class.getSimpleName(), m); 635 return JSON.toString(finalMap); 636 } 637 638 /** Convert a Json map to a AclStatus object. */ 639 public static AclStatus toAclStatus(final Map<?, ?> json) { 640 if (json == null) { 641 return null; 642 } 643 644 final Map<?, ?> m = (Map<?, ?>) json.get(AclStatus.class.getSimpleName()); 645 646 AclStatus.Builder aclStatusBuilder = new AclStatus.Builder(); 647 aclStatusBuilder.owner((String) m.get("owner")); 648 aclStatusBuilder.group((String) m.get("group")); 649 aclStatusBuilder.stickyBit((Boolean) m.get("stickyBit")); 650 651 final Object[] entries = (Object[]) m.get("entries"); 652 653 List<AclEntry> aclEntryList = new ArrayList<AclEntry>(); 654 for (int i = 0; i < entries.length; i++) { 655 AclEntry aclEntry = AclEntry.parseAclEntry((String) entries[i], true); 656 aclEntryList.add(aclEntry); 657 } 658 aclStatusBuilder.addEntries(aclEntryList); 659 return aclStatusBuilder.build(); 660 } 661 }