001: /*
002: * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
003: *
004: * http://izpack.org/
005: * http://izpack.codehaus.org/
006: *
007: * Copyright 2002 Elmar Grom
008: *
009: * Licensed under the Apache License, Version 2.0 (the "License");
010: * you may not use this file except in compliance with the License.
011: * You may obtain a copy of the License at
012: *
013: * http://www.apache.org/licenses/LICENSE-2.0
014: *
015: * Unless required by applicable law or agreed to in writing, software
016: * distributed under the License is distributed on an "AS IS" BASIS,
017: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018: * See the License for the specific language governing permissions and
019: * limitations under the License.
020: */
021:
022: package com.izforge.izpack.util.os;
023:
024: import java.io.File;
025: import java.io.UnsupportedEncodingException;
026: import java.util.Vector;
027:
028: import com.izforge.izpack.util.Debug;
029: import com.izforge.izpack.util.StringTool;
030:
031: /*---------------------------------------------------------------------------*/
032: /**
033: * This is the Microsoft Windows specific implementation of <code>Shortcut</code>.
034: *
035: * @version 0.0.1 / 3/4/02
036: * @author Elmar Grom
037: */
038: /*---------------------------------------------------------------------------*/
039: public class Win_Shortcut extends Shortcut {
040:
041: // ------------------------------------------------------------------------
042: // Constant Definitions
043: // ------------------------------------------------------------------------
044:
045: // ------------------------------------------------------------------------
046: // Variable Declarations
047: // ------------------------------------------------------------------------
048: private ShellLink shortcut;
049:
050: private static String myClass = Win_Shortcut.class.getName() + ": ";
051:
052: private static final String CLASS = "Class: ";
053:
054: /** SUPPORTED = true */
055: private static final boolean SUPPORTED = true;
056:
057: /*--------------------------------------------------------------------------*/
058: /**
059: * This method initializes the object. It is used as a replacement for the constructor because
060: * of the way it is instantiated through the <code>TargetFactory</code>.
061: *
062: * @param type the type or classification of the program group in which the link should exist.
063: * The following types are recognized: <br>
064: * <ul>
065: * <li>{@link com.izforge.izpack.util.os.Shortcut#APPLICATIONS}
066: * <li>{@link com.izforge.izpack.util.os.Shortcut#START_MENU}
067: * <li>{@link com.izforge.izpack.util.os.Shortcut#DESKTOP}
068: * <li>{@link com.izforge.izpack.util.os.Shortcut#START_UP}
069: * </ul>
070: * @param name the name of the shortcut.
071: */
072: public void initialize(int type, String name) throws Exception {
073: Debug.log(CLASS + myClass + ".initialize() '"
074: + Integer.toString(type) + "', '" + name + "'");
075: switch (type) {
076: case APPLICATIONS: {
077: shortcut = new ShellLink(ShellLink.PROGRAM_MENU, name);
078: break;
079: }
080: case START_MENU: {
081: shortcut = new ShellLink(ShellLink.START_MENU, name);
082: break;
083: }
084: case DESKTOP: {
085: shortcut = new ShellLink(ShellLink.DESKTOP, name);
086: break;
087: }
088: case START_UP: {
089: shortcut = new ShellLink(ShellLink.STARTUP, name);
090: break;
091: }
092: default: {
093: shortcut = new ShellLink(ShellLink.PROGRAM_MENU, name);
094: break;
095: }
096: }
097: }
098:
099: /*--------------------------------------------------------------------------*/
100: /**
101: * Returns the base path of the shortcut depending on type. The base path is the directory that
102: * the short cut, (or its program group) will be created in. For instance, on Windows NT, a
103: * shortcut with user-type ALL_USERS, and link-type DESKTOP might have the base path
104: * "C:\Program Files\All Users\Desktop"
105: *
106: * @see #setLinkType(int)
107: * @see #setUserType(int)
108: *
109: * translates from ShellLink-UserTypes to Shortcut-UserTypes.
110: */
111: public String getBasePath() throws Exception {
112: String result = shortcut.getLinkPath(shortcut.getUserType());
113: Debug.log(CLASS + myClass + ".getBasePath() '" + result + "'");
114: return result;
115: }
116:
117: /**
118: * Returns a list of currently existing program groups, based on the requested type. For example
119: * if the type is <code>APPLICATIONS</code> then all the names of the program groups in the
120: * Start Menu\Programs menu would be returned.
121: *
122: * @param userType the type of user for the program group set. (as Shortcut.utype)
123: *
124: * @return a <code>Vector</code> of <code>String</code> objects that represent the names of
125: * the existing program groups. It is theoretically possible that this list is empty.
126: *
127: * @see #APPLICATIONS
128: * @see #START_MENU
129: */
130: public Vector<String> getProgramGroups(int userType) {
131: int logentry = 0;
132: Debug.log(CLASS + myClass + ".getProgramGroups()-" + logentry++
133: + " '" + Integer.toString(userType) + "'");
134: // ----------------------------------------------------
135: // translate the user type
136: // ----------------------------------------------------
137: int type = ShellLink.CURRENT_USER;
138:
139: if (userType == ALL_USERS) {
140: type = ShellLink.ALL_USERS;
141: } else {
142: type = ShellLink.CURRENT_USER;
143: }
144:
145: // ----------------------------------------------------
146: // get a list of all files and directories that are
147: // located at the link path.
148: // ----------------------------------------------------
149: String linkPath = shortcut.getLinkPath(type);
150:
151: Debug.log(CLASS + myClass + ".getProgramGroups()-" + logentry++
152: + " '" + linkPath + "'");
153:
154: // in case there is a problem obtaining a path return
155: // an empty vector (there are no preexisting program
156: // groups)
157: if (linkPath == null) {
158: return (new Vector<String>());
159: }
160:
161: File path = new File(linkPath);
162: File[] file = path.listFiles();
163:
164: // ----------------------------------------------------
165: // build a vector that contains only the names of
166: // the directories.
167: // ----------------------------------------------------
168: Vector<String> groups = new Vector<String>();
169:
170: if (file != null) {
171: for (File aFile : file) {
172: String aFilename = aFile.getName();
173: if (aFile.isDirectory()) {
174:
175: Debug.log(CLASS + myClass + ".getProgramGroups()-"
176: + logentry++ + " '" + aFilename + "'");
177: groups.add(aFilename);
178: } else {
179: Debug.log(CLASS + myClass + ".getProgramGroups()-"
180: + logentry++ + " Skip (NoDirectory): '"
181: + aFilename + "'");
182: }
183: }
184: }
185:
186: return (groups);
187: }
188:
189: /*--------------------------------------------------------------------------*/
190: /**
191: * Returns the fully qualified file name under which the link is saved on disk. <b>Note: </b>
192: * this method returns valid results only if the instance was created from a file on disk or
193: * after a successful save operation.
194: *
195: * @return the fully qualified file name for the shell link
196: */
197: public String getFileName() {
198: String aFilename = shortcut.getFileName();
199: Debug.log(CLASS + myClass + ".getFileName() '" + aFilename
200: + "'");
201: return (aFilename);
202: }
203:
204: /*--------------------------------------------------------------------------*/
205: /**
206: * Returns the path of the directory where the link file is stored, if it was necessary during
207: * the previous save operation to create the directory. This method returns <code>null</code>
208: * if no save operation was carried out or there was no need to create a directory during the
209: * previous save operation.
210: *
211: * @return the path of the directory where the link file is stored or <code>null</code> if no
212: * save operation was carried out or there was no need to create a directory during the previous
213: * save operation.
214: */
215: public String getDirectoryCreated() {
216: String directoryCreated = shortcut.getDirectoryCreated();
217: Debug.log(CLASS + myClass + ".getDirectoryCreated() '"
218: + directoryCreated + "'");
219: return (directoryCreated);
220: }
221:
222: /*--------------------------------------------------------------------------*/
223: /**
224: * Returns <code>true</code> if the target OS supports current user and all users.
225: *
226: * @return <code>true</code> if the target OS supports current and all users.
227: */
228: public boolean multipleUsers() {
229: boolean result = false;
230: // Win NT4 won't have PROGRAMS for CURRENT_USER.
231: // Win 98 may not have 'Start Menu\Programs' for ALL_USERS
232: String allUsers = shortcut.getallUsersLinkPath();
233:
234: Debug.log(CLASS + myClass + ".multipleUsers()-1 '" + allUsers
235: + "'");
236:
237: String currentUsers = shortcut.getcurrentUserLinkPath();
238: Debug.log(CLASS + myClass + ".multipleUsers()-2 '"
239: + currentUsers + "'");
240:
241: if (allUsers == null || currentUsers == null)
242: result = false;
243: else
244: result = allUsers.length() > 0 && currentUsers.length() > 0;
245:
246: Debug.log(CLASS + myClass + ".multipleUsers()-3 '" + result
247: + "'");
248: return (result);
249: }
250:
251: /*--------------------------------------------------------------------------*/
252: /**
253: * Signals that this flavor of <code>{@link com.izforge.izpack.util.os.Shortcut}</code>
254: * supports the creation of shortcuts.
255: *
256: * @return always <code>true</code>
257: */
258: public boolean supported() {
259: Debug.log(CLASS + myClass + ".supported() '" + SUPPORTED + "'");
260: return (SUPPORTED);
261: }
262:
263: /*--------------------------------------------------------------------------*/
264: /**
265: * Sets the command line arguments that will be passed to the target when the link is activated.
266: *
267: * @param arguments the command line arguments
268: */
269: public void setArguments(String arguments) {
270: Debug.log(CLASS + myClass + ".setArguments() '" + arguments
271: + "'");
272: shortcut.setArguments(arguments);
273: }
274:
275: /*--------------------------------------------------------------------------*/
276: /**
277: * Sets the description string that is used to identify the link in a menu or on the desktop.
278: *
279: * @param description the descriptiojn string
280: */
281: public void setDescription(String description) {
282: Debug.log(CLASS + myClass + ".setDescription() '" + description
283: + "'");
284: shortcut.setDescription(description);
285: }
286:
287: /*--------------------------------------------------------------------------*/
288: /**
289: * Sets the location of the icon that is shown for the shortcut on the desktop.
290: *
291: * @param path a fully qualified file name of a file that contains the icon.
292: * @param index the index of the specific icon to use in the file. If there is only one icon in
293: * the file, use an index of 0.
294: */
295: public void setIconLocation(String path, int index) {
296: Debug.log(CLASS + myClass + ".setIconLocation() '" + path
297: + "', '" + Integer.toString(index) + "'");
298: shortcut.setIconLocation(path, index);
299: }
300:
301: /*--------------------------------------------------------------------------*/
302: /**
303: * returns icon Location
304: *
305: * @return iconLocation
306: */
307: public String getIconLocation() {
308: String result = shortcut.getIconLocation();
309: Debug.log(CLASS + myClass + ".getIconLocation() '" + result
310: + "'");
311: return result;
312: }
313:
314: /*--------------------------------------------------------------------------*/
315: /**
316: * Sets the name of the program group this ShellLinbk should be placed in.
317: *
318: * @param groupName the name of the program group
319: */
320: public void setProgramGroup(String groupName) {
321: Debug.log(CLASS + myClass + ".setProgramGroup() '" + groupName
322: + "'");
323: shortcut.setProgramGroup(groupName);
324: }
325:
326: /*--------------------------------------------------------------------------*/
327: /**
328: * Sets the show command that is passed to the target application when the link is activated.
329: * The show command determines if the the window will be restored to the previous size,
330: * minimized, maximized or visible at all. <br>
331: * <br>
332: * <b>Note: </b> <br>
333: * Using <code>HIDE</code> will cause the target window not to show at all. There is not even
334: * a button on the taskbar. This is a very useful setting when batch files are used to launch a
335: * Java application as it will then appear to run just like any native Windows application. <br>
336: *
337: *
338: * @param show the show command. Valid settings are: <br>
339: * <ul>
340: * <li>{@link com.izforge.izpack.util.os.Shortcut#HIDE}
341: * <li>{@link com.izforge.izpack.util.os.Shortcut#NORMAL}
342: * <li>{@link com.izforge.izpack.util.os.Shortcut#MINIMIZED}
343: * <li>{@link com.izforge.izpack.util.os.Shortcut#MAXIMIZED}
344: * </ul>
345: *
346: * @see #getShowCommand internally maps from Shortcut. to ShellLink.
347: */
348: public void setShowCommand(int show)
349: throws IllegalArgumentException {
350: Debug.log(CLASS + myClass + ".setShowCommand() '"
351: + Integer.toString(show) + "'");
352: switch (show) {
353: case HIDE: {
354: shortcut.setShowCommand(ShellLink.MINNOACTIVE);
355: break;
356: }
357: case NORMAL: {
358: shortcut.setShowCommand(ShellLink.NORMAL);
359: break;
360: }
361: case MINIMIZED: {
362: shortcut.setShowCommand(ShellLink.MINNOACTIVE);
363: break;
364: }
365: case MAXIMIZED: {
366: shortcut.setShowCommand(ShellLink.MAXIMIZED);
367: break;
368: }
369: default: {
370: throw (new IllegalArgumentException(show
371: + "is not recognized as a show command"));
372: }
373: }
374: }
375:
376: /*
377: * returns current showCommand. internally maps from ShellLink. to Shortcut.
378: *
379: */
380: public int getShowCommand() {
381: int showCommand = shortcut.getShowCommand();
382:
383: Debug.log(CLASS + myClass + ".getShowCommand() '"
384: + Integer.toString(showCommand) + "'");
385:
386: switch (showCommand) {
387: case ShellLink.NORMAL:
388: showCommand = NORMAL;
389: break;
390: // both MINNOACTIVE and MINIMIZED map to Shortcut.MINIMIZED
391: case ShellLink.MINNOACTIVE:
392: case ShellLink.MINIMIZED:
393: showCommand = MINIMIZED;
394: break;
395: case ShellLink.MAXIMIZED:
396: showCommand = MAXIMIZED;
397: break;
398: default:
399: break;
400: }
401:
402: return showCommand;
403: }
404:
405: /*--------------------------------------------------------------------------*/
406: /**
407: * Sets the absolute path to the shortcut target.
408: *
409: * @param path the fully qualified file name of the target
410: */
411: public void setTargetPath(String path) {
412: Debug.log(CLASS + myClass + ".setTargetPath() '" + path + "'");
413: shortcut.setTargetPath(path);
414: }
415:
416: /*--------------------------------------------------------------------------*/
417: /**
418: * Sets the working directory for the link target.
419: *
420: * @param dir the working directory
421: */
422: public void setWorkingDirectory(String dir) {
423: Debug.log(CLASS + myClass + ".setWorkingDirectory() '" + dir
424: + "'");
425: shortcut.setWorkingDirectory(dir);
426: }
427:
428: /*--------------------------------------------------------------------------*/
429: /**
430: * Gets the working directory for the link target.
431: *
432: * @return the working directory.
433: */
434: public String getWorkingDirectory() {
435: String result = shortcut.getWorkingDirectory();
436: Debug.log(CLASS + myClass + ".getWorkingDirectory() '" + result
437: + "'");
438: return result;
439: }
440:
441: /*--------------------------------------------------------------------------*/
442: /**
443: * Sets the name shown in a menu or on the desktop for the link.
444: *
445: * @param name The name that the link should display on a menu or on the desktop. Do not include
446: * a file extension.
447: */
448: public void setLinkName(String name) {
449: Debug.log(CLASS + myClass + ".setLinkName() '" + name + "'");
450: shortcut.setLinkName(name);
451: }
452:
453: /*--------------------------------------------------------------------------*/
454: /**
455: * Gets the type of link types are: <br>
456: * <ul>
457: * <li>{@link com.izforge.izpack.util.os.Shortcut#DESKTOP}
458: * <li>{@link com.izforge.izpack.util.os.Shortcut#APPLICATIONS}
459: * <li>{@link com.izforge.izpack.util.os.Shortcut#START_MENU}
460: * <li>{@link com.izforge.izpack.util.os.Shortcut#START_UP}
461: * </ul>
462: * maps from ShellLink-types to Shortcut-types.
463: */
464: public int getLinkType() {
465: int typ = shortcut.getLinkType();
466: Debug.log(CLASS + myClass + ".getLinkType() '" + typ + "'");
467: switch (typ) {
468: case ShellLink.DESKTOP:
469: typ = DESKTOP;
470: break;
471: case ShellLink.PROGRAM_MENU:
472: typ = APPLICATIONS;
473: break;
474: case ShellLink.START_MENU:
475: typ = START_MENU;
476: break;
477: case ShellLink.STARTUP:
478: typ = START_UP;
479: break;
480: default:
481: break;
482: }
483:
484: return typ;
485: }
486:
487: /*--------------------------------------------------------------------------*/
488: /**
489: * Sets the type of link
490: *
491: * @param type The type of link desired. The following values can be set: <br>
492: * (note APPLICATION on Windows is 'Start Menu\Programs') APPLICATION is a Mac term.
493: * <ul>
494: * <li>{@link com.izforge.izpack.util.os.Shortcut#DESKTOP}
495: * <li>{@link com.izforge.izpack.util.os.Shortcut#APPLICATIONS}
496: * <li>{@link com.izforge.izpack.util.os.Shortcut#START_MENU}
497: * <li>{@link com.izforge.izpack.util.os.Shortcut#START_UP}
498: * </ul>
499: *
500: * @exception IllegalArgumentException if an an invalid type is passed
501: * @throws UnsupportedEncodingException
502: */
503: public void setLinkType(int type) throws IllegalArgumentException,
504: UnsupportedEncodingException {
505: Debug.log(CLASS + myClass + ".setLinkType() '" + type + "'");
506: switch (type) {
507: case DESKTOP: {
508: shortcut.setLinkType(ShellLink.DESKTOP);
509: break;
510: }
511: case APPLICATIONS: {
512: shortcut.setLinkType(ShellLink.PROGRAM_MENU);
513: break;
514: }
515: case START_MENU: {
516: shortcut.setLinkType(ShellLink.START_MENU);
517: break;
518: }
519: case START_UP: {
520: shortcut.setLinkType(ShellLink.STARTUP);
521: break;
522: }
523: default: {
524: throw (new IllegalArgumentException(type
525: + "is not recognized as a valid link type"));
526: }
527: }
528: }
529:
530: /*--------------------------------------------------------------------------*/
531: /**
532: * Gets the user type for the link
533: *
534: * @return userType
535: * @see #CURRENT_USER
536: * @see #ALL_USERS
537: */
538: public int getUserType() {
539: int utype = shortcut.getUserType();
540:
541: Debug.log(CLASS + myClass + ".getUserType() '" + utype + "'");
542:
543: switch (utype) {
544: case ShellLink.ALL_USERS:
545: utype = ALL_USERS;
546: break;
547:
548: case ShellLink.CURRENT_USER:
549: utype = CURRENT_USER;
550: break;
551: }
552:
553: return utype;
554: }
555:
556: /*--------------------------------------------------------------------------*/
557: /**
558: * Sets the user type for the link
559: *
560: * @param type the type of user for the link.
561: *
562: * @see Shortcut#CURRENT_USER
563: * @see Shortcut#ALL_USERS
564: *
565: * if the linkPath for that type is empty, refuse to set.
566: */
567: /*--------------------------------------------------------------------------*/
568: public void setUserType(int type) {
569: Debug.log(CLASS + myClass + ".setUserType() '" + type + "'");
570: if (type == CURRENT_USER) {
571: if (shortcut.getcurrentUserLinkPath().length() > 0) {
572: shortcut.setUserType(ShellLink.CURRENT_USER);
573: }
574: } else if (type == ALL_USERS) {
575: if (shortcut.getallUsersLinkPath().length() > 0) {
576: shortcut.setUserType(ShellLink.ALL_USERS);
577: }
578: }
579: }
580:
581: /*--------------------------------------------------------------------------*/
582: /**
583: * Saves this link.
584: *
585: * @exception Exception if problems are encountered
586: */
587: public void save() throws Exception {
588:
589: shortcut.save();
590: }
591:
592: /*--------------------------------------------------------------------------*/
593: /**
594: * Gets the link hotKey
595: *
596: * @return int hotKey
597: */
598: public int getHotkey() {
599: int result = shortcut.getHotkey();
600: Debug.log(CLASS + myClass + ".getHotkey() '" + result + "'");
601: return result;
602: }
603:
604: /*--------------------------------------------------------------------------*/
605: /**
606: * Sets the link hotKey
607: *
608: * @param hotkey
609: *
610: * incoming 2 byte hotkey is: high byte modifier: SHIFT = 0x01 CONTROL= 0x02 ALT = 0x04 EXT =
611: * 0x08
612: *
613: * lower byte contains ascii letter. ie 0x0278 represents CTRL+x 0x068a represents CTRL+ALT+z
614: */
615: public void setHotkey(int hotkey) {
616: Debug.log(CLASS + myClass + ".setHotkey() '" + hotkey + "'");
617: shortcut.setHotkey(hotkey);
618: }
619:
620: /**
621: * Gets the Folders where to place the program-groups and their shortcuts, for the given
622: * usertype.
623: * @see com.izforge.izpack.util.os.Shortcut#getProgramsFolder(int)
624: */
625: public String getProgramsFolder(int current_user) {
626: /** CURRENT_USER = 0; the constant to use for selecting the current user. */
627: int USER = 0;
628:
629: if (current_user == Shortcut.CURRENT_USER)
630: USER = ShellLink.CURRENT_USER;
631:
632: else if (current_user == Shortcut.ALL_USERS)
633: USER = ShellLink.ALL_USERS;
634:
635: String result = null;
636: try {
637: result = new String(shortcut.getLinkPath(USER).getBytes(
638: StringTool.getPlatformEncoding()), StringTool
639: .getPlatformEncoding());
640: } catch (UnsupportedEncodingException e) {
641: // TODO Auto-generated catch block
642: e.printStackTrace();
643: }
644: Debug.log(CLASS + myClass + ".getProgramsFolder() '"
645: + current_user + "', '" + result + "'");
646: return result;
647: }
648: }
649: /*---------------------------------------------------------------------------*/
|