/*
* Copyright (c) 2012-2015 iWave Software LLC
* All Rights Reserved
*/
package com.iwave.ext.text;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import com.iwave.ext.text.TextParserTest.DiskUtilVolume.DiskUtilVolumeParser;
public class TextParserTest {
private static final String DISKUTIL_FILENAME = "diskutil_list";
@Test
public void diskUtilTest() {
String diskUtilOutput = readFile(DISKUTIL_FILENAME);
List<DiskUtilDisk> disks = new DiskUtilDisk.DiskUtilParser().getDisks(diskUtilOutput);
assertEquals(3, disks.size());
assertDisk0(disks.get(0));
assertDisk2(disks.get(1));
assertDisk4(disks.get(2));
}
private void assertDisk0(DiskUtilDisk disk) {
disk.dump();
assertEquals(4, disk.volumes.size());
DiskUtilVolume vol1 = disk.volumes.get(0);
assertEquals(0, vol1.number);
assertTrue(vol1.partitionMap);
assertEquals("", vol1.name.trim());
assertEquals("GUID_partition_scheme", vol1.type);
assertEquals(251.0, vol1.size, 0.0);
assertEquals("GB", vol1.units);
assertEquals("disk0", vol1.id);
DiskUtilVolume vol2 = disk.volumes.get(1);
assertFalse(vol2.partitionMap);
assertEquals(1, vol2.number);
assertEquals("", vol2.name.trim());
assertEquals("EFI", vol2.type);
assertEquals(209.7, vol2.size, 0.0);
assertEquals("MB", vol2.units);
assertEquals("disk0s1", vol2.id);
DiskUtilVolume vol3 = disk.volumes.get(2);
assertFalse(vol3.partitionMap);
assertEquals(2, vol3.number);
assertEquals("Macintosh HD", vol3.name.trim());
assertEquals("Apple_HFS", vol3.type);
assertEquals(250.1, vol3.size, 0.0);
assertEquals("GB", vol3.units);
assertEquals("disk0s2", vol3.id);
DiskUtilVolume vol4 = disk.volumes.get(3);
assertFalse(vol4.partitionMap);
assertEquals(3, vol4.number);
assertEquals("Recovery HD", vol4.name.trim());
assertEquals("Apple_Boot", vol4.type);
assertEquals(650.0, vol4.size, 0.0);
assertEquals("MB", vol4.units);
assertEquals("disk0s3", vol4.id);
}
private void assertDisk2(DiskUtilDisk disk) {
disk.dump();
assertEquals(4, disk.volumes.size());
DiskUtilVolume vol1 = disk.volumes.get(0);
assertEquals(0, vol1.number);
assertTrue(vol1.partitionMap);
assertEquals("", vol1.name.trim());
assertEquals("FDisk_partition_scheme", vol1.type);
assertEquals(1.0, vol1.size, 0.0);
assertEquals("TB", vol1.units);
assertEquals("disk2", vol1.id);
DiskUtilVolume vol2 = disk.volumes.get(1);
assertFalse(vol2.partitionMap);
assertEquals(1, vol2.number);
assertEquals("exFAT", vol2.name.trim());
assertEquals("Windows_NTFS", vol2.type);
assertEquals(925.3, vol2.size, 0.0);
assertEquals("GB", vol2.units);
assertEquals("disk2s1", vol2.id);
DiskUtilVolume vol3 = disk.volumes.get(2);
assertFalse(vol3.partitionMap);
assertEquals(2, vol3.number);
assertEquals("HFS+", vol3.name.trim());
assertEquals("Apple_HFS", vol3.type);
assertEquals(50.1, vol3.size, 0.0);
assertEquals("GB", vol3.units);
assertEquals("disk2s2", vol3.id);
DiskUtilVolume vol4 = disk.volumes.get(3);
assertFalse(vol4.partitionMap);
assertEquals(3, vol4.number);
assertEquals("FAT32", vol4.name.trim());
assertEquals("DOS_FAT_32", vol4.type);
assertEquals(24.7, vol4.size, 0.0);
assertEquals("GB", vol4.units);
assertEquals("disk2s3", vol4.id);
}
private void assertDisk4(DiskUtilDisk disk) {
disk.dump();
assertEquals(1, disk.volumes.size());
DiskUtilVolume vol1 = disk.volumes.get(0);
assertEquals(0, vol1.number);
assertTrue(vol1.partitionMap);
assertEquals("Ubuntu 10.04.4 L", vol1.name.trim());
assertEquals(null, vol1.type);
assertEquals(728.2, vol1.size, 0.0);
assertEquals("MB", vol1.units);
assertEquals("disk4", vol1.id);
}
static class DiskUtilDisk {
public String name;
public List<DiskUtilVolume> volumes;
public void dump() {
println("Disk Name:\t%s", name);
for (DiskUtilVolume volume : volumes) {
volume.dump();
}
println();
}
static class DiskUtilParser {
private static final String DISK_REGEX = "\\/\\w+\\/([\\w\\d]+)";
// \/\w+\/([\w\d]+)
private static final String DISK_UTIL_UNTIL_NEXT_REGEX = "(?:(?!\\/dev).*\\n?)*";
// (?:(?!\/dev).*\n?)*
private static final String DISK_UTIL_BLOCK_REGEX = "(" + DISK_REGEX + "\\n" + DISK_UTIL_UNTIL_NEXT_REGEX + ")";
private static final String HEADER_REGEX = "\\s+#:\\s+TYPE\\sNAME\\s+SIZE\\s+IDENTIFIER";
// \s+#:\s+TYPE\sNAME\s+SIZE\s+IDENTIFIER$
public static final Pattern DISK_UTIL_START_PATTERN = Pattern.compile(DISK_REGEX + "\\n" + HEADER_REGEX + "\\n");
public static final Pattern DISK_UTIL_BLOCK_PATTERN = Pattern.compile(DISK_UTIL_BLOCK_REGEX);
public static final Pattern DISK_PATTERN = Pattern.compile(DISK_REGEX);
private final TextParser diskParser;
private final DiskUtilVolumeParser volumeParser;
public DiskUtilParser() {
diskParser = new TextParser();
diskParser.setStartPattern(DISK_UTIL_START_PATTERN);
diskParser.setRepeatPattern(DISK_UTIL_BLOCK_PATTERN);
volumeParser = new DiskUtilVolumeParser();
}
public List<DiskUtilDisk> getDisks(String diskUtilOutput) {
List<DiskUtilDisk> disks = new ArrayList<DiskUtilDisk>();
List<String> diskBlocks = diskParser.parseTextBlocks(diskUtilOutput);
for (String diskBlock : diskBlocks) {
disks.add(parseDisk(diskBlock));
}
return disks;
}
private DiskUtilDisk parseDisk(String diskBlock) {
Matcher diskMatch = DISK_PATTERN.matcher(diskBlock);
if (diskMatch.find()) {
DiskUtilDisk disk = new DiskUtilDisk();
disk.name = diskMatch.group(0);
disk.volumes = volumeParser.getDiskUtilVolumes(diskBlock);
return disk;
}
return null;
}
}
}
static class DiskUtilVolume {
public int number;
public String type;
public String name;
public boolean partitionMap;
public double size;
public String units;
public String id;
static class DiskUtilVolumeParser {
private static final String VOLUME_REGEX = "\\s+(\\d+):\\s{1,27}(\\w+)?\\s([\\w\\W]+?)\\s+(\\*?)(\\d+\\.\\d+)\\s(MB|GB|TB)\\s+(\\w+)";
// \s+(\d+):\s{1,27}(\w+)?\s([\w\W]+?)\s+(\*?)(\d+\.\d+)\s(MB|GB|TB)\s+(\w+)
private static final Pattern VOLUME_PATTERN = Pattern.compile(VOLUME_REGEX);
private final TextParser volumeParser;
public DiskUtilVolumeParser() {
volumeParser = new TextParser();
volumeParser.setStartPattern(DiskUtilDisk.DiskUtilParser.DISK_UTIL_START_PATTERN);
volumeParser.setRepeatPattern(VOLUME_PATTERN);
}
public List<DiskUtilVolume> getDiskUtilVolumes(String diskUtilBlock) {
List<DiskUtilVolume> volumes = new ArrayList<DiskUtilVolume>();
List<String> volumeBlocks = volumeParser.parseTextBlocks(diskUtilBlock);
for (String volumeBlock : volumeBlocks) {
Matcher volumeMatch = DiskUtilVolumeParser.VOLUME_PATTERN.matcher(volumeBlock);
if (volumeMatch.find()) {
DiskUtilVolume volume = new DiskUtilVolume();
volume.number = Integer.valueOf(volumeMatch.group(1));
volume.type = volumeMatch.group(2);
volume.name = volumeMatch.group(3);
volume.partitionMap = StringUtils.equals(volumeMatch.group(4), "*");
volume.size = Double.valueOf(volumeMatch.group(5));
volume.units = volumeMatch.group(6);
volume.id = volumeMatch.group(7);
volumes.add(volume);
}
}
return volumes;
}
}
public void dump() {
println("\tVolume Name:\t%s", name);
println("\t\tPartition Map:\t%s", partitionMap);
println("\t\tVolume Id:\t%s", id);
println("\t\tVolume #:\t%s", number);
println("\t\tVolume Type:\t%s", type);
println("\t\tVolume Size:\t%s %s", size, units);
}
}
protected String readFile(String filename) {
InputStream diskUtilFile = getClass().getResourceAsStream(filename);
StringWriter writer = new StringWriter();
try {
IOUtils.copy(diskUtilFile, writer);
} catch (IOException e) {
// This is a test class, it is ok to do a exception printStackTrace()
e.printStackTrace(); // NOSONAR (Throwable.printStackTrace(...) should not be called)
throw new RuntimeException(e);
}
String text = writer.toString();
return text;
}
public static void println() {
println("");
}
public static void println(String format, Object... args) {
print(format, args);
print("\n");
}
public static void print(String format, Object... args) {
System.out.print(String.format(format, args));
}
}