This is an automated email from the ASF dual-hosted git repository. dbalek pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push: new 44de9726dd Allow for creating Micronaut Controllers based on Data Repository interfaces. new f6083fc341 Merge pull request #6702 from dbalek/dbalek/micronaut-controllers-from-repositories 44de9726dd is described below commit 44de9726ddae5112921821b046b003e285766bd8 Author: Dusan Balek <dusan.ba...@oracle.com> AuthorDate: Wed Nov 15 14:25:30 2023 +0100 Allow for creating Micronaut Controllers based on Data Repository interfaces. --- .../modules/micronaut/db/Bundle.properties | 24 ++- ...ClassesPanel.form => ClassesSelectorPanel.form} | 63 +++--- ...ClassesPanel.java => ClassesSelectorPanel.java} | 223 ++++++++++++--------- .../modules/micronaut/db/MicronautController.java | 196 +++++++++++++++--- .../modules/micronaut/db/MicronautRepository.java | 21 +- .../modules/micronaut/resources/Controller.html | 4 +- 6 files changed, 354 insertions(+), 177 deletions(-) diff --git a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/Bundle.properties b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/Bundle.properties index 9363d7ff68..3fe100ed34 100644 --- a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/Bundle.properties +++ b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/Bundle.properties @@ -16,7 +16,7 @@ # under the License. Templates/Micronaut=Micronaut -Templates/Micronaut/Controller=Micronaut Controller Class +Templates/Micronaut/Controller=Micronaut Controller Classes (from Data Repositories) Templates/Micronaut/Entity=Micronaut Data Entity Classes from Database Templates/Micronaut/Repository=Micronaut Data Repository Interfaces from Entities @@ -30,19 +30,33 @@ MSG_PK_Class=Primary Key class {0} for entity class {1}\n USG_PERSISTENCE_ENTITY_DB_CREATED={0} entity classes was generated from db -LBL_EntityClasses=Entity Classes +LBL_Entities=Entity Classes LBL_AvailableEntities=Available &Entity Classes: TXT_AvailableEntities=Available Entity Classes ACSN_AvailableEntities=Available entity classes ACSD_AvailableEntities=List of all available entity classes LBL_SelectedEntities=S&elected Entity Classes: TXT_SelectedEntities=Selected Entity Classes +ACSN_SelectedEntities=Selected entity classes +ACSD_SelectedEntities=List of selected entity classes + +LBL_Repositories=Repository Interfaces +LBL_AvailableRepositories=Available Repository &Interfaces: +TXT_AvailableRepositories=Available Repository Interfaces +ACSN_AvailableRepositories=Available repository interfaces +ACSD_AvailableRepositories=List of all available repository interfaces +LBL_SelectedRepositories=S&elected Repository Interfaces: +TXT_SelectedRepositories=Selected Repository Interfaces +ACSN_SelectedRepositories=Selected repository interfaces +ACSD_SelectedRepositories=List of selected repository interfaces + LBL_AddAll=Add A&ll >> LBL_Add=&Add > LBL_Remove=< &Remove LBL_RemoveAll=<< Re&move All -ACSN_SelectedEntities=Selected entity classes -ACSD_SelectedEntities=List of selected entity classes + ERR_SelectEntities=Select at least one entity class # {0} = project name -ERR_NoEntities=No entity class found in {0} \ No newline at end of file +ERR_NoEntities=No entity class found in {0} +# {0} = project name +ERR_NoRepositories=No repository interface found in {0} \ No newline at end of file diff --git a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/EntityClassesPanel.form b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/ClassesSelectorPanel.form similarity index 80% rename from enterprise/micronaut/src/org/netbeans/modules/micronaut/db/EntityClassesPanel.form rename to enterprise/micronaut/src/org/netbeans/modules/micronaut/db/ClassesSelectorPanel.form index 0a3bcbb9cf..7ce55b6e3c 100644 --- a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/EntityClassesPanel.form +++ b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/ClassesSelectorPanel.form @@ -26,8 +26,8 @@ <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Dimension value="[200, 300]"/> </Property> - <Property name="name" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/netbeans/modules/micronaut/db/Bundle.properties" key="LBL_EntityClasses" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Property name="name" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_" + bundleKey)" type="code"/> </Property> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Dimension value="[496, 350]"/> @@ -48,33 +48,28 @@ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> <SubComponents> - <Container class="javax.swing.JPanel" name="entitiesPanel"> - <Properties> - <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> - <Dimension value="[440, 174]"/> - </Property> - </Properties> + <Container class="javax.swing.JPanel" name="classesPanel"> <AuxValues> - <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new EntitiesPanel();"/> + <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new ClassesPanel();"/> </AuxValues> <Constraints> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="80" insetsTop="6" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="2.0"/> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="80" insetsTop="6" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/> </Constraint> </Constraints> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/> <SubComponents> - <Component class="javax.swing.JLabel" name="availableEntitiesLabel"> + <Component class="javax.swing.JLabel" name="availableLabel"> <Properties> <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> - <ComponentRef name="availableEntitiesList"/> + <ComponentRef name="availableList"/> </Property> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/netbeans/modules/micronaut/db/Bundle.properties" key="LBL_AvailableEntities" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Available" + bundleKey)" type="code"/> </Property> - <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/netbeans/modules/micronaut/db/Bundle.properties" key="TXT_AvailableEntities" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Available" + bundleKey)" type="code"/> </Property> </Properties> <Constraints> @@ -83,7 +78,7 @@ </Constraint> </Constraints> </Component> - <Container class="javax.swing.JScrollPane" name="availableEntitiesScrollPane"> + <Container class="javax.swing.JScrollPane" name="availableScrollPane"> <Properties> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Dimension value="[160, 130]"/> @@ -100,18 +95,18 @@ <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <SubComponents> - <Component class="javax.swing.JList" name="availableEntitiesList"> + <Component class="javax.swing.JList" name="availableList"> <Properties> <Property name="nextFocusableComponent" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> <ComponentRef name="addButton"/> </Property> </Properties> <AccessibilityProperties> - <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/netbeans/modules/micronaut/db/Bundle.properties" key="ACSN_AvailableEntities" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "ACSN_Available" + bundleKey)" type="code"/> </Property> - <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/netbeans/modules/micronaut/db/Bundle.properties" key="ACSD_AvailableEntities" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "ACSD_Available" + bundleKey)" type="code"/> </Property> </AccessibilityProperties> <AuxValues> @@ -120,16 +115,16 @@ </Component> </SubComponents> </Container> - <Component class="javax.swing.JLabel" name="selectedEntitiesLabel"> + <Component class="javax.swing.JLabel" name="selectedLabel"> <Properties> <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor"> - <ComponentRef name="selectedEntitiesList"/> + <ComponentRef name="selectedList"/> </Property> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/netbeans/modules/micronaut/db/Bundle.properties" key="LBL_SelectedEntities" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Selected" + bundleKey)" type="code"/> </Property> - <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/netbeans/modules/micronaut/db/Bundle.properties" key="TXT_SelectedEntities" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Selected" + bundleKey)" type="code"/> </Property> </Properties> <Constraints> @@ -138,7 +133,7 @@ </Constraint> </Constraints> </Component> - <Container class="javax.swing.JScrollPane" name="selectedEntitiesScrollPane"> + <Container class="javax.swing.JScrollPane" name="selectedScrollPane"> <Properties> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Dimension value="[160, 130]"/> @@ -155,13 +150,13 @@ <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <SubComponents> - <Component class="javax.swing.JList" name="selectedEntitiesList"> + <Component class="javax.swing.JList" name="selectedList"> <AccessibilityProperties> - <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/netbeans/modules/micronaut/db/Bundle.properties" key="ACSN_SelectedEntities" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "ACSN_Selected" + bundleKey)" type="code"/> </Property> - <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="org/netbeans/modules/micronaut/db/Bundle.properties" key="ACSD_SelectedEntities" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "ACSD_Selected" + bundleKey)" type="code"/> </Property> </AccessibilityProperties> <AuxValues> diff --git a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/EntityClassesPanel.java b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/ClassesSelectorPanel.java similarity index 58% rename from enterprise/micronaut/src/org/netbeans/modules/micronaut/db/EntityClassesPanel.java rename to enterprise/micronaut/src/org/netbeans/modules/micronaut/db/ClassesSelectorPanel.java index ef4515ea98..215c76451a 100644 --- a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/EntityClassesPanel.java +++ b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/ClassesSelectorPanel.java @@ -22,9 +22,11 @@ package org.netbeans.modules.micronaut.db; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Rectangle; +import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; @@ -42,13 +44,18 @@ import org.openide.util.NbBundle; * * @author Dusan Balek */ -public class EntityClassesPanel extends javax.swing.JPanel { +public class ClassesSelectorPanel extends javax.swing.JPanel { + + static final String PROP_CLASSES = "wizard-classes"; //NOI18N + static final String PROP_SELECTED_CLASSES = "wizard-selected-classes"; //NOI18N private final ChangeSupport changeSupport = new ChangeSupport(this); - private final Set<String> availableEntities = new HashSet<>(); - private final Set<String> selectedEntities = new HashSet<>(); + private final Set<String> available = new HashSet<>(); + private final Set<String> selected = new HashSet<>(); + private final String bundleKey; - public EntityClassesPanel() { + public ClassesSelectorPanel(String key) { + bundleKey = key; initComponents(); ListSelectionListener selectionListener = new ListSelectionListener() { @Override @@ -56,8 +63,8 @@ public class EntityClassesPanel extends javax.swing.JPanel { updateButtons(); } }; - availableEntitiesList.getSelectionModel().addListSelectionListener(selectionListener); - selectedEntitiesList.getSelectionModel().addListSelectionListener(selectionListener); + availableList.getSelectionModel().addListSelectionListener(selectionListener); + selectedList.getSelectionModel().addListSelectionListener(selectionListener); } public void addChangeListener(ChangeListener listener) { @@ -65,21 +72,29 @@ public class EntityClassesPanel extends javax.swing.JPanel { } public void initialize(Set<String> entities) { - availableEntities.addAll(entities); - availableEntitiesList.setListData(availableEntities.toArray(new String[availableEntities.size()])); - selectedEntitiesList.setListData(selectedEntities.toArray(new String[selectedEntities.size()])); + available.addAll(entities.stream().map(fqn -> { + int idx = fqn.lastIndexOf('.'); + return idx < 0 ? fqn : fqn.substring(idx + 1) + " (" + fqn.substring(0, idx) + ')'; + }).collect(Collectors.toSet())); + String[] availableArray = available.toArray(new String[0]); + Arrays.sort(availableArray); + availableList.setListData(availableArray); + selectedList.setListData(selected.toArray(new String[0])); updateButtons(); } - public Set<String> getSelectedEntities() { - return selectedEntities; + public Set<String> getSelectedClasses() { + return selected.stream().map(item -> { + int idx = item.indexOf(" ("); + return idx < 0 ? item : item.substring(idx + 2, item.length() - 1) + '.' + item.substring(0, idx); + }).collect(Collectors.toSet()); } private void updateButtons() { - addButton.setEnabled(availableEntitiesList.getSelectedIndices().length > 0); - addAllButton.setEnabled(!availableEntities.isEmpty()); - removeButton.setEnabled(selectedEntitiesList.getSelectedIndices().length > 0); - removeAllButton.setEnabled(!selectedEntities.isEmpty()); + addButton.setEnabled(availableList.getSelectedIndices().length > 0); + addAllButton.setEnabled(!available.isEmpty()); + removeButton.setEnabled(selectedList.getSelectedIndices().length > 0); + removeAllButton.setEnabled(!selected.isEmpty()); } /** This method is called from within the constructor to @@ -91,13 +106,13 @@ public class EntityClassesPanel extends javax.swing.JPanel { private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; - entitiesPanel = new EntitiesPanel(); - availableEntitiesLabel = new javax.swing.JLabel(); - availableEntitiesScrollPane = new javax.swing.JScrollPane(); - availableEntitiesList = new javax.swing.JList<>(); - selectedEntitiesLabel = new javax.swing.JLabel(); - selectedEntitiesScrollPane = new javax.swing.JScrollPane(); - selectedEntitiesList = new javax.swing.JList<>(); + classesPanel = new ClassesPanel(); + availableLabel = new javax.swing.JLabel(); + availableScrollPane = new javax.swing.JScrollPane(); + availableList = new javax.swing.JList<>(); + selectedLabel = new javax.swing.JLabel(); + selectedScrollPane = new javax.swing.JScrollPane(); + selectedList = new javax.swing.JList<>(); buttonPanel = new javax.swing.JPanel(); addButton = new javax.swing.JButton(); removeButton = new javax.swing.JButton(); @@ -105,27 +120,26 @@ public class EntityClassesPanel extends javax.swing.JPanel { removeAllButton = new javax.swing.JButton(); setMinimumSize(new java.awt.Dimension(200, 300)); - setName(org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "LBL_EntityClasses")); // NOI18N + setName(org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_" + bundleKey)); setPreferredSize(new java.awt.Dimension(496, 350)); setLayout(new java.awt.GridBagLayout()); - entitiesPanel.setPreferredSize(new java.awt.Dimension(440, 174)); - entitiesPanel.setLayout(new java.awt.GridBagLayout()); + classesPanel.setLayout(new java.awt.GridBagLayout()); - availableEntitiesLabel.setLabelFor(availableEntitiesList); - org.openide.awt.Mnemonics.setLocalizedText(availableEntitiesLabel, org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "LBL_AvailableEntities")); // NOI18N - availableEntitiesLabel.setToolTipText(org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "TXT_AvailableEntities")); // NOI18N + availableLabel.setLabelFor(availableList); + org.openide.awt.Mnemonics.setLocalizedText(availableLabel, org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Available" + bundleKey)); + availableLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Available" + bundleKey)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0); - entitiesPanel.add(availableEntitiesLabel, gridBagConstraints); + classesPanel.add(availableLabel, gridBagConstraints); - availableEntitiesScrollPane.setPreferredSize(new java.awt.Dimension(160, 130)); + availableScrollPane.setPreferredSize(new java.awt.Dimension(160, 130)); - availableEntitiesList.setNextFocusableComponent(addButton); - availableEntitiesScrollPane.setViewportView(availableEntitiesList); - availableEntitiesList.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "ACSN_AvailableEntities")); // NOI18N - availableEntitiesList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "ACSD_AvailableEntities")); // NOI18N + availableList.setNextFocusableComponent(addButton); + availableScrollPane.setViewportView(availableList); + availableList.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "ACSN_Available" + bundleKey)); + availableList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "ACSD_Available" + bundleKey)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; @@ -134,22 +148,22 @@ public class EntityClassesPanel extends javax.swing.JPanel { gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; - entitiesPanel.add(availableEntitiesScrollPane, gridBagConstraints); + classesPanel.add(availableScrollPane, gridBagConstraints); - selectedEntitiesLabel.setLabelFor(selectedEntitiesList); - org.openide.awt.Mnemonics.setLocalizedText(selectedEntitiesLabel, org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "LBL_SelectedEntities")); // NOI18N - selectedEntitiesLabel.setToolTipText(org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "TXT_SelectedEntities")); // NOI18N + selectedLabel.setLabelFor(selectedList); + org.openide.awt.Mnemonics.setLocalizedText(selectedLabel, org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Selected" + bundleKey)); + selectedLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Selected" + bundleKey)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0); - entitiesPanel.add(selectedEntitiesLabel, gridBagConstraints); + classesPanel.add(selectedLabel, gridBagConstraints); - selectedEntitiesScrollPane.setPreferredSize(new java.awt.Dimension(160, 130)); - selectedEntitiesScrollPane.setViewportView(selectedEntitiesList); - selectedEntitiesList.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "ACSN_SelectedEntities")); // NOI18N - selectedEntitiesList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "ACSD_SelectedEntities")); // NOI18N + selectedScrollPane.setPreferredSize(new java.awt.Dimension(160, 130)); + selectedScrollPane.setViewportView(selectedList); + selectedList.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "ACSN_Selected" + bundleKey)); + selectedList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "ACSD_Selected" + bundleKey)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; @@ -158,11 +172,11 @@ public class EntityClassesPanel extends javax.swing.JPanel { gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; - entitiesPanel.add(selectedEntitiesScrollPane, gridBagConstraints); + classesPanel.add(selectedScrollPane, gridBagConstraints); buttonPanel.setLayout(new java.awt.GridBagLayout()); - org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "LBL_Add")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Add")); // NOI18N addButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addButtonActionPerformed(evt); @@ -172,7 +186,7 @@ public class EntityClassesPanel extends javax.swing.JPanel { gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; buttonPanel.add(addButton, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(removeButton, org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "LBL_Remove")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(removeButton, org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_Remove")); // NOI18N removeButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { removeButtonActionPerformed(evt); @@ -185,7 +199,7 @@ public class EntityClassesPanel extends javax.swing.JPanel { gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0); buttonPanel.add(removeButton, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(addAllButton, org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "LBL_AddAll")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(addAllButton, org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_AddAll")); // NOI18N addAllButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addAllButtonActionPerformed(evt); @@ -198,7 +212,7 @@ public class EntityClassesPanel extends javax.swing.JPanel { gridBagConstraints.insets = new java.awt.Insets(17, 0, 0, 0); buttonPanel.add(addAllButton, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(removeAllButton, org.openide.util.NbBundle.getMessage(EntityClassesPanel.class, "LBL_RemoveAll")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(removeAllButton, org.openide.util.NbBundle.getMessage(ClassesSelectorPanel.class, "LBL_RemoveAll")); // NOI18N removeAllButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { removeAllButtonActionPerformed(evt); @@ -217,51 +231,52 @@ public class EntityClassesPanel extends javax.swing.JPanel { gridBagConstraints.gridheight = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.insets = new java.awt.Insets(0, 11, 0, 11); - entitiesPanel.add(buttonPanel, gridBagConstraints); + classesPanel.add(buttonPanel, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 1; + gridBagConstraints.gridy = 0; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.ipady = 80; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.weighty = 2.0; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 0); - add(entitiesPanel, gridBagConstraints); + add(classesPanel, gridBagConstraints); }// </editor-fold>//GEN-END:initComponents private void removeAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeAllButtonActionPerformed - availableEntities.addAll(selectedEntities); - selectedEntities.clear(); - availableEntitiesList.setListData(availableEntities.toArray(new String[availableEntities.size()])); - selectedEntitiesList.setListData(selectedEntities.toArray(new String[selectedEntities.size()])); + available.addAll(selected); + selected.clear(); + availableList.setListData(available.toArray(new String[available.size()])); + selectedList.setListData(selected.toArray(new String[selected.size()])); updateButtons(); changeSupport.fireChange(); }//GEN-LAST:event_removeAllButtonActionPerformed private void addAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addAllButtonActionPerformed - selectedEntities.addAll(availableEntities); - availableEntities.clear(); - availableEntitiesList.setListData(availableEntities.toArray(new String[availableEntities.size()])); - selectedEntitiesList.setListData(selectedEntities.toArray(new String[selectedEntities.size()])); + selected.addAll(available); + available.clear(); + availableList.setListData(available.toArray(new String[available.size()])); + selectedList.setListData(selected.toArray(new String[selected.size()])); updateButtons(); changeSupport.fireChange(); }//GEN-LAST:event_addAllButtonActionPerformed private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed - availableEntities.addAll(selectedEntitiesList.getSelectedValuesList()); - selectedEntities.removeAll(selectedEntitiesList.getSelectedValuesList()); - availableEntitiesList.setListData(availableEntities.toArray(new String[availableEntities.size()])); - selectedEntitiesList.setListData(selectedEntities.toArray(new String[selectedEntities.size()])); + available.addAll(selectedList.getSelectedValuesList()); + selected.removeAll(selectedList.getSelectedValuesList()); + availableList.setListData(available.toArray(new String[available.size()])); + selectedList.setListData(selected.toArray(new String[selected.size()])); updateButtons(); changeSupport.fireChange(); }//GEN-LAST:event_removeButtonActionPerformed private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed - selectedEntities.addAll(availableEntitiesList.getSelectedValuesList()); - availableEntities.removeAll(availableEntitiesList.getSelectedValuesList()); - availableEntitiesList.setListData(availableEntities.toArray(new String[availableEntities.size()])); - selectedEntitiesList.setListData(selectedEntities.toArray(new String[selectedEntities.size()])); + selected.addAll(availableList.getSelectedValuesList()); + available.removeAll(availableList.getSelectedValuesList()); + availableList.setListData(available.toArray(new String[available.size()])); + selectedList.setListData(selected.toArray(new String[selected.size()])); updateButtons(); changeSupport.fireChange(); }//GEN-LAST:event_addButtonActionPerformed @@ -270,26 +285,26 @@ public class EntityClassesPanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addAllButton; private javax.swing.JButton addButton; - private javax.swing.JLabel availableEntitiesLabel; - private javax.swing.JList<String> availableEntitiesList; - private javax.swing.JScrollPane availableEntitiesScrollPane; + private javax.swing.JLabel availableLabel; + private javax.swing.JList<String> availableList; + private javax.swing.JScrollPane availableScrollPane; private javax.swing.JPanel buttonPanel; - private javax.swing.JPanel entitiesPanel; + private javax.swing.JPanel classesPanel; private javax.swing.JButton removeAllButton; private javax.swing.JButton removeButton; - private javax.swing.JLabel selectedEntitiesLabel; - private javax.swing.JList<String> selectedEntitiesList; - private javax.swing.JScrollPane selectedEntitiesScrollPane; + private javax.swing.JLabel selectedLabel; + private javax.swing.JList<String> selectedList; + private javax.swing.JScrollPane selectedScrollPane; // End of variables declaration//GEN-END:variables - private final class EntitiesPanel extends JPanel { + private final class ClassesPanel extends JPanel { @Override public void doLayout() { super.doLayout(); - Rectangle availableBounds = availableEntitiesScrollPane.getBounds(); - Rectangle selectedBounds = selectedEntitiesScrollPane.getBounds(); + Rectangle availableBounds = availableScrollPane.getBounds(); + Rectangle selectedBounds = selectedScrollPane.getBounds(); if (Math.abs(availableBounds.width - selectedBounds.width) > 1) { GridBagConstraints buttonPanelConstraints = ((GridBagLayout)getLayout()).getConstraints(buttonPanel); @@ -298,40 +313,44 @@ public class EntityClassesPanel extends javax.swing.JPanel { int xOffset = equalWidth - availableBounds.width; availableBounds.width = equalWidth; - availableEntitiesScrollPane.setBounds(availableBounds); + availableScrollPane.setBounds(availableBounds); Rectangle buttonBounds = buttonPanel.getBounds(); buttonBounds.x += xOffset; buttonPanel.setBounds(buttonBounds); - Rectangle labelBounds = selectedEntitiesLabel.getBounds(); + Rectangle labelBounds = selectedLabel.getBounds(); labelBounds.x += xOffset; - selectedEntitiesLabel.setBounds(labelBounds); + selectedLabel.setBounds(labelBounds); selectedBounds.x += xOffset; selectedBounds.width = totalWidth - equalWidth; - selectedEntitiesScrollPane.setBounds(selectedBounds); + selectedScrollPane.setBounds(selectedBounds); } } } - public static final class WizardPanel implements WizardDescriptor.Panel<WizardDescriptor>, ChangeListener { + public static final class WizardPanel implements WizardDescriptor.FinishablePanel<WizardDescriptor>, ChangeListener { private final ChangeSupport changeSupport = new ChangeSupport(this); private final String title; - private EntityClassesPanel component; + private final String key; + private final Function<Set<String>, String> validator; + private ClassesSelectorPanel component; private boolean componentInitialized; private WizardDescriptor wizardDescriptor; - private Map<String, String> entities; + private Map<String, Object> classes; - public WizardPanel(String wizardTitle) { - title = wizardTitle; + public WizardPanel(String title, String key, Function<Set<String>, String> validator) { + this.title = title; + this.key = key; + this.validator = validator; } @Override - public EntityClassesPanel getComponent() { + public ClassesSelectorPanel getComponent() { if (component == null) { - component = new EntityClassesPanel(); + component = new ClassesSelectorPanel(key); component.addChangeListener(this); } return component; @@ -339,7 +358,7 @@ public class EntityClassesPanel extends javax.swing.JPanel { @Override public HelpCtx getHelp() { - return new HelpCtx(EntityClassesPanel.class); + return new HelpCtx(ClassesSelectorPanel.class); } @Override @@ -360,30 +379,36 @@ public class EntityClassesPanel extends javax.swing.JPanel { } if (!componentInitialized) { componentInitialized = true; - entities = (Map<String, String>) settings.getProperty(MicronautRepository.PROP_ENTITIES); - getComponent().initialize(entities.keySet()); + classes = (Map<String, Object>) settings.getProperty(PROP_CLASSES); + getComponent().initialize(classes.keySet()); } } @Override public boolean isValid() { - if (entities.isEmpty()) { - setErrorMessage(NbBundle.getMessage(EntityClassesPanel.class, "ERR_NoEntities", ProjectUtils.getInformation(Templates.getProject(wizardDescriptor)).getDisplayName())); + if (classes.isEmpty()) { + setErrorMessage(NbBundle.getMessage(ClassesSelectorPanel.class, "ERR_No" + key, ProjectUtils.getInformation(Templates.getProject(wizardDescriptor)).getDisplayName())); return false; } - if (getComponent().getSelectedEntities().isEmpty()) { - setErrorMessage(NbBundle.getMessage(EntityClassesPanel.class, "ERR_SelectEntities")); + String err = validator.apply(getComponent().getSelectedClasses()); + if (err != null) { + setErrorMessage(err); return false; } setErrorMessage(" "); // NOI18N return true; } + @Override + public boolean isFinishPanel() { + return !getComponent().getSelectedClasses().isEmpty(); + } + @Override public void storeSettings(WizardDescriptor settings) { - Set<String> selected = getComponent().getSelectedEntities(); - Map<String, String> selEntities = entities.entrySet().stream().filter(entry -> selected.contains(entry.getKey())).collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue())); - wizardDescriptor.putProperty(MicronautRepository.PROP_SELECTED_ENTITIES, selEntities); + Set<String> selected = getComponent().getSelectedClasses(); + Map<String, Object> selEntities = classes.entrySet().stream().filter(entry -> selected.contains(entry.getKey())).collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue())); + wizardDescriptor.putProperty(PROP_SELECTED_CLASSES, selEntities); } @Override diff --git a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/MicronautController.java b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/MicronautController.java index 80b2c25b3b..f8fb06ac09 100644 --- a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/MicronautController.java +++ b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/MicronautController.java @@ -29,21 +29,41 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.NoSuchElementException; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.ExecutableType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; import javax.swing.event.ChangeListener; import org.netbeans.api.java.project.JavaProjectConstants; +import org.netbeans.api.java.source.ClassIndex; +import org.netbeans.api.java.source.ClasspathInfo; +import org.netbeans.api.java.source.ElementHandle; import org.netbeans.api.java.source.JavaSource; import org.netbeans.api.java.source.TreeMaker; +import org.netbeans.api.project.FileOwnerQuery; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.SourceGroup; import org.netbeans.api.project.Sources; import org.netbeans.api.templates.CreateDescriptor; import org.netbeans.api.templates.CreateFromTemplateHandler; +import org.netbeans.modules.j2ee.core.api.support.SourceGroups; import org.netbeans.modules.j2ee.core.api.support.java.GenerationUtils; import org.netbeans.modules.j2ee.core.api.support.wizard.Wizards; import org.netbeans.spi.java.project.support.ui.templates.JavaTemplates; @@ -69,6 +89,8 @@ public class MicronautController implements TemplateWizard.Iterator { } @NbBundle.Messages({ + "MSG_SelectRepository=Select Data Repository Classes", + "MSG_SelectRepository_Prompt=Repositories to be called from Controllers", "MSG_SelectControllerName=Controller Name" }) public static CreateFromTemplateHandler handler() { @@ -81,13 +103,52 @@ public class MicronautController implements TemplateWizard.Iterator { @Override protected List<FileObject> createFromTemplate(CreateDescriptor desc) throws IOException { try { + final FileObject folder = desc.getTarget(); + final Project project = FileOwnerQuery.getOwner(folder); + if (project == null) { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(Bundle.MSG_NoProject(folder.getPath()), NotifyDescriptor.ERROR_MESSAGE)); + return Collections.emptyList(); + } + final SourceGroup sourceGroup = SourceGroups.getFolderSourceGroup(ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA), folder); + if (sourceGroup != null) { + Set<ElementHandle<TypeElement>> repositoryClasses = getRepositoryClasses(sourceGroup); + if (!repositoryClasses.isEmpty()) { + List<NotifyDescriptor.QuickPick.Item> items = repositoryClasses.stream().map(handle -> { + String fqn = handle.getQualifiedName(); + int idx = fqn.lastIndexOf('.'); + return idx < 0 ? new NotifyDescriptor.QuickPick.Item(fqn, null) : new NotifyDescriptor.QuickPick.Item(fqn.substring(idx + 1), fqn.substring(0, idx)); + }).collect(Collectors.toList()); + NotifyDescriptor.QuickPick qpt = new NotifyDescriptor.QuickPick(Bundle.MSG_SelectRepository(), Bundle.MSG_SelectRepository_Prompt(), items, true); + if (DialogDescriptor.OK_OPTION != DialogDisplayer.getDefault().notify(qpt)) { + return Collections.emptyList(); + } + List<FileObject> generated = new ArrayList<>(); + for (NotifyDescriptor.QuickPick.Item item : qpt.getItems()) { + if (item.isSelected()) { + String label = item.getLabel(); + if (label.toLowerCase().endsWith(("repository"))) { //NOI18N + label = label.substring(0, label.length() - 10); + } + FileObject fo = generate(folder, label, item.getDescription() != null ? item.getDescription() + '.' + item.getLabel() : item.getLabel()); + if (fo != null) { + generated.add(fo); + } + } + } + if (!generated.isEmpty()) { + return generated; + } + } + } NotifyDescriptor.InputLine inputLine = new NotifyDescriptor.InputLine(Bundle.MSG_SelectControllerName(), Bundle.MSG_SelectControllerName()); if (DialogDescriptor.OK_OPTION == DialogDisplayer.getDefault().notify(inputLine)) { List<FileObject> generated = new ArrayList<>(); String name = inputLine.getInputText(); if (!name.isEmpty()) { - String controllerName = name.substring(0, 1).toUpperCase() + name.substring(1) + "Controller"; // NOI18N - FileObject fo = generate(desc.getTarget(), controllerName); + if (name.toLowerCase().endsWith(("controller"))) { //NOI18N + name = name.substring(0, name.length() - 10); + } + FileObject fo = generate(desc.getTarget(), name, null); if (fo != null) { generated.add(fo); } @@ -102,20 +163,35 @@ public class MicronautController implements TemplateWizard.Iterator { }; } - private WizardDescriptor.Panel panel; + private WizardDescriptor.Panel[] panels; + private int index; private WizardDescriptor wizardDescriptor; + private FileObject targetFolder; @Override public Set<DataObject> instantiate(TemplateWizard wiz) throws IOException { Set<DataObject> generated = new HashSet<>(); - FileObject targetFolder = Templates.getTargetFolder(wiz); - String targetName = Templates.getTargetName(wiz); - if (targetFolder != null && targetName != null && !targetName.isEmpty()) { - FileObject fo = generate(targetFolder, targetName); + Map<String, ElementHandle<TypeElement>> selectedRepositories = (Map<String, ElementHandle<TypeElement>>) wiz.getProperty(ClassesSelectorPanel.PROP_SELECTED_CLASSES); + for (String fqn : selectedRepositories.keySet()) { + int idx = fqn.lastIndexOf('.'); + String label = idx < 0 ? fqn : fqn.substring(idx + 1); + if (label.toLowerCase().endsWith(("repository"))) { //NOI18N + label = label.substring(0, label.length() - 10); + } + FileObject fo = generate(targetFolder, label, fqn); if (fo != null) { generated.add(DataObject.find(fo)); } } + if (generated.isEmpty()) { + String targetName = Templates.getTargetName(wiz); + if (targetName != null && !targetName.isEmpty()) { + FileObject fo = generate(targetFolder, targetName, null); + if (fo != null) { + generated.add(DataObject.find(fo)); + } + } + } return generated; } @@ -123,18 +199,35 @@ public class MicronautController implements TemplateWizard.Iterator { public void initialize(TemplateWizard wiz) { wizardDescriptor = wiz; + targetFolder = Templates.getTargetFolder(wizardDescriptor); Project project = Templates.getProject(wizardDescriptor); Sources sources = ProjectUtils.getSources(project); SourceGroup[] sourceGroups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); if(sourceGroups.length == 0) { sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC); - panel = Templates.buildSimpleTargetChooser(project, sourceGroups).create(); + panels = new WizardDescriptor.Panel[] { + Templates.buildSimpleTargetChooser(project, sourceGroups).create() + }; } else { - panel = JavaTemplates.createPackageChooser(project, sourceGroups); + List<WizardDescriptor.Panel> p = new ArrayList<>(); + SourceGroup sourceGroup = SourceGroups.getFolderSourceGroup(sourceGroups, targetFolder); + if (sourceGroup != null) { + Set<ElementHandle<TypeElement>> repositoryClasses = getRepositoryClasses(sourceGroup); + if (!repositoryClasses.isEmpty()) { + Map<String, ElementHandle<TypeElement>> repositories = new HashMap<>(); + for (ElementHandle<TypeElement> handle : repositoryClasses) { + repositories.put(handle.getQualifiedName(), handle); + } + wiz.putProperty(ClassesSelectorPanel.PROP_CLASSES, repositories); + p.add(new ClassesSelectorPanel.WizardPanel(NbBundle.getMessage(MicronautController.class, "Templates/Micronaut/Controller"), "Repositories", s -> null)); //NOI18N + } + } + p.add(JavaTemplates.createPackageChooser(project, sourceGroups)); + panels = p.toArray(new WizardDescriptor.Panel[0]); } - Wizards.mergeSteps(wiz, new WizardDescriptor.Panel[] {panel}, null); + Wizards.mergeSteps(wiz, panels, null); } @Override @@ -143,7 +236,7 @@ public class MicronautController implements TemplateWizard.Iterator { @Override public WizardDescriptor.Panel<WizardDescriptor> current() { - return panel; + return panels[index]; } @Override @@ -153,22 +246,28 @@ public class MicronautController implements TemplateWizard.Iterator { @Override public boolean hasNext() { - return false; + return index < (panels.length - 1) && !(current() instanceof WizardDescriptor.FinishablePanel && ((WizardDescriptor.FinishablePanel) current()).isFinishPanel()); } @Override public boolean hasPrevious() { - return false; + return index > 0; } @Override public void nextPanel() { - throw new NoSuchElementException(); + if ((index + 1) == panels.length) { + throw new NoSuchElementException(); + } + index++; } @Override public void previousPanel() { - throw new NoSuchElementException(); + if (index == 0) { + throw new NoSuchElementException(); + } + index--; } @Override @@ -179,11 +278,27 @@ public class MicronautController implements TemplateWizard.Iterator { public void removeChangeListener(ChangeListener l) { } + private static Set<ElementHandle<TypeElement>> getRepositoryClasses(final SourceGroup sourceGroup) throws IllegalArgumentException { + ClasspathInfo cpInfo = ClasspathInfo.create(sourceGroup.getRootFolder()); + Set<ElementHandle<TypeElement>> repositoryClasses = new HashSet<>(); + LinkedList<ElementHandle<TypeElement>> bases = new LinkedList<>(); + bases.add(ElementHandle.createTypeElementHandle(ElementKind.INTERFACE, "io.micronaut.data.repository.CrudRepository")); //NOI18N + while (!bases.isEmpty()) { + ElementHandle<TypeElement> base = bases.removeFirst(); + bases.addAll(cpInfo.getClassIndex().getElements(base, EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS), EnumSet.of(ClassIndex.SearchScope.DEPENDENCIES))); + Set<ElementHandle<TypeElement>> srcElements = cpInfo.getClassIndex().getElements(base, EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS), EnumSet.of(ClassIndex.SearchScope.SOURCE)); + bases.addAll(srcElements); + repositoryClasses.addAll(srcElements); + } + return repositoryClasses; + } + @NbBundle.Messages({ "MSG_ControllerClass=Controller class {0}\n" }) - private static FileObject generate(FileObject folder, String controllerName) { + private static FileObject generate(FileObject folder, String name, String repositoryFQN) { try { + String controllerName = name.substring(0, 1).toUpperCase() + name.substring(1) + "Controller"; // NOI18N FileObject fo = GenerationUtils.createClass(folder, controllerName, Bundle.MSG_ControllerClass(controllerName)); if (fo != null) { JavaSource js = JavaSource.forFileObject(fo); @@ -194,16 +309,47 @@ public class MicronautController implements TemplateWizard.Iterator { if (origTree.getKind() == Tree.Kind.CLASS) { GenerationUtils gu = GenerationUtils.newInstance(copy); TreeMaker tm = copy.getTreeMaker(); - String name = controllerName.toLowerCase(); - if (name.endsWith("controller")) { - name = name.substring(0, name.length() - 10); - } List<ExpressionTree> annArgs = Collections.singletonList(gu.createAnnotationArgument(null, "/" + name.toLowerCase())); //NOI18N - ClassTree cls = gu.addAnnotation((ClassTree) origTree, gu.createAnnotation("io.micronaut.http.annotation.Controller", annArgs)); - List<ExpressionTree> getAnnArgs = Arrays.asList(gu.createAnnotationArgument("uri", "/"), gu.createAnnotationArgument("produces", "text/plain")); //NOI18N - ModifiersTree mods = tm.Modifiers(Collections.singleton(Modifier.PUBLIC), Collections.singletonList(gu.createAnnotation("io.micronaut.http.annotation.Get", getAnnArgs))); //NOI18N - MethodTree indexMethod = tm.Method(mods, "index", tm.QualIdent("java.lang.String"), Collections.<TypeParameterTree>emptyList(), Collections.<VariableTree>emptyList(), Collections.<ExpressionTree>emptyList(), "{return \"Example Response\";}", null); //NOI18N - cls = tm.addClassMember(cls, indexMethod); + ClassTree cls = gu.addAnnotation((ClassTree) origTree, gu.createAnnotation("io.micronaut.http.annotation.Controller", annArgs)); //NOI18N + if (repositoryFQN != null) { + String repositoryFieldName = name.substring(0, 1).toLowerCase() + name.substring(1) + "Repository"; //NOI18N + VariableTree repositoryField = tm.Variable(tm.Modifiers(EnumSet.of(Modifier.PRIVATE, Modifier.FINAL)), repositoryFieldName, tm.QualIdent(repositoryFQN), null); + cls = tm.addClassMember(cls, repositoryField); + VariableTree repositoryParam = tm.Variable(tm.Modifiers(Collections.emptySet()), repositoryFieldName, tm.QualIdent(repositoryFQN), null); + MethodTree ctor = tm.Constructor(tm.Modifiers(Collections.singleton(Modifier.PUBLIC)), Collections.<TypeParameterTree>emptyList(), Collections.singletonList(repositoryParam), Collections.<ExpressionTree>emptyList(), "{this." + repositoryFieldName + "=" + repositoryFieldName + ";}"); //NOI18N + cls = tm.addClassMember(cls, ctor); + TypeElement te = copy.getElements().getTypeElement(repositoryFQN); + if (te != null) { + ModifiersTree mods = tm.Modifiers(Collections.singleton(Modifier.PUBLIC), Collections.singletonList(gu.createAnnotation("io.micronaut.http.annotation.Get"))); //NOI18N + List<? extends ExecutableElement> findAllMethods = ElementFilter.methodsIn(copy.getElements().getAllMembers(te)).stream().filter(el -> "findAll".contentEquals(el.getSimpleName())).collect(Collectors.toList()); //NOI18N + Optional<? extends ExecutableElement> findAll = findAllMethods.stream().filter(el -> el.getParameters().isEmpty()).findAny(); + if (findAll.isPresent()) { + TypeMirror returnType = ((ExecutableType) copy.getTypes().asMemberOf((DeclaredType) te.asType(), findAll.get())).getReturnType(); + Optional<? extends ExecutableElement> findAllPageable = findAllMethods.stream().filter(el -> { + if (el.getParameters().size() != 1) { + return false; + } + TypeMirror paramType = el.getParameters().get(0).asType(); + return paramType.getKind() == TypeKind.DECLARED && "io.micronaut.data.model.Pageable".contentEquals(((TypeElement) ((DeclaredType) paramType).asElement()).getQualifiedName()); //NOI18N + }).findFirst(); + if (findAllPageable.isPresent()) { + ExecutableElement el = findAllPageable.get(); + ExecutableType type = (ExecutableType) copy.getTypes().asMemberOf((DeclaredType) te.asType(), el); + VariableTree param = tm.Variable(tm.Modifiers(0, Collections.singletonList(gu.createAnnotation("jakarta.validation.Valid"))), "pageable", tm.Type(type.getParameterTypes().get(0)), null); //NOI18N + MethodTree indexMethod = tm.Method(mods, "list", tm.Type(returnType), Collections.<TypeParameterTree>emptyList(), Collections.singletonList(param), Collections.<ExpressionTree>emptyList(), "{return " + repositoryFieldName + ".findAll(pageable).getContent();}", null); //NOI18N + cls = tm.addClassMember(cls, indexMethod); + } else { + MethodTree indexMethod = tm.Method(mods, "list", tm.Type(returnType), Collections.<TypeParameterTree>emptyList(), Collections.<VariableTree>emptyList(), Collections.<ExpressionTree>emptyList(), "{return " + repositoryFieldName + ".findAll();}", null); //NOI18N + cls = tm.addClassMember(cls, indexMethod); + } + } + } + } else { + List<ExpressionTree> getAnnArgs = Arrays.asList(gu.createAnnotationArgument("uri", "/"), gu.createAnnotationArgument("produces", "text/plain")); //NOI18N + ModifiersTree mods = tm.Modifiers(Collections.singleton(Modifier.PUBLIC), Collections.singletonList(gu.createAnnotation("io.micronaut.http.annotation.Get", getAnnArgs))); //NOI18N + MethodTree indexMethod = tm.Method(mods, "index", tm.QualIdent("java.lang.String"), Collections.<TypeParameterTree>emptyList(), Collections.<VariableTree>emptyList(), Collections.<ExpressionTree>emptyList(), "{return \"Example Response\";}", null); //NOI18N + cls = tm.addClassMember(cls, indexMethod); + } copy.rewrite(origTree, cls); } }).commit(); diff --git a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/MicronautRepository.java b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/MicronautRepository.java index 82999146bd..ebbed0d11b 100644 --- a/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/MicronautRepository.java +++ b/enterprise/micronaut/src/org/netbeans/modules/micronaut/db/MicronautRepository.java @@ -18,15 +18,10 @@ */ package org.netbeans.modules.micronaut.db; -import com.sun.source.tree.BlockTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.ExpressionTree; -import com.sun.source.tree.MethodTree; -import com.sun.source.tree.ModifiersTree; import com.sun.source.tree.ParameterizedTypeTree; import com.sun.source.tree.Tree; -import com.sun.source.tree.TypeParameterTree; -import com.sun.source.tree.VariableTree; import com.sun.source.util.TreePath; import java.io.IOException; import java.sql.Connection; @@ -176,8 +171,6 @@ public class MicronautRepository implements TemplateWizard.Iterator { }; } - static final String PROP_ENTITIES = "wizard-entities"; //NOI18N - static final String PROP_SELECTED_ENTITIES = "wizard-selected-entities"; //NOI18N private WizardDescriptor.Panel panel; private WizardDescriptor wizardDescriptor; private FileObject targetFolder; @@ -187,7 +180,7 @@ public class MicronautRepository implements TemplateWizard.Iterator { public Set<DataObject> instantiate(TemplateWizard wiz) throws IOException { String dialect = getDialect(jpaSupported); Set<DataObject> generated = new HashSet<>(); - Map<String, String> selectedEntities = (Map<String, String>) wiz.getProperty(PROP_SELECTED_ENTITIES); + Map<String, String> selectedEntities = (Map<String, String>) wiz.getProperty(ClassesSelectorPanel.PROP_SELECTED_CLASSES); for (Map.Entry<String, String> entry : selectedEntities.entrySet()) { String fqn = entry.getKey(); int idx = fqn.lastIndexOf('.'); @@ -204,11 +197,13 @@ public class MicronautRepository implements TemplateWizard.Iterator { public void initialize(TemplateWizard wiz) { wizardDescriptor = wiz; - panel = new EntityClassesPanel.WizardPanel(NbBundle.getMessage(MicronautRepository.class, "Templates/Micronaut/Repository")); + panel = new ClassesSelectorPanel.WizardPanel(NbBundle.getMessage(MicronautRepository.class, "Templates/Micronaut/Repository"), "Entities", selectedEntities -> { + return selectedEntities.isEmpty() ? NbBundle.getMessage(MicronautRepository.class, "ERR_SelectEntities") : null; + }); Wizards.mergeSteps(wizardDescriptor, new WizardDescriptor.Panel[] { panel }, new String[] { - NbBundle.getMessage(MicronautRepository.class, "LBL_EntityClasses") + NbBundle.getMessage(MicronautRepository.class, "LBL_Entities") }); targetFolder = Templates.getTargetFolder(wizardDescriptor); @@ -216,8 +211,8 @@ public class MicronautRepository implements TemplateWizard.Iterator { SourceGroup sourceGroup = SourceGroups.getFolderSourceGroup(ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA), targetFolder); if (sourceGroup != null) { jpaSupported = Utils.isJPASupported(sourceGroup); - Map<String, String> entities = MicronautRepository.getEntityClasses(sourceGroup, jpaSupported); - wiz.putProperty(PROP_ENTITIES, entities); + Map<String, String> entities = getEntityClasses(sourceGroup, jpaSupported); + wiz.putProperty(ClassesSelectorPanel.PROP_CLASSES, entities); } } @@ -263,7 +258,7 @@ public class MicronautRepository implements TemplateWizard.Iterator { public void removeChangeListener(ChangeListener l) { } - static Map<String, String> getEntityClasses(SourceGroup sg, boolean jpaSupported) { + private static Map<String, String> getEntityClasses(SourceGroup sg, boolean jpaSupported) { final Map<String, String> entities = new HashMap<>(); JavaSource js = JavaSource.create(ClasspathInfo.create(sg.getRootFolder())); if (js != null) { diff --git a/enterprise/micronaut/src/org/netbeans/modules/micronaut/resources/Controller.html b/enterprise/micronaut/src/org/netbeans/modules/micronaut/resources/Controller.html index 71db5d378c..07df97765d 100644 --- a/enterprise/micronaut/src/org/netbeans/modules/micronaut/resources/Controller.html +++ b/enterprise/micronaut/src/org/netbeans/modules/micronaut/resources/Controller.html @@ -24,5 +24,7 @@ <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <BODY> -Creates a Micronaut Controller class with a default GET endpoint. +Creates Micronaut Controller classes with default GET endpoints based on +existing data repository interfaces or plain. This template creates a controller +class for each selected repository interface. </BODY></HTML> --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists