diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml
index fe4229cdf..de03eb6ab 100644
--- a/resources/META-INF/plugin.xml
+++ b/resources/META-INF/plugin.xml
@@ -69,6 +69,7 @@
+
diff --git a/resources/fileTemplates/internal/Magento Queue Communication XML.xml.ft b/resources/fileTemplates/internal/Magento Queue Communication XML.xml.ft
new file mode 100644
index 000000000..efc3ec094
--- /dev/null
+++ b/resources/fileTemplates/internal/Magento Queue Communication XML.xml.ft
@@ -0,0 +1,4 @@
+
+
+
diff --git a/resources/fileTemplates/internal/Magento Queue Communication XML.xml.html b/resources/fileTemplates/internal/Magento Queue Communication XML.xml.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/resources/fileTemplates/internal/Magento Queue Consumer XML.xml.ft b/resources/fileTemplates/internal/Magento Queue Consumer XML.xml.ft
new file mode 100644
index 000000000..a20377ed1
--- /dev/null
+++ b/resources/fileTemplates/internal/Magento Queue Consumer XML.xml.ft
@@ -0,0 +1,4 @@
+
+
+
diff --git a/resources/fileTemplates/internal/Magento Queue Consumer XML.xml.html b/resources/fileTemplates/internal/Magento Queue Consumer XML.xml.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/resources/fileTemplates/internal/Magento Queue Publisher XML.xml.ft b/resources/fileTemplates/internal/Magento Queue Publisher XML.xml.ft
new file mode 100644
index 000000000..bd8c544e5
--- /dev/null
+++ b/resources/fileTemplates/internal/Magento Queue Publisher XML.xml.ft
@@ -0,0 +1,4 @@
+
+
+
diff --git a/resources/fileTemplates/internal/Magento Queue Publisher XML.xml.html b/resources/fileTemplates/internal/Magento Queue Publisher XML.xml.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/resources/fileTemplates/internal/Magento Queue Topology XML.xml.ft b/resources/fileTemplates/internal/Magento Queue Topology XML.xml.ft
new file mode 100644
index 000000000..f316f98b7
--- /dev/null
+++ b/resources/fileTemplates/internal/Magento Queue Topology XML.xml.ft
@@ -0,0 +1,4 @@
+
+
+
diff --git a/resources/fileTemplates/internal/Magento Queue Topology XML.xml.html b/resources/fileTemplates/internal/Magento Queue Topology XML.xml.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/resources/magento2/validation.properties b/resources/magento2/validation.properties
index d836d2655..5637532ea 100644
--- a/resources/magento2/validation.properties
+++ b/resources/magento2/validation.properties
@@ -3,12 +3,15 @@ validator.box.notEmpty=The {0} field must contain a valid selection from the dro
validator.package.validPath=Please specify a valid Magento 2 installation path
validator.alphaNumericCharacters=The {0} field must contain letters and numbers only
validator.alphaNumericAndUnderscoreCharacters={0} must contain letters, numbers and underscores only
+validator.alphaAndPeriodCharacters=The {0} field must contain alphabets and periods only
+validator.alphaAndDashCharacters=The {0} field must contain alphabets and dashes only
validator.alreadyDeclared={0} is already declared in the {1} module
validator.startWithNumberOrCapitalLetter=The {0} field must start with a number or a capital letter
validator.onlyNumbers=The {0} field must contain numbers only
validator.mustNotBeNegative={0} must not be negative
validator.identifier=The {0} field must contain letters, numbers, dashes, and underscores only
validator.class.isNotValid=The {0} field does not contain a valid class name
+validator.fqn.isNotValid=The {0} field does not contain a valid fully qualified class name
validator.class.shouldBeUnique=Duplicated class {0}
validator.namespace.isNotValid=The {0} field does not contain a valid namespace
validator.directory.isNotValid=The {0} field does not contain a valid directory
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/NewMessageQueueAction.java b/src/com/magento/idea/magento2plugin/actions/generation/NewMessageQueueAction.java
new file mode 100644
index 000000000..d562f076a
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/NewMessageQueueAction.java
@@ -0,0 +1,57 @@
+/*
+ * 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.NewMessageQueueDialog;
+import org.jetbrains.annotations.NotNull;
+
+public class NewMessageQueueAction extends AnAction {
+ public static final String ACTION_NAME = "Magento 2 Message Queue";
+ public static final String ACTION_DESCRIPTION = "Create a new Magento 2 Message Queue";
+
+ /**
+ * Constructor.
+ */
+ public NewMessageQueueAction() {
+ super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE);
+ }
+
+ @Override
+ public void actionPerformed(@NotNull final AnActionEvent event) {
+ final DataContext dataContext = event.getDataContext();
+
+ final IdeView view = LangDataKeys.IDE_VIEW.getData(dataContext);
+ if (view == null) {
+ return;
+ }
+
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ if (project == null) {
+ return;
+ }
+
+ final PsiDirectory directory = view.getOrChooseDirectory();
+ if (directory == null) {
+ return;
+ }
+
+ NewMessageQueueDialog.open(project, directory);
+ }
+
+ @Override
+ public boolean isDumbAware() {
+ return false;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/QueueCommunicationData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/QueueCommunicationData.java
new file mode 100644
index 000000000..ad7bd0afd
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/data/QueueCommunicationData.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.data;
+
+public class QueueCommunicationData {
+ private final String topicName;
+ private final String handlerName;
+ private final String handlerType;
+ private final String handlerMethod;
+ private final String moduleName;
+
+ /**
+ * Constructor.
+ */
+ public QueueCommunicationData(
+ final String topicName,
+ final String handlerName,
+ final String handlerType,
+ final String handlerMethod,
+ final String moduleName
+ ) {
+ this.topicName = topicName;
+ this.handlerName = handlerName;
+ this.handlerType = handlerType;
+ this.handlerMethod = handlerMethod;
+ this.moduleName = moduleName;
+ }
+
+ public String getTopicName() {
+ return topicName;
+ }
+
+ public String getHandlerName() {
+ return handlerName;
+ }
+
+ public String getHandlerType() {
+ return handlerType;
+ }
+
+ public String getHandlerMethod() {
+ return handlerMethod;
+ }
+
+ public String getModuleName() {
+ return moduleName;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/QueueConsumerData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/QueueConsumerData.java
new file mode 100644
index 000000000..6724f2481
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/data/QueueConsumerData.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.data;
+
+public class QueueConsumerData {
+ private final String consumerName;
+ private final String queueName;
+ private final String consumerType;
+ private final String maxMessages;
+ private final String connectionName;
+ private final String moduleName;
+
+ /**
+ * Constructor.
+ */
+ public QueueConsumerData(
+ final String consumerName,
+ final String queueName,
+ final String consumerType,
+ final String maxMessages,
+ final String connectionName,
+ final String moduleName
+ ) {
+ this.consumerName = consumerName;
+ this.queueName = queueName;
+ this.consumerType = consumerType;
+ this.maxMessages = maxMessages;
+ this.connectionName = connectionName;
+ this.moduleName = moduleName;
+ }
+
+ public String getConsumerName() {
+ return consumerName;
+ }
+
+ public String getQueueName() {
+ return queueName;
+ }
+
+ public String getConsumerType() {
+ return consumerType;
+ }
+
+ public String getMaxMessages() {
+ return maxMessages;
+ }
+
+ public String getConnectionName() {
+ return connectionName;
+ }
+
+ public String getModuleName() {
+ return moduleName;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/QueuePublisherData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/QueuePublisherData.java
new file mode 100644
index 000000000..7eaff709a
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/data/QueuePublisherData.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.data;
+
+public class QueuePublisherData {
+ private final String topicName;
+ private final String connectionName;
+ private final String exchangeName;
+ private final String moduleName;
+
+ /**
+ * Constructor.
+ */
+ public QueuePublisherData(
+ final String topicName,
+ final String connectionName,
+ final String exchangeName,
+ final String moduleName
+ ) {
+ this.topicName = topicName;
+ this.connectionName = connectionName;
+ this.exchangeName = exchangeName;
+ this.moduleName = moduleName;
+ }
+
+ public String getTopicName() {
+ return topicName;
+ }
+
+ public String getConnectionName() {
+ return connectionName;
+ }
+
+ public String getExchangeName() {
+ return exchangeName;
+ }
+
+ public String getModuleName() {
+ return moduleName;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/QueueTopologyData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/QueueTopologyData.java
new file mode 100644
index 000000000..bbf85b8e4
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/data/QueueTopologyData.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.data;
+
+public class QueueTopologyData {
+ private final String exchangeName;
+ private final String connectionName;
+ private final String bindingId;
+ private final String bindingTopic;
+ private final String bindingQueue;
+ private final String moduleName;
+
+ /**
+ * Constructor.
+ */
+ public QueueTopologyData(
+ final String exchangeName,
+ final String connectionName,
+ final String bindingId,
+ final String bindingTopic,
+ final String bindingQueue,
+ final String moduleName
+ ) {
+ this.exchangeName = exchangeName;
+ this.connectionName = connectionName;
+ this.bindingId = bindingId;
+ this.bindingTopic = bindingTopic;
+ this.bindingQueue = bindingQueue;
+ this.moduleName = moduleName;
+ }
+
+ public String getExchangeName() {
+ return exchangeName;
+ }
+
+ public String getConnectionName() {
+ return connectionName;
+ }
+
+ public String getBindingId() {
+ return bindingId;
+ }
+
+ public String getBindingTopic() {
+ return bindingTopic;
+ }
+
+ public String getBindingQueue() {
+ return bindingQueue;
+ }
+
+ public String getModuleName() {
+ return moduleName;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.form b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.form
new file mode 100644
index 000000000..852059489
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.form
@@ -0,0 +1,257 @@
+
+
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.java
new file mode 100644
index 000000000..fa108e58e
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.java
@@ -0,0 +1,286 @@
+/*
+ * 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.magento.idea.magento2plugin.actions.generation.NewDataModelAction;
+import com.magento.idea.magento2plugin.actions.generation.NewMessageQueueAction;
+import com.magento.idea.magento2plugin.actions.generation.data.QueueCommunicationData;
+import com.magento.idea.magento2plugin.actions.generation.data.QueueConsumerData;
+import com.magento.idea.magento2plugin.actions.generation.data.QueuePublisherData;
+import com.magento.idea.magento2plugin.actions.generation.data.QueueTopologyData;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphaWithDashRule;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphaWithPeriodRule;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphanumericWithUnderscoreRule;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.Lowercase;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NumericRule;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.PhpClassFqnRule;
+import com.magento.idea.magento2plugin.actions.generation.generator.QueueCommunicationGenerator;
+import com.magento.idea.magento2plugin.actions.generation.generator.QueueConsumerGenerator;
+import com.magento.idea.magento2plugin.actions.generation.generator.QueuePublisherGenerator;
+import com.magento.idea.magento2plugin.actions.generation.generator.QueueTopologyGenerator;
+import com.magento.idea.magento2plugin.util.magento.GetModuleNameByDirectoryUtil;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
+
+@SuppressWarnings({
+ "PMD.TooManyFields",
+ "PMD.ExcessiveImports",
+})
+public class NewMessageQueueDialog extends AbstractDialog {
+ private static final String TOPIC_NAME = "Topic Name";
+ private static final String HANDLER_NAME = "Handler Name";
+ private static final String HANDLER_TYPE = "Handler Type";
+ private static final String CONSUMER_NAME = "Consumer Name";
+ private static final String QUEUE_NAME = "Queue Name";
+ private static final String CONSUMER_TYPE = "Consumer Type";
+ private static final String MAX_MESSAGES = "Maximum Messages";
+ private static final String CONNECTION_NAME = "Connection Name";
+ private static final String EXCHANGE_NAME = "Exchange Name";
+ private static final String BINDING_ID = "Binding ID";
+ private static final String BINDING_TOPIC = "Binding Topic";
+
+ /* TODO: Improve validation */
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, TOPIC_NAME})
+ @FieldValidation(rule = RuleRegistry.ALPHA_WITH_PERIOD,
+ message = {AlphaWithPeriodRule.MESSAGE, TOPIC_NAME})
+ @FieldValidation(rule = RuleRegistry.LOWERCASE,
+ message = {Lowercase.MESSAGE, TOPIC_NAME})
+ private JTextField topicName;
+
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, HANDLER_NAME})
+ @FieldValidation(rule = RuleRegistry.ALPHANUMERIC_WITH_UNDERSCORE,
+ message = {AlphanumericWithUnderscoreRule.MESSAGE, HANDLER_NAME})
+ private JTextField handlerName;
+
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, HANDLER_TYPE})
+ @FieldValidation(rule = RuleRegistry.PHP_CLASS_FQN,
+ message = {PhpClassFqnRule.MESSAGE, HANDLER_TYPE})
+ private JTextField handlerType;
+
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, CONSUMER_NAME})
+ @FieldValidation(rule = RuleRegistry.ALPHA_WITH_PERIOD,
+ message = {AlphaWithPeriodRule.MESSAGE, CONSUMER_NAME})
+ @FieldValidation(rule = RuleRegistry.LOWERCASE,
+ message = {Lowercase.MESSAGE, CONSUMER_NAME})
+ private JTextField consumerName;
+
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, QUEUE_NAME})
+ @FieldValidation(rule = RuleRegistry.ALPHA_WITH_PERIOD,
+ message = {AlphaWithPeriodRule.MESSAGE, QUEUE_NAME})
+ @FieldValidation(rule = RuleRegistry.LOWERCASE,
+ message = {Lowercase.MESSAGE, QUEUE_NAME})
+ private JTextField queueName;
+
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, CONSUMER_TYPE})
+ @FieldValidation(rule = RuleRegistry.PHP_CLASS_FQN,
+ message = {PhpClassFqnRule.MESSAGE, CONSUMER_TYPE})
+ private JTextField consumerType;
+
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, MAX_MESSAGES})
+ @FieldValidation(rule = RuleRegistry.NUMERIC,
+ message = {NumericRule.MESSAGE, MAX_MESSAGES})
+ private JTextField maxMessages;
+
+ // TODO: Can this be made a dropdown?
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, CONNECTION_NAME})
+ private JTextField connectionName;
+
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, EXCHANGE_NAME})
+ @FieldValidation(rule = RuleRegistry.ALPHA_WITH_DASH,
+ message = {AlphaWithDashRule.MESSAGE, EXCHANGE_NAME})
+ private JTextField exchangeName;
+
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, BINDING_ID})
+ @FieldValidation(rule = RuleRegistry.ALPHANUMERIC_WITH_UNDERSCORE,
+ message = {AlphaWithDashRule.MESSAGE, BINDING_ID})
+ private JTextField bindingId;
+
+ // TODO: New validation rule
+ @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
+ message = {NotEmptyRule.MESSAGE, BINDING_TOPIC})
+ private JTextField bindingTopic;
+
+ private JPanel contentPanel;
+ private JButton buttonOK;
+ private JButton buttonCancel;
+
+ private final Project project;
+ private final String moduleName;
+
+ /**
+ * Constructor.
+ */
+ public NewMessageQueueDialog(final Project project, final PsiDirectory directory) {
+ super();
+
+ this.project = project;
+ this.moduleName = GetModuleNameByDirectoryUtil.execute(directory, project);
+
+ setContentPane(contentPanel);
+ setModal(true);
+ setTitle(NewDataModelAction.ACTION_DESCRIPTION);
+ getRootPane().setDefaultButton(buttonOK);
+
+ buttonOK.addActionListener((final ActionEvent event) -> onOK());
+ buttonCancel.addActionListener((final ActionEvent event) -> onCancel());
+
+ // call onCancel() on dialog close
+ setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+ addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(final WindowEvent event) {
+ onCancel();
+ }
+ });
+
+ // call onCancel() on ESCAPE KEY press
+ contentPanel.registerKeyboardAction(
+ (final ActionEvent event) -> onCancel(),
+ KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
+ );
+ }
+
+ /**
+ * Opens the dialog window.
+ */
+ public static void open(final Project project, final PsiDirectory directory) {
+ final NewMessageQueueDialog dialog = new NewMessageQueueDialog(project, directory);
+ dialog.pack();
+ dialog.centerDialog(dialog);
+ dialog.setVisible(true);
+ }
+
+ @Override
+ public void onCancel() {
+ dispose();
+ }
+
+ private void onOK() {
+ if (validateFormFields()) {
+ generateCommunication();
+ generateConsumer();
+ generateTopology();
+ generatePublisher();
+ this.setVisible(false);
+ }
+ }
+
+ private void generateCommunication() {
+ new QueueCommunicationGenerator(project, new QueueCommunicationData(
+ getTopicName(),
+ getHandlerName(),
+ getHandlerType(),
+ getHandlerMethod(),
+ getModuleName()
+ )).generate(NewMessageQueueAction.ACTION_NAME, true);
+ }
+
+ private void generateConsumer() {
+ new QueueConsumerGenerator(project, new QueueConsumerData(
+ getConsumerName(),
+ getQueueName(),
+ getConsumerType(),
+ getMaxMessages(),
+ getConnectionName(),
+ getModuleName()
+ )).generate(NewMessageQueueAction.ACTION_NAME, true);
+ }
+
+ private void generateTopology() {
+ new QueueTopologyGenerator(project, new QueueTopologyData(
+ getExchangeName(),
+ getConnectionName(),
+ getBindingId(),
+ getBindingTopic(),
+ getQueueName(),
+ getModuleName()
+ )).generate(NewMessageQueueAction.ACTION_NAME, true);
+ }
+
+ private void generatePublisher() {
+ new QueuePublisherGenerator(project, new QueuePublisherData(
+ getTopicName(),
+ getConnectionName(),
+ getExchangeName(),
+ getModuleName()
+ )).generate(NewMessageQueueAction.ACTION_NAME, true);
+ }
+
+ public String getTopicName() {
+ return topicName.getText().trim();
+ }
+
+ public String getHandlerName() {
+ return handlerName.getText().trim();
+ }
+
+ public String getHandlerType() {
+ return handlerType.getText().trim();
+ }
+
+ public String getHandlerMethod() {
+ return "execute";
+ }
+
+ public String getConsumerName() {
+ return consumerName.getText().trim();
+ }
+
+ public String getQueueName() {
+ return queueName.getText().trim();
+ }
+
+ public String getConsumerType() {
+ return consumerType.getText().trim();
+ }
+
+ public String getMaxMessages() {
+ return maxMessages.getText().trim();
+ }
+
+ public String getConnectionName() {
+ return connectionName.getText().trim();
+ }
+
+ public String getExchangeName() {
+ return exchangeName.getText().trim();
+ }
+
+ public String getBindingId() {
+ return bindingId.getText().trim();
+ }
+
+ public String getBindingTopic() {
+ return bindingTopic.getText().trim();
+ }
+
+ public String getModuleName() {
+ return moduleName;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java
index e0b7fa5bd..ce444dc66 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java
@@ -6,6 +6,8 @@
package com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AclResourceIdRule;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphaWithDashRule;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphaWithPeriodRule;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphanumericRule;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphanumericWithUnderscoreRule;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.BoxNotEmptyRule;
@@ -17,6 +19,7 @@
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.Lowercase;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NumericRule;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.PhpClassFqnRule;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.PhpClassRule;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.PhpDirectoryRule;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.PhpNamespaceNameRule;
@@ -27,9 +30,12 @@ public enum RuleRegistry {
NOT_EMPTY(NotEmptyRule.class),
BOX_NOT_EMPTY(BoxNotEmptyRule.class),
PHP_CLASS(PhpClassRule.class),
+ PHP_CLASS_FQN(PhpClassFqnRule.class),
ROUTE_ID(RouteIdRule.class),
ALPHANUMERIC(AlphanumericRule.class),
ALPHANUMERIC_WITH_UNDERSCORE(AlphanumericWithUnderscoreRule.class),
+ ALPHA_WITH_PERIOD(AlphaWithPeriodRule.class),
+ ALPHA_WITH_DASH(AlphaWithDashRule.class),
DIRECTORY(DirectoryRule.class),
PHP_DIRECTORY(PhpDirectoryRule.class),
IDENTIFIER(IdentifierRule.class),
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/AlphaWithDashRule.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/AlphaWithDashRule.java
new file mode 100644
index 000000000..a9e9b877b
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/AlphaWithDashRule.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule;
+
+import com.magento.idea.magento2plugin.util.RegExUtil;
+
+public class AlphaWithDashRule implements ValidationRule {
+ public static final String MESSAGE = "validator.alphaAndDashCharacters";
+ private static final ValidationRule INSTANCE = new AlphaWithDashRule();
+
+ @Override
+ public boolean check(final String value) {
+ return value.matches(RegExUtil.ALPHA_WITH_DASH);
+ }
+
+ public static ValidationRule getInstance() {
+ return INSTANCE;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/AlphaWithPeriodRule.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/AlphaWithPeriodRule.java
new file mode 100644
index 000000000..806e59795
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/AlphaWithPeriodRule.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule;
+
+import com.magento.idea.magento2plugin.util.RegExUtil;
+
+public class AlphaWithPeriodRule implements ValidationRule {
+ public static final String MESSAGE = "validator.alphaAndPeriodCharacters";
+ private static final ValidationRule INSTANCE = new AlphaWithPeriodRule();
+
+ @Override
+ public boolean check(final String value) {
+ return value.matches(RegExUtil.ALPHA_WITH_PERIOD);
+ }
+
+ public static ValidationRule getInstance() {
+ return INSTANCE;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/PhpClassFqnRule.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/PhpClassFqnRule.java
new file mode 100644
index 000000000..31e906220
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/PhpClassFqnRule.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule;
+
+import com.magento.idea.magento2plugin.util.RegExUtil;
+
+public class PhpClassFqnRule implements ValidationRule {
+ public static final String MESSAGE = "validator.fqn.isNotValid";
+ private static final ValidationRule INSTANCE = new PhpClassFqnRule();
+
+ @Override
+ public boolean check(final String value) {
+ return value.matches(RegExUtil.Magento.PHP_CLASS_FQN);
+ }
+
+ public static ValidationRule getInstance() {
+ return INSTANCE;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueCommunicationGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueCommunicationGenerator.java
new file mode 100644
index 000000000..b1bba1831
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueCommunicationGenerator.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.xml.XmlAttribute;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.psi.xml.XmlTag;
+import com.magento.idea.magento2plugin.actions.generation.data.QueueCommunicationData;
+import com.magento.idea.magento2plugin.actions.generation.generator.util.FindOrCreateCommunicationXml;
+import java.util.Properties;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class QueueCommunicationGenerator extends FileGenerator {
+ public static final String ATTRIBUTE_NAME = "name";
+ private final QueueCommunicationData communicationData;
+ private final Project project;
+ private final FindOrCreateCommunicationXml findOrCreateCommunicationXml;
+
+ /**
+ * Constructor.
+ */
+ public QueueCommunicationGenerator(
+ final Project project,
+ final @NotNull QueueCommunicationData communicationData
+ ) {
+ super(project);
+
+ this.communicationData = communicationData;
+ this.project = project;
+ this.findOrCreateCommunicationXml = new FindOrCreateCommunicationXml(project);
+ }
+
+ @Override
+ public PsiFile generate(final String actionName) {
+ final XmlFile communicationXml = (XmlFile) findOrCreateCommunicationXml.execute(
+ actionName,
+ communicationData.getModuleName()
+ );
+ final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
+ final Document document = psiDocumentManager.getDocument(communicationXml);
+
+ WriteCommandAction.runWriteCommandAction(project, () -> {
+ final XmlTag rootTag = communicationXml.getRootTag();
+ if (rootTag == null) {
+ return;
+ }
+ final XmlTag[] topicTags = rootTag.findSubTags("topic");
+ boolean topicTagIsGenerated = true;
+ XmlTag topicTag = null;
+ for (final XmlTag tag: topicTags) {
+ if (communicationData.getTopicName().equals(
+ tag.getAttribute(ATTRIBUTE_NAME).getValue())
+ ) {
+ topicTagIsGenerated = false;
+ topicTag = tag;
+ break;
+ }
+ }
+ if (topicTagIsGenerated) {
+ topicTag = rootTag.createChildTag("topic", null, "", false);
+ topicTag.setAttribute(ATTRIBUTE_NAME, communicationData.getTopicName());
+ topicTag.setAttribute("request", "string");
+ topicTag.setAttribute("response", "string");
+ }
+
+ @NotNull final XmlTag[] handlerTags = topicTag.findSubTags("handler");
+ boolean isDeclared = false;
+ for (final XmlTag handlerTag: handlerTags) {
+ @Nullable final XmlAttribute handlerName = handlerTag.getAttribute(ATTRIBUTE_NAME);
+ if (communicationData.getHandlerName().equals(handlerName.getValue())) {
+ isDeclared = true;
+ }
+ }
+
+ if (!isDeclared) {
+ final XmlTag handlerTag = topicTag.createChildTag("handler", null, null, false);
+
+ handlerTag.setAttribute(ATTRIBUTE_NAME, communicationData.getHandlerName());
+ handlerTag.setAttribute("type",communicationData.getHandlerType());
+ handlerTag.setAttribute("method",communicationData.getHandlerMethod());
+
+ topicTag.addSubTag(handlerTag, false);
+
+ if (topicTagIsGenerated) {
+ rootTag.addSubTag(topicTag, false);
+ }
+ }
+
+ psiDocumentManager.commitDocument(document);
+ });
+
+ return communicationXml;
+ }
+
+ @Override
+ protected void fillAttributes(Properties attributes) {}//NOPMD
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGenerator.java
new file mode 100644
index 000000000..961b55bfa
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGenerator.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.psi.xml.XmlTag;
+import com.magento.idea.magento2plugin.actions.generation.data.QueueConsumerData;
+import com.magento.idea.magento2plugin.actions.generation.generator.util.FindOrCreateQueueConsumerXml;
+import java.util.Properties;
+
+public class QueueConsumerGenerator extends FileGenerator {
+ private final QueueConsumerData consumerData;
+ private final Project project;
+ private final FindOrCreateQueueConsumerXml findOrCreateQueueConsumerXml;
+
+ /**
+ * Constructor.
+ */
+ public QueueConsumerGenerator(final Project project, final QueueConsumerData consumerData) {
+ super(project);
+
+ this.consumerData = consumerData;
+ this.project = project;
+ this.findOrCreateQueueConsumerXml = new FindOrCreateQueueConsumerXml(project);
+ }
+
+ @Override
+ public PsiFile generate(final String actionName) {
+ final XmlFile consumerXml = (XmlFile) findOrCreateQueueConsumerXml.execute(
+ actionName,
+ consumerData.getModuleName()
+ );
+ final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
+ final Document document = psiDocumentManager.getDocument(consumerXml);
+
+ WriteCommandAction.runWriteCommandAction(project, () -> {
+ final XmlTag rootTag = consumerXml.getRootTag();
+ if (rootTag == null) {
+ return;
+ }
+ final XmlTag[] consumerTags = rootTag.findSubTags("consumer");
+ boolean tagIsGenerated = true;
+ for (final XmlTag tag: consumerTags) {
+ if (consumerData.getConsumerName().equals(tag.getAttribute("name").getValue())) {
+ tagIsGenerated = false;
+ break;
+ }
+ }
+ if (tagIsGenerated) {
+ final XmlTag consumerTag = rootTag.createChildTag("consumer", null, null, false);
+ consumerTag.setAttribute("name", consumerData.getConsumerName());
+ consumerTag.setAttribute("queue", consumerData.getQueueName());
+ consumerTag.setAttribute("consumerInstance", consumerData.getConsumerType());
+ consumerTag.setAttribute("connection", consumerData.getConnectionName());
+ consumerTag.setAttribute("maxMessages", consumerData.getMaxMessages());
+
+ rootTag.addSubTag(consumerTag, false);
+ }
+
+ psiDocumentManager.commitDocument(document);
+ });
+
+ return consumerXml;
+ }
+
+ @Override
+ protected void fillAttributes(Properties attributes) {}//NOPMD
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/QueuePublisherGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueuePublisherGenerator.java
new file mode 100644
index 000000000..e202c4182
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueuePublisherGenerator.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.xml.XmlAttribute;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.psi.xml.XmlTag;
+import com.magento.idea.magento2plugin.actions.generation.data.QueuePublisherData;
+import com.magento.idea.magento2plugin.actions.generation.generator.util.FindOrCreateQueuePublisherXml;
+import java.util.Properties;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class QueuePublisherGenerator extends FileGenerator {
+ private final QueuePublisherData publisherData;
+ private final Project project;
+ private final FindOrCreateQueuePublisherXml findOrCreateQueuePublisherXml;
+
+ /**
+ * Constructor.
+ */
+ public QueuePublisherGenerator(
+ final Project project,
+ final QueuePublisherData publisherData
+ ) {
+ super(project);
+
+ this.publisherData = publisherData;
+ this.project = project;
+ this.findOrCreateQueuePublisherXml = new FindOrCreateQueuePublisherXml(project);
+ }
+
+ @Override
+ public PsiFile generate(final String actionName) {
+ final XmlFile publisherXml = (XmlFile) findOrCreateQueuePublisherXml.execute(
+ actionName,
+ publisherData.getModuleName()
+ );
+ final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
+ final Document document = psiDocumentManager.getDocument(publisherXml);
+
+ WriteCommandAction.runWriteCommandAction(project, () -> {
+ final XmlTag rootTag = publisherXml.getRootTag();
+ if (rootTag == null) {
+ return;
+ }
+ final XmlTag[] publisherTags = rootTag.findSubTags("publisher");
+ boolean publisherTagIsGenerated = true;
+ XmlTag publisherTag = null;
+ for (final XmlTag tag: publisherTags) {
+ if (publisherData.getTopicName().equals(tag.getAttribute("topic").getValue())) {
+ publisherTagIsGenerated = false;
+ publisherTag = tag;
+ break;
+ }
+ }
+ if (publisherTagIsGenerated) {
+ publisherTag = rootTag.createChildTag("publisher", null, "", false);
+
+ publisherTag.setAttribute("topic", publisherData.getTopicName());
+ }
+
+ @NotNull final XmlTag[] connectionTags = publisherTag.findSubTags("connection");
+ boolean isDeclared = false;
+ for (final XmlTag connectionTag: connectionTags) {
+ @Nullable final XmlAttribute connectionName = connectionTag.getAttribute("name");
+ if (publisherData.getConnectionName().equals(connectionName.getValue())) {
+ isDeclared = true;
+ }
+ }
+
+ if (!isDeclared) {
+ final XmlTag connectionTag = publisherTag.createChildTag(
+ "connection", null, null, false
+ );
+
+ connectionTag.setAttribute("name", publisherData.getConnectionName());
+ connectionTag.setAttribute("exchange",publisherData.getExchangeName());
+
+ publisherTag.addSubTag(connectionTag, false);
+
+ if (publisherTagIsGenerated) {
+ rootTag.addSubTag(publisherTag, false);
+ }
+ }
+
+ psiDocumentManager.commitDocument(document);
+ });
+
+ return publisherXml;
+ }
+
+ @Override
+ protected void fillAttributes(final Properties attributes) {}//NOPMD
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueTopologyGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueTopologyGenerator.java
new file mode 100644
index 000000000..bb22d991e
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueTopologyGenerator.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.xml.XmlAttribute;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.psi.xml.XmlTag;
+import com.magento.idea.magento2plugin.actions.generation.data.QueueTopologyData;
+import com.magento.idea.magento2plugin.actions.generation.generator.util.FindOrCreateQueueTopologyXml;
+import java.util.Properties;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class QueueTopologyGenerator extends FileGenerator {
+ private final QueueTopologyData topologyData;
+ private final Project project;
+ private final FindOrCreateQueueTopologyXml findOrCreateQueueTopologyXml;
+
+ /**
+ * Constructor.
+ */
+ public QueueTopologyGenerator(final Project project, final QueueTopologyData topologyData) {
+ super(project);
+
+ this.topologyData = topologyData;
+ this.project = project;
+ this.findOrCreateQueueTopologyXml = new FindOrCreateQueueTopologyXml(project);
+ }
+
+ @Override
+ public PsiFile generate(final String actionName) {
+ final XmlFile topologyXml = (XmlFile) findOrCreateQueueTopologyXml.execute(
+ actionName,
+ topologyData.getModuleName()
+ );
+ final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
+ final Document document = psiDocumentManager.getDocument(topologyXml);
+
+ WriteCommandAction.runWriteCommandAction(project, () -> {
+ final XmlTag rootTag = topologyXml.getRootTag();
+ if (rootTag == null) {
+ return;
+ }
+ final XmlTag[] exchangeTags = rootTag.findSubTags("exchange");
+ boolean exchangeTagIsGenerated = true;
+ XmlTag exchangeTag = null;
+ for (final XmlTag tag: exchangeTags) {
+ if (topologyData.getExchangeName().equals(tag.getAttribute("name").getValue())) {
+ exchangeTagIsGenerated = false;
+ exchangeTag = tag;
+ break;
+ }
+ }
+ if (exchangeTagIsGenerated) {
+ exchangeTag = rootTag.createChildTag("exchange", null, "", false);
+
+ exchangeTag.setAttribute("name", topologyData.getExchangeName());
+ exchangeTag.setAttribute("type", "topic");
+ exchangeTag.setAttribute("connection", topologyData.getConnectionName());
+ }
+
+ @NotNull final XmlTag[] bindingTags = exchangeTag.findSubTags("binding");
+ boolean isDeclared = false;
+ for (final XmlTag bindingTag: bindingTags) {
+ @Nullable final XmlAttribute bindingId = bindingTag.getAttribute("id");
+ if (topologyData.getBindingId().equals(bindingId.getValue())) {
+ isDeclared = true;
+ }
+ }
+
+ if (!isDeclared) {
+ final XmlTag bindingTag = exchangeTag.createChildTag("binding", null, null, false);
+
+ bindingTag.setAttribute("id", topologyData.getBindingId());
+ bindingTag.setAttribute("topic", topologyData.getBindingTopic());
+ bindingTag.setAttribute("destinationType", "queue");
+ bindingTag.setAttribute("destination", topologyData.getBindingQueue());
+
+ exchangeTag.addSubTag(bindingTag, false);
+
+ if (exchangeTagIsGenerated) {
+ rootTag.addSubTag(exchangeTag, false);
+ }
+ }
+
+ psiDocumentManager.commitDocument(document);
+ });
+
+ return topologyXml;
+ }
+
+ @Override
+ protected void fillAttributes(Properties attributes) {}//NOPMD
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateCommunicationXml.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateCommunicationXml.java
new file mode 100644
index 000000000..5cd1d1f73
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateCommunicationXml.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator.util;
+
+import com.intellij.openapi.project.Project;
+import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface;
+import com.magento.idea.magento2plugin.magento.files.QueueCommunicationXml;
+
+public class FindOrCreateCommunicationXml extends FindOrCreateQueueXml {
+ /**
+ * Constructor.
+ */
+ public FindOrCreateCommunicationXml(final Project project) {
+ super(project);
+ }
+
+ @Override
+ protected ModuleFileInterface instantiateXmlFile() {
+ return new QueueCommunicationXml();
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueueConsumerXml.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueueConsumerXml.java
new file mode 100644
index 000000000..137f518a9
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueueConsumerXml.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator.util;
+
+import com.intellij.openapi.project.Project;
+import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface;
+import com.magento.idea.magento2plugin.magento.files.QueueConsumerXml;
+
+public class FindOrCreateQueueConsumerXml extends FindOrCreateQueueXml {
+ /**
+ * Constructor.
+ */
+ public FindOrCreateQueueConsumerXml(final Project project) {
+ super(project);
+ }
+
+ @Override
+ protected ModuleFileInterface instantiateXmlFile() {
+ return new QueueConsumerXml();
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueuePublisherXml.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueuePublisherXml.java
new file mode 100644
index 000000000..e37690773
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueuePublisherXml.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator.util;
+
+import com.intellij.openapi.project.Project;
+import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface;
+import com.magento.idea.magento2plugin.magento.files.QueuePublisherXml;
+
+public class FindOrCreateQueuePublisherXml extends FindOrCreateQueueXml {
+ /**
+ * Constructor.
+ */
+ public FindOrCreateQueuePublisherXml(final Project project) {
+ super(project);
+ }
+
+ @Override
+ protected ModuleFileInterface instantiateXmlFile() {
+ return new QueuePublisherXml();
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueueTopologyXml.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueueTopologyXml.java
new file mode 100644
index 000000000..616102507
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueueTopologyXml.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator.util;
+
+import com.intellij.openapi.project.Project;
+import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface;
+import com.magento.idea.magento2plugin.magento.files.QueueTopologyXml;
+
+public class FindOrCreateQueueTopologyXml extends FindOrCreateQueueXml {
+ /**
+ * Constructor.
+ */
+ public FindOrCreateQueueTopologyXml(final Project project) {
+ super(project);
+ }
+
+ @Override
+ protected ModuleFileInterface instantiateXmlFile() {
+ return new QueueTopologyXml();
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueueXml.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueueXml.java
new file mode 100644
index 000000000..0f9e47d5c
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateQueueXml.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator.util;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
+import com.magento.idea.magento2plugin.indexes.ModuleIndex;
+import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface;
+import com.magento.idea.magento2plugin.magento.packages.Areas;
+import com.magento.idea.magento2plugin.magento.packages.Package;
+import com.magento.idea.magento2plugin.util.magento.FileBasedIndexUtil;
+import java.util.ArrayList;
+import java.util.Properties;
+
+public abstract class FindOrCreateQueueXml {
+ private final Project project;
+ private final DirectoryGenerator directoryGenerator;
+ private final FileFromTemplateGenerator fileFromTemplateGenerator;
+ private final ModuleIndex moduleIndex;
+
+ /**
+ * Constructor.
+ */
+ public FindOrCreateQueueXml(final Project project) {
+ this.project = project;
+
+ this.directoryGenerator = DirectoryGenerator.getInstance();
+ this.fileFromTemplateGenerator = FileFromTemplateGenerator.getInstance(project);
+ this.moduleIndex = ModuleIndex.getInstance(project);
+ }
+
+ /**
+ * Finds or creates message queue XML file.
+ */
+ public PsiFile execute(final String actionName, final String moduleName) {
+ PsiDirectory parentDirectory = this.moduleIndex.getModuleDirectoryByModuleName(moduleName);
+ final ArrayList fileDirectories = new ArrayList<>();
+
+ fileDirectories.add(Package.moduleBaseAreaDir);
+
+ for (final String fileDirectory: fileDirectories) {
+ parentDirectory = this.directoryGenerator.findOrCreateSubdirectory(
+ parentDirectory,
+ fileDirectory
+ );
+ }
+
+ final ModuleFileInterface xml = instantiateXmlFile();
+
+ PsiFile xmlFile = FileBasedIndexUtil.findModuleConfigFile(
+ xml.getFileName(),
+ Areas.base,
+ moduleName,
+ project
+ );
+
+ // crontab.xml is already declared
+ if (xmlFile != null) {
+ return xmlFile;
+ }
+
+ // create a new empty XML file
+ xmlFile = fileFromTemplateGenerator.generate(
+ xml,
+ new Properties(),
+ parentDirectory,
+ actionName
+ );
+
+ return xmlFile;
+ }
+
+ protected abstract ModuleFileInterface instantiateXmlFile();
+}
diff --git a/src/com/magento/idea/magento2plugin/magento/files/QueueCommunicationXml.java b/src/com/magento/idea/magento2plugin/magento/files/QueueCommunicationXml.java
new file mode 100644
index 000000000..76598b78e
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/files/QueueCommunicationXml.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.magento.files;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.xml.XMLLanguage;
+
+public class QueueCommunicationXml implements ModuleFileInterface {
+ public static String fileName = "communication.xml";
+ public static String template = "Magento Queue Communication XML";
+
+ @Override
+ public String getFileName() {
+ return fileName;
+ }
+
+ @Override
+ public String getTemplate() {
+ return template;
+ }
+
+ @Override
+ public Language getLanguage() {
+ return XMLLanguage.INSTANCE;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/magento/files/QueueConsumerXml.java b/src/com/magento/idea/magento2plugin/magento/files/QueueConsumerXml.java
new file mode 100644
index 000000000..31ccba1a5
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/files/QueueConsumerXml.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.magento.files;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.xml.XMLLanguage;
+
+public class QueueConsumerXml implements ModuleFileInterface {
+ public static String fileName = "queue_consumer.xml";
+ public static String template = "Magento Queue Consumer XML";
+
+ @Override
+ public String getFileName() {
+ return fileName;
+ }
+
+ @Override
+ public String getTemplate() {
+ return template;
+ }
+
+ @Override
+ public Language getLanguage() {
+ return XMLLanguage.INSTANCE;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/magento/files/QueuePublisherXml.java b/src/com/magento/idea/magento2plugin/magento/files/QueuePublisherXml.java
new file mode 100644
index 000000000..789cc9000
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/files/QueuePublisherXml.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.magento.files;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.xml.XMLLanguage;
+
+public class QueuePublisherXml implements ModuleFileInterface {
+ public static String fileName = "queue_publisher.xml";
+ public static String template = "Magento Queue Publisher XML";
+
+ @Override
+ public String getFileName() {
+ return fileName;
+ }
+
+ @Override
+ public String getTemplate() {
+ return template;
+ }
+
+ @Override
+ public Language getLanguage() {
+ return XMLLanguage.INSTANCE;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/magento/files/QueueTopologyXml.java b/src/com/magento/idea/magento2plugin/magento/files/QueueTopologyXml.java
new file mode 100644
index 000000000..6a6451bc8
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/files/QueueTopologyXml.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.magento.files;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.xml.XMLLanguage;
+
+public class QueueTopologyXml implements ModuleFileInterface {
+ public static String fileName = "queue_topology.xml";
+ public static String template = "Magento Queue Topology XML";
+
+ @Override
+ public String getFileName() {
+ return fileName;
+ }
+
+ @Override
+ public String getTemplate() {
+ return template;
+ }
+
+ @Override
+ public Language getLanguage() {
+ return XMLLanguage.INSTANCE;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/util/RegExUtil.java b/src/com/magento/idea/magento2plugin/util/RegExUtil.java
index 2ca243d6a..86f135e9e 100644
--- a/src/com/magento/idea/magento2plugin/util/RegExUtil.java
+++ b/src/com/magento/idea/magento2plugin/util/RegExUtil.java
@@ -16,6 +16,12 @@ public class RegExUtil {
public static final String ALPHANUMERIC_WITH_UNDERSCORE
= "[a-zA-Z0-9_]*";
+ public static final String ALPHA_WITH_PERIOD
+ = "[a-zA-Z.]*";
+
+ public static final String ALPHA_WITH_DASH
+ = "[a-zA-Z-]*";
+
public static final String NUMERIC
= "[0-9]*";
@@ -38,6 +44,9 @@ public static class Magento {
public static final String PHP_CLASS
= "[A-Z][a-zA-Z0-9]+";
+ public static final String PHP_CLASS_FQN
+ = "(" + PHP_CLASS + ")?(\\" + PHP_CLASS + ")+";
+
public static final String MODULE_NAME
= "[A-Z][a-zA-Z0-9]+_[A-Z][a-zA-Z0-9]+";
diff --git a/testData/actions/generation/generator/QueueCommunicationGenerator/generateCommunicationXmlFile/communication.xml b/testData/actions/generation/generator/QueueCommunicationGenerator/generateCommunicationXmlFile/communication.xml
new file mode 100644
index 000000000..a1614910f
--- /dev/null
+++ b/testData/actions/generation/generator/QueueCommunicationGenerator/generateCommunicationXmlFile/communication.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/testData/actions/generation/generator/QueueConsumerGenerator/generateConsumerXmlFile/queue_consumer.xml b/testData/actions/generation/generator/QueueConsumerGenerator/generateConsumerXmlFile/queue_consumer.xml
new file mode 100644
index 000000000..ca08e43aa
--- /dev/null
+++ b/testData/actions/generation/generator/QueueConsumerGenerator/generateConsumerXmlFile/queue_consumer.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/testData/actions/generation/generator/QueuePublisherGenerator/generatePublisherXmlFile/queue_publisher.xml b/testData/actions/generation/generator/QueuePublisherGenerator/generatePublisherXmlFile/queue_publisher.xml
new file mode 100644
index 000000000..b15fbee1c
--- /dev/null
+++ b/testData/actions/generation/generator/QueuePublisherGenerator/generatePublisherXmlFile/queue_publisher.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/testData/actions/generation/generator/QueueTopologyGenerator/generateTopologyXmlFile/queue_topology.xml b/testData/actions/generation/generator/QueueTopologyGenerator/generateTopologyXmlFile/queue_topology.xml
new file mode 100644
index 000000000..a355bc8b5
--- /dev/null
+++ b/testData/actions/generation/generator/QueueTopologyGenerator/generateTopologyXmlFile/queue_topology.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueCommunicationGeneratorTest.java b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueCommunicationGeneratorTest.java
new file mode 100644
index 000000000..72b53a621
--- /dev/null
+++ b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueCommunicationGeneratorTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.magento.idea.magento2plugin.actions.generation.NewMessageQueueAction;
+import com.magento.idea.magento2plugin.actions.generation.data.QueueCommunicationData;
+import com.magento.idea.magento2plugin.magento.files.QueueCommunicationXml;
+
+public class QueueCommunicationGeneratorTest extends BaseGeneratorTestCase {
+ private static final String TOPIC_NAME = "topic.name";
+ private static final String HANDLER_NAME = "handlerName";
+ private static final String HANDLER_TYPE = "Foo\\Bar\\Model\\Handler";
+ private static final String HANDLER_METHOD = "execute";
+ private static final String MODULE_NAME = "Foo_Bar";
+ private static final String EXPECTED_DIRECTORY = "src/app/code/Foo/Bar/etc";
+
+ /**
+ * Tests for generation of communication.xml file.
+ */
+ public void testGenerateCommunicationXmlFile() {
+ final String filePath = this.getFixturePath(QueueCommunicationXml.fileName);
+ final PsiFile expectedFile = myFixture.configureByFile(filePath);
+ final Project project = myFixture.getProject();
+ final QueueCommunicationGenerator communicationGenerator = new QueueCommunicationGenerator(
+ project,
+ new QueueCommunicationData(
+ TOPIC_NAME,
+ HANDLER_NAME,
+ HANDLER_TYPE,
+ HANDLER_METHOD,
+ MODULE_NAME
+ )
+ );
+
+ final PsiFile file = communicationGenerator.generate(NewMessageQueueAction.ACTION_NAME);
+
+ assertGeneratedFileIsCorrect(expectedFile, EXPECTED_DIRECTORY, file);
+ }
+}
diff --git a/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGeneratorTest.java b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGeneratorTest.java
new file mode 100644
index 000000000..65613f482
--- /dev/null
+++ b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGeneratorTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.magento.idea.magento2plugin.actions.generation.NewMessageQueueAction;
+import com.magento.idea.magento2plugin.actions.generation.data.QueueConsumerData;
+import com.magento.idea.magento2plugin.magento.files.QueueConsumerXml;
+
+public class QueueConsumerGeneratorTest extends BaseGeneratorTestCase {
+ private static final String CONSUMER_NAME = "consumer.name";
+ private static final String QUEUE_NAME = "queue.name";
+ private static final String CONSUMER_TYPE = "Foo\\Bar\\Model\\Consumer";
+ private static final String MAX_MESSAGES = "100";
+ private static final String CONNECTION_NAME = "amqp";
+ private static final String MODULE_NAME = "Foo_Bar";
+ private static final String EXPECTED_DIRECTORY = "src/app/code/Foo/Bar/etc";
+
+ /**
+ * Tests for generation of queue_consumer.xml file.
+ */
+ public void testGenerateConsumerXmlFile() {
+ final String filePath = this.getFixturePath(QueueConsumerXml.fileName);
+ final PsiFile expectedFile = myFixture.configureByFile(filePath);
+ final Project project = myFixture.getProject();
+ final QueueConsumerGenerator consumerGenerator = new QueueConsumerGenerator(
+ project,
+ new QueueConsumerData(
+ CONSUMER_NAME,
+ QUEUE_NAME,
+ CONSUMER_TYPE,
+ MAX_MESSAGES,
+ CONNECTION_NAME,
+ MODULE_NAME
+ )
+ );
+
+ final PsiFile file = consumerGenerator.generate(NewMessageQueueAction.ACTION_NAME);
+
+ assertGeneratedFileIsCorrect(expectedFile, EXPECTED_DIRECTORY, file);
+ }
+}
diff --git a/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueuePublisherGeneratorTest.java b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueuePublisherGeneratorTest.java
new file mode 100644
index 000000000..f761c65e2
--- /dev/null
+++ b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueuePublisherGeneratorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.magento.idea.magento2plugin.actions.generation.NewMessageQueueAction;
+import com.magento.idea.magento2plugin.actions.generation.data.QueuePublisherData;
+import com.magento.idea.magento2plugin.magento.files.QueuePublisherXml;
+
+public class QueuePublisherGeneratorTest extends BaseGeneratorTestCase {
+ private static final String EXCHANGE_NAME = "exchange-name";
+ private static final String TOPIC_NAME = "topic.name";
+ private static final String CONNECTION_NAME = "amqp";
+ private static final String MODULE_NAME = "Foo_Bar";
+ private static final String EXPECTED_DIRECTORY = "src/app/code/Foo/Bar/etc";
+
+ /**
+ * Tests for generation of queue_publisher.xml file.
+ */
+ public void testGeneratePublisherXmlFile() {
+ final String filePath = this.getFixturePath(QueuePublisherXml.fileName);
+ final PsiFile expectedFile = myFixture.configureByFile(filePath);
+ final Project project = myFixture.getProject();
+ final QueuePublisherGenerator publisherGenerator = new QueuePublisherGenerator(
+ project,
+ new QueuePublisherData(
+ TOPIC_NAME,
+ CONNECTION_NAME,
+ EXCHANGE_NAME,
+ MODULE_NAME
+ )
+ );
+
+ final PsiFile file = publisherGenerator.generate(NewMessageQueueAction.ACTION_NAME);
+
+ assertGeneratedFileIsCorrect(expectedFile, EXPECTED_DIRECTORY, file);
+ }
+}
diff --git a/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueTopologyGeneratorTest.java b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueTopologyGeneratorTest.java
new file mode 100644
index 000000000..df01ec4f4
--- /dev/null
+++ b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueTopologyGeneratorTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.magento.idea.magento2plugin.actions.generation.NewMessageQueueAction;
+import com.magento.idea.magento2plugin.actions.generation.data.QueueTopologyData;
+import com.magento.idea.magento2plugin.magento.files.QueueTopologyXml;
+
+public class QueueTopologyGeneratorTest extends BaseGeneratorTestCase {
+ private static final String EXCHANGE_NAME = "exchange-name";
+ private static final String BINDING_ID = "bindingId";
+ private static final String BINDING_TOPIC = "topic.name";
+ private static final String BINDING_QUEUE = "queue.name";
+ private static final String CONNECTION_NAME = "amqp";
+ private static final String MODULE_NAME = "Foo_Bar";
+ private static final String EXPECTED_DIRECTORY = "src/app/code/Foo/Bar/etc";
+
+ /**
+ * Tests for generation of queue_topology.xml file.
+ */
+ public void testGenerateTopologyXmlFile() {
+ final String filePath = this.getFixturePath(QueueTopologyXml.fileName);
+ final PsiFile expectedFile = myFixture.configureByFile(filePath);
+ final Project project = myFixture.getProject();
+ final QueueTopologyGenerator topologyGenerator = new QueueTopologyGenerator(
+ project,
+ new QueueTopologyData(
+ EXCHANGE_NAME,
+ CONNECTION_NAME,
+ BINDING_ID,
+ BINDING_TOPIC,
+ BINDING_QUEUE,
+ MODULE_NAME
+ )
+ );
+
+ final PsiFile file = topologyGenerator.generate(NewMessageQueueAction.ACTION_NAME);
+
+ assertGeneratedFileIsCorrect(expectedFile, EXPECTED_DIRECTORY, file);
+ }
+}