001: /*
002: * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
003: *
004: * http://izpack.org/
005: * http://izpack.codehaus.org/
006: *
007: * Copyright 2004 Klaus Bartz
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.panels;
023:
024: import java.awt.event.ActionEvent;
025: import java.awt.event.ActionListener;
026: import java.io.BufferedReader;
027: import java.io.File;
028: import java.io.IOException;
029: import java.io.InputStream;
030: import java.io.InputStreamReader;
031:
032: import com.izforge.izpack.gui.IzPanelLayout;
033: import com.izforge.izpack.installer.AutomatedInstallData;
034: import com.izforge.izpack.installer.InstallData;
035: import com.izforge.izpack.installer.InstallerFrame;
036: import com.izforge.izpack.installer.IzPanel;
037: import com.izforge.izpack.installer.ResourceNotFoundException;
038: import com.izforge.izpack.util.AbstractUIHandler;
039: import com.izforge.izpack.util.Debug;
040: import com.izforge.izpack.util.IoHelper;
041: import com.izforge.izpack.util.OsVersion;
042: import com.izforge.izpack.util.VariableSubstitutor;
043:
044: /**
045: * Base class for panels which asks for paths.
046: *
047: * @author Klaus Bartz
048: *
049: */
050: public class PathInputPanel extends IzPanel implements ActionListener {
051:
052: /**
053: *
054: */
055: private static final long serialVersionUID = 3257566217698292531L;
056:
057: /** Flag whether the choosen path must exist or not */
058: protected boolean mustExist = false;
059:
060: /** Files which should be exist */
061: protected String[] existFiles = null;
062:
063: /** The path which was chosen */
064: // protected String chosenPath;
065: /** The path selection sub panel */
066: protected PathSelectionPanel pathSelectionPanel;
067:
068: protected String emptyTargetMsg;
069:
070: protected String warnMsg;
071:
072: protected static String defaultInstallDir = null;
073:
074: /**
075: * The constructor.
076: *
077: * @param parent The parent window.
078: * @param idata The installation data.
079: */
080: public PathInputPanel(InstallerFrame parent, InstallData idata) {
081: super (parent, idata, new IzPanelLayout());
082: // Set default values
083: emptyTargetMsg = getI18nStringForClass("empty_target",
084: "TargetPanel");
085: warnMsg = getI18nStringForClass("warn", "TargetPanel");
086:
087: String introText = getI18nStringForClass("extendedIntro",
088: "PathInputPanel");
089: if (introText == null || introText.endsWith("extendedIntro")
090: || introText.indexOf('$') > -1) {
091: introText = getI18nStringForClass("intro", "PathInputPanel");
092: if (introText == null || introText.endsWith("intro"))
093: introText = "";
094: }
095: // Intro
096: // row 0 column 0
097: add(createMultiLineLabel(introText));
098:
099: add(IzPanelLayout.createParagraphGap());
100:
101: // Label for input
102: // row 1 column 0.
103: add(createLabel("info", "TargetPanel", "open", LEFT, true),
104: NEXT_LINE);
105: // Create path selection components and add they to this panel.
106: pathSelectionPanel = new PathSelectionPanel(this , idata);
107: add(pathSelectionPanel, NEXT_LINE);
108: createLayoutBottom();
109: getLayoutHelper().completeLayout();
110: }
111:
112: /**
113: * This method does nothing. It is called from ctor of PathInputPanel, to give in a derived
114: * class the possibility to add more components under the path input components.
115: */
116: public void createLayoutBottom() {
117: // Derived classes implements additional elements.
118: }
119:
120: /**
121: * Actions-handling method.
122: *
123: * @param e The event.
124: */
125: public void actionPerformed(ActionEvent e) {
126: Object source = e.getSource();
127: if (source == pathSelectionPanel.getPathInputField()) {
128: parent.navigateNext();
129: }
130:
131: }
132:
133: /**
134: * Indicates wether the panel has been validated or not.
135: *
136: * @return Wether the panel has been validated or not.
137: */
138: public boolean isValidated() {
139: String chosenPath = pathSelectionPanel.getPath();
140: boolean ok = true;
141:
142: boolean modifyinstallation = Boolean.valueOf(idata
143: .getVariable(InstallData.MODIFY_INSTALLATION));
144: if (modifyinstallation) {
145: // installation directory has to exist in a modification installation
146: mustExist = true;
147:
148: File installationinformation = new File(pathSelectionPanel
149: .getPath()
150: + File.separator
151: + AutomatedInstallData.INSTALLATION_INFORMATION);
152: if (!installationinformation.exists()) {
153: emitError(
154: parent.langpack.getString("installer.error"),
155: parent.langpack
156: .getString("PathInputPanel.required.forModificationInstallation"));
157:
158: return false;
159: }
160: }
161:
162: // We put a warning if the specified target is nameless
163: if (chosenPath.length() == 0) {
164: if (isMustExist()) {
165: emitError(parent.langpack.getString("installer.error"),
166: parent.langpack
167: .getString("PathInputPanel.required"));
168: return false;
169: }
170: ok = emitWarning(parent.langpack
171: .getString("installer.warning"), emptyTargetMsg);
172: }
173: if (!ok)
174: return ok;
175:
176: // Normalize the path
177: File path = new File(chosenPath).getAbsoluteFile();
178: chosenPath = path.toString();
179: pathSelectionPanel.setPath(chosenPath);
180: if (isMustExist()) {
181: if (!path.exists()) {
182: emitError(parent.langpack.getString("installer.error"),
183: parent.langpack
184: .getString(getI18nStringForClass(
185: "required", "PathInputPanel")));
186: return false;
187: }
188: if (!pathIsValid()) {
189: emitError(parent.langpack.getString("installer.error"),
190: parent.langpack
191: .getString(getI18nStringForClass(
192: "notValid", "PathInputPanel")));
193: return false;
194: }
195: } else {
196: // We assume, that we would install something into this dir
197: if (!isWriteable()) {
198: emitError(parent.langpack.getString("installer.error"),
199: getI18nStringForClass("notwritable",
200: "TargetPanel"));
201: return false;
202: }
203: // We put a warning if the directory exists else we warn
204: // that it will be created
205: if (path.exists()) {
206: int res = askQuestion(parent.langpack
207: .getString("installer.warning"), warnMsg,
208: AbstractUIHandler.CHOICES_YES_NO,
209: AbstractUIHandler.ANSWER_YES);
210: ok = res == AbstractUIHandler.ANSWER_YES;
211: } else {
212: ok = this
213: .emitNotificationFeedback(getI18nStringForClass(
214: "createdir", "TargetPanel")
215: + "\n" + chosenPath);
216:
217: }
218: }
219: return ok;
220: }
221:
222: /**
223: * Returns whether the chosen path is true or not. If existFiles are not null, the existence of
224: * it under the choosen path are detected. This method can be also implemented in derived
225: * classes to handle special verification of the path.
226: *
227: * @return true if existFiles are exist or not defined, else false
228: */
229: protected boolean pathIsValid() {
230: if (existFiles == null)
231: return true;
232: for (String existFile : existFiles) {
233: File path = new File(pathSelectionPanel.getPath(),
234: existFile).getAbsoluteFile();
235: if (!path.exists()) {
236: return false;
237: }
238: }
239: return true;
240: }
241:
242: /**
243: * Returns the must exist state.
244: *
245: * @return the must exist state
246: */
247: public boolean isMustExist() {
248: return mustExist;
249: }
250:
251: /**
252: * Sets the must exist state. If it is true, the path must exist.
253: *
254: * @param b must exist state
255: */
256: public void setMustExist(boolean b) {
257: mustExist = b;
258: }
259:
260: /**
261: * Returns the array of strings which are described the files which must exist.
262: *
263: * @return paths of files which must exist
264: */
265: public String[] getExistFiles() {
266: return existFiles;
267: }
268:
269: /**
270: * Sets the paths of files which must exist under the chosen path.
271: *
272: * @param strings paths of files which must exist under the chosen path
273: */
274: public void setExistFiles(String[] strings) {
275: existFiles = strings;
276: }
277:
278: /**
279: * Loads up the "dir" resource associated with TargetPanel. Acceptable dir resource names:
280: * <code>
281: * TargetPanel.dir.macosx
282: * TargetPanel.dir.mac
283: * TargetPanel.dir.windows
284: * TargetPanel.dir.unix
285: * TargetPanel.dir.xxx,
286: * where xxx is the lower case version of System.getProperty("os.name"),
287: * with any spaces replace with underscores
288: * TargetPanel.dir (generic that will be applied if none of above is found)
289: * </code>
290: * As with all IzPack resources, each the above ids should be associated with a separate
291: * filename, which is set in the install.xml file at compile time.
292: */
293: public static void loadDefaultInstallDir(
294: InstallerFrame parentFrame, InstallData idata) {
295: // Load only once ...
296: if (getDefaultInstallDir() != null)
297: return;
298: BufferedReader br = null;
299: try {
300: InputStream in = null;
301:
302: if (OsVersion.IS_WINDOWS) {
303: try {
304: in = parentFrame
305: .getResource("TargetPanel.dir.windows");
306: } catch (ResourceNotFoundException rnfe) {
307: }//it's usual, that the resource does not exist
308: } else if (OsVersion.IS_OSX) {
309: try {
310: in = parentFrame
311: .getResource("TargetPanel.dir.macosx");
312: } catch (ResourceNotFoundException rnfe) {
313: }//it's usual, that the resource does not exist
314: } else {
315: String os = System.getProperty("os.name");
316: // first try to look up by specific os name
317: os = os.replace(' ', '_'); // avoid spaces in file names
318: os = os.toLowerCase(); // for consistency among TargetPanel res
319: // files
320: try {
321: in = parentFrame.getResource("TargetPanel.dir."
322: .concat(os));
323: } catch (ResourceNotFoundException rnfe) {
324: }
325: // if not specific os, try getting generic 'unix' resource file
326: if (in == null) {
327: try {
328: in = parentFrame
329: .getResource("TargetPanel.dir.unix");
330: } catch (ResourceNotFoundException eee) {
331: }
332: }
333:
334: }
335:
336: // if all above tests failed, there is no resource file,
337: // so use system default
338: if (in == null) {
339: try {
340: in = parentFrame.getResource("TargetPanel.dir");
341: } catch (ResourceNotFoundException eee) {
342: }
343: }
344:
345: if (in != null) {
346: // now read the file, once we've identified which one to read
347: InputStreamReader isr = new InputStreamReader(in);
348: br = new BufferedReader(isr);
349: String line;
350: while ((line = br.readLine()) != null) {
351: line = line.trim();
352: // use the first non-blank line
353: if (!"".equals(line))
354: break;
355: }
356: defaultInstallDir = line;
357: VariableSubstitutor vs = new VariableSubstitutor(idata
358: .getVariables());
359: defaultInstallDir = vs.substitute(defaultInstallDir,
360: null);
361: }
362: } catch (Exception e) {
363: //mar: what's the common way to log an exception ?
364: e.printStackTrace();
365: defaultInstallDir = null;
366: // leave unset to take the system default set by Installer class
367: } finally {
368: try {
369: if (br != null)
370: br.close();
371: } catch (IOException ignored) {
372: }
373: }
374: }
375:
376: /**
377: * This method determines whether the chosen dir is writeable or not.
378: *
379: * @return whether the chosen dir is writeable or not
380: */
381: public boolean isWriteable() {
382: File existParent = IoHelper.existingParent(new File(
383: pathSelectionPanel.getPath()));
384: if (existParent == null)
385: return false;
386: // On windows we cannot use canWrite because
387: // it looks to the dos flags which are not valid
388: // on NT or 2k XP or ...
389: if (OsVersion.IS_WINDOWS) {
390: File tmpFile;
391: try {
392: tmpFile = File.createTempFile("izWrTe", ".tmp",
393: existParent);
394: tmpFile.deleteOnExit();
395: } catch (IOException e) {
396: Debug.trace(e.toString());
397: return false;
398: }
399: return true;
400: }
401: return existParent.canWrite();
402: }
403:
404: /**
405: * Returns the default for the installation directory.
406: *
407: * @return the default for the installation directory
408: */
409: public static String getDefaultInstallDir() {
410: return defaultInstallDir;
411: }
412:
413: /**
414: * Sets the default for the installation directory to the given string.
415: *
416: * @param string path for default for the installation directory
417: */
418: public static void setDefaultInstallDir(String string) {
419: defaultInstallDir = string;
420: }
421:
422: }
|