001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2016 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028package edu.wisc.ssec.mcidasv.startupmanager; 029 030import java.io.File; 031import java.nio.file.Files; 032import java.nio.file.Path; 033import java.nio.file.Paths; 034import java.util.Objects; 035 036import edu.wisc.ssec.mcidasv.Constants; 037import edu.wisc.ssec.mcidasv.startupmanager.options.OptionMaster; 038 039/** 040 * Represents platform specific details used by McIDAS-V. In particular, there 041 * are useful methods related to the McIDAS-V {@literal "userpath"}. 042 * 043 * <p>Currently McIDAS-V distinguishes between {@literal "Unix-like"} and 044 * {@literal "Windows"}; these can be accessed using {@code Platform.UNIXLIKE} 045 * or {@code Platform.WINDOWS}.</p> 046 */ 047public enum Platform { 048 /** Instance of unix-specific platform information. */ 049 UNIXLIKE("runMcV.prefs", "\n"), 050 051 /** Instance of windows-specific platform information. */ 052 WINDOWS("runMcV-Prefs.bat", "\r\n"); 053 054 /** Path to the user's {@literal "userpath"} directory. */ 055 private String userDirectory; 056 057 /** The path to the user's copy of the startup preferences. */ 058 private String userPrefs; 059 060 /** Path to the preference file that ships with McIDAS-V. */ 061 private final String defaultPrefs; 062 063 /** Holds the platform's representation of a new line. */ 064 private final String newLine; 065 066 /** Path to the bundles subdirectory within {@code userDirectory}. */ 067 private final String userBundles; 068 069 /** Total amount of memory avilable in megabytes */ 070 private int availableMemory = 0; 071 072 /** 073 * Initializes the platform-specific paths to the different files 074 * required by the startup manager. 075 * 076 * @param defaultPrefs Path to the preferences file that ships with 077 * McIDAS-V. Cannot be {@code null} or empty. 078 * @param newLine Character(s!) that represent a new line for this 079 * platform. Cannot be {@code null} or empty. 080 * 081 * @throws NullPointerException if either {@code defaultPrefs} or 082 * {@code newLine} are {@code null}. 083 * 084 * @throws IllegalArgumentException if either {@code defaultPrefs} or 085 * {@code newLine} are an empty string. 086 */ 087 Platform(final String defaultPrefs, final String newLine) { 088 Objects.requireNonNull(defaultPrefs); 089 Objects.requireNonNull(newLine); 090 if (defaultPrefs.isEmpty() || newLine.isEmpty()) { 091 throw new IllegalArgumentException(""); 092 } 093 094 String osName = System.getProperty("os.name"); 095 Path tmpPath; 096 if (osName.startsWith("Mac OS X")) { 097 tmpPath = Paths.get(System.getProperty("user.home"), "Documents", Constants.USER_DIRECTORY_NAME); 098 } else { 099 tmpPath = Paths.get(System.getProperty("user.home"), Constants.USER_DIRECTORY_NAME); 100 } 101 102 this.userDirectory = tmpPath.toString(); 103 this.userPrefs = Paths.get(userDirectory, defaultPrefs).toString(); 104 this.defaultPrefs = defaultPrefs; 105 this.newLine = newLine; 106 this.userBundles = Paths.get(this.userDirectory, "bundles").toString(); 107 } 108 109 /** 110 * Sets the path to the user's {@literal "userpath"} directory explicitly. 111 * If the specified path does not yet exist, this method will first 112 * attempt to create it. The method will then attempt to verify whether or 113 * not McIDAS-V can use the path. 114 * 115 * @param path New path. Cannot be {@code null}, but does not have to exist 116 * prior to running this method. Be aware that this method will attempt to 117 * create {@code path} if it does not already exist. 118 * 119 * @throws IllegalArgumentException if {@code path} is not a 120 * directory, or if it not both readable and writable. 121 */ 122 public void setUserDirectory(final String path) throws IllegalArgumentException { 123 File tmp = new File(path); 124 if (!tmp.exists()) { 125 tmp.mkdir(); 126 } 127 128 // TODO(jon): or would tmp.isFile() suffice? 129 if (tmp.exists() && !tmp.isDirectory()) { 130 throw new IllegalArgumentException('\'' +path+"' is not a directory."); 131 } 132 133 Path p = tmp.toPath(); 134 boolean canRead = Files.isReadable(p); 135 boolean canWrite = Files.isWritable(p); 136 137 if (!canRead && !canWrite) { 138 throw new IllegalArgumentException('\''+path+"' must be both readable and writable by McIDAS-V."); 139 } else if (!canRead) { 140 throw new IllegalArgumentException('\''+path+"' must be readable by McIDAS-V."); 141 } else if (!canWrite) { 142 throw new IllegalArgumentException('\''+path+"' must be writable by McIDAS-V."); 143 } 144 145 userDirectory = path; 146 userPrefs = Paths.get(userDirectory, defaultPrefs).toString(); 147 } 148 149 /** 150 * Sets the amount of available memory. {@code megabytes} must be 151 * greater than or equal to zero. 152 * 153 * @param megabytes Memory in megabytes. 154 * 155 * @throws NullPointerException if {@code megabytes} is {@code null}. 156 * @throws IllegalArgumentException if {@code megabytes} is less than 157 * zero or does not represent an integer. 158 * 159 * @see StartupManager#getArgs 160 * 161 * @deprecated There's not really a need for this method; the JVM can 162 * tell us the amount of memory. 163 */ 164 public void setAvailableMemory(String megabytes) { 165 Objects.requireNonNull(megabytes, "Available memory cannot be null"); 166 if (megabytes.isEmpty()) { 167 megabytes = "0"; 168 } 169 170 try { 171 int test = Integer.parseInt(megabytes); 172 if (test < 0) { 173 throw new IllegalArgumentException("Available memory must be a non-negative integer, not \""+megabytes+"\""); 174 } 175 availableMemory = test; 176 } catch (NumberFormatException e) { 177 throw new IllegalArgumentException("Could not convert \""+megabytes+"\" to a non-negative integer", e); 178 } 179 } 180 181 /** 182 * Returns the path to the user's {@literal "userpath"} directory. 183 * 184 * @return Path to the user's directory. 185 */ 186 public String getUserDirectory() { 187 return userDirectory; 188 } 189 190 /** 191 * Returns the path to a file in the user's {@literal "userpath"} directory. 192 * 193 * @param filename Filename within the {@code userpath}. Cannot be 194 * {@code null}, but does not need to be a filename that already exists 195 * within the {@code userpath}. 196 * 197 * @return Path to a file in the user's directory. <b>Note:</b> the file 198 * may not yet exist. 199 */ 200 public String getUserFile(String filename) { 201 return Paths.get(userDirectory, filename).toString(); 202 } 203 204 /** 205 * Returns the path to the user's bundles directory. Note: this should be 206 * a directory within {@link #getUserDirectory()}. 207 * 208 * @return Path to the user's bundles directory. 209 */ 210 public String getUserBundles() { 211 return userBundles; 212 } 213 214 /** 215 * Returns the amount of available memory in megabytes. 216 * 217 * @return Available memory in megabytes. 218 */ 219 public int getAvailableMemory() { 220 return availableMemory; 221 } 222 223 /** 224 * Returns the path of user's copy of the startup preferences. 225 * 226 * @return Path to the user's startup preferences file. 227 */ 228 public String getUserPrefs() { 229 return userPrefs; 230 } 231 232 /** 233 * Returns the path of the startup preferences included in the McIDAS-V 234 * distribution. Mostly useful for normalizing the user directory. 235 * 236 * @return Path to the default startup preferences. 237 * 238 * @see OptionMaster#normalizeUserDirectory() 239 */ 240 public String getDefaultPrefs() { 241 return defaultPrefs; 242 } 243 244 /** 245 * Returns the platform's notion of a new line. 246 * 247 * @return Unix-like: {@literal \n}; Windows: {@literal \r\n}. 248 */ 249 public String getNewLine() { 250 return newLine; 251 } 252 253 /** 254 * Returns a brief summary of the platform specific file locations. 255 * Please note that the format and contents are subject to change. 256 * 257 * @return String that looks like 258 * {@code [Platform@HASHCODE: defaultPrefs=..., userDirectory=..., 259 * userPrefs=...]} 260 */ 261 @Override public String toString() { 262 return String.format( 263 "[Platform@%x: defaultPrefs=%s, userDirectory=%s, userPrefs=%s]", 264 hashCode(), defaultPrefs, userDirectory, userPrefs); 265 } 266}