2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.java.j2seproject.ui.wizards;
44
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyChangeEvent;
47
import java.text.MessageFormat;
48
import java.util.ArrayList;
49
import java.util.List;
50
import javax.swing.JButton;
51
import javax.swing.event.ChangeListener;
52
import org.netbeans.spi.project.ui.templates.support.Templates;
53
import org.openide.DialogDisplayer;
54
import org.openide.NotifyDescriptor;
55
import org.openide.WizardDescriptor;
56
import org.openide.WizardValidationException;
57
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileUtil;
59
import org.openide.util.ChangeSupport;
60
import org.openide.util.HelpCtx;
61
import org.openide.util.NbBundle;
63
//XXX There should be a way how to add nonexistent test dir
66
* Sets up name and location for new Java project from existing sources.
67
* @author Tomas Zezula et al.
69
public class PanelSourceFolders extends SettingsPanel implements PropertyChangeListener {
72
private WizardDescriptor wizardDescriptor;
74
// key to action value that influence folder list current directory
75
public static final String INITIAL_SOURCE_ROOT = "EXISTING_SOURCES_CURRENT_DIRECTORY"; // NOI18N
77
/** Creates new form PanelSourceFolders */
78
public PanelSourceFolders (Panel panel) {
81
this.setName(NbBundle.getMessage(PanelConfigureProjectVisual.class,"LAB_ConfigureSourceRoots"));
82
this.putClientProperty ("NewProjectWizard_Title", NbBundle.getMessage(PanelSourceFolders.class,"TXT_JavaExtSourcesProjectLocation")); // NOI18N
83
this.getAccessibleContext().setAccessibleName(NbBundle.getMessage(PanelSourceFolders.class,"AN_PanelSourceFolders"));
84
this.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PanelSourceFolders.class,"AD_PanelSourceFolders"));
85
this.sourcePanel.addPropertyChangeListener (this);
86
this.testsPanel.addPropertyChangeListener(this);
87
((FolderList)this.sourcePanel).setRelatedFolderList((FolderList)this.testsPanel);
88
((FolderList)this.testsPanel).setRelatedFolderList((FolderList)this.sourcePanel);
91
public void propertyChange(PropertyChangeEvent evt) {
92
if (FolderList.PROP_FILES.equals(evt.getPropertyName())) {
95
else if (FolderList.PROP_LAST_USED_DIR.equals (evt.getPropertyName())) {
96
if (evt.getSource() == this.sourcePanel) {
97
((FolderList)this.testsPanel).setLastUsedDir
98
((File)evt.getNewValue());
100
else if (evt.getSource() == this.testsPanel) {
101
((FolderList)this.sourcePanel).setLastUsedDir
102
((File)evt.getNewValue());
107
private void dataChanged () {
108
this.firer.fireChangeEvent();
112
void read (WizardDescriptor settings) {
113
this.wizardDescriptor = settings;
114
File projectLocation = (File) settings.getProperty ("projdir"); //NOI18N
115
((FolderList)this.sourcePanel).setProjectFolder(projectLocation);
116
((FolderList)this.testsPanel).setProjectFolder(projectLocation);
117
File[] srcRoot = (File[]) settings.getProperty ("sourceRoot"); //NOI18N
118
assert srcRoot != null : "sourceRoot property must be initialized!" ; //NOI18N
119
((FolderList)this.sourcePanel).setFiles(srcRoot);
120
File[] testRoot = (File[]) settings.getProperty ("testRoot"); //NOI18N
121
assert testRoot != null : "testRoot property must be initialized!"; //NOI18N
122
((FolderList)this.testsPanel).setFiles (testRoot);
124
// #58489 honor existing source folder
125
File currentDirectory = null;
126
FileObject folder = Templates.getExistingSourcesFolder(wizardDescriptor);
127
if (folder != null) {
128
currentDirectory = FileUtil.toFile(folder);
130
if (currentDirectory != null && currentDirectory.isDirectory()) {
131
((FolderList)sourcePanel).setLastUsedDir(currentDirectory);
132
((FolderList)testsPanel).setLastUsedDir(currentDirectory);
136
void store (WizardDescriptor settings) {
137
File[] sourceRoots = ((FolderList)this.sourcePanel).getFiles();
138
File[] testRoots = ((FolderList)this.testsPanel).getFiles();
139
settings.putProperty ("sourceRoot",sourceRoots); //NOI18N
140
settings.putProperty("testRoot",testRoots); //NOI18N
143
boolean valid (WizardDescriptor settings) {
144
File projectLocation = (File) settings.getProperty ("projdir"); //NOI18N
145
File[] sourceRoots = ((FolderList)this.sourcePanel).getFiles();
146
File[] testRoots = ((FolderList)this.testsPanel).getFiles();
147
String result = checkValidity (projectLocation, sourceRoots, testRoots);
148
if (result == null) {
149
wizardDescriptor.putProperty( "WizardPanel_errorMessage",""); //NOI18N
153
wizardDescriptor.putProperty( "WizardPanel_errorMessage",result); //NOI18N
158
static String checkValidity (final File projectLocation, final File[] sources, final File[] tests ) {
159
String ploc = projectLocation.getAbsolutePath ();
160
for (int i=0; i<sources.length;i++) {
161
if (!sources[i].isDirectory() || !sources[i].canRead()) {
162
return MessageFormat.format(NbBundle.getMessage(PanelSourceFolders.class,"MSG_IllegalSources"),
163
new Object[] {sources[i].getAbsolutePath()});
165
String sloc = sources[i].getAbsolutePath ();
166
if (ploc.equals (sloc) || ploc.startsWith (sloc + File.separatorChar)) {
167
return NbBundle.getMessage(PanelSourceFolders.class,"MSG_IllegalProjectFolder");
170
for (int i=0; i<tests.length; i++) {
171
if (!tests[i].isDirectory() || !tests[i].canRead()) {
172
return MessageFormat.format(NbBundle.getMessage(PanelSourceFolders.class,"MSG_IllegalTests"),
173
new Object[] {sources[i].getAbsolutePath()});
175
String tloc = tests[i].getAbsolutePath();
176
if (ploc.equals(tloc) || ploc.startsWith(tloc + File.separatorChar)) {
177
return NbBundle.getMessage(PanelSourceFolders.class,"MSG_IllegalProjectFolder");
183
void validate (WizardDescriptor d) throws WizardValidationException {
185
searchClassFiles (((FolderList)this.sourcePanel).getFiles());
186
// test root, not asked in issue 48198
187
//searchClassFiles (FileUtil.toFileObject (FileUtil.normalizeFile(new File (tests.getText ()))));
190
private static void findClassFiles(File folder, List<File> files) {
191
File[] kids = folder.listFiles();
195
for (File kid : kids) {
196
if (kid.isFile() && kid.getName().endsWith(".class")) {
198
} else if (kid.isDirectory()) {
199
findClassFiles(kid, files);
203
private void searchClassFiles (File[] folders) throws WizardValidationException {
204
List<File> classFiles = new ArrayList<File>();
205
for (File folder : folders) {
206
findClassFiles(folder, classFiles);
208
if (!classFiles.isEmpty()) {
209
JButton DELETE_OPTION = new JButton (NbBundle.getMessage (PanelSourceFolders.class, "TXT_DeleteOption")); // NOI18N
210
JButton KEEP_OPTION = new JButton (NbBundle.getMessage (PanelSourceFolders.class, "TXT_KeepOption")); // NOI18N
211
JButton CANCEL_OPTION = new JButton (NbBundle.getMessage (PanelSourceFolders.class, "TXT_CancelOption")); // NOI18N
212
KEEP_OPTION.setMnemonic(NbBundle.getMessage (PanelSourceFolders.class, "MNE_KeepOption").charAt(0));
213
DELETE_OPTION.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage (PanelSourceFolders.class, "AD_DeleteOption"));
214
KEEP_OPTION.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage (PanelSourceFolders.class, "AD_KeepOption"));
215
CANCEL_OPTION.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage (PanelSourceFolders.class, "AD_CancelOption"));
216
NotifyDescriptor desc = new NotifyDescriptor (
217
NbBundle.getMessage (PanelSourceFolders.class, "MSG_FoundClassFiles"), // NOI18N
218
NbBundle.getMessage (PanelSourceFolders.class, "MSG_FoundClassFiles_Title"), // NOI18N
219
NotifyDescriptor.YES_NO_CANCEL_OPTION,
220
NotifyDescriptor.QUESTION_MESSAGE,
221
new Object[] {DELETE_OPTION, KEEP_OPTION, CANCEL_OPTION},
224
Object result = DialogDisplayer.getDefault().notify(desc);
225
if (DELETE_OPTION.equals (result)) {
226
for (File f : classFiles) {
227
f.delete(); // ignore if fails
229
} else if (!KEEP_OPTION.equals (result)) {
230
// cancel, back to wizard
231
throw new WizardValidationException (this.sourcePanel, "", ""); // NOI18N
236
/** This method is called from within the constructor to
237
* initialize the form.
238
* WARNING: Do NOT modify this code. The content of this method is
239
* always regenerated by the Form Editor.
241
private void initComponents() {//GEN-BEGIN:initComponents
242
java.awt.GridBagConstraints gridBagConstraints;
244
jLabel3 = new javax.swing.JLabel();
245
sourcePanel = new FolderList (NbBundle.getMessage(PanelSourceFolders.class,"CTL_SourceRoots"), NbBundle.getMessage(PanelSourceFolders.class,"MNE_SourceRoots").charAt(0),NbBundle.getMessage(PanelSourceFolders.class,"AD_SourceRoots"), NbBundle.getMessage(PanelSourceFolders.class,"CTL_AddSourceRoot"),
246
NbBundle.getMessage(PanelSourceFolders.class,"MNE_AddSourceFolder").charAt(0), NbBundle.getMessage(PanelSourceFolders.class,"AD_AddSourceFolder"),NbBundle.getMessage(PanelSourceFolders.class,"MNE_RemoveSourceFolder").charAt(0), NbBundle.getMessage(PanelSourceFolders.class,"AD_RemoveSourceFolder"));
247
testsPanel = new FolderList (NbBundle.getMessage(PanelSourceFolders.class,"CTL_TestRoots"), NbBundle.getMessage(PanelSourceFolders.class,"MNE_TestRoots").charAt(0),NbBundle.getMessage(PanelSourceFolders.class,"AD_TestRoots"), NbBundle.getMessage(PanelSourceFolders.class,"CTL_AddTestRoot"),
248
NbBundle.getMessage(PanelSourceFolders.class,"MNE_AddTestFolder").charAt(0), NbBundle.getMessage(PanelSourceFolders.class,"AD_AddTestFolder"),NbBundle.getMessage(PanelSourceFolders.class,"MNE_RemoveTestFolder").charAt(0), NbBundle.getMessage(PanelSourceFolders.class,"AD_RemoveTestFolder"));
250
setLayout(new java.awt.GridBagLayout());
252
getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(PanelSourceFolders.class, "ACSN_PanelSourceFolders"));
253
getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PanelSourceFolders.class, "ACSD_PanelSourceFolders"));
254
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(PanelSourceFolders.class, "LBL_SourceDirectoriesLabel"));
255
gridBagConstraints = new java.awt.GridBagConstraints();
256
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
257
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
258
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
259
add(jLabel3, gridBagConstraints);
260
jLabel3.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getBundle(PanelSourceFolders.class).getString("ACSN_jLabel3"));
261
jLabel3.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getBundle(PanelSourceFolders.class).getString("ACSD_jLabel3"));
263
gridBagConstraints = new java.awt.GridBagConstraints();
264
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
265
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
266
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
267
gridBagConstraints.weightx = 1.0;
268
gridBagConstraints.weighty = 0.45;
269
gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0);
270
add(sourcePanel, gridBagConstraints);
272
gridBagConstraints = new java.awt.GridBagConstraints();
273
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
274
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
275
gridBagConstraints.weightx = 1.0;
276
gridBagConstraints.weighty = 0.45;
277
gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0);
278
add(testsPanel, gridBagConstraints);
280
}//GEN-END:initComponents
284
// Variables declaration - do not modify//GEN-BEGIN:variables
285
private javax.swing.JLabel jLabel3;
286
private javax.swing.JPanel sourcePanel;
287
private javax.swing.JPanel testsPanel;
288
// End of variables declaration//GEN-END:variables
291
static class Panel implements WizardDescriptor.ValidatingPanel, WizardDescriptor.FinishablePanel {
293
private final ChangeSupport changeSupport = new ChangeSupport(this);
294
private PanelSourceFolders component;
295
private WizardDescriptor settings;
297
public void removeChangeListener(ChangeListener l) {
298
changeSupport.removeChangeListener(l);
301
public void addChangeListener(ChangeListener l) {
302
changeSupport.addChangeListener(l);
305
public void readSettings(Object settings) {
306
this.settings = (WizardDescriptor) settings;
307
this.component.read (this.settings);
308
// XXX hack, TemplateWizard in final setTemplateImpl() forces new wizard's title
309
// this name is used in NewProjectWizard to modify the title
310
Object substitute = component.getClientProperty ("NewProjectWizard_Title"); // NOI18N
311
if (substitute != null) {
312
this.settings.putProperty ("NewProjectWizard_Title", substitute); // NOI18N
316
public void storeSettings(Object settings) {
317
this.component.store (this.settings);
320
public void validate() throws WizardValidationException {
321
this.component.validate(this.settings);
324
public boolean isValid() {
325
return this.component.valid (this.settings);
328
public synchronized java.awt.Component getComponent() {
329
if (this.component == null) {
330
this.component = new PanelSourceFolders (this);
332
return this.component;
335
public HelpCtx getHelp() {
336
return new HelpCtx (PanelSourceFolders.class);
339
private void fireChangeEvent () {
340
changeSupport.fireChange();
343
public boolean isFinishPanel() {