001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.compapp.projects.base.ui.wizards;
021:
022: import java.io.File;
023: import java.io.IOException;
024: import java.text.MessageFormat;
025:
026: import javax.swing.JFileChooser;
027: import javax.swing.event.DocumentEvent;
028: import javax.swing.event.DocumentListener;
029: import javax.swing.text.Document;
030:
031: import org.netbeans.modules.compapp.projects.base.ui.FoldersListSettings;
032: import org.netbeans.spi.project.ui.support.ProjectChooser;
033:
034: import org.openide.WizardDescriptor;
035: import org.openide.filesystems.FileUtil;
036: import org.openide.util.NbBundle;
037:
038: class PanelProjectLocationVisual extends SettingsPanel implements
039: DocumentListener,
040: org.netbeans.modules.compapp.projects.base.IcanproConstants {
041:
042: public static final String PROP_PROJECT_NAME = "projectName"; //NOI18N
043: private PanelConfigureProject panel;
044:
045: /** Creates new form PanelProjectLocationVisual */
046: public PanelProjectLocationVisual(PanelConfigureProject panel) {
047: initComponents();
048: this .panel = panel;
049:
050: // Register listener on the textFields to make the automatic updates
051: projectNameTextField.getDocument().addDocumentListener(this );
052: projectLocationTextField.getDocument()
053: .addDocumentListener(this );
054: }
055:
056: /** This method is called from within the constructor to
057: * initialize the form.
058: * WARNING: Do NOT modify this code. The content of this method is
059: * always regenerated by the Form Editor.
060: */
061: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
062: private void initComponents() {
063: java.awt.GridBagConstraints gridBagConstraints;
064:
065: projectNameLabel = new javax.swing.JLabel();
066: projectNameTextField = new javax.swing.JTextField();
067: projectLocationLabel = new javax.swing.JLabel();
068: projectLocationTextField = new javax.swing.JTextField();
069: Button = new javax.swing.JButton();
070: createdFolderLabel = new javax.swing.JLabel();
071: createdFolderTextField = new javax.swing.JTextField();
072:
073: setLayout(new java.awt.GridBagLayout());
074:
075: projectNameLabel.setLabelFor(projectNameTextField);
076: org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel,
077: org.openide.util.NbBundle.getMessage(
078: PanelProjectLocationVisual.class,
079: "LBL_NWP1_ProjectName_Label")); // NOI18N
080: gridBagConstraints = new java.awt.GridBagConstraints();
081: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
082: gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 0);
083: add(projectNameLabel, gridBagConstraints);
084: projectNameLabel.getAccessibleContext().setAccessibleName(
085: org.openide.util.NbBundle.getMessage(
086: PanelProjectLocationVisual.class,
087: "LBL_NWP1_ProjectName_Label")); // NOI18N
088: projectNameLabel.getAccessibleContext()
089: .setAccessibleDescription(
090: org.openide.util.NbBundle.getMessage(
091: PanelProjectLocationVisual.class,
092: "ACS_LBL_NWP1_ProjectName_A11YDesc")); // NOI18N
093:
094: gridBagConstraints = new java.awt.GridBagConstraints();
095: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
096: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
097: gridBagConstraints.weightx = 1.0;
098: gridBagConstraints.insets = new java.awt.Insets(0, 12, 12, 0);
099: add(projectNameTextField, gridBagConstraints);
100: projectNameTextField.getAccessibleContext()
101: .setAccessibleDescription(
102: org.openide.util.NbBundle.getMessage(
103: PanelProjectLocationVisual.class,
104: "ACS_LBL_NWP1_ProjectName_A11YDesc")); // NOI18N
105:
106: projectLocationLabel.setLabelFor(projectLocationTextField);
107: org.openide.awt.Mnemonics.setLocalizedText(
108: projectLocationLabel, org.openide.util.NbBundle
109: .getMessage(PanelProjectLocationVisual.class,
110: "LBL_NWP1_ProjectLocation_Label")); // NOI18N
111: gridBagConstraints = new java.awt.GridBagConstraints();
112: gridBagConstraints.gridy = 1;
113: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
114: gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
115: add(projectLocationLabel, gridBagConstraints);
116: projectLocationLabel.getAccessibleContext().setAccessibleName(
117: org.openide.util.NbBundle.getMessage(
118: PanelProjectLocationVisual.class,
119: "LBL_NWP1_ProjectLocation_Label")); // NOI18N
120:
121: gridBagConstraints = new java.awt.GridBagConstraints();
122: gridBagConstraints.gridy = 1;
123: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
124: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
125: gridBagConstraints.weightx = 1.0;
126: gridBagConstraints.insets = new java.awt.Insets(0, 12, 5, 0);
127: add(projectLocationTextField, gridBagConstraints);
128: projectLocationTextField
129: .getAccessibleContext()
130: .setAccessibleDescription(
131: org.openide.util.NbBundle
132: .getMessage(
133: PanelProjectLocationVisual.class,
134: "ACS_LBL_NPW1_ProjectLocation_A11YDesc")); // NOI18N
135:
136: org.openide.awt.Mnemonics.setLocalizedText(Button,
137: org.openide.util.NbBundle.getMessage(
138: PanelProjectLocationVisual.class,
139: "LBL_NWP1_BrowseLocation_Button")); // NOI18N
140: Button.setActionCommand("BROWSE");
141: Button.addActionListener(new java.awt.event.ActionListener() {
142: public void actionPerformed(java.awt.event.ActionEvent evt) {
143: browseLocationAction(evt);
144: }
145: });
146: gridBagConstraints = new java.awt.GridBagConstraints();
147: gridBagConstraints.gridy = 1;
148: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
149: gridBagConstraints.insets = new java.awt.Insets(0, 6, 5, 0);
150: add(Button, gridBagConstraints);
151: Button.getAccessibleContext().setAccessibleDescription(
152: org.openide.util.NbBundle.getMessage(
153: PanelProjectLocationVisual.class,
154: "ACS_LBL_NWP1_BrowseLocation_A11YDesc")); // NOI18N
155:
156: createdFolderLabel.setLabelFor(createdFolderTextField);
157: org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel,
158: org.openide.util.NbBundle.getMessage(
159: PanelProjectLocationVisual.class,
160: "LBL_NWP1_CreatedProjectFolder_Lablel")); // NOI18N
161: gridBagConstraints = new java.awt.GridBagConstraints();
162: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
163: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
164: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
165: add(createdFolderLabel, gridBagConstraints);
166:
167: createdFolderTextField.setEditable(false);
168: gridBagConstraints = new java.awt.GridBagConstraints();
169: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
170: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
171: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
172: gridBagConstraints.weightx = 1.0;
173: gridBagConstraints.weighty = 1.0;
174: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
175: add(createdFolderTextField, gridBagConstraints);
176: createdFolderTextField
177: .getAccessibleContext()
178: .setAccessibleDescription(
179: org.openide.util.NbBundle
180: .getMessage(
181: PanelProjectLocationVisual.class,
182: "ACS_LBL_NWP1_CreatedProjectFolder_A11YDesc")); // NOI18N
183: }// </editor-fold>//GEN-END:initComponents
184:
185: private void browseLocationAction(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseLocationAction
186: String command = evt.getActionCommand();
187:
188: if ("BROWSE".equals(command)) { //NOI18N
189: JFileChooser chooser = new JFileChooser();
190: chooser.setDialogTitle(NbBundle.getBundle(WIZARD_BUNDLE)
191: .getString("LBL_NWP1_SelectProjectLocation")); //NOI18N
192: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
193: String path = projectLocationTextField.getText();
194: if (path.length() > 0) {
195: File f = new File(path);
196: if (f.exists())
197: chooser.setSelectedFile(f);
198: }
199: if (JFileChooser.APPROVE_OPTION == chooser
200: .showOpenDialog(this )) {
201: File projectDir = chooser.getSelectedFile();
202: projectLocationTextField.setText(projectDir
203: .getAbsolutePath());
204: }
205: panel.fireChangeEvent();
206: }
207: }//GEN-LAST:event_browseLocationAction
208:
209: @Override
210: public void addNotify() {
211: super .addNotify();
212: //same problem as in 31086, initial focus on Cancel button
213: projectNameTextField.requestFocus();
214: }
215:
216: boolean valid(WizardDescriptor wizardDescriptor) {
217: String projectName = projectNameTextField.getText();
218: if (projectName.length() == 0 //String indexOf is not picking up \ char if this is the
219: // first char
220: || projectName.substring(0, 1).equals("\\")
221: || projectName.indexOf('/') >= 0 //NOI18N
222: || projectName.indexOf("\\") >= 0 //NOI18N
223: || projectName.indexOf(':') >= 0
224: || !isValidName(projectName)) {
225: wizardDescriptor.putProperty("WizardPanel_errorMessage",
226: NbBundle.getBundle(WIZARD_BUNDLE).getString(
227: "MSG_IllegalProjectName")); //NOI18N
228: return false; // Display name not specified
229: }
230:
231: if (projectName.indexOf(' ') >= 0) { //NOI18N
232: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
233: NbBundle.getMessage(
234: PanelProjectLocationVisual.class,
235: "MSG_IllegalProjectNameWithWhiteSpace"));
236: return false;
237: }
238:
239: File f = new File(projectLocationTextField.getText())
240: .getAbsoluteFile();
241: if (getCanonicalFile(f) == null) {
242: String message = NbBundle.getMessage(
243: PanelProjectLocationVisual.class,
244: "MSG_IllegalProjectLocation");
245: wizardDescriptor.putProperty("WizardPanel_errorMessage",
246: message);
247: return false;
248: }
249:
250: File destFolder = new File(createdFolderTextField.getText());
251: if (getCanonicalFile(destFolder) == null) {
252: String message = NbBundle.getMessage(
253: PanelProjectLocationVisual.class,
254: "MSG_IllegalProjectName");
255: wizardDescriptor.putProperty("WizardPanel_errorMessage",
256: message);
257: return false;
258: }
259:
260: File projLoc = FileUtil.normalizeFile(destFolder);
261: while (projLoc != null && !projLoc.exists()) {
262: projLoc = projLoc.getParentFile();
263: }
264: if (projLoc == null || !projLoc.canWrite()) {
265: wizardDescriptor.putProperty("WizardPanel_errorMessage", // NOI18N
266: NbBundle.getMessage(
267: PanelProjectLocationVisual.class,
268: "MSG_ProjectFolderReadOnly"));
269: return false;
270: }
271:
272: if (FileUtil.toFileObject(projLoc) == null) {
273: String message = NbBundle.getMessage(
274: PanelProjectLocationVisual.class,
275: "MSG_IllegalProjectLocation");
276: wizardDescriptor.putProperty("WizardPanel_errorMessage",
277: message);
278: return false;
279: }
280:
281: File[] children = destFolder.listFiles();
282: if (destFolder.exists() && children != null
283: && children.length > 0) {
284: // Folder exists and is not empty
285: wizardDescriptor.putProperty("WizardPanel_errorMessage",
286: NbBundle.getBundle(WIZARD_BUNDLE).getString(
287: "MSG_ProjectFolderExists")); //NOI18N
288: return false;
289: }
290:
291: wizardDescriptor.putProperty("WizardPanel_errorMessage", ""); //NOI18N
292: return true;
293: }
294:
295: static boolean isValidName(String fileName) {
296: try {
297: boolean bValid = true;
298: File tempFile = new File(fileName);
299: // fix 113726
300: // String tempFileName = 0+fileName;
301: String tempFileName = "00" + fileName;
302: File actualTempFile = File.createTempFile(tempFileName,
303: null);
304:
305: if (!FileUtil.normalizeFile(tempFile).equals(
306: tempFile.getCanonicalFile())) {
307: bValid = false;
308: }
309: actualTempFile.delete();
310: actualTempFile = null;
311: tempFile = null;
312: return bValid;
313: } catch (Exception e) {
314: return false;
315: }
316: }
317:
318: void store(WizardDescriptor d) {
319: String name = projectNameTextField.getText().trim();
320:
321: d.putProperty(WizardProperties.PROJECT_DIR, new File(
322: createdFolderTextField.getText().trim()));
323: d.putProperty(WizardProperties.NAME, name);
324:
325: File projectsDir = new File(this .projectLocationTextField
326: .getText());
327: if (projectsDir.isDirectory()) {
328: ProjectChooser.setProjectsFolder(projectsDir);
329: }
330: }
331:
332: void read(WizardDescriptor settings) {
333: File projectLocation = (File) settings
334: .getProperty(WizardProperties.PROJECT_DIR);
335: if (projectLocation == null)
336: projectLocation = ProjectChooser.getProjectsFolder();
337: else
338: projectLocation = projectLocation.getParentFile();
339:
340: projectLocationTextField.setText(projectLocation
341: .getAbsolutePath());
342:
343: String projectName = (String) settings
344: .getProperty(WizardProperties.NAME);
345: if (projectName == null) {
346: int baseCount = FoldersListSettings.getDefault()
347: .getNewProjectCount() + 1;
348: String formater = panel.getDefaultName(); // NbBundle.getBundle(WIZARD_BUNDLE).getString("LBL_NPW1_DefaultProjectName");
349: while ((projectName = validFreeProjectName(projectLocation,
350: formater, baseCount)) == null)
351: baseCount++;
352: }
353:
354: projectNameTextField.setText(projectName);
355: projectNameTextField.selectAll();
356: }
357:
358: // Variables declaration - do not modify//GEN-BEGIN:variables
359: private javax.swing.JButton Button;
360: private javax.swing.JLabel createdFolderLabel;
361: private javax.swing.JTextField createdFolderTextField;
362: private javax.swing.JLabel projectLocationLabel;
363: private javax.swing.JTextField projectLocationTextField;
364: private javax.swing.JLabel projectNameLabel;
365: protected javax.swing.JTextField projectNameTextField;
366:
367: // End of variables declaration//GEN-END:variables
368:
369: private static JFileChooser createChooser() {
370: JFileChooser chooser = new JFileChooser();
371: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
372: chooser.setAcceptAllFileFilterUsed(false);
373:
374: return chooser;
375: }
376:
377: private String validFreeProjectName(final File parentFolder,
378: final String formater, final int index) {
379: String name = MessageFormat.format(formater,
380: new Object[] { new Integer(index) });
381: File file = new File(parentFolder, name);
382: return file.exists() ? null : name;
383: }
384:
385: // Implementation of DocumentListener --------------------------------------
386: public void changedUpdate(DocumentEvent e) {
387: updateTexts(e);
388: if (this .projectNameTextField.getDocument() == e.getDocument()) {
389: firePropertyChange(PROP_PROJECT_NAME, null,
390: this .projectNameTextField.getText());
391: }
392: }
393:
394: public void insertUpdate(DocumentEvent e) {
395: updateTexts(e);
396: if (this .projectNameTextField.getDocument() == e.getDocument()) {
397: firePropertyChange(PROP_PROJECT_NAME, null,
398: this .projectNameTextField.getText());
399: }
400: }
401:
402: public void removeUpdate(DocumentEvent e) {
403: updateTexts(e);
404: if (this .projectNameTextField.getDocument() == e.getDocument()) {
405: firePropertyChange(PROP_PROJECT_NAME, null,
406: this .projectNameTextField.getText());
407: }
408: }
409:
410: // End if implementation of DocumentListener -------------------------------
411:
412: /** Handles changes in the project name and project directory
413: */
414: private void updateTexts(DocumentEvent e) {
415: Document doc = e.getDocument();
416: if (doc == projectNameTextField.getDocument()
417: || doc == projectLocationTextField.getDocument()) {
418: // Change in the project name
419: String projectName = projectNameTextField.getText();
420: String projectFolder = projectLocationTextField.getText();
421: String projFolderPath = FileUtil.normalizeFile(
422: new File(projectFolder)).getAbsolutePath();
423: if (projFolderPath.endsWith(File.separator)) {
424: createdFolderTextField.setText(projFolderPath
425: + projectName);
426: } else {
427: createdFolderTextField.setText(projFolderPath
428: + File.separator + projectName);
429: }
430: }
431: panel.fireChangeEvent(); // Notify that the panel changed
432: }
433:
434: private String getCreatedFolderPath() {
435: StringBuffer folder = new StringBuffer(projectLocationTextField
436: .getText().trim());
437: if (!projectLocationTextField.getText()
438: .endsWith(File.separator)) {
439: folder.append(File.separatorChar);
440: }
441: folder.append(projectNameTextField.getText().trim());
442:
443: return folder.toString();
444: }
445:
446: static File getCanonicalFile(File file) {
447: try {
448: return file.getCanonicalFile();
449: } catch (IOException e) {
450: return null;
451: }
452: }
453: }
454:
455: //TODO implement check for project folder name and location
|