From 9558140e0f2b3b73e3240be20a51fe5682775037 Mon Sep 17 00:00:00 2001 From: Nicola Isotta Date: Sun, 5 Apr 2026 11:15:08 +0200 Subject: [PATCH] modernize/upgrade "New JSF bean" wizard * added Faces 4 ClientWindowScoped (with warning if project uses JSF 3.0 or older) * disabled "Add data to configuration file" check for Faces 4+ projects * moved some logic from switch/maps to enum fields * small refactor/modernization of the code --- .../web/jsf/wizards/ManagedBeanIterator.java | 135 +++++++----------- .../web/jsf/wizards/ManagedBeanPanel.java | 22 ++- .../jsf/wizards/ManagedBeanPanelVisual.form | 6 + .../jsf/wizards/ManagedBeanPanelVisual.java | 56 +++++--- 4 files changed, 104 insertions(+), 115 deletions(-) diff --git a/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanIterator.java b/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanIterator.java index d4019ede5de6..0e8bb7a0a1ea 100644 --- a/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanIterator.java +++ b/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanIterator.java @@ -78,21 +78,6 @@ public class ManagedBeanIterator implements TemplateWizard.Iterator { FACES_SCOPE.put(ManagedBean.Scope.VIEW, "ViewScoped"); // NOI18N } - /** - * List of ContextDependencyInjection scopes. - */ - private static final Map NAMED_SCOPE = new EnumMap<>(NamedScope.class); - static { - NAMED_SCOPE.put(NamedScope.DEPENDENT, "Dependent"); //NOI18N - NAMED_SCOPE.put(NamedScope.APPLICATION, "ApplicationScoped"); //NOI18N - NAMED_SCOPE.put(NamedScope.REQUEST, "RequestScoped"); //NOI18N - NAMED_SCOPE.put(NamedScope.SESSION, "SessionScoped"); //NOI18N - NAMED_SCOPE.put(NamedScope.CONVERSATION, "ConversationScoped"); //NOI18N - NAMED_SCOPE.put(NamedScope.FLOW, "FlowScoped"); //NOI18N - NAMED_SCOPE.put(NamedScope.VIEW, "ViewScoped"); //NOI18N - - } - @Override public void initialize(TemplateWizard wizard) { index = 0; @@ -101,18 +86,15 @@ public void initialize(TemplateWizard wizard) { SourceGroup[] sourceGroups = ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); managedBeanPanel = new ManagedBeanPanel(project, wizard); - WizardDescriptor.Panel javaPanel; + WizardDescriptor.Panel javaPanel; if (sourceGroups.length == 0) { wizard.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, NbBundle.getMessage(ManagedBeanIterator.class, "MSG_No_Sources_found")); javaPanel = managedBeanPanel; } else { javaPanel = JavaTemplates.createPackageChooser(project, sourceGroups, managedBeanPanel); - javaPanel.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - managedBeanPanel.updateManagedBeanName((WizardDescriptor.Panel) e.getSource()); - } + javaPanel.addChangeListener((ChangeEvent e) -> { + managedBeanPanel.updateManagedBeanName((WizardDescriptor.Panel) e.getSource()); }); } panels = new WizardDescriptor.Panel[]{javaPanel}; @@ -120,8 +102,8 @@ public void stateChanged(ChangeEvent e) { // Creating steps. Object prop = wizard.getProperty(WizardDescriptor.PROP_CONTENT_DATA); // NOI18N String[] beforeSteps = null; - if (prop instanceof String[]) { - beforeSteps = (String[]) prop; + if (prop instanceof String[] strings) { + beforeSteps = strings; } String[] steps = createSteps(beforeSteps, panels); for (int i = 0; i < panels.length; i++) { @@ -140,7 +122,7 @@ public void uninitialize(TemplateWizard wizard) { } @Override - public Set instantiate(TemplateWizard wizard) throws IOException { + public Set instantiate(TemplateWizard wizard) throws IOException { FileObject dir = Templates.getTargetFolder(wizard); DataFolder df = DataFolder.findFolder(dir); FileObject template = Templates.getTemplate(wizard); @@ -162,16 +144,10 @@ public Set instantiate(TemplateWizard wizard) throws IOException { DataObject dobj = null; if (isAnnotate && (Utilities.isJavaEE6Plus(wizard) || (JSFUtils.isJSF20Plus(wm, true) && JSFUtils.isJavaEE5(wizard)))) { - Map templateProperties = new HashMap(); + Map templateProperties = new HashMap<>(); String targetName = Templates.getTargetName(wizard); - boolean jakartaJsfPackages; - if(JSFUtils.isJakartaEE9Plus(wizard)) { - templateProperties.put("jakartaJsfPackages", true); - jakartaJsfPackages = true; - } else { - templateProperties.put("jakartaJsfPackages", false); - jakartaJsfPackages = false; - } + boolean jakartaJsfPackages = JSFUtils.isJakartaEE9Plus(wizard); + templateProperties.put("jakartaJsfPackages", jakartaJsfPackages); org.netbeans.modules.web.beans.CdiUtil cdiUtil = project.getLookup().lookup(org.netbeans.modules.web.beans.CdiUtil.class); boolean isCdiEnabled = cdiUtil != null && cdiUtil.isCdiEnabled(); if (isCdiEnabled) { @@ -179,14 +155,8 @@ public Set instantiate(TemplateWizard wizard) throws IOException { templateProperties.put("classAnnotation", "@Named(value=\"" + beanName + "\")"); //NOI18N templateProperties.put("scope", ScopeEntry.getFor(scope, jakartaJsfPackages)); //NOI18N NamedScope namedScope = (NamedScope) scope; - switch (namedScope) { - case SESSION: - case CONVERSATION: - case VIEW: - templateProperties.put("passivationCapable", "true"); //NOI18N - break; - default: - break; + if (namedScope.isPassivationCapable()) { + templateProperties.put("passivationCapable", "true"); //NOI18N } } else { if (targetName.equalsIgnoreCase(beanName) && targetName.substring(0, 1).equalsIgnoreCase(beanName.substring(0, 1))) { @@ -220,8 +190,8 @@ public Set instantiate(TemplateWizard wizard) throws IOException { } else { packageName = ""; } - String className = null; - if (packageName.length() > 0) { + String className; + if (!packageName.isEmpty()) { className = packageName + "." + targetName; //NOI18N } else { className = targetName; @@ -243,11 +213,8 @@ public Set instantiate(TemplateWizard wizard) throws IOException { bean.addDescription(beanDescription); } - JSFConfigModelUtilities.doInTransaction(configModel, new Runnable() { - @Override - public void run() { - facesConfig.addManagedBean(bean); - } + JSFConfigModelUtilities.doInTransaction(configModel, () -> { + facesConfig.addManagedBean(bean); }); JSFConfigModelUtilities.saveChanges(configModel); } @@ -329,23 +296,44 @@ private String getUniqueName(String original, Project project) { } protected enum NamedScope { - DEPENDENT("dependent"), //NOI18N - APPLICATION("application"), //NOI18N - REQUEST("request"), //NOI18N - SESSION("session"), //NOI18N - CONVERSATION("conversation"), //NOI18N - FLOW("flow"), //NOI18N - VIEW("view"); //NOI18N - - private String scope; - - NamedScope(String scope) { - this.scope = scope; + DEPENDENT("Dependent", false), //NOI18N + APPLICATION("ApplicationScoped", false), //NOI18N + REQUEST("RequestScoped", false), //NOI18N + SESSION("SessionScoped", true), //NOI18N + CONVERSATION("ConversationScoped", true), //NOI18N + FLOW("FlowScoped", false, "faces.flow"), //NOI18N + VIEW("ViewScoped", true, "faces.view"), //NOI18N + CLIENT_WINDOW("ClientWindowScoped", true, "faces.lifecycle"); //NOI18N + + private final String simpleName; + private final boolean passivationCapable; + private final String subpackage; + + private NamedScope(String simpleName, boolean passivationCapable) { + this(simpleName, passivationCapable, "enterprise.context"); + } + + private NamedScope(String simpleName, boolean passivationCapable, String subpackage) { + this.simpleName = simpleName; + this.passivationCapable = passivationCapable; + this.subpackage = subpackage; } @Override public String toString() { - return scope; + return name().toLowerCase(); + } + + public String getSimpleName() { + return simpleName; + } + + public boolean isPassivationCapable() { + return passivationCapable; + } + + public String getSubpackage() { + return subpackage; } } @@ -373,12 +361,11 @@ public String getParameters() { } private static ScopeEntry getFor(Object scope, boolean jakartaJsfPackages) { - if (scope instanceof Scope) { - Scope typedScope = (Scope) scope; + if (scope instanceof Scope typedScope) { return new ScopeEntry(FACES_SCOPE.get(typedScope), getScopeImport(typedScope, jakartaJsfPackages)); } else { NamedScope typedScope = (NamedScope) scope; - ScopeEntry se = new ScopeEntry(NAMED_SCOPE.get(typedScope), getScopeImport(typedScope, jakartaJsfPackages)); + ScopeEntry se = new ScopeEntry(typedScope.getSimpleName(), getScopeImport(typedScope, jakartaJsfPackages)); if (typedScope == NamedScope.FLOW) { se.parameters = "\"\""; //NOI18N } @@ -395,24 +382,8 @@ private static String getScopeImport(Scope scope, boolean jakartaJsfPackages) { } private static String getScopeImport(NamedScope scope, boolean jakartaJsfPackages) { - String scopeSimpleName = NAMED_SCOPE.get(scope); - if (jakartaJsfPackages) { - if (scope == NamedScope.FLOW) { - return "jakarta.faces.flow." + scopeSimpleName; //NOI18N - } else if (scope == NamedScope.VIEW) { - return "jakarta.faces.view." + scopeSimpleName; //NOI18N - } else { - return "jakarta.enterprise.context." + scopeSimpleName; //NOI18N - } - } else { - if (scope == NamedScope.FLOW) { - return "javax.faces.flow." + scopeSimpleName; //NOI18N - } else if (scope == NamedScope.VIEW) { - return "javax.faces.view." + scopeSimpleName; //NOI18N - } else { - return "javax.enterprise.context." + scopeSimpleName; //NOI18N - } - } + return jakartaJsfPackages ? "jakarta." : "javax." + + scope.getSubpackage() + "." + scope.getSimpleName(); } } } diff --git a/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanel.java b/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanel.java index 138ce6c82549..7f52237ce6cc 100644 --- a/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanel.java +++ b/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanel.java @@ -28,7 +28,6 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.netbeans.api.project.Project; -import org.netbeans.modules.j2ee.common.ProjectUtil; import org.netbeans.modules.j2ee.common.ServerUtil; import org.openide.WizardDescriptor; @@ -40,7 +39,7 @@ * Panel asking for web frameworks to use. * @author Radko Najman */ -final class ManagedBeanPanel implements WizardDescriptor.Panel, WizardDescriptor.FinishablePanel, ChangeListener { +final class ManagedBeanPanel implements WizardDescriptor.FinishablePanel, ChangeListener { private TemplateWizard wizard; private ManagedBeanPanelVisual component; @@ -81,7 +80,7 @@ public void updateManagedBeanName(WizardDescriptor.Panel panel) { return; } - if ((targetName == null) || targetName.trim().equals("")) { + if ((targetName == null) || targetName.trim().isEmpty()) { return; } @@ -140,21 +139,21 @@ public final void removeChangeListener(ChangeListener l) { } } protected final void fireChangeEvent() { - Iterator it; + Iterator it; synchronized (listeners) { - it = new HashSet(listeners).iterator(); + it = new HashSet<>(listeners).iterator(); } ChangeEvent ev = new ChangeEvent(this); while (it.hasNext()) { - ((ChangeListener)it.next()).stateChanged(ev); + it.next().stateChanged(ev); } } @Override - public void readSettings(Object settings) { + public void readSettings(WizardDescriptor settings) { wizard = (TemplateWizard) settings; component.read(wizard); - + // XXX hack, TemplateWizard in final setTemplateImpl() forces new wizard's title // this name is used in NewProjectWizard to modify the title Object substitute = ((JComponent) component).getClientProperty("NewProjectWizard_Title"); // NOI18N @@ -163,11 +162,10 @@ public void readSettings(Object settings) { } @Override - public void storeSettings(Object settings) { - WizardDescriptor d = (WizardDescriptor) settings; - component.store(d); + public void storeSettings(WizardDescriptor settings) { + component.store(settings); - ((WizardDescriptor) d).putProperty("NewProjectWizard_Title", null); // NOI18N + settings.putProperty("NewProjectWizard_Title", null); // NOI18N } @Override diff --git a/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanelVisual.form b/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanelVisual.form index 418692745e00..b55f1a9021e7 100644 --- a/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanelVisual.form +++ b/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanelVisual.form @@ -117,6 +117,9 @@ + + + @@ -157,6 +160,9 @@ + + + diff --git a/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanelVisual.java b/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanelVisual.java index 8713a39f8fd3..7dc4077b302f 100644 --- a/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanelVisual.java +++ b/enterprise/web.jsf/src/org/netbeans/modules/web/jsf/wizards/ManagedBeanPanelVisual.java @@ -18,11 +18,14 @@ */ package org.netbeans.modules.web.jsf.wizards; + import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.swing.DefaultComboBoxModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -55,8 +58,10 @@ @SuppressWarnings("serial") // not used to be serialized public class ManagedBeanPanelVisual extends javax.swing.JPanel implements HelpCtx.Provider { - private final DefaultComboBoxModel scopeModel = new DefaultComboBoxModel(); + private final DefaultComboBoxModel scopeModel = new DefaultComboBoxModel<>(); private boolean isCDIEnabled = false; + private JsfVersion jsfVersion = null; + /** * Creates new form PropertiesPanelVisual */ @@ -68,17 +73,15 @@ public ManagedBeanPanelVisual(Project proj) { WebModule wm = WebModule.getWebModule(proj.getProjectDirectory()); Profile profile = null; if (wm != null){ + jsfVersion = JsfVersionUtils.forWebModule(wm); String[] configFiles = JSFConfigUtilities.getConfigFiles(wm); if (configFiles.length > 0){ FileObject documentBase = wm.getDocumentBase(); - ArrayList files = new ArrayList(); - for (int i = 0; i < configFiles.length; i++){ - if (documentBase.getFileObject(configFiles[i]) != null) - files.add(configFiles[i]); - } - configFiles = (String[])files.toArray(new String[0]); + configFiles = Stream.of(configFiles) + .filter(configFile -> documentBase.getFileObject(configFile) != null) + .toArray(String[]::new); } - jComboBoxConfigFile.setModel(new javax.swing.DefaultComboBoxModel(configFiles)); + jComboBoxConfigFile.setModel(new DefaultComboBoxModel<>(configFiles)); //No config files found if (configFiles.length==0) { addToConfigCheckBox.setEnabled(false); @@ -90,6 +93,9 @@ public ManagedBeanPanelVisual(Project proj) { addToConfigCheckBox.setSelected(true); setVisibleBeanDescription(true); addToConfigCheckBox.setEnabled(false); + } else if (jsfVersion != null && jsfVersion.isAtLeast(JsfVersion.JSF_4_0)) { + addToConfigCheckBox.setEnabled(false); + jComboBoxConfigFile.setEnabled(false); } } } @@ -140,11 +146,11 @@ private void updateScopeModel(boolean addToConfig) { private void initComponents() { jLabelConfigFile = new javax.swing.JLabel(); - jComboBoxConfigFile = new javax.swing.JComboBox(); + jComboBoxConfigFile = new javax.swing.JComboBox<>(); jLabelName = new javax.swing.JLabel(); jTextFieldName = new javax.swing.JTextField(); jLabelScope = new javax.swing.JLabel(); - jComboBoxScope = new javax.swing.JComboBox(); + jComboBoxScope = new javax.swing.JComboBox<>(); jLabelDesc = new javax.swing.JLabel(); jScrollPaneDesc = new javax.swing.JScrollPane(); jTextAreaDesc = new javax.swing.JTextArea(); @@ -247,8 +253,8 @@ private void addToConfigCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox addToConfigCheckBox; - private javax.swing.JComboBox jComboBoxConfigFile; - private javax.swing.JComboBox jComboBoxScope; + private javax.swing.JComboBox jComboBoxConfigFile; + private javax.swing.JComboBox jComboBoxScope; private javax.swing.JLabel jLabelConfigFile; private javax.swing.JLabel jLabelDesc; private javax.swing.JLabel jLabelName; @@ -259,7 +265,8 @@ private void addToConfigCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) { // End of variables declaration//GEN-END:variables @Messages({ - "ManagedBeanPanelVisual.warn.flowScoped.low.version=FlowScoped bean can be used only in projects with JSF2.2+" + "ManagedBeanPanelVisual.warn.flowScoped.low.version=FlowScoped bean can be used only in projects with JSF2.2+", + "ManagedBeanPanelVisual.warn.clientWindowScoped.low.version=ClientWindowScoped can be used only in projects with Faces 4.0+" }) boolean valid(WizardDescriptor wizardDescriptor) { String configFile = (String) jComboBoxConfigFile.getSelectedItem(); @@ -276,7 +283,7 @@ boolean valid(WizardDescriptor wizardDescriptor) { if (configFile == null) { if (!Utilities.isJavaEE6Plus((TemplateWizard) wizardDescriptor) && !isAddBeanToConfig() - && !(JSFUtils.isJavaEE5((TemplateWizard) wizardDescriptor) && JSFUtils.isJSF20Plus(wm, true))) { + && !(JSFUtils.isJavaEE5((TemplateWizard) wizardDescriptor) && jsfVersion != null && jsfVersion.isAtLeast(JsfVersion.JSF_2_0))) { wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, NbBundle.getMessage(ManagedBeanPanelVisual.class, "MSG_NoConfigFile")); //NOI18N return false; @@ -294,19 +301,26 @@ boolean valid(WizardDescriptor wizardDescriptor) { } String name = jTextFieldName.getText(); - if (name.trim().equals("")) { // NOI18N + if (name.isBlank()) { // NOI18N wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, NbBundle.getMessage(ManagedBeanPanelVisual.class, "MSG_InvalidBeanName")); //NOI18N return false; } Object scope = jComboBoxScope.getSelectedItem(); - if (scope instanceof NamedScope && scope == NamedScope.FLOW) { - JsfVersion jsfVersion = JsfVersionUtils.forWebModule(wm); - if (jsfVersion != null && !jsfVersion.isAtLeast(JsfVersion.JSF_2_2)) { - wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, - Bundle.ManagedBeanPanelVisual_warn_flowScoped_low_version()); - return false; + if (scope instanceof NamedScope namedScope) { + if (namedScope == NamedScope.FLOW) { + if (jsfVersion != null && !jsfVersion.isAtLeast(JsfVersion.JSF_2_2)) { + wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, + Bundle.ManagedBeanPanelVisual_warn_flowScoped_low_version()); + return false; + } + } else if (namedScope == NamedScope.CLIENT_WINDOW) { + if (jsfVersion != null && !jsfVersion.isAtLeast(JsfVersion.JSF_4_0)) { + wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, + Bundle.ManagedBeanPanelVisual_warn_clientWindowScoped_low_version()); + return false; + } } }