From ca8b6a639773a35cbfe59118e044aa1784e01af5 Mon Sep 17 00:00:00 2001 From: Alexander Shkurko Date: Wed, 27 May 2020 16:07:02 +0300 Subject: [PATCH] Admin menu index --- resources/META-INF/plugin.xml | 2 + resources/magento2/common.properties | 4 + .../actions/generation/NewMenuItemAction.java | 56 ++++++++ .../generation/dialog/NewMenuItemDialog.form | 128 ++++++++++++++++++ .../generation/dialog/NewMenuItemDialog.java | 116 ++++++++++++++++ .../validator/NewMenuItemValidator.java | 54 ++++++++ .../indexes/AdminMenuIndex.java | 54 ++++++++ .../magento2plugin/indexes/IndexManager.java | 26 ++-- .../magento/files/AdminMenuItems.java | 14 ++ .../stubs/indexes/AdminMenuIndexer.java | 112 +++++++++++++++ 10 files changed, 555 insertions(+), 11 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/NewMenuItemAction.java create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMenuItemDialog.form create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMenuItemDialog.java create mode 100644 src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/NewMenuItemValidator.java create mode 100644 src/com/magento/idea/magento2plugin/indexes/AdminMenuIndex.java create mode 100644 src/com/magento/idea/magento2plugin/magento/files/AdminMenuItems.java create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/AdminMenuIndexer.java diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index 65043f747..962946718 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -62,6 +62,7 @@ + @@ -94,6 +95,7 @@ + diff --git a/resources/magento2/common.properties b/resources/magento2/common.properties index 53526f9a6..3ee248406 100644 --- a/resources/magento2/common.properties +++ b/resources/magento2/common.properties @@ -39,3 +39,7 @@ common.cli.generate.error=New CLI Command Generation Error common.cli.class.title=CLI Command Class common.validationErrorTitle=Validation Error common.defaultConsoleDirectory=Console +common.create.new.menu.item.title=Create a new Magento 2 menu item +common.title=Title +common.action=Action +common.resource=Resource diff --git a/src/com/magento/idea/magento2plugin/actions/generation/NewMenuItemAction.java b/src/com/magento/idea/magento2plugin/actions/generation/NewMenuItemAction.java new file mode 100644 index 000000000..417ec7ced --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/NewMenuItemAction.java @@ -0,0 +1,56 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation; + +import com.intellij.ide.IdeView; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.magento.idea.magento2plugin.MagentoIcons; +import com.magento.idea.magento2plugin.actions.generation.dialog.NewMenuItemDialog; + +@SuppressWarnings({"PMD.FieldNamingConventions"}) +public class NewMenuItemAction extends AnAction { + public static String ACTION_NAME = "Magento 2 Menu Item"; + public static String ACTION_DESCRIPTION = "Create a new Magento 2 Menu Item"; + + public NewMenuItemAction() { + super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE); + } + + @Override + public void actionPerformed( + @org.jetbrains.annotations.NotNull + final AnActionEvent event + ) { + final DataContext context = event.getDataContext(); + final IdeView view = LangDataKeys.IDE_VIEW.getData(context); + if (view == null) { + return; + } + + final Project project = CommonDataKeys.PROJECT.getData(context); + if (project == null) { + return; + } + + final PsiDirectory directory = view.getOrChooseDirectory(); + if (directory == null) { + return; + } + + NewMenuItemDialog.open(project, directory); + } + + @Override + public boolean isDumbAware() { + return false; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMenuItemDialog.form b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMenuItemDialog.form new file mode 100644 index 000000000..cdbc413ee --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMenuItemDialog.form @@ -0,0 +1,128 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMenuItemDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMenuItemDialog.java new file mode 100644 index 000000000..fe98e0c0b --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMenuItemDialog.java @@ -0,0 +1,116 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.intellij.ui.treeStructure.Tree; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.NewMenuItemValidator; +import com.magento.idea.magento2plugin.indexes.AdminMenuIndex; +import com.magento.idea.magento2plugin.util.magento.GetModuleNameByDirectory; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.List; +import javax.swing.JComponent; +import javax.swing.JTree; +import javax.swing.KeyStroke; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +public class NewMenuItemDialog extends AbstractDialog { + private javax.swing.JPanel controlPanel; + private javax.swing.JTextField titleFieldName; + private javax.swing.JTextField actionFieldName; + private javax.swing.JTextField resourceFieldName; + private javax.swing.JButton buttonOK; + private javax.swing.JButton buttonCancel; + private JTree moduleMenuTree; + + private final Project project; + private final String moduleName; + private final NewMenuItemValidator validator; + + /** + * Open new dialog for adding a new menu item. + * + * @param project Project + * @param directory PsiDirectory + */ + public NewMenuItemDialog(final Project project, final PsiDirectory directory) { + super(); + this.project = project; + this.moduleName = GetModuleNameByDirectory.getInstance(project).execute(directory); + this.validator = new NewMenuItemValidator(); + + setContentPane(controlPanel); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + setTitle(this.bundle.message("common.create.new.menu.item.title")); + + buttonOK.addActionListener(e -> onOK()); + buttonCancel.addActionListener(e -> onCancel()); + + setMenuTree(); + + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent event) { + onCancel(); + } + }); + + controlPanel.registerKeyboardAction( + event -> onCancel(), + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + } + + private void setMenuTree() { + final List menuItems = AdminMenuIndex.getInstance(project).getAdminMenuItems(); + DefaultMutableTreeNode root = new DefaultMutableTreeNode("Contacts"); // root node + + DefaultMutableTreeNode contact1 = new DefaultMutableTreeNode("Contact # 1"); // level 1 node + DefaultMutableTreeNode nickName1 = new DefaultMutableTreeNode("drocktapiff"); // level 2 (leaf) node + contact1.add(nickName1); + + DefaultMutableTreeNode contact2 = new DefaultMutableTreeNode("Contact # 2"); + DefaultMutableTreeNode nickName2 = new DefaultMutableTreeNode("dic19"); + contact2.add(nickName2); + + root.add(contact1); + root.add(contact2); + + DefaultTreeModel model = new DefaultTreeModel(root); + JTree tree = new Tree(model); + + moduleMenuTree.setModel(tree.getModel()); + } + + /** + * Open a new CLI command dialog. + * + * @param project Project + * @param directory Directory + */ + public static void open(final Project project, final PsiDirectory directory) { + final NewMenuItemDialog dialog = new NewMenuItemDialog(project, directory); + + dialog.pack(); + dialog.centerDialog(dialog); + dialog.setVisible(true); + } + + private void onOK() { + //if (!validator.validate(this.project,this)) { + // return; + // } + //this.generate(); + this.setVisible(false); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/NewMenuItemValidator.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/NewMenuItemValidator.java new file mode 100644 index 000000000..6c2d3dc47 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/NewMenuItemValidator.java @@ -0,0 +1,54 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.validator; + + +import com.magento.idea.magento2plugin.bundles.CommonBundle; +import com.magento.idea.magento2plugin.bundles.ValidatorBundle; +import com.intellij.openapi.project.Project; +import com.magento.idea.magento2plugin.actions.generation.dialog.NewCLICommandDialog; + +@SuppressWarnings({ + "PMD.FieldNamingConventions", + "PMD.RedundantFieldInitializer", + "PMD.OnlyOneReturn", + "PMD.AvoidDuplicateLiterals", +}) +public class NewMenuItemValidator { + private static NewMenuItemValidator INSTANCE = null; + private final ValidatorBundle validatorBundle; + private final CommonBundle commonBundle; + + /** + * Returns a new instance of a class. + * + * @return NewMenuItemValidator + */ + public static NewMenuItemValidator getInstance() { + if (null != INSTANCE) { + return INSTANCE; + } + INSTANCE = new NewMenuItemValidator(); + + return INSTANCE; + } + + public NewMenuItemValidator() { + this.validatorBundle = new ValidatorBundle(); + this.commonBundle = new CommonBundle(); + } + + /** + * Validate new menu item command form data. + * + * @param project Project + * @param dialog Dialog + * @return boolen + */ + public boolean validate(final Project project, final NewCLICommandDialog dialog) { + return true; + } +} diff --git a/src/com/magento/idea/magento2plugin/indexes/AdminMenuIndex.java b/src/com/magento/idea/magento2plugin/indexes/AdminMenuIndex.java new file mode 100644 index 000000000..6b07b4e27 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/indexes/AdminMenuIndex.java @@ -0,0 +1,54 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.indexes; + +import com.intellij.openapi.project.Project; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.stubs.indexes.AdminMenuIndexer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class AdminMenuIndex { + private static AdminMenuIndex INSTANCE; + + private Project project; + + private AdminMenuIndex() { + } + + /** + * Return admin menu item index class instance. + * + * @param project Project + * @return AdminMenuIndex instance + */ + public static AdminMenuIndex getInstance(final Project project) { + if (null == INSTANCE) { + INSTANCE = new AdminMenuIndex(); + } + INSTANCE.project = project; + + return INSTANCE; + } + + /** + * Get admin menu items. + * + * @return List List of menu items + */ + public List getAdminMenuItems() { + FileBasedIndex index = FileBasedIndex.getInstance(); + + List adminMenu = new ArrayList<>(index.getAllKeys( + AdminMenuIndexer.KEY, + project) + ); + Collections.sort(adminMenu); + + return adminMenu; + } +} diff --git a/src/com/magento/idea/magento2plugin/indexes/IndexManager.java b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java index 27e4612e4..3dc8ea7d4 100644 --- a/src/com/magento/idea/magento2plugin/indexes/IndexManager.java +++ b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java @@ -2,46 +2,50 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + package com.magento.idea.magento2plugin.indexes; import com.intellij.util.indexing.FileBasedIndexImpl; import com.intellij.util.indexing.ID; -import com.magento.idea.magento2plugin.stubs.indexes.*; +import com.magento.idea.magento2plugin.stubs.indexes.BlockNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.ContainerNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.EventNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.EventObserverIndex; +import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.ModulePackageIndex; import com.magento.idea.magento2plugin.stubs.indexes.PluginIndex; +import com.magento.idea.magento2plugin.stubs.indexes.VirtualTypeIndex; +import com.magento.idea.magento2plugin.stubs.indexes.WebApiTypeIndex; +import com.magento.idea.magento2plugin.stubs.indexes.graphql.GraphQlResolverIndex; import com.magento.idea.magento2plugin.stubs.indexes.js.MagentoLibJsIndex; import com.magento.idea.magento2plugin.stubs.indexes.js.RequireJsIndex; -import com.magento.idea.magento2plugin.stubs.indexes.graphql.GraphQlResolverIndex; -import com.magento.idea.magento2plugin.stubs.indexes.mftf.*; +import com.magento.idea.magento2plugin.stubs.indexes.mftf.ActionGroupIndex; +import com.magento.idea.magento2plugin.stubs.indexes.mftf.DataIndex; +import com.magento.idea.magento2plugin.stubs.indexes.mftf.PageIndex; +import com.magento.idea.magento2plugin.stubs.indexes.mftf.SectionIndex; +import com.magento.idea.magento2plugin.stubs.indexes.mftf.TestNameIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.PhpClassNameIndex; public class IndexManager { public static void manualReindex() { ID[] indexIds = new ID[] { - // php ModulePackageIndex.KEY, - // xml|di configuration PluginIndex.KEY, VirtualTypeIndex.KEY, - // layouts BlockNameIndex.KEY, ContainerNameIndex.KEY, - // events EventNameIndex.KEY, EventObserverIndex.KEY, - // webapi WebApiTypeIndex.KEY, ModuleNameIndex.KEY, PhpClassNameIndex.KEY, - //require_js RequireJsIndex.KEY, MagentoLibJsIndex.KEY, - // mftf ActionGroupIndex.KEY, DataIndex.KEY, PageIndex.KEY, SectionIndex.KEY, TestNameIndex.KEY, - //graphql GraphQlResolverIndex.KEY }; diff --git a/src/com/magento/idea/magento2plugin/magento/files/AdminMenuItems.java b/src/com/magento/idea/magento2plugin/magento/files/AdminMenuItems.java new file mode 100644 index 000000000..360ff608b --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/files/AdminMenuItems.java @@ -0,0 +1,14 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.files; + +public class AdminMenuItems { + public static String ADMIN_MENU_FILE_TAG = "menu"; + public static String MENU_TAG = "menu"; + public static String CONFIG_TAG = "config"; + public static String ITEM_ADD_TAG = "add"; + public static String ID_ATTRIBUTE = "id"; +} diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/AdminMenuIndexer.java b/src/com/magento/idea/magento2plugin/stubs/indexes/AdminMenuIndexer.java new file mode 100644 index 000000000..932e8b02c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/AdminMenuIndexer.java @@ -0,0 +1,112 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileBasedIndex.InputFilter; +import com.intellij.util.indexing.FileBasedIndexExtension; +import com.intellij.util.indexing.FileContent; +import com.intellij.util.indexing.ID; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.magento.idea.magento2plugin.magento.files.AdminMenuItems; +import com.magento.idea.magento2plugin.project.Settings; +import java.util.HashMap; +import java.util.Map; +import org.jetbrains.annotations.NotNull; + +public class AdminMenuIndexer extends FileBasedIndexExtension { + public static final ID KEY = ID.create( + "com.magento.idea.magento2plugin.stubs.indexes.admin_menu" + ); + private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + + @NotNull + @Override + public ID getName() { + return KEY; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return fileContent -> { + Map map = new HashMap<>(); + PsiFile psiFile = fileContent.getPsiFile(); + + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + + if (!(psiFile instanceof XmlFile)) { + return map; + } + + XmlDocument document = ((XmlFile) psiFile).getDocument(); + if (document == null) { + return map; + } + + XmlTag[] xmlTags = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); + if (xmlTags == null) { + return map; + } + + for (XmlTag xmlTag: xmlTags) { + if (xmlTag.getName().equals(AdminMenuItems.CONFIG_TAG)) { + XmlTag menuTag = xmlTag.findFirstSubTag(AdminMenuItems.MENU_TAG); + assert menuTag != null; + for (XmlTag menuNode: menuTag.findSubTags(AdminMenuItems.ITEM_ADD_TAG)) { + String menuItemId = menuNode.getAttributeValue(AdminMenuItems.ID_ATTRIBUTE); + if (menuItemId != null) { + map.put(menuItemId, fileContent.getFile().getPath()); + } + } + } + } + + return map; + }; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return myKeyDescriptor; + } + + @NotNull + @Override + public DataExternalizer getValueExternalizer() { + return new EnumeratorStringDescriptor(); + } + + @NotNull + @Override + public InputFilter getInputFilter() { + return virtualFile -> (virtualFile.getFileType() == XmlFileType.INSTANCE + && virtualFile.getNameWithoutExtension().equals( + AdminMenuItems.ADMIN_MENU_FILE_TAG) + ); + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 1; + } +}