Java tutorial
/* * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved. * * http://www.izforge.com/izpack/ * http://izpack.codehaus.org/ * * Copyright 2003 Marc Eppelmann * Copyright 2015 Bill Root * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This represents a Implementation of the KDE/GNOME DesktopEntry. * which is standard from * "Desktop Entry Standard" * "The format of .desktop files, supported by KDE and GNOME." * http://www.freedesktop.org/standards/desktop-entry-spec/ * * [Desktop Entry] // Comment=$Comment // Comment[de]= // Encoding=$UTF-8 // Exec=$'/home/marc/CPS/tomcat/bin/catalina.sh' run // GenericName=$ // GenericName[de]=$ // Icon=$inetd // MimeType=$ // Name=$Start Tomcat // Name[de]=$Start Tomcat // Path=$/home/marc/CPS/tomcat/bin/ // ServiceTypes=$ // SwallowExec=$ // SwallowTitle=$ // Terminal=$true // TerminalOptions=$ // Type=$Application // X-KDE-SubstituteUID=$false // X-KDE-Username=$ * */ package com.izforge.izpack.util.os; import com.izforge.izpack.api.data.InstallData; import com.izforge.izpack.api.exception.ResourceNotFoundException; import com.izforge.izpack.api.resource.Resources; import com.izforge.izpack.util.FileExecutor; import com.izforge.izpack.util.StringTool; import com.izforge.izpack.util.unix.ShellScript; import com.izforge.izpack.util.unix.UnixHelper; import com.izforge.izpack.util.unix.UnixUser; import com.izforge.izpack.util.unix.UnixUsers; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * This is the Implementation of the RFC-Based Desktop-Link. Used in KDE and GNOME. * * @author marc.eppelmann@reddot.de * @author Bill Root */ public class Unix_Shortcut extends Shortcut { // *********************************************************************** // ~ Static fields/initializers // *********************************************************************** private static final Logger logger = Logger.getLogger(Unix_Shortcut.class.getName()); /** * version = "$Id$" */ private static final String version = "$Id$"; /** * rev = "$Revision$" */ private static final String rev = "$Revision$"; /** * DESKTOP_EXT = ".desktop" */ private static final String DESKTOP_EXT = ".desktop"; /** * N = "\n" */ private final static String N = "\n"; /** * H = "#" */ private final static String H = "#"; /** * S = " " */ private final static String S = " "; /** * C = Comment = H+S = "# " */ private final static String C = H + S; private static ShellScript rootScript = null; private static ShellScript uninstallScript = null; private List<UnixUser> users; // *********************************************************************** // ~ Instance fields // *********************************************************************** /** * The data fields defining the shortcut. */ private String arguments; private String categories; private String description; private String encoding; private String iconLocation; private String kdeSubstituteUID; private String kdeUserName; private String linkName; private int linkType; private String mimeType; private String programGroup; private String targetPath; private String terminal; private String terminalOptions; private String type; private String url; private int userType; private String workingDirectory; /** * internal String itsFileName */ private String itsFileName; /** * my Install ShellScript * */ private ShellScript myInstallScript; /** * Internal Constant: FS = File.separator // * */ private final String FS = File.separator; /** * Internal Constant: myHome = System.getProperty("user.home") * */ private final String myHome = System.getProperty("user.home"); /** * Cached value from {@link UnixHelper#getSuCommand()}. */ private String su; /** * Cached value from <tt>UnixHelper.getCustomCommand("xdg-desktop-icon")</tt>. */ private String xdgDesktopIconCmd; private String myXdgDesktopIconCmd = null; /** * The resources. */ private final Resources resources; /** * The installation data. */ private final InstallData installData; // *********************************************************************** // ~ Constructors // *********************************************************************** /** * Constructs a <tt>Unix_Shortcut</tt>. * * @param resources the resources * @param installData the installation data */ @SuppressWarnings("WeakerAccess") public Unix_Shortcut(Resources resources, InstallData installData) { this.resources = resources; this.installData = installData; if (rootScript == null) { rootScript = new ShellScript(); } if (uninstallScript == null) { uninstallScript = new ShellScript(); } if (myInstallScript == null) { myInstallScript = new ShellScript(); } } // *********************************************************************** // ~ Methods // *********************************************************************** /** * Builds contents of desktop file. */ public String build() { StringBuilder result = new StringBuilder(); String userLanguage = System.getProperty("user.language", "en"); result.append("[Desktop Entry]" + N); // TODO implement Attribute: X-KDE-StartupNotify=true result.append("Categories=").append(categories).append(N); result.append("Comment=").append(description).append(N); result.append("Comment[").append(userLanguage).append("]=").append(description).append(N); if (!encoding.isEmpty()) { logger.warning( String.format("using deprecated Desktop Entry key " + "Encoding with value %s", encoding)); result.append("Encoding=").append(encoding).append(N); } // this causes too many problems // result.append("TryExec=" + $E_QUOT + $Exec + $E_QUOT + S + $Arguments + N); if (!targetPath.isEmpty() || !arguments.isEmpty()) { result.append("Exec="); result.append(targetPath); //escaping needs to be handed more fine-grained (putting '' //around everything after `Exec=` is not a solution because it //causes invalid .desktop files (`desktop-file-validate` fails //due to `error: value "'[...]'" for key "Exec" in group //"Desktop Entry" contains a reserved character ''' outside of //a quote`) if (!arguments.isEmpty()) result.append(S).append(arguments); result.append(N); } result.append("GenericName=").append(N); result.append("GenericName[").append(userLanguage).append("]=").append(N); result.append("Icon=").append(iconLocation).append(N); result.append("MimeType=").append(mimeType).append(N); result.append("Name=").append(linkName).append(N); result.append("Name[").append(userLanguage).append("]=").append(linkName).append(N); result.append("Path=").append(workingDirectory).append(N); result.append("ServiceTypes=").append(N); result.append("SwallowExec=").append(N); result.append("SwallowTitle=").append(N); result.append("Terminal=").append(terminal).append(N); if (!terminal.isEmpty() && !terminal.equals("true") && !terminal.equals("false")) logger.warning(String.format("Shortcut '%s' has terminal '%s' but should be 'true' or 'false'", linkName, terminal)); result.append("TerminalOptions=").append(terminalOptions).append(N); result.append("Type=").append(type).append(N); if (type.equalsIgnoreCase("Link") && url.isEmpty()) logger.warning(String.format("Shortcut '%s' has type '%s' but URL is empty", linkName, type)); if (!url.isEmpty()) { result.append("URL=").append(url).append(N); if (!type.equalsIgnoreCase("Link")) logger.warning( String.format("Shortcut '%s' has URL but type ('%s') is not 'Link'", linkName, type)); } result.append("X-KDE-SubstituteUID=").append(kdeSubstituteUID).append(N); result.append("X-KDE-Username=").append(kdeUserName).append(N); result.append(N); result.append(C + "created by" + S).append(getClass().getName()).append(S).append(rev).append(N); result.append(C).append(version); return result.toString(); } @Override public void initialize(int aType, String aName) throws Exception { this.linkName = aName; } @Override public boolean supported() { return true; } @Override public String getFileName() { return (this.itsFileName); } @Override public List<String> getProgramGroups(int userType) { List<String> groups = new ArrayList<String>(); groups.add("(Default)"); // Should be the same value as DEFAULT_FOLDER from ShortcutConstants File kdeShareApplnk = getKdeShareApplnkFolder(userType); try { File[] listing = kdeShareApplnk.listFiles(); if (listing != null) { for (File aListing : listing) { if (aListing.isDirectory()) { groups.add(aListing.getName()); } } } } catch (Exception e) { // ignore and return an empty vector. } return groups; } @Override public String getProgramsFolder(int current_user) { String result; // result = getKdeShareApplnkFolder(current_user).toString(); return result; } /** * Gets the XDG path to place the menu shortcuts * * @param userType to get for. * @return handle to the directory */ private File getKdeShareApplnkFolder(int userType) { if (userType == Shortcut.ALL_USERS) { return new File(File.separator + "usr" + File.separator + "share" + File.separator + "applications"); } else { return new File(System.getProperty("user.home") + File.separator + ".local" + File.separator + "share" + File.separator + "applications"); } } /** * Makes a filename usable in a script by escaping spaces. * This should <b>not</b> be used for filenames passed to Java filesystem * methods. * @param filename filename to process * @return escaped filename */ private String makeFilenameScriptable(String filename) { return filename.replace(" ", "\\ "); } /** * overridden method * * @return true * @see com.izforge.izpack.util.os.Shortcut#multipleUsers() */ @Override public boolean multipleUsers() { // EVER true for UNIXes ;-) return (true); } /** * Creates and stores the shortcut-files. * * @throws java.lang.Exception error occured * @see com.izforge.izpack.util.os.Shortcut#save() */ @Override public void save() throws Exception { String shortCutDef = this.build(); boolean rootUser4All = this.getUserType() == Shortcut.ALL_USERS; boolean create4All = this.getCreateForAll(); // Create The Desktop Shortcuts if ("".equals(this.programGroup) && (this.getLinkType() == Shortcut.DESKTOP)) { this.itsFileName = null; // read the userdefined / overridden / wished Shortcut Location // This can be an absolute Path name or a relative Path to the InstallPath File shortCutLocation = null; File ApplicationShortcutPath; String ApplicationShortcutPathName = installData.getVariable("ApplicationShortcutPath"/* TODO <-- Put in Docu and in Un/InstallerConstantsClass */ ); if (null != ApplicationShortcutPathName && !ApplicationShortcutPathName.equals("")) { ApplicationShortcutPath = new File(ApplicationShortcutPathName); if (ApplicationShortcutPath.isAbsolute()) { // I know :-) Can be m"ORed" elegant :) if (!ApplicationShortcutPath.exists() && ApplicationShortcutPath.mkdirs() && ApplicationShortcutPath.canWrite()) { shortCutLocation = ApplicationShortcutPath; } if (ApplicationShortcutPath.exists() && ApplicationShortcutPath.isDirectory() && ApplicationShortcutPath.canWrite()) { shortCutLocation = ApplicationShortcutPath; } } else { File relativePath = new File(installData.getInstallPath() + FS + ApplicationShortcutPath); //noinspection ResultOfMethodCallIgnored relativePath.mkdirs(); shortCutLocation = new File(relativePath.toString()); } } if (shortCutLocation == null) shortCutLocation = new File(installData.getInstallPath()); // write the App ShortCut File writtenDesktopFile = writeAppShortcutWithOutSpace(shortCutLocation.toString(), this.linkName, shortCutDef); uninstaller.addFile(writtenDesktopFile.toString(), true); // Now install my Own with xdg-if available // Note the The reverse Uninstall-Task is on // TODO: "WHICH another place" String cmd = getXdgDesktopIconCmd(); if (cmd != null) { createExtXdgDesktopIconCmd(shortCutLocation); // / TODO: DELETE the ScriptFiles myInstallScript.appendln(new String[] { makeFilenameScriptable(myXdgDesktopIconCmd), "install", "--novendor", StringTool.escapeSpaces(writtenDesktopFile.toString()) }); ShellScript myUninstallScript = new ShellScript(); myUninstallScript.appendln(new String[] { makeFilenameScriptable(myXdgDesktopIconCmd), "uninstall", "--novendor", StringTool.escapeSpaces(writtenDesktopFile.toString()) }); uninstaller.addUninstallScript(myUninstallScript.getContentAsString()); } else { // otherwise copy to my desktop and add to uninstaller File myDesktopFile; do { myDesktopFile = new File(myHome + FS + "Desktop" + writtenDesktopFile.getName() + "-" + System.currentTimeMillis() + DESKTOP_EXT); } while (myDesktopFile.exists()); FileUtils.copyFile(writtenDesktopFile, myDesktopFile, false); uninstaller.addFile(myDesktopFile.toString(), true); } // If I'm root and this Desktop.ShortCut should be for all other users if (rootUser4All && create4All) { if (cmd != null) { installDesktopFileToAllUsersDesktop(writtenDesktopFile); } else // OLD ( Backward-Compatible/hardwired-"Desktop"-Foldername Styled Mechanic ) { copyDesktopFileToAllUsersDesktop(writtenDesktopFile); } } } // This is - or should be only a Link in the [K?]-Menu else { // the following is for backwards compatibility to older versions of KDE! // on newer versions of KDE the icons will appear duplicated unless you set // the category="" // removed because of compatibility issues /* * Object categoryobject = props.getProperty($Categories); if(categoryobject != null && * ((String)categoryobject).length()>0) { File kdeHomeShareApplnk = * getKdeShareApplnkFolder(this.getUserType()); target = kdeHomeShareApplnk.toString() + * FS + this.itsGroupName + FS + this.itsName + DESKTOP_EXT; this.itsFileName = target; * File kdemenufile = writeShortCut(target, shortCutDef); * * uninstaller.addFile(kdemenufile.toString(), true); } */ if (rootUser4All && create4All) { { // write the icon pixmaps into /usr/share/pixmaps File theIcon = new File(this.getIconLocation()); File commonIcon = new File("/usr/share/pixmaps/" + theIcon.getName()); try { FileUtils.copyFile(theIcon, commonIcon, false); uninstaller.addFile(commonIcon.toString(), true); } catch (Exception e) { logger.log(Level.WARNING, "Could not copy " + theIcon + " to " + commonIcon + " (" + e.getMessage() + ")", e); } // write *.desktop this.itsFileName = null; File writtenFile = writeAppShortcut("/usr/share/applications/", this.linkName, shortCutDef); setWrittenFileName(writtenFile.getName()); uninstaller.addFile(writtenFile.toString(), true); } } else // create local XDG shortcuts { // System.out.println("Creating gnome shortcut"); String localApps = myHome + "/.local/share/applications/"; String localPixmaps = myHome + "/.local/share/pixmaps/"; // System.out.println("Creating "+localApps); try { java.io.File file = new java.io.File(localApps); //noinspection ResultOfMethodCallIgnored file.mkdirs(); file = new java.io.File(localPixmaps); //noinspection ResultOfMethodCallIgnored file.mkdirs(); } catch (Exception ignore) { // System.out.println("Failed creating "+localApps + " or " + localPixmaps); logger.warning("Failed creating " + localApps + " or " + localPixmaps); } // write the icon pixmaps into ~/share/pixmaps File theIcon = new File(this.getIconLocation()); File commonIcon = new File(localPixmaps + theIcon.getName()); try { FileUtils.copyFile(theIcon, commonIcon, false); uninstaller.addFile(commonIcon.toString(), true); } catch (Exception e) { logger.log(Level.WARNING, "Could not copy " + theIcon + " to " + commonIcon + " (" + e.getMessage() + ")", e); } // write *.desktop in the local folder this.itsFileName = null; File writtenFile = writeAppShortcut(localApps, this.linkName, shortCutDef); setWrittenFileName(writtenFile.getName()); uninstaller.addFile(writtenFile.toString(), true); } } } /** * Creates Extended Locale Enabled XdgDesktopIcon Command script. * Fills the File myXdgDesktopIconScript with the content of * com/izforge/izpack/util/os/unix/xdgscript.sh and uses this to * creates User Desktop icons * * @param shortCutLocation in which folder should this stored. * @throws ResourceNotFoundException resource not found error */ private void createExtXdgDesktopIconCmd(File shortCutLocation) throws ResourceNotFoundException { ShellScript myXdgDesktopIconScript = new ShellScript(null); String lines = resources.getString("/com/izforge/izpack/util/unix/xdgdesktopiconscript.sh", null); myXdgDesktopIconScript.append(lines); myXdgDesktopIconCmd = shortCutLocation + FS + "IzPackLocaleEnabledXdgDesktopIconScript.sh"; myXdgDesktopIconScript.write(myXdgDesktopIconCmd); FileExecutor.getExecOutput(new String[] { UnixHelper.getCustomCommand("chmod"), "+x", myXdgDesktopIconCmd }, true); } /** * Calls and creates the Install/Uninstall Script which installs Desktop Icons using * xdgDesktopIconCmd un-/install * * @param writtenDesktopFile An applications desktop file, which should be installed. */ private void installDesktopFileToAllUsersDesktop(File writtenDesktopFile) { for (UnixUser user : getUsers()) { if (user.getHome().equals(myHome)) { logger.info("Skipping self-copy: " + user.getHome() + " == " + myHome); continue; } try { // / THE Following does such as #> su username -c "xdg-desktopicon install // --novendor /Path/to/Filename\ with\ or\ without\ Space.desktop" rootScript.append(new String[] { getSuCommand(), user.getName(), "-c" }); rootScript.appendln(new String[] { "\"" + myXdgDesktopIconCmd, "install", "--novendor", StringTool.escapeSpaces(writtenDesktopFile.toString()) + "\"" }); uninstallScript.append(new String[] { getSuCommand(), user.getName(), "-c" }); uninstallScript.appendln(new String[] { "\"" + myXdgDesktopIconCmd, "uninstall", "--novendor", StringTool.escapeSpaces(writtenDesktopFile.toString()) + "\"" }); } catch (Exception e) { logger.log(Level.WARNING, e.getMessage(), e); } } logger.fine("=============================="); logger.fine(rootScript.getContentAsString()); } private String getSuCommand() { if (su == null) { su = UnixHelper.getSuCommand(); } return su; } private String getXdgDesktopIconCmd() { if (xdgDesktopIconCmd == null) { xdgDesktopIconCmd = UnixHelper.getCustomCommand("xdg-desktop-icon"); } return xdgDesktopIconCmd; } private List<UnixUser> getUsers() { if (users == null) { users = UnixUsers.getUsersWithValidShellsExistingHomesAndDesktops(); } return users; } /** * @param writtenDesktopFile User desktop file * @throws IOException I/O error occured */ private void copyDesktopFileToAllUsersDesktop(File writtenDesktopFile) throws IOException { String chmod = UnixHelper.getCustomCommand("chmod"); String chown = UnixHelper.getCustomCommand("chown"); String rm = UnixHelper.getRmCommand(); String copy = UnixHelper.getCpCommand(); File dest; // Create a tempFileName of this ShortCut File tempFile = File.createTempFile(this.getClass().getName(), Long.toString(System.currentTimeMillis()) + ".tmp"); FileUtils.copyFile(writtenDesktopFile, tempFile, false); // Debug.log("Wrote Tempfile: " + tempFile.toString()); FileExecutor.getExecOutput(new String[] { chmod, "uga+rwx", tempFile.toString() }); // su marc.eppelmann -c "/bin/cp /home/marc.eppelmann/backup.job.out.txt // /home/marc.eppelmann/backup.job.out2.txt" for (UnixUser user : getUsers()) { if (user.getHome().equals(myHome)) { logger.info("Skipping self-copy: " + user.getHome() + " == " + myHome); continue; } try { // aHomePath = userHomesList[idx]; dest = new File(user.getHome() + FS + "Desktop" + FS + writtenDesktopFile.getName()); // // I'm root and cannot write into Users Home as root; // But I'm Root and I can slip in every users skin :-) // // by# su username // // This works as well // su $username -c "cp /tmp/desktopfile $HOME/Desktop/link.desktop" // chown $username $HOME/Desktop/link.desktop // Debug.log("Will Copy: " + tempFile.toString() + " to " + dest.toString()); rootScript.append(getSuCommand()); rootScript.append(S); rootScript.append(user.getName()); rootScript.append(S); rootScript.append("-c"); rootScript.append(S); rootScript.append('"'); rootScript.append(copy); rootScript.append(S); rootScript.append(tempFile.toString()); rootScript.append(S); rootScript.append(StringTool.replace(dest.toString(), " ", "\\ ")); rootScript.appendln('"'); rootScript.append('\n'); // Debug.log("Will exec: " + script.toString()); rootScript.append(chown); rootScript.append(S); rootScript.append(user.getName()); rootScript.append(S); rootScript.appendln(StringTool.replace(dest.toString(), " ", "\\ ")); rootScript.append('\n'); rootScript.append('\n'); // Debug.log("Will exec: " + script.toString()); uninstallScript.append(getSuCommand()); uninstallScript.append(S); uninstallScript.append(user.getName()); uninstallScript.append(S); uninstallScript.append("-c"); uninstallScript.append(S); uninstallScript.append('"'); uninstallScript.append(rm); uninstallScript.append(S); uninstallScript.append(StringTool.replace(dest.toString(), " ", "\\ ")); uninstallScript.appendln('"'); uninstallScript.appendln(); // Debug.log("Uninstall will exec: " + uninstallScript.toString()); } catch (Exception e) { logger.log(Level.INFO, "Could not copy as root: " + e.getMessage(), e); /* ignore */ // most distros does not allow root to access any user // home (ls -la /home/user drwx------) // But try it anyway... } } rootScript.append(rm); rootScript.append(S); rootScript.appendln(tempFile.toString()); rootScript.appendln(); } /** * Post Exec Action especially for the Unix Root User. which executes the Root ShortCut * Shellscript. to copy all ShellScripts to the users Desktop. */ @Override public void execPostAction() { logger.fine("Launching post execution action"); String pseudoUnique = this.getClass().getName() + Long.toString(System.currentTimeMillis()); String scriptFilename; try { scriptFilename = File.createTempFile(pseudoUnique, ".sh").toString(); } catch (IOException e) { scriptFilename = System.getProperty("java.io.tmpdir", "/tmp") + "/" + pseudoUnique + ".sh"; e.printStackTrace(); } rootScript.write(scriptFilename); rootScript.exec(); rootScript.delete(); logger.fine(rootScript.toString()); // Quick an dirty copy & paste code - will be cleanup in one of 4.1.1++ pseudoUnique = this.getClass().getName() + Long.toString(System.currentTimeMillis()); try { scriptFilename = File.createTempFile(pseudoUnique, ".sh").toString(); } catch (IOException e) { scriptFilename = System.getProperty("java.io.tmpdir", "/tmp") + "/" + pseudoUnique + ".sh"; e.printStackTrace(); } myInstallScript.write(scriptFilename); myInstallScript.exec(); myInstallScript.delete(); logger.fine(myInstallScript.toString()); // End OF Quick AND Dirty logger.fine(uninstallScript.toString()); uninstaller.addUninstallScript(uninstallScript.getContentAsString()); } private String writtenFileName; public String getWrittenFileName() { return writtenFileName; } private void setWrittenFileName(String s) { writtenFileName = s; } /** * Write the given ShortDefinition in a File $ShortcutName-$timestamp.desktop in the given * TargetPath. * * @param targetPath The Path in which the files should be written. * @param shortcutName The Name for the File * @param shortcutDef The Shortcut FileContent * @return The written File */ private File writeAppShortcut(String targetPath, String shortcutName, String shortcutDef) { return writeAppShortcutWithSimpleSpacehandling(targetPath, shortcutName, shortcutDef, false); } /** * Write the given ShortDefinition in a File $ShortcutName-$timestamp.desktop in the given * TargetPath. ALSO all WhiteSpaces in the ShortCutName will be replaced with "-" * * @param targetPath The Path in which the files should be written. * @param shortcutName The Name for the File * @param shortcutDef The Shortcut FileContent * @return The written File */ private File writeAppShortcutWithOutSpace(String targetPath, String shortcutName, String shortcutDef) { return writeAppShortcutWithSimpleSpacehandling(targetPath, shortcutName, shortcutDef, true); } /** * Write the given ShortDefinition in a File $ShortcutName-$timestamp.desktop in the given * TargetPath. If the given replaceSpaces was true ALSO all WhiteSpaces in the ShortCutName will * be replaced with "-" * * @param targetPath The Path in which the files should be written. * @param shortcutName The Name for the File * @param shortcutDef The Shortcut FileContent * @return The written File */ private File writeAppShortcutWithSimpleSpacehandling(String targetPath, String shortcutName, String shortcutDef, boolean replaceSpacesWithMinus) { File shortcutFile = new File(FilenameUtils.getFullPathNoEndSeparator(targetPath) + '/' + (replaceSpacesWithMinus ? StringTool.replaceSpacesWithMinus(shortcutName) : shortcutName) + DESKTOP_EXT); try { FileUtils.writeStringToFile(shortcutFile, shortcutDef); } catch (IOException e) { logger.warning("Application shortcut could not be created (" + e.getMessage() + ")"); } return shortcutFile; } @Override public void setArguments(String args) { this.arguments = args; } @Override public void setCategories(String theCategories) { this.categories = theCategories; } @Override public void setDescription(String description) { this.description = description; } @Override public void setEncoding(String aEncoding) { this.encoding = aEncoding; } @Override public void setKdeSubstUID(String trueFalseOrNothing) { this.kdeSubstituteUID = trueFalseOrNothing; } @Override public void setKdeUserName(String aUserName) { this.kdeUserName = aUserName; } @Override public void setIconLocation(String path, int index) { this.iconLocation = path; } @Override public String getIconLocation() { return this.iconLocation; } @Override public void setLinkName(String aName) { this.linkName = aName; } @Override public void setLinkType(int aType) throws IllegalArgumentException, UnsupportedEncodingException { this.linkType = aType; } @Override public int getLinkType() { return linkType; } @Override public void setMimetype(String aMimeType) { this.mimeType = aMimeType; } @Override public void setProgramGroup(String aGroupName) { this.programGroup = aGroupName; } @Override public void setShowCommand(int show) { // ignored for Linux } @Override public void setTargetPath(String aPath) { this.targetPath = aPath; } @Override public void setUserType(int aUserType) { this.userType = aUserType; } @Override public int getUserType() { return userType; } @Override public void setWorkingDirectory(String aDirectory) { this.workingDirectory = aDirectory; } @Override public void setTerminal(String trueFalseOrNothing) { this.terminal = trueFalseOrNothing; } @Override public void setTerminalOptions(String someTerminalOptions) { this.terminalOptions = someTerminalOptions; } @Override public void setTryExec(String aTryExec) { // currently ignored } @Override public void setType(String aType) { this.type = aType; } @Override public void setURL(String anUrl) { this.url = anUrl; } @Override public String toString() { return this.linkName + N + build(); } }