Java tutorial
/* * Copyright (C) 2006-2015 Ronald Blankendaal * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.dbgl.model; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.dbgl.exception.DrivelettersExhaustedException; import org.dbgl.exception.InvalidHostfileException; import org.dbgl.exception.InvalidMountstringException; import org.dbgl.util.FileUtils; import org.dbgl.util.PlatformUtils; import org.dbgl.util.StringRelatedUtils; public class Mount { private final static Pattern MOUNT_PATRN = Pattern.compile( "^(?:mount)(?:(?:\\s+-u\\s+([a-y]))|(?:(?:\\s+([a-y]))(?:\\s+((?:\\S+)|(?:\"[^\"]+\")))(?:(?:(?:\\s+-t\\s+(dir|floppy|cdrom|iso))|(?:\\s+-label (\\S+))|(?:\\s+-(ioctl(?:_dx|_dio|_mci)?|noioctl|aspi))|(?:\\s+-freesize\\s+(\\d+))|(?:\\s+-usecd\\s+(\\d+))|(?:\\s+-size\\s+(\\d+,\\d+,\\d+,\\d+))){0,6})))\\s*$", Pattern.CASE_INSENSITIVE); private final static Pattern IMGMOUNT_PATRN = Pattern.compile( "^(?:imgmount)(?:\\s+([a-y0-3]))((?:\\s+(?:(?:[^-][^\\s]+)|(?:\"[^\"]+\")))+)(?:(?:(?:\\s+-t\\s+(hdd|floppy|cdrom|iso))|(?:\\s+-fs\\s+(fat|iso|none))|(?:\\s+-size\\s+(\\d+,\\d+,\\d+,\\d+))){0,3})\\s*$", Pattern.CASE_INSENSITIVE); public enum MountingType { DIR, IMAGE, PHYSFS }; private MountingType mountingType; private String mountAs; private char driveletter; private String label; private File[] path; private File write; private String lowlevelCD; private String useCD; private String freesize; private String fs; private String size; private boolean unmounted; public Mount(final MountingType mountingType, final String mountAs, final String driveletter, final String[] paths, final String label, final String low, final String usecd, final String write, final String freesize, final String fs, final String size) { this.mountingType = mountingType; this.mountAs = mountAs.toLowerCase(); this.driveletter = Character.toUpperCase(driveletter.charAt(0)); this.path = new File[paths.length]; for (int i = 0; i < paths.length; i++) { this.path[i] = new File(paths[i]); } this.write = (write == null) ? null : new File(write); this.label = label; this.lowlevelCD = low; this.useCD = usecd; this.freesize = freesize; this.fs = fs; this.size = size; this.unmounted = false; } public Mount(final Mount otherMount) { this.mountingType = otherMount.mountingType; this.mountAs = otherMount.mountAs; this.driveletter = otherMount.driveletter; this.label = otherMount.label; this.path = otherMount.path.clone(); this.write = otherMount.write; this.lowlevelCD = otherMount.lowlevelCD; this.useCD = otherMount.useCD; this.freesize = otherMount.freesize; this.fs = otherMount.fs; this.size = otherMount.size; this.unmounted = otherMount.unmounted; } private void init() { mountingType = MountingType.DIR; mountAs = ""; driveletter = '\0'; label = ""; path = new File[0]; write = null; lowlevelCD = ""; useCD = ""; freesize = ""; fs = ""; size = ""; unmounted = false; } private void initForPhysFS(final String physFSPath) { mountingType = MountingType.PHYSFS; int colonIndex1 = physFSPath.indexOf(':'); if (colonIndex1 == 1) { colonIndex1 = physFSPath.indexOf(":", colonIndex1 + 1); } int colonIndex2 = physFSPath.lastIndexOf(":"); path = new File[1]; if (colonIndex1 == colonIndex2) { path[0] = new File(physFSPath.substring(0, colonIndex2)); } else { write = new File(physFSPath.substring(0, colonIndex1)); path[0] = new File(physFSPath.substring(colonIndex1 + 1, colonIndex2)); } } private void initForIso(final String IsoPath) { mountingType = MountingType.IMAGE; mountAs = "iso"; path = new File[1]; path[0] = new File(IsoPath.substring(0, FileUtils.containsIso(IsoPath))); } private void initForFat(final String fatImagePath) { mountingType = MountingType.IMAGE; mountAs = "floppy"; path = new File[1]; path[0] = new File(fatImagePath.substring(0, FileUtils.containsFatImage(fatImagePath))); } public Mount(final boolean floppy, final String hostFileLocation, final Set<Character> usedDriveLetters) throws InvalidHostfileException, DrivelettersExhaustedException { init(); if ("".equals(hostFileLocation)) { throw new InvalidHostfileException(); } driveletter = getFreeDriveletter(floppy, usedDriveLetters); if (FileUtils.containsPhysFS(hostFileLocation) != -1) { initForPhysFS(hostFileLocation); } else if (FileUtils.containsIso(hostFileLocation) != -1) { initForIso(hostFileLocation); } else if (FileUtils.containsFatImage(hostFileLocation) != -1) { driveletter = getFreeDriveletter(true, usedDriveLetters); initForFat(hostFileLocation); } else { File hostFile = new File(hostFileLocation); path = new File[1]; path[0] = hostFile.getParentFile(); if (path[0] == null) { path[0] = new File("."); } if (FileUtils.isStoredOnFloppyDrive(hostFile)) mountAs = "floppy"; else if (FileUtils.isStoredOnCDRomDrive(hostFile)) mountAs = "cdrom"; } } public Mount(String hostFileLocation, final Set<Character> usedDriveLetters, File[] overrideFilesToMount) throws InvalidHostfileException, DrivelettersExhaustedException { this(false, hostFileLocation, usedDriveLetters); if (overrideFilesToMount != null && overrideFilesToMount.length > 0) { path = overrideFilesToMount; } } public Mount(final String mount) throws InvalidMountstringException { init(); Matcher mountMatcher = MOUNT_PATRN.matcher(mount); Matcher imgmountMatcher = IMGMOUNT_PATRN.matcher(mount); if (mountMatcher.matches()) { if (mountMatcher.group(1) != null) { unmounted = true; driveletter = Character.toUpperCase(mountMatcher.group(1).charAt(0)); return; } driveletter = Character.toUpperCase(mountMatcher.group(2).charAt(0)); String mountLocation = StringUtils.strip(PlatformUtils.toNativePath(mountMatcher.group(3)), "\""); if (FileUtils.isPhysFS(mountLocation)) initForPhysFS(mountLocation); else path = new File[] { FileUtils.makeRelativeToDosroot(FileUtils.canonicalToDosroot(mountLocation)) }; mountAs = StringUtils.defaultString(mountMatcher.group(4)); label = StringUtils.defaultString(mountMatcher.group(5)); lowlevelCD = StringUtils.defaultString(mountMatcher.group(6)); freesize = StringUtils.defaultString(mountMatcher.group(7)); useCD = StringUtils.defaultString(mountMatcher.group(8)); } else if (imgmountMatcher.matches()) { mountingType = MountingType.IMAGE; driveletter = Character.toUpperCase(imgmountMatcher.group(1).charAt(0)); String[] paths = StringUtils.stripAll(PlatformUtils.toNativePath(imgmountMatcher.group(2)).trim() .split("\\s(?=([^\"]*\"[^\"]*\")*[^\"]*$)"), "\""); path = new File[paths.length]; for (int i = 0; i < paths.length; i++) path[i] = FileUtils.makeRelativeToDosroot(FileUtils.canonicalToDosroot(paths[i])); mountAs = StringUtils.defaultString(imgmountMatcher.group(3)); if (mountAs.equalsIgnoreCase("cdrom")) mountAs = "iso"; fs = StringUtils.defaultString(imgmountMatcher.group(4)); size = StringUtils.defaultString(imgmountMatcher.group(5)); } else { throw new InvalidMountstringException(); } } public static char getFreeDriveletter(final boolean floppy, final Set<Character> usedDriveLetters) throws DrivelettersExhaustedException { List<Character> freeDriveletters = new ArrayList<Character>(); char start = floppy ? 'A' : 'C'; for (char i = start; i < 'Z'; i++) { freeDriveletters.add(i); } if (!floppy) { freeDriveletters.add('A'); freeDriveletters.add('B'); } for (Character c : usedDriveLetters) { freeDriveletters.remove(c); } if (freeDriveletters.isEmpty()) { throw new DrivelettersExhaustedException(); } return freeDriveletters.get(0); } public String toString(final boolean forList) { StringBuffer result = new StringBuffer(); switch (mountingType) { case DIR: result.append("mount ").append(driveletter).append(" \"").append(getPathAsString()).append('"'); if (lowlevelCD.length() > 0) { result.append(" -").append(lowlevelCD); } if (useCD.length() > 0) { result.append(" -usecd ").append(useCD); } break; case PHYSFS: result.append("mount ").append(driveletter).append(" \""); if (write != null) { result.append(write.getPath()).append(':'); } result.append(path[0].getPath()).append(":\\\""); break; case IMAGE: result.append("imgmount ").append(driveletter); for (int i = 0; i < path.length; i++) { result.append(" \"").append(path[i].getPath()).append('"'); } break; default: } if (!"".equals(label)) { result.append(" -label ").append(label); } if (!"".equals(mountAs)) { result.append(" -t ").append(mountAs); } if (!"".equals(freesize)) { result.append(" -freesize ").append(freesize); } if (!"".equals(fs)) { result.append(" -fs ").append(fs); } if (!"".equals(size)) { result.append(" -size ").append(size); } if (unmounted) { if (forList) { result.append(" (UNMOUNTED)"); } else { result = new StringBuffer("mount -u ").append(driveletter); } } return result.toString(); } public String toString() { return toString(false); } public void toggleMount() { unmounted = !unmounted; } public char getDriveletter() { return driveletter; } public String getDriveletterString() { return String.valueOf(driveletter); } public String getLowlevelCD() { return lowlevelCD; } public String getUseCD() { return useCD; } public boolean isUnmounted() { return unmounted; } public String getLabel() { return label; } public String getPathAsString() { if (path.length <= 0) { return ""; } return path[0].getPath(); } public File getWrite() { return write; } public char getDriveletterFromPath() { return Character.toUpperCase(path[0].getAbsolutePath().charAt(0)); } public String getImgMountAsString(final String delimiter) { String[] paths = new String[path.length]; for (int i = 0; i < path.length; i++) { paths[i] = path[i].getPath(); } return StringRelatedUtils.stringArrayToString(paths, delimiter); } public File[] getPath() { return path; } public String getHostPathAsString() { return (mountingType == MountingType.PHYSFS) ? getPathAsString() + ':' : getPathAsString(); } public MountingType getMountingType() { return mountingType; } public String getMountAs() { return mountAs; } public String getFreesize() { return freesize; } public String getFs() { return fs; } public String getSize() { return size; } public File canBeUsedFor(final File hostFile) { if (!unmounted) { File canHostFile = FileUtils.getCanMainFile(hostFile); File mountFile = FileUtils.canonicalToDosroot(getPathAsString()); if (mountingType != MountingType.DIR && (FileUtils.isIsoFile(canHostFile.getPath()) || FileUtils.isArchive(canHostFile.getPath()) || FileUtils.isFatImage(canHostFile.getPath()))) { return (mountFile.equals(canHostFile)) ? FileUtils.makeRelativeTo(FileUtils.canonicalToDosroot(hostFile.getPath()), FileUtils.canonicalToDosroot(getHostPathAsString())) : null; } if (FileUtils.areRelated(mountFile, canHostFile)) { if ((hostFile.getPath().indexOf('~') > 0)) { if (hostFile.isAbsolute()) canHostFile = hostFile; else canHostFile = new File(FileUtils.getDosRoot(), hostFile.getPath()); } return FileUtils.makeRelativeTo(canHostFile, mountFile); } } return null; } public boolean matchesImageMountPath(final String hostFile) { return (mountingType == MountingType.IMAGE && getPathAsString().equals(hostFile)); } public void migrateToDosroot(final File fromPath, final boolean prefixDosroot) { for (int i = 0; i < path.length; i++) { path[i] = FileUtils.makeRelativeToDosroot(FileUtils.makeRelativeTo( prefixDosroot ? FileUtils.canonicalToDosroot(path[i].getPath()) : path[i], fromPath)); } if (write != null) { write = FileUtils.makeRelativeToDosroot(FileUtils.makeRelativeTo( prefixDosroot ? FileUtils.canonicalToDosroot(write.getPath()) : write, fromPath)); } } public void migrateTo(final File fromPath, final File toPath) { File from = FileUtils.makeRelativeToDosroot(fromPath); File to = FileUtils.makeRelativeToDosroot(toPath); for (int i = 0; i < path.length; i++) { if (path[i].getPath().equals(from.getPath())) path[i] = to; } if (write != null) { if (write.getPath().equals(from.getPath())) write = to; } } public void updateForTargetImportBaseDir(final File basePath) { for (int i = 0; i < path.length; i++) { path[i] = FileUtils.prefixAndSanitizeToDosroot(basePath, path[i]); } if (write != null) { write = FileUtils.prefixAndSanitizeToDosroot(basePath, write); } } public int hashCode() { return toString(false).hashCode(); } public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Mount otherMount = (Mount) obj; return (driveletter == otherMount.driveletter && unmounted == otherMount.unmounted); } }