Package fr.adrienbrault.idea.symfony2plugin.action.ui

Source Code of fr.adrienbrault.idea.symfony2plugin.action.ui.SymfonyCreateService$IconColumn

package fr.adrienbrault.idea.symfony2plugin.action.ui;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.psi.PsiFile;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.table.TableView;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import com.jetbrains.php.lang.psi.elements.*;
import fr.adrienbrault.idea.symfony2plugin.Symfony2InterfacesUtil;
import fr.adrienbrault.idea.symfony2plugin.dic.ContainerService;
import fr.adrienbrault.idea.symfony2plugin.stubs.ContainerCollectionResolver;
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.yaml.psi.YAMLFile;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.TableCellEditor;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;

public class SymfonyCreateService extends JDialog {

    private JPanel panel1;
    private JPanel content;
    private JTextField textFieldClassName;
    private JPanel tableViewPanel;
    private JTextArea textAreaOutput;
    private JButton generateButton;
    private JButton buttonCopy;
    private JButton closeButton;

    private JRadioButton radioButtonOutXml;
    private JRadioButton radioButtonOutYaml;
    private JTextField textFieldServiceName;

    private TableView<MethodParameter.MethodModelParameter> tableView;
    private ListTableModel<MethodParameter.MethodModelParameter> modelList;

    private Map<String, ContainerService> serviceClass;
    private Set<String> serviceSetComplete;

    private Project project;
    private String className;

    @Nullable
    private PsiFile psiFile;

    public SymfonyCreateService(Project project, String className) {
        this(project, (PsiFile) null);
        this.className = className;
    }

    public SymfonyCreateService(Project project, @Nullable PsiFile psiFile) {
        this.project = project;
        this.psiFile = psiFile;
    }

    public void init() {

        setContentPane(panel1);
        setModal(true);

        this.modelList = new ListTableModel<MethodParameter.MethodModelParameter>(
            new IconColumn(),
            new NamespaceColumn(),
            new ParameterIndexColumn(),
            new ServiceColumn(),
            new IsServiceColumn()
        );

        // default is xml
        radioButtonOutXml.setSelected(true);
        if(this.psiFile instanceof YAMLFile) {
            radioButtonOutYaml.setSelected(true);
        }


        this.tableView = new TableView<MethodParameter.MethodModelParameter>();
        this.tableView.setModelAndUpdateColumns(this.modelList);

        tableViewPanel.add(ToolbarDecorator.createDecorator(this.tableView)
            .disableAddAction()
            .disableDownAction()
            .disableRemoveAction()
            .disableUpDownActions()
            .createPanel()
        );

        this.serviceClass = ContainerCollectionResolver.getServices(project);

        this.serviceSetComplete = new TreeSet<String>();
        serviceSetComplete.add("");
        serviceSetComplete.addAll(this.serviceClass.keySet());

        //update();

        this.modelList.addTableModelListener(new TableModelListener() {
            @Override
            public void tableChanged(TableModelEvent e) {
                generateServiceDefinition();
            }

        });

        this.generateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                update();
            }
        });


        this.closeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setEnabled(false);
                dispose();
            }
        });

        this.buttonCopy.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(StringUtils.isBlank(textAreaOutput.getText())) {
                    return;
                }

                StringSelection stringSelection = new StringSelection(textAreaOutput.getText());
                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard ();
                clipboard.setContents(stringSelection, null);
            }
        });

        if(this.className != null) {
            this.textFieldClassName.setText(this.className);
            update();
        }

        radioButtonOutXml.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                generateServiceDefinition();
            }
        });

        radioButtonOutYaml.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                generateServiceDefinition();
            }
        });

        textFieldServiceName.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                generateServiceDefinition();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                generateServiceDefinition();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                generateServiceDefinition();
            }
        });

    }

    private void generateServiceDefinition() {

        if(StringUtils.isBlank(textFieldClassName.getText())) {
            return;
        }

        ServiceBuilder.OutputType outputType = ServiceBuilder.OutputType.XML;
        if(radioButtonOutYaml.isSelected()) {
            outputType = ServiceBuilder.OutputType.Yaml;
        }

        textAreaOutput.setText(new ServiceBuilder(this.modelList.getItems(), this.project).build(
            outputType,
            textFieldClassName.getText(),
            textFieldServiceName.getText()
        ));
    }

    private void update() {
        ApplicationManager.getApplication().runReadAction(new Thread(new Runnable() {
            @Override
            public void run() {
                updateTask();
            }
        }));
    }

    private void updateTask() {

        String className = textFieldClassName.getText();
        if(className.startsWith("\\")) {
            className = className.substring(1);
        }

        if(className.length() == 0) {
            return;
        }

        textFieldServiceName.setText(generateServiceName(className));

        PhpClass phpClass = PhpElementsUtil.getClass(project, className);
        if(phpClass == null) {
            JOptionPane.showMessageDialog(null, String.format("invalid %s class", className));
            return;
        }

        ArrayList<MethodParameter.MethodModelParameter> modelParameters = new ArrayList<MethodParameter.MethodModelParameter>();

        for(Method method: phpClass.getMethods()) {
            if(method.getModifier().isPublic()) {
                Parameter[] parameters = method.getParameters();
                for (int i = 0; i < parameters.length; i++) {
                    Set<String> possibleServices = getPossibleServices(parameters[i]);
                    if(possibleServices.size() > 0) {
                        modelParameters.add(new MethodParameter.MethodModelParameter(method, parameters[i], i, possibleServices, getServiceName(possibleServices)));
                    } else {
                        modelParameters.add(new MethodParameter.MethodModelParameter(method, parameters[i], i, serviceSetComplete));
                    }

                }
            }

            method.getName();
        }

        Collections.sort(modelParameters, new Comparator<MethodParameter.MethodModelParameter>() {
            @Override
            public int compare(MethodParameter.MethodModelParameter o1, MethodParameter.MethodModelParameter o2) {
                int i = o1.getName().compareTo(o2.getName());
                if (i != 0) {
                    return i;
                }

                return Integer.valueOf(o1.getIndex()).compareTo(o2.getIndex());
            }
        });

        while(this.modelList.getRowCount() > 0) {
            this.modelList.removeRow(0);
        }

        this.modelList.addRows(modelParameters);
        generateServiceDefinition();
    }

    @Nullable
    private String getServiceName(Set<String> services) {
        if(services.size() == 0) {
            return null;
        }

        // we have a weight sorted Set, so first one
        return services.iterator().next();
    }

    @Override
    protected void dialogInit() {
        super.dialogInit();
    }

    public void setClassName(String className) {
        this.className = className;
    }

    private class IsServiceColumn extends ColumnInfo<MethodParameter.MethodModelParameter, Boolean> {

        public IsServiceColumn() {
            super("Act");
        }

        @Nullable
        @Override
        public Boolean valueOf(MethodParameter.MethodModelParameter modelParameter) {
            return modelParameter.isPossibleService();
        }

        public void setValue(MethodParameter.MethodModelParameter modelParameter, Boolean value){
            modelParameter.setPossibleService(value);
            tableView.getListTableModel().fireTableDataChanged();
        }

        public Class getColumnClass() {
            return Boolean.class;
        }

        public boolean isCellEditable(MethodParameter.MethodModelParameter modelParameter) {
            return true;
        }

        @Override
        public int getWidth(JTable table) {
            return 36;
        }

    }

    private class ServiceColumn extends ColumnInfo<MethodParameter.MethodModelParameter, String> {

        public ServiceColumn() {
            super("Service");
        }

        @Nullable
        @Override
        public String valueOf(MethodParameter.MethodModelParameter modelParameter) {
            return modelParameter.getCurrentService();
        }

        public void setValue(MethodParameter.MethodModelParameter modelParameter, String value){
            modelParameter.setCurrentService(value);
            tableView.getListTableModel().fireTableDataChanged();
        }

        @Override
        public boolean isCellEditable(MethodParameter.MethodModelParameter modelParameter) {
            return true;
        }

        @Nullable
        @Override
        public TableCellEditor getEditor(MethodParameter.MethodModelParameter modelParameter) {

            Set<String> sorted = modelParameter.getPossibleServices();
            ComboBox comboBox = new ComboBox(sorted.toArray(new String[sorted.size()] ), 200);
            comboBox.setEditable(true);

            return new DefaultCellEditor(comboBox);
        }
    }

    private class NamespaceColumn extends ColumnInfo<MethodParameter.MethodModelParameter, String> {

        public NamespaceColumn() {
            super("Method");
        }

        @Nullable
        @Override
        public String valueOf(MethodParameter.MethodModelParameter modelParameter) {
            return modelParameter.getName();
        }
    }

    private class IconColumn extends ColumnInfo<MethodParameter.MethodModelParameter, Icon> {
        public IconColumn() {
            super("");
        }

        @Nullable
        @Override
        public Icon valueOf(MethodParameter.MethodModelParameter modelParameter) {
            return modelParameter.getMethod().getIcon();
        }

        public java.lang.Class getColumnClass() {
            return ImageIcon.class;
        }

        @Override
        public int getWidth(JTable table) {
            return 32;
        }

    }

    private class ParameterIndexColumn extends ColumnInfo<MethodParameter.MethodModelParameter, String> {

        public ParameterIndexColumn() {
            super("Parameter");
        }

        @Nullable
        @Override
        public String valueOf(MethodParameter.MethodModelParameter modelParameter) {
            return modelParameter.getParameter().getName();
        }
    }


    private Set<String> getPossibleServices(Parameter parameter) {

        Set<String> possibleServices = new LinkedHashSet<String>();
        List<ContainerService> matchedContainer = new ArrayList<ContainerService>();

        PhpPsiElement phpPsiElement = parameter.getFirstPsiChild();
        if(!(phpPsiElement instanceof ClassReference)) {
            return possibleServices;
        }

        String type = ((ClassReference) phpPsiElement).getFQN();
        if(type != null) {
            PhpClass typeClass = PhpElementsUtil.getClassInterface(project, type);
            if(typeClass != null) {
                for(Map.Entry<String, ContainerService> entry: serviceClass.entrySet()) {
                    if(entry.getValue().getClassName() != null) {
                        PhpClass serviceClass = PhpElementsUtil.getClassInterface(project, entry.getValue().getClassName());
                        if(serviceClass != null) {
                            if(new Symfony2InterfacesUtil().isInstanceOf(serviceClass, typeClass)) {
                                matchedContainer.add(entry.getValue());
                            }
                        }
                    }

                }
            }
        }

        if(matchedContainer.size() > 0) {

            // weak service have lower priority
            Collections.sort(matchedContainer, new ContainerServicePriorityWeakComparator());

            // lower priority of services like "doctrine.orm.default_entity_manager"
            Collections.sort(matchedContainer, new ContainerServicePriorityNameComparator());

            for(ContainerService containerService: matchedContainer) {
                possibleServices.add(containerService.getName());
            }

        }



        return possibleServices;
    }


    private static class ContainerServicePriorityNameComparator implements Comparator<ContainerService> {

        private static String[] LOWER_PRIORITY = new String[] { "debug", "default", "abstract"};

        @Override
        public int compare(ContainerService o1, ContainerService o2) {

            if(this.isLowerPriority(o1.getName()) && this.isLowerPriority(o2.getName())) {
                return 0;
            }

            if(this.isLowerPriority(o1.getName())) {
                return 1;
            }

            return -1;
        }

        private boolean isLowerPriority(String name) {

            for(String lowerName: LOWER_PRIORITY) {
                if(name.contains(lowerName)) {
                    return true;
                }
            }

            return false;
        }

    }

    private static class ContainerServicePriorityWeakComparator implements Comparator<ContainerService> {
        @Override
        public int compare(ContainerService o1, ContainerService o2) {

            if(o1.isWeak() == o2.isWeak()) {
                return 0;
            }

            return (o1.isWeak() ? 1 : -1);
        }
    }

    private String generateServiceName(String className) {

        if(className.contains("Bundle")) {
            String formattedName = className.substring(0, className.indexOf("Bundle") + 6).toLowerCase().replace("\\", "_");
            formattedName += className.substring(className.indexOf("Bundle") + 6).toLowerCase().replace("\\", ".");
            return formattedName;
        }

        return className.toLowerCase().replace("\\", "_");
    }

}





TOP

Related Classes of fr.adrienbrault.idea.symfony2plugin.action.ui.SymfonyCreateService$IconColumn

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
d', 'pageview');