blob: 0a46d09cbd11cd602b21cf3e6bfa1f0b8c9dd02f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.netbeans.modules.maven.newproject;
import java.awt.EventQueue;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;
import javax.swing.text.Document;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.netbeans.api.options.OptionsDisplayer;
import org.netbeans.api.progress.aggregate.AggregateProgressHandle;
import org.netbeans.api.progress.aggregate.BasicAggregateProgressFactory;
import org.netbeans.api.progress.aggregate.ProgressContributor;
import org.netbeans.modules.maven.api.MavenValidators;
import org.netbeans.modules.maven.api.archetype.Archetype;
import org.netbeans.modules.maven.embedder.exec.ProgressTransferListener;
import org.netbeans.modules.maven.indexer.api.RepositoryIndexer;
import org.netbeans.modules.maven.indexer.api.RepositoryPreferences;
import static org.netbeans.modules.maven.newproject.Bundle.*;
import org.netbeans.modules.maven.options.MavenOptionController;
import org.netbeans.modules.maven.options.MavenSettings;
import org.netbeans.modules.options.java.api.JavaOptions;
import org.netbeans.spi.project.ui.support.CommonProjectActions;
import org.netbeans.spi.project.ui.support.ProjectChooser;
import org.netbeans.validation.api.AbstractValidator;
import org.netbeans.validation.api.Problems;
import org.netbeans.validation.api.ValidatorUtils;
import org.netbeans.validation.api.builtin.stringvalidation.StringValidators;
import org.netbeans.validation.api.ui.ValidationGroup;
import org.netbeans.validation.api.ui.ValidationListener;
import org.netbeans.validation.api.ui.ValidationUI;
import org.netbeans.validation.api.ui.swing.SwingValidationGroup;
import org.openide.WizardDescriptor;
import org.openide.awt.Mnemonics;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataFolder;
import org.openide.loaders.TemplateWizard;
import org.openide.util.NbBundle.Messages;
import org.openide.util.RequestProcessor;
import org.openide.util.Utilities;
/**
*
* @author mkleint
*/
public class BasicPanelVisual extends JPanel implements DocumentListener, WindowFocusListener, Runnable {
public static final String PROP_PROJECT_NAME = "projectName"; //NOI18N
private static final String ERROR_MSG = "WizardPanel_errorMessage"; //NOI18N
private static final ArtifactVersion BORDER_VERSION = new DefaultArtifactVersion("2.0.7"); //NOI18N
private boolean askedForVersion;
private ArtifactVersion mavenVersion;
private static final Object MAVEN_VERSION_LOCK = new Object();
private BasicWizardPanel panel;
private final Archetype arch;
private final ValidationGroup vg;
private boolean changedPackage = false;
private AggregateProgressHandle handle;
private final Object HANDLE_LOCK = new Object();
private static final RequestProcessor RPgetver = new RequestProcessor("BasicPanelVisual-getCommandLineMavenVersion"); //NOI18N
private static final RequestProcessor RPprep = new RequestProcessor("BasicPanelVisual-prepareAdditionalProperties", 5); //NOI18N
private Archetype currentArchetype;
/** Creates new form PanelProjectLocationVisual */
@SuppressWarnings("unchecked")
@Messages({
"VAL_projectLocationTextField=Project Location",
"VAL_projectNameTextField=Project Name",
"VAL_ArtifactId=ArtifactId",
"VAL_Version=Version",
"VAL_GroupId=GroupId",
"VAL_Package=Package",
"ERR_Project_Folder_cannot_be_created=Project Folder cannot be created.",
"ERR_Project_Folder_is_not_valid_path=Project Folder is not a valid path.",
"ERR_Project_Folder_is_UNC=Project Folder cannot be located on UNC path.",
"ERR_Package_ends_in_dot=Package name can not end in '.'.",
"# {0} - version", "ERR_old_maven=Maven {0} is too old, version 2.0.7 or newer is needed.",
"ERR_Project_Folder_exists=Project Folder already exists and is not empty.",
"ERR_Project_Folder_not_directory=Project Folder is not a directory."
})
BasicPanelVisual(BasicWizardPanel panel, Archetype arch) {
this.panel = panel;
this.arch = arch;
initComponents();
SwingValidationGroup.setComponentName(projectLocationTextField, VAL_projectLocationTextField());
SwingValidationGroup.setComponentName(projectNameTextField, VAL_projectNameTextField());
SwingValidationGroup.setComponentName(txtArtifactId, VAL_ArtifactId());
SwingValidationGroup.setComponentName(txtVersion, VAL_Version());
SwingValidationGroup.setComponentName(txtGroupId, VAL_GroupId());
SwingValidationGroup.setComponentName(txtPackage, VAL_Package());
// Register listener on the textFields to make the automatic updates
projectNameTextField.getDocument().addDocumentListener(this);
projectLocationTextField.getDocument().addDocumentListener(this);
txtArtifactId.getDocument().addDocumentListener(this);
txtGroupId.getDocument().addDocumentListener(this);
txtVersion.getDocument().addDocumentListener(this);
txtPackage.getDocument().addDocumentListener(this);
tblAdditionalProps.setVisible(false);
lblAdditionalProps.setVisible(false);
jScrollPane1.setVisible(false);
btnSetupNewer.setVisible(false);
getAccessibleContext().setAccessibleDescription(LBL_CreateProjectStep2());
txtGroupId.setText(MavenSettings.getDefault().getLastArchetypeGroupId());
txtVersion.setText(MavenSettings.getDefault().getLastArchetypeVersion());
vg = ValidationGroup.create();
runInAWT(new Runnable() {
@Override
public void run() {
vg.add(txtGroupId, MavenValidators.createGroupIdValidators());
vg.add(txtArtifactId, MavenValidators.createArtifactIdValidators());
vg.add(txtVersion, MavenValidators.createVersionValidators());
vg.add(txtPackage, ValidatorUtils.merge(
StringValidators.JAVA_PACKAGE_NAME,
new AbstractValidator<String>(String.class) {
@Override
public void validate(Problems problems, String compName, String model)
{
// MAY_NOT_END_WITH_PERIOD validator broken in NB's
// version (empty string); so copy current version' code.
if(model != null && !model.isEmpty() && model.charAt(model.length() - 1) == '.')
problems.add(ERR_Package_ends_in_dot());
}}));
vg.add(projectNameTextField, ValidatorUtils.merge(
MavenValidators.createArtifactIdValidators(),
StringValidators.REQUIRE_VALID_FILENAME
));
vg.add(projectLocationTextField,
// ValidatorUtils.merge(Validators.FILE_MUST_BE_DIRECTORY,
new AbstractValidator<String>(String.class) {
@Override public void validate(Problems problems, String compName, String model) {
File fil = FileUtil.normalizeFile(new File(model));
File projLoc = fil;
while (projLoc != null && !projLoc.exists()) {
projLoc = projLoc.getParentFile();
}
if (projLoc == null || !projLoc.canWrite()) {
problems.add(ERR_Project_Folder_cannot_be_created());
return;
}
if (FileUtil.toFileObject(projLoc) == null) {
problems.add(ERR_Project_Folder_is_not_valid_path());
return;
}
//#167136
if (Utilities.isWindows() && fil.getAbsolutePath().startsWith("\\\\")) {
problems.add(ERR_Project_Folder_is_UNC());
}
}
});
vg.addItem(new ValidationListener<Void>(Void.class, ValidationUI.NO_OP, null) {
@Override
protected void performValidation(Problems problems) {
boolean tooOld = isMavenTooOld();
btnSetupNewer.setVisible(tooOld);
if (tooOld) {
problems.add(ERR_old_maven(getCommandLineMavenVersion()));
return;
}
File destFolder = FileUtil.normalizeFile(new File(new File(projectLocationTextField.getText().trim()), projectNameTextField.getText().trim()).getAbsoluteFile());
if(destFolder.exists() && !destFolder.isDirectory()) {
problems.add(ERR_Project_Folder_not_directory());
return;
}
File[] kids = destFolder.listFiles();
if (destFolder.exists() && kids != null && kids.length > 0) {
// Folder exists and is not empty
problems.add(ERR_Project_Folder_exists());
}
}
}, true);
}
});
}
public String getProjectName() {
return this.projectNameTextField.getText();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
projectNameLabel = new javax.swing.JLabel();
projectNameTextField = new javax.swing.JTextField();
projectLocationLabel = new javax.swing.JLabel();
projectLocationTextField = new javax.swing.JTextField();
browseButton = new javax.swing.JButton();
createdFolderLabel = new javax.swing.JLabel();
createdFolderTextField = new javax.swing.JTextField();
lblArtifactId = new javax.swing.JLabel();
txtArtifactId = new javax.swing.JTextField();
lblGroupId = new javax.swing.JLabel();
txtGroupId = new javax.swing.JTextField();
lblVersion = new javax.swing.JLabel();
txtVersion = new javax.swing.JTextField();
lblPackage = new javax.swing.JLabel();
txtPackage = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
pnlAdditionals = new javax.swing.JPanel();
lblAdditionalProps = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane();
tblAdditionalProps = new javax.swing.JTable();
btnSetupNewer = new javax.swing.JButton();
projectNameLabel.setLabelFor(projectNameTextField);
org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "LBL_ProjectName")); // NOI18N
projectLocationLabel.setLabelFor(projectLocationTextField);
org.openide.awt.Mnemonics.setLocalizedText(projectLocationLabel, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "LBL_ProjectLocation")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BTN_Browse")); // NOI18N
browseButton.setActionCommand("BROWSE");
browseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
browseButtonActionPerformed(evt);
}
});
createdFolderLabel.setLabelFor(createdFolderTextField);
org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "LBL_ProjectFolder")); // NOI18N
createdFolderTextField.setEditable(false);
createdFolderTextField.setEnabled(false);
lblArtifactId.setLabelFor(txtArtifactId);
org.openide.awt.Mnemonics.setLocalizedText(lblArtifactId, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "LBL_ArtifactId")); // NOI18N
txtArtifactId.setEditable(false);
txtArtifactId.setEnabled(false);
lblGroupId.setLabelFor(txtGroupId);
org.openide.awt.Mnemonics.setLocalizedText(lblGroupId, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "LBL_GroupId")); // NOI18N
lblVersion.setLabelFor(txtVersion);
org.openide.awt.Mnemonics.setLocalizedText(lblVersion, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "LBL_Version")); // NOI18N
txtVersion.setText("1.0-SNAPSHOT");
lblPackage.setLabelFor(txtPackage);
org.openide.awt.Mnemonics.setLocalizedText(lblPackage, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "LBL_Package")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "LBL_Optional")); // NOI18N
lblAdditionalProps.setLabelFor(tblAdditionalProps);
org.openide.awt.Mnemonics.setLocalizedText(lblAdditionalProps, "<additional properties>"); // NOI18N
tblAdditionalProps.setModel(createPropModel());
tblAdditionalProps.setColumnSelectionAllowed(true);
jScrollPane1.setViewportView(tblAdditionalProps);
tblAdditionalProps.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
tblAdditionalProps.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.tblAdditionalProps.AccessibleContext.accessibleDescription")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(btnSetupNewer, org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BTN_SetupNewer.text")); // NOI18N
btnSetupNewer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnSetupNewerActionPerformed(evt);
}
});
javax.swing.GroupLayout pnlAdditionalsLayout = new javax.swing.GroupLayout(pnlAdditionals);
pnlAdditionals.setLayout(pnlAdditionalsLayout);
pnlAdditionalsLayout.setHorizontalGroup(
pnlAdditionalsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnlAdditionalsLayout.createSequentialGroup()
.addComponent(lblAdditionalProps)
.addContainerGap(379, Short.MAX_VALUE))
.addGroup(pnlAdditionalsLayout.createSequentialGroup()
.addComponent(btnSetupNewer)
.addContainerGap())
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 550, Short.MAX_VALUE)
);
pnlAdditionalsLayout.setVerticalGroup(
pnlAdditionalsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnlAdditionalsLayout.createSequentialGroup()
.addComponent(lblAdditionalProps)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnSetupNewer))
);
btnSetupNewer.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.btnSetupNewer.AccessibleContext.accessibleDescription")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(createdFolderLabel)
.addComponent(projectLocationLabel)
.addComponent(projectNameLabel)
.addComponent(lblPackage)
.addComponent(lblVersion)
.addComponent(lblGroupId)
.addComponent(lblArtifactId))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtArtifactId, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
.addComponent(txtGroupId, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
.addComponent(txtVersion, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
.addComponent(txtPackage, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
.addComponent(createdFolderTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
.addComponent(projectLocationTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
.addComponent(projectNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(browseButton, javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jLabel1)
.addContainerGap())))
.addGroup(layout.createSequentialGroup()
.addComponent(pnlAdditionals, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap(12, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(projectNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(projectNameLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(projectLocationTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(browseButton)
.addComponent(projectLocationLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(createdFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(createdFolderLabel))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtArtifactId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblArtifactId))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtGroupId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblGroupId))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtVersion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblVersion))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txtPackage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblPackage)
.addComponent(jLabel1))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnlAdditionals, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
projectNameTextField.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.projectNameTextField.AccessibleContext.accessibleDescription")); // NOI18N
projectLocationTextField.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.projectLocationTextField.AccessibleContext.accessibleDescription")); // NOI18N
browseButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.browseButton.AccessibleContext.accessibleDescription")); // NOI18N
createdFolderTextField.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.createdFolderTextField.AccessibleContext.accessibleDescription")); // NOI18N
txtArtifactId.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.txtArtifactId.AccessibleContext.accessibleDescription")); // NOI18N
txtGroupId.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.txtGroupId.AccessibleContext.accessibleDescription")); // NOI18N
txtVersion.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.txtVersion.AccessibleContext.accessibleDescription")); // NOI18N
txtPackage.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.txtPackage.AccessibleContext.accessibleDescription")); // NOI18N
jLabel1.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.jLabel1.AccessibleContext.accessibleDescription")); // NOI18N
getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BasicPanelVisual.class, "BasicPanelVisual.AccessibleContext.accessibleDescription")); // NOI18N
}// </editor-fold>//GEN-END:initComponents
@Messages("TIT_Select_Project_Location=Select Project Location")
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
String command = evt.getActionCommand();
if ("BROWSE".equals(command)) { //NOI18N
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(null);
chooser.setDialogTitle(TIT_Select_Project_Location());
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
String path = this.projectLocationTextField.getText();
if (path.length() > 0) {
File f = new File(path);
if (f.exists()) {
chooser.setSelectedFile(f);
}
}
if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this)) {
File projectDir = chooser.getSelectedFile();
projectLocationTextField.setText(FileUtil.normalizeFile(projectDir).getAbsolutePath());
}
panel.fireChangeEvent();
}
}//GEN-LAST:event_browseButtonActionPerformed
private void btnSetupNewerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSetupNewerActionPerformed
OptionsDisplayer.getDefault().open(JavaOptions.JAVA + "/" + MavenOptionController.OPTIONS_SUBPATH); //NOI18N
panel.getValidationGroup().performValidation();
}//GEN-LAST:event_btnSetupNewerActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton browseButton;
private javax.swing.JButton btnSetupNewer;
private javax.swing.JLabel createdFolderLabel;
private javax.swing.JTextField createdFolderTextField;
private javax.swing.JLabel jLabel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JLabel lblAdditionalProps;
private javax.swing.JLabel lblArtifactId;
private javax.swing.JLabel lblGroupId;
private javax.swing.JLabel lblPackage;
private javax.swing.JLabel lblVersion;
private javax.swing.JPanel pnlAdditionals;
private javax.swing.JLabel projectLocationLabel;
private javax.swing.JTextField projectLocationTextField;
private javax.swing.JLabel projectNameLabel;
private javax.swing.JTextField projectNameTextField;
private javax.swing.JTable tblAdditionalProps;
private javax.swing.JTextField txtArtifactId;
private javax.swing.JTextField txtGroupId;
private javax.swing.JTextField txtPackage;
private javax.swing.JTextField txtVersion;
// End of variables declaration//GEN-END:variables
@Override
public void addNotify() {
super.addNotify();
//same problem as in 31086, initial focus on Cancel button
projectNameTextField.requestFocus();
tblAdditionalProps.setVisible(false);
lblAdditionalProps.setVisible(false);
jScrollPane1.setVisible(false);
// for maven version checking
SwingUtilities.getWindowAncestor(this).addWindowFocusListener(this);
}
@Messages("ERR_multibyte=Multibyte chars not permitted in project name or Maven coordinates.")
static boolean containsMultiByte (String text, WizardDescriptor wd) {
char[] textChars = text.toCharArray();
for (int i = 0; i < textChars.length; i++) {
if ((int)textChars[i] > 255) {
wd.putProperty(ERROR_MSG, ERR_multibyte());
return true;
}
}
return false;
}
private boolean isMavenTooOld () {
ArtifactVersion version = getCommandLineMavenVersion();
return version != null ? BORDER_VERSION.compareTo(version) > 0 : false;
}
private ArtifactVersion getCommandLineMavenVersion () {
synchronized (MAVEN_VERSION_LOCK) {
if (!askedForVersion) {
askedForVersion = true;
// obtain version asynchronously, as it takes some time
RPgetver.post(this);
}
return mavenVersion;
}
}
void store(WizardDescriptor d) {
synchronized (HANDLE_LOCK) {
if (handle != null) {
handle.finish();
handle = null;
}
}
String name = projectNameTextField.getText().trim();
String folder = createdFolderTextField.getText().trim();
final File projectFolder = new File(folder);
// PROJECT_PARENT_FOLDER confusing, better name is PROJECT_BASE_FOLDER
d.putProperty(CommonProjectActions.PROJECT_PARENT_FOLDER, projectFolder);
if (d instanceof TemplateWizard) {
((TemplateWizard) d).setTargetFolderLazy(() -> {
projectFolder.mkdirs();
return DataFolder.findFolder(FileUtil.toFileObject(projectFolder));
});
}
d.putProperty("name", name); //NOI18N
if (d instanceof TemplateWizard) {
((TemplateWizard) d).setTargetName(name);
}
d.putProperty("artifactId", txtArtifactId.getText().trim()); //NOI18N
d.putProperty("groupId", txtGroupId.getText().trim()); //NOI18N
MavenSettings.getDefault().setLastArchetypeGroupId(txtGroupId.getText().trim());
d.putProperty("version", txtVersion.getText().trim()); //NOI18N
MavenSettings.getDefault().setLastArchetypeVersion(txtVersion.getText().trim());
d.putProperty("package", txtPackage.getText().trim()); //NOI18N
if (tblAdditionalProps.isVisible()) {
if (tblAdditionalProps.isEditing()) {
TableCellEditor edito = tblAdditionalProps.getCellEditor();
if (edito != null) {
edito.stopCellEditing();
}
}
TableModel mdl = tblAdditionalProps.getModel();
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < mdl.getRowCount(); i++) {
map.put((String)mdl.getValueAt(i, 0), (String)mdl.getValueAt(i, 1));
}
d.putProperty(ArchetypeWizardUtils.ADDITIONAL_PROPS, map);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
panel.getValidationGroup().remove(vg);
}
});
}
private static final String SETTINGS_HAVE_READ = "BasicPanelVisual-read-properties-before"; //NOI18N
@Messages({
"# {0} - project count", "TXT_MavenProjectName=mavenproject{0}",
"TXT_Checking1=Checking additional creation properties..."
})
void read(WizardDescriptor settings, Map<String,String> defaultProps) {
synchronized (HANDLE_LOCK) {
if (handle != null) {
handle.finish();
handle = null;
}
}
// PROJECT_PARENT_FOLDER usage is confusing. Sometimes it's the
// parent directory, sometimes it's the project directory.
// Maybe introduce PROJECT_BASE_FOLDER, to clarify and differentiate.
// But for local fix [NETBEANS-4206] keep track of whether
// these properties have been read before.
boolean haveRead = Boolean.parseBoolean((String)settings.getProperty(SETTINGS_HAVE_READ)); //NOI18N
File projectFolder = (File) settings.getProperty(CommonProjectActions.PROJECT_PARENT_FOLDER); //NOI18N
File projectLocation;
if(!haveRead && projectFolder != null) {
// First time in here, dialog was started with project folder;
// example is creating a project from pom parent
projectLocation = projectFolder;
} else {
if (projectFolder == null || projectFolder.getParentFile() == null || !projectFolder.getParentFile().isDirectory()) {
projectLocation = ProjectChooser.getProjectsFolder();
} else {
projectLocation = projectFolder.getParentFile();
}
}
if(!haveRead) {
settings.putProperty(SETTINGS_HAVE_READ, "true"); //NOI18N
}
this.projectLocationTextField.setText(projectLocation.getAbsolutePath());
String projectName = (String) settings.getProperty("name"); //NOI18N
if(projectName == null) {
int baseCount = 1;
while ((projectName = validFreeProjectName(projectLocation, TXT_MavenProjectName(baseCount))) == null) {
baseCount++;
}
}
String gr = (String) settings.getProperty("groupId");
if (gr != null) {
txtGroupId.setText(gr);
}
String ver = (String) settings.getProperty("version");
if (ver != null) {
txtVersion.setText(ver);
}
this.projectNameTextField.setText(projectName);
this.projectNameTextField.selectAll();
// skip additional properties if direct known archetypes without additional props used
if (panel.areAdditional()) {
final Archetype archet = getArchetype(settings);
this.currentArchetype = archet;
lblAdditionalProps.setText(TXT_Checking1());
lblAdditionalProps.setVisible(true);
tblAdditionalProps.setVisible(false);
jScrollPane1.setVisible(false);
RPprep.post(new Runnable() {
@Override
public void run() {
prepareAdditionalProperties(archet, defaultProps);
}
});
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
panel.getValidationGroup().addItem(vg, true);
}
});
}
@Messages({
"COL_Key=Key",
"COL_Value=Value",
"TXT_Checking2=A&dditional Creation Properties:"
})
private void prepareAdditionalProperties(Archetype arch, Map<String, String> defaultProps) {
final DefaultTableModel dtm = new DefaultTableModel();
dtm.addColumn(COL_Key());
dtm.addColumn(COL_Value());
try {
Artifact art = downloadArchetype(arch);
File fil = art.getFile();
if (fil.exists()) {
Map<String, String> props = arch.loadRequiredProperties();
for (Map.Entry<String, String> entry : props.entrySet()) {
String key = entry.getKey();
String defVal = entry.getValue();
if ("groupId".equals(key) || "artifactId".equals(key) || "version".equals(key)) {
continue; //don't show the basic props as additionals..
}
if (defaultProps != null && defaultProps.containsKey(key)) {
defVal = defaultProps.get(key);
}
if (defVal == null) {
defVal = "";
}
dtm.addRow(new Object[] {key, defVal });
}
}
} catch (ArtifactResolutionException ex) {
//#143026
Logger.getLogger( BasicPanelVisual.class.getName()).log( Level.FINE, "Cannot download archetype", ex);
} catch (ArtifactNotFoundException ex) {
//#143026
Logger.getLogger( BasicPanelVisual.class.getName()).log( Level.FINE, "Cannot download archetype", ex);
}
if (arch != currentArchetype || !this.isVisible()) {
//prevent old runnables from overwriting the ui.
return;
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (dtm.getRowCount() > 0) {
Mnemonics.setLocalizedText(lblAdditionalProps, TXT_Checking2());
lblAdditionalProps.setVisible(true);
jScrollPane1.setVisible(true);
tblAdditionalProps.setModel(dtm);
tblAdditionalProps.setVisible(true);
} else {
tblAdditionalProps.setVisible(false);
lblAdditionalProps.setVisible(false);
jScrollPane1.setVisible(false);
}
}
});
}
private Archetype getArchetype (WizardDescriptor settings) {
if (arch != null) {
return arch;
}
return (Archetype) settings.getProperty(MavenWizardIterator.PROP_ARCHETYPE);
}
@Messages("Handle_Download=Downloading Archetype")
private Artifact downloadArchetype(Archetype arch) throws ArtifactResolutionException, ArtifactNotFoundException {
AggregateProgressHandle hndl = BasicAggregateProgressFactory.createHandle(Handle_Download(),
new ProgressContributor[] {
BasicAggregateProgressFactory.createProgressContributor("zaloha") }, //NOI18N
ProgressTransferListener.cancellable(), null);
synchronized (HANDLE_LOCK) {
handle = hndl;
}
try {
arch.resolveArtifacts(hndl);
} finally {
synchronized (HANDLE_LOCK) {//prevent store()/read() methods to call finish - issue 236251
if (hndl == handle) {
handle = null;
}
}
}
//#154913
RepositoryIndexer.updateIndexWithArtifacts(RepositoryPreferences.getInstance().getLocalRepository(), Collections.singletonList(arch.getArtifact()));
return arch.getArtifact();
}
private TableModel createPropModel() {
return new DefaultTableModel();
}
// Implementation of DocumentListener --------------------------------------
@Override
public void changedUpdate(DocumentEvent e) {
updateTexts(e);
if (this.projectNameTextField.getDocument() == e.getDocument()) {
firePropertyChange(PROP_PROJECT_NAME,null,this.projectNameTextField.getText());
}
}
@Override
public void insertUpdate(DocumentEvent e) {
updateTexts(e);
if (this.projectNameTextField.getDocument() == e.getDocument()) {
firePropertyChange(PROP_PROJECT_NAME,null,this.projectNameTextField.getText());
}
}
@Override
public void removeUpdate(DocumentEvent e) {
updateTexts(e);
if (this.projectNameTextField.getDocument() == e.getDocument()) {
firePropertyChange(PROP_PROJECT_NAME,null,this.projectNameTextField.getText());
}
}
/** Handles changes in the Project name and project directory, */
private void updateTexts(DocumentEvent e) {
Document doc = e.getDocument();
if (doc == projectNameTextField.getDocument() || doc == projectLocationTextField.getDocument()) {
// Change in the project name
String projectName = projectNameTextField.getText();
String projectFolder = projectLocationTextField.getText();
//if (projectFolder.trim().length() == 0 || projectFolder.equals(oldName)) {
createdFolderTextField.setText(projectFolder + File.separatorChar + projectName);
//}
}
if (projectNameTextField.getDocument() == doc) {
String projName = projectNameTextField.getText().trim();
txtArtifactId.setText(projName.replace(" ", ""));
}
if (!changedPackage && (projectNameTextField.getDocument() == doc || txtGroupId.getDocument() == doc)) {
txtPackage.getDocument().removeDocumentListener(this);
txtPackage.setText(getPackageName(txtGroupId.getText() + "." + txtArtifactId.getText().replace("-", "."))); //NOI18N
txtPackage.getDocument().addDocumentListener(this);
}
if (txtPackage.getDocument() == doc) {
changedPackage = txtPackage.getText().trim().length() != 0;
}
if (vg != null) {
vg.performValidation(); // Notify that the panel changed
}
}
private String validFreeProjectName(File parentFolder, String name) {
File file = new File (parentFolder, name);
return file.exists() ? null : name;
}
static String getPackageName (String displayName) {
StringBuilder builder = new StringBuilder ();
boolean firstLetter = true;
for (int i=0; i< displayName.length(); i++) {
char c = displayName.charAt(i);
if ((!firstLetter && Character.isJavaIdentifierPart (c))
|| (firstLetter && Character.isJavaIdentifierStart(c))) {
firstLetter = false;
if (Character.isUpperCase(c)) {
c = Character.toLowerCase(c);
}
builder.append(c);
continue;
}
if (!firstLetter && c == '.') {
firstLetter = true;
builder.append(c);
continue;
}
}
String toRet = builder.length() == 0 ? "pkg" : builder.toString(); //NOI18N
return toRet;
}
/*** Implementation of WindowFocusListener ***/
@Override
public void windowGainedFocus(WindowEvent e) {
// trigger re-check of maven version
askedForVersion = false;
getCommandLineMavenVersion();
}
@Override
public void windowLostFocus(WindowEvent e) {
}
/*** Implementation of Runnable, checks Maven version ***/
@Override
public void run() {
if (!EventQueue.isDispatchThread()) {
// phase one, outside EQ thread
String version = MavenSettings.getCommandLineMavenVersion();
mavenVersion = version != null ? new DefaultArtifactVersion(version.trim()) : null;
// trigger revalidation -> phase two
SwingUtilities.invokeLater(this);
} else {
// phase two, inside EQ thread
vg.performValidation();
}
}
private void runInAWT(Runnable runnable) {
if (!EventQueue.isDispatchThread()) {
EventQueue.invokeLater(runnable);
} else {
runnable.run();
}
}
}