/*
* Copyright (c) 2012-2015 iWave Software LLC
* All Rights Reserved
*/
package com.iwave.ext.windows;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.text.StrBuilder;
import com.google.common.collect.Lists;
import com.iwave.ext.command.CommandOutput;
public class WindowsUtils {
/** Message indicating that there was an error in DiskPart. */
private static final String DISKPART_ERROR = "DiskPart has encountered an error:";
/** DiskPart prompt in the output. */
private static final String DISKPART_PROMPT = "DISKPART>";
/** FAT drive labels are limited to 11 chars. */
private static final int MAX_DRIVE_LABEL_LENGTH = 11;
/** NTFS drive labels are limited to 32 chars. */
private static final int MAX_DRIVE_LABEL_LENGTH_NTFS = 32;
private static final String FS_TYPE_NTFS = "ntfs";
private static final String FS_TYPE_FAT32 = "fat32";
public static final String PARTITION_TYPE_MBR = "MBR";
public static final String PARTITION_TYPE_GPT = "GPT";
// 32 GB
private static final long MAX_BYTES_FAT32 = (32L * 1024 * 1024 * 1024) - 1;
// 2 TB
private static final long MAX_BYTES_2TB = (2L * 1024 * 1024 * 1024 * 1024) - 1;
public static List<String> getRescanCommands() {
return Lists.newArrayList("RESCAN");
}
public static List<String> getFormatAndMountDiskCommands(int diskNumber, String fsType, String allocationUnitSize, String label,
String mountpoint, String partitionType) {
List<String> commands = Lists.newArrayList();
commands.add("SELECT DISK " + diskNumber);
commands.addAll(getFormatCommands(fsType, allocationUnitSize, label, partitionType));
commands.add(getAssignCommand(mountpoint));
return commands;
}
public static List<String> getMountVolumeCommands(int volumeNumber, String mountpoint) {
List<String> commands = Lists.newArrayList();
commands.add("SELECT VOLUME " + volumeNumber);
commands.add("ONLINE VOLUME");
commands.add(getAssignCommand(mountpoint));
return commands;
}
public static String getAssignCommand(String mountpoint) {
if (StringUtils.isNotBlank(mountpoint)) {
if (mountpoint.length() == 1) {
return "ASSIGN LETTER=" + mountpoint;
}
else {
return "ASSIGN MOUNT=" + mountpoint;
}
}
else {
return "ASSIGN";
}
}
public static String getPartitionType(String partitionType) {
if (isGPT(partitionType)) {
return "CONVERT GPT";
}
return "";
}
public static List<String> getUnmountVolumeCommands(int volumeNumber, String mountPoint) {
List<String> commands = Lists.newArrayList();
commands.add("SELECT VOLUME " + volumeNumber);
commands.add("REMOVE");
return commands;
}
private static List<String> getFormatCommands(String fsType, String allocationUnitSize, String label, String partitionType) {
return Lists.newArrayList("CLEAN", getPartitionType(partitionType), "CREATE PARTITION PRIMARY", "ONLINE VOLUME",
getFormatCommand(fsType, allocationUnitSize, label));
}
private static String getFormatCommand(String fsType, String allocationUnitSize, String label) {
StrBuilder format = new StrBuilder();
format.append("FORMAT QUICK");
if (StringUtils.isNotBlank(fsType)) {
format.append(" FS=").append(fsType);
}
if (StringUtils.isNotBlank(allocationUnitSize)) {
format.append(" UNIT=").append(allocationUnitSize);
}
if (StringUtils.isNotBlank(label)) {
format.append(" LABEL=").append(normalizeDriveLabel(fsType, label));
}
return format.toString();
}
public static List<String> getDetailDiskCommands(int diskNumber) {
return Lists.newArrayList("SELECT DISK " + diskNumber, "DETAIL DISK");
}
public static List<String> getOnlineDiskCommands(int diskNumber, boolean currentReadOnlyState) {
List<String> commands = Lists.newArrayList();
commands.add("SELECT DISK " + diskNumber);
if (currentReadOnlyState) {
commands.add("ATTRIBUTES DISK CLEAR READONLY");
}
commands.add("ONLINE DISK");
return commands;
}
public static List<String> getOfflineDiskCommands(int diskNumber) {
return Lists.newArrayList("SELECT DISK " + diskNumber, "OFFLINE DISK");
}
public static List<String> getExtendVolumeCommands(String mountpoint) {
return Lists.newArrayList("SELECT VOLUME " + mountpoint, "EXTEND");
}
public static List<String> getListDiskCommands() {
return Lists.newArrayList("LIST DISK");
}
public static String getDiskPartError(CommandOutput output) {
String error = getDiskPartError(output.getStdout());
if (error == null) {
error = getDiskPartError(output.getStderr());
}
return error;
}
public static String getDiskPartError(String output) {
String error = StringUtils.substringAfter(output, DISKPART_ERROR);
if (StringUtils.isNotBlank(error)) {
return StringUtils.trim(StringUtils.substringBefore(error, DISKPART_PROMPT));
}
return null;
}
public static String normalizeDriveLabel(String fsType, String label) {
if (StringUtils.isNotBlank(label)) {
String driveLabel = StringUtils.trim(label);
driveLabel = driveLabel.replaceAll("[^A-Za-z0-9_]", "_");
if (isNTFS(fsType)) {
driveLabel = StringUtils.substring(driveLabel, 0, MAX_DRIVE_LABEL_LENGTH_NTFS);
}
else {
driveLabel = StringUtils.substring(driveLabel, 0, MAX_DRIVE_LABEL_LENGTH);
}
return driveLabel;
}
else {
return null;
}
}
public static boolean isNTFS(String fileSystemType) {
return StringUtils.equals(fileSystemType, FS_TYPE_NTFS);
}
public static boolean isFat32(String fileSystemType) {
return StringUtils.equals(fileSystemType, FS_TYPE_FAT32);
}
public static boolean isFat32CapacityInBytesTooLarge(long capacityInBytes) {
return capacityInBytes > MAX_BYTES_FAT32;
}
public static boolean isGPT(String partitionType) {
return StringUtils.equals(partitionType, PARTITION_TYPE_GPT);
}
public static boolean isMBR(String partitionType) {
return StringUtils.equals(partitionType, PARTITION_TYPE_MBR);
}
public static boolean isMBRCapacityInBytesTooLarge(long capacityInBytes) {
return capacityInBytes > MAX_BYTES_2TB;
}
}