org.ebayopensource.turmeric.eclipse.services.ui.properties.SOAServiceDependenciesPage.java Source code

Java tutorial

Introduction

Here is the source code for org.ebayopensource.turmeric.eclipse.services.ui.properties.SOAServiceDependenciesPage.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *******************************************************************************/
package org.ebayopensource.turmeric.eclipse.services.ui.properties;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.StringUtils;
import org.ebayopensource.turmeric.eclipse.buildsystem.utils.ProjectProtoBufFileUtil;
import org.ebayopensource.turmeric.eclipse.buildsystem.utils.PropertiesUtil;
import org.ebayopensource.turmeric.eclipse.core.logging.SOALogger;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOAProjectConstants;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOAProjectConstants.Binding;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOAProjectConstants.DataBinding;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOAProjectConstants.MessageProtocol;
import org.ebayopensource.turmeric.eclipse.exception.resources.SOAResourceModifyFailedException;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.GlobalRepositorySystem;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.ISOAAssetRegistry;
import org.ebayopensource.turmeric.eclipse.repositorysystem.utils.TurmericServiceUtils;
import org.ebayopensource.turmeric.eclipse.resources.model.ISOAConsumerProject.SOAClientConfig;
import org.ebayopensource.turmeric.eclipse.resources.model.ISOAConsumerProject.SOAClientEnvironment;
import org.ebayopensource.turmeric.eclipse.resources.model.ISOAProject;
import org.ebayopensource.turmeric.eclipse.resources.model.ProjectInfo;
import org.ebayopensource.turmeric.eclipse.resources.model.SOAIntfProject;
import org.ebayopensource.turmeric.eclipse.resources.util.SOAConsumerUtil;
import org.ebayopensource.turmeric.eclipse.resources.util.SOAConsumerUtil.EnvironmentItem;
import org.ebayopensource.turmeric.eclipse.resources.util.SOAIntfUtil;
import org.ebayopensource.turmeric.eclipse.ui.components.SOAConsumerServicesViewer;
import org.ebayopensource.turmeric.eclipse.ui.components.SimpleComboBoxEditor;
import org.ebayopensource.turmeric.eclipse.utils.io.PropertiesFileUtil;
import org.ebayopensource.turmeric.eclipse.utils.plugin.EclipseMessageUtils;
import org.ebayopensource.turmeric.eclipse.utils.plugin.ProgressUtil;
import org.ebayopensource.turmeric.eclipse.utils.plugin.WorkspaceUtil;
import org.ebayopensource.turmeric.eclipse.utils.ui.UIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IWorkbenchPropertyPage;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.jdom.JDOMException;

/**
 * @author yayu
 * 
 */
public class SOAServiceDependenciesPage extends FieldEditorPreferencePage implements IWorkbenchPropertyPage {
    public static final String REQUIRED_SERVICES_DELIMITER = ",";
    private IProject project;
    private boolean isOldClientConfigDirStructure = false;

    private Map<FieldEditor, Composite> editorParentMap = new ConcurrentHashMap<FieldEditor, Composite>();
    // single selection list
    private SOAConsumerServicesViewer serviceList;
    private StringFieldEditor serviceLocationEditor;
    private SimpleComboBoxEditor serviceBindingEditor;
    private SimpleComboBoxEditor serviceRequestBindingEditor;
    private SimpleComboBoxEditor serviceResponseBindingEditor;
    private SimpleComboBoxEditor messageProtocolEditor;

    private String currentAdminName = null;
    private boolean currentCanUseProtoBuf = false;

    private String currentServiceLocation = "";

    private static final SOALogger logger = SOALogger.getLogger();

    private static String[][] FULL_PROTOCOL_LIST;

    private static String[][] DEFAULT_PROTOCOL_LIST;

    private boolean isEnvEmpty = true;

    static {
        FULL_PROTOCOL_LIST = new String[DataBinding.values().length][2];
        DEFAULT_PROTOCOL_LIST = new String[DataBinding.values().length - 1][2];
        int index = 0;
        int defaultIndex = 0;
        for (DataBinding binding : DataBinding.values()) {
            String bindingName = binding.name();
            FULL_PROTOCOL_LIST[index][0] = bindingName;
            FULL_PROTOCOL_LIST[index][1] = bindingName;
            index++;
            if ("PROTOBUF".equalsIgnoreCase(bindingName) == false) {
                DEFAULT_PROTOCOL_LIST[defaultIndex][0] = bindingName;
                DEFAULT_PROTOCOL_LIST[defaultIndex][1] = bindingName;
                defaultIndex++;
            }
        }
    }

    public SOAServiceDependenciesPage() {
        super(FieldEditorPreferencePage.GRID);
        noDefaultAndApplyButton();
    }

    @Override
    protected void createFieldEditors() {
        if (project != null) {
            try {
                addServiceDependenciesList();
                // create a group
                Composite parent = getFieldEditorParent();
                Group group = new Group(parent, SWT.NONE);
                group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));// why 2? 2 is the max num of controls
                group.setText("Client Config Details");
                // add controls in the group
                addServiceLocation(group);
                addServiceBinding(group);
                addServiceRequestDataBinding(group);
                addServiceResponseDataBinding(group);
                addMessageProtocol(group);

                /*
                 * Do not move the following 6 lines of code above, the
                 * createControl method of FieldEditor would always create a new
                 * layout for group. so we create a new layout after all
                 * controls are inited and thus re-layout the page.
                 */
                GridLayout layout = new GridLayout(2, false);
                initGridLayout(layout, true);
                group.setLayout(layout);
                Layout parentLayout = parent.getLayout();
                if (parentLayout instanceof GridLayout) {
                    ((GridLayout) parentLayout).verticalSpacing = 12;
                }
            } catch (Exception e) {
                logger.error(e);
                UIUtil.showErrorDialog(e);
            }
        }
    }

    private GridLayout initGridLayout(GridLayout layout, boolean margins) {
        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
        if (margins) {
            layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
            layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
        } else {
            layout.marginWidth = 0;
            layout.marginHeight = 0;
        }

        return layout;
    }

    public IAdaptable getElement() {
        return null;
    }

    private SOAClientEnvironment getCurrentSelectedService() {
        if (serviceList != null && serviceList.getTree().getSelectionCount() == 1) {
            TreeItem item = serviceList.getTree().getSelection()[0];
            if (item.getParentItem() == null)
                return null;

            Object parentObj = item.getParentItem().getData();
            currentAdminName = item.getData().toString();
            if (parentObj instanceof EnvironmentItem) {
                String envName = isOldClientConfigDirStructure ? null : ((EnvironmentItem) parentObj).getName();
                return new SOAClientEnvironment(envName, currentAdminName);
            }
        }
        return null;
    }

    private void addServiceDependenciesList() throws CoreException, IOException {
        Composite parent = getFieldEditorParent();
        /*
         * { Composite composite = new Composite(parent, SWT.NONE);
         * composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
         * composite.setLayout(new GridLayout(2, false)); Label label = new
         * Label(composite, SWT.NONE); label.setText("Client Name:"); Text text
         * = new Text(composite, SWT.BORDER); text.setEditable(false);
         * text.setText(SOAConsumerUtil.getServiceClientName(project));
         * text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); }
         */

        final Group listComposite = new Group(parent, SWT.NONE);
        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
        gridData.heightHint = 200;
        listComposite.setLayoutData(gridData);
        listComposite.setLayout(new GridLayout(1, false));
        listComposite.setText("Client Configurations");

        serviceList = new SOAConsumerServicesViewer(listComposite, false);
        List<EnvironmentItem> envList = SOAConsumerUtil.getClientConfigStructure(project);
        isEnvEmpty = envList == null || envList.isEmpty();
        serviceList.setInput(envList);

        this.serviceList.addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(SelectionChangedEvent event) {
                try {
                    load();
                } catch (Exception eX) {
                    logger.error(eX);
                    UIUtil.showErrorDialog(eX);
                }
            }

        });
    }

    private void addServiceLocation(Group group) {
        serviceLocationEditor = new StringFieldEditor("", "Service Location: ", group);
        // serviceLocationEditor.getTextControl(group).setEnabled(false);
        editorParentMap.put(serviceLocationEditor, group);
        addField(serviceLocationEditor);
    }

    @Override
    protected void initialize() {
        super.initialize();
        try {
            isOldClientConfigDirStructure = SOAConsumerUtil.isOldClientConfigDirStructure(project);
            if (isOldClientConfigDirStructure) {
                String message = GlobalRepositorySystem.instanceOf().getActiveRepositorySystem()
                        .getProjectHealthChecker().getWarningMessageConsumeProjectStructureOld();
                setMessage(message, IStatus.WARNING);
            }
        } catch (CoreException e) {
            logger.warning(e);
        }
        if (this.serviceList != null && this.serviceList.getTree().getItemCount() > 0) {
            TreeItem item = this.serviceList.getTree().getItem(0);

            if (item.getData() instanceof EnvironmentItem && item.getItemCount() > 0) {
                item = item.getItem(0);
            }
            this.serviceList.getTree().setSelection(item);
            try {
                load();
            } catch (Exception e) {
                logger.error(e);
                UIUtil.showErrorDialog(e);
            }
        } else {
            setFieldEditorEnabled(false, true);
        }

    }

    private void load() throws IOException, JDOMException {
        final SOAClientEnvironment clientEnv = getCurrentSelectedService();
        if (clientEnv == null) {
            // currently selected is the environment
            setFieldEditorEnabled(false, true);
            return;
        }

        SOAClientConfig config = null;
        try {
            if (isOldClientConfigDirStructure) {
                config = SOAConsumerUtil.loadClientConfig(project, null, clientEnv.getServiceName());
            } else {
                config = SOAConsumerUtil.loadClientConfig(project, clientEnv.getEnvironment(),
                        clientEnv.getServiceName());
            }
        } catch (CoreException e) {
            logger.error(e);
        }

        if (config != null) {
            final String serviceLocation = config != null && config.getServiceLocation() != null
                    ? config.getServiceLocation()
                    : "";
            currentServiceLocation = serviceLocation;
            currentCanUseProtoBuf = validateProtoBuf(serviceLocation);
            String[][] nvPares = DEFAULT_PROTOCOL_LIST;
            if (currentCanUseProtoBuf == true) {
                nvPares = FULL_PROTOCOL_LIST;
            }
            final String serviceBinding = config != null && config.getServiceBinding() != null
                    ? config.getServiceBinding()
                    : Binding.LOCAL.name();
            final String requestBinding = config != null && config.getRequestDataBinding() != null
                    ? config.getRequestDataBinding()
                    : DataBinding.XML.name();
            final String responseBinding = config != null && config.getResponseDataBinding() != null
                    ? config.getResponseDataBinding()
                    : DataBinding.XML.name();
            final String messageProtocol = config != null && config.getMessageProtocol() != null
                    ? config.getMessageProtocol()
                    : MessageProtocol.NONE.name();

            serviceLocationEditor.setStringValue(serviceLocation);

            serviceRequestBindingEditor.updateProtocolList(requestBinding, nvPares);
            serviceResponseBindingEditor.updateProtocolList(responseBinding, nvPares);
            // serviceRequestBindingEditor.getComboBoxControl(
            // editorParentMap.get(serviceRequestBindingEditor)).setText(
            // requestBinding);
            // serviceResponseBindingEditor.getComboBoxControl(
            // editorParentMap.get(serviceResponseBindingEditor)).setText(
            // responseBinding);
            messageProtocolEditor.getComboBoxControl(editorParentMap.get(messageProtocolEditor))
                    .setText(messageProtocol);

            // invoke this so that the modify listener will be triggered.
            serviceBindingEditor.getComboBoxControl(editorParentMap.get(serviceBindingEditor))
                    .setText(serviceBinding);

            setFieldEditorEnabled(true, false);
        }
    }

    private boolean validateProtoBuf(String serviceLocation) {
        try {
            // if this project is intf project and have nonXSDFormats=protobuf
            // in sipp, return true;
            IProject project = WorkspaceUtil.getProject(currentAdminName);
            if (project.isAccessible() == true) {
                ISOAProject soaProject = GlobalRepositorySystem.instanceOf().getActiveRepositorySystem()
                        .getAssetRegistry().getSOAProject(project);
                if (soaProject instanceof SOAIntfProject) {
                    IFile sipp = project.getFile(SOAProjectConstants.PROPS_FILE_SERVICE_INTERFACE);
                    if (sipp.isAccessible()) {
                        String noXSDSchema = PropertiesFileUtil.getPropertyValueByKey(sipp.getContents(),
                                SOAProjectConstants.PROP_KEY_NON_XSD_FORMATS);
                        if (noXSDSchema != null && noXSDSchema.contains(SOAProjectConstants.SVC_PROTOCOL_BUF)) {
                            return true;
                        }
                    }
                    return false;
                }
            }
            // try to find service in service jar

            String noXSDSchema = getValueFromServiceProps(currentAdminName,
                    SOAProjectConstants.PROP_KEY_NON_XSD_FORMATS);
            if (noXSDSchema != null && noXSDSchema.contains(SOAProjectConstants.SVC_PROTOCOL_BUF)) {
                return true;
            }
            // try to access service location?proto
            String content = ProjectProtoBufFileUtil.getProtoBufFile(serviceLocation);
            return StringUtils.isNotBlank(content);
        } catch (Exception e) {
            return false;
        }
    }

    private static String getValueFromServiceProps(final String serviceName, final String key) throws Exception {
        final ISOAAssetRegistry registry = GlobalRepositorySystem.instanceOf().getActiveRepositorySystem()
                .getAssetRegistry();
        final String assetLocation = registry.getAssetLocation(serviceName);
        final Properties props = SOAIntfUtil.loadMetadataProps(assetLocation, serviceName);
        if (props != null) {
            return StringUtils.trim(props.getProperty(key));
        }
        return null;
    }

    private void setFieldEditorEnabled(boolean enabled, boolean clearData) {
        for (FieldEditor editor : editorParentMap.keySet()) {
            if (editor instanceof SimpleComboBoxEditor) {
                ((SimpleComboBoxEditor) editor).getComboBoxControl(editorParentMap.get(editor)).setEnabled(enabled);
                if (clearData == true)
                    ((SimpleComboBoxEditor) editor).getComboBoxControl(editorParentMap.get(editor))
                            .clearSelection();
            } else if (editor instanceof StringFieldEditor) {
                ((StringFieldEditor) editor).getTextControl(editorParentMap.get(editor)).setEnabled(enabled);
                if (clearData == true)
                    ((StringFieldEditor) editor).getTextControl(editorParentMap.get(editor)).setText("");
            }
        }
    }

    private void addServiceBinding(Group group) {
        String strArray[][] = new String[Binding.values().length][2];
        int index = 0;
        for (Binding binding : Binding.values()) {
            strArray[index][0] = binding.name();
            strArray[index][1] = binding.name();
            index++;
        }
        serviceBindingEditor = new SimpleComboBoxEditor("", "Service Binding:", strArray, group);
        addField(serviceBindingEditor);
        editorParentMap.put(serviceBindingEditor, group);

        final Combo bindingList = serviceBindingEditor
                .getComboBoxControl(editorParentMap.get(serviceBindingEditor));
        bindingList.addModifyListener(new ModifyListener() {

            public void modifyText(ModifyEvent e) {
                String bindingStr = bindingList.getText();
                Text svcLoctext = serviceLocationEditor.getTextControl(editorParentMap.get(serviceLocationEditor));
                if (Binding.LOCAL.name().equals(bindingStr)) {
                    svcLoctext.setText(currentServiceLocation);
                    svcLoctext.setEditable(false);
                } else {
                    svcLoctext.setEditable(true);
                }
            }
        });
    }

    private void addServiceRequestDataBinding(Group group) {
        serviceRequestBindingEditor = new SimpleComboBoxEditor("", "Request DataBinding:", FULL_PROTOCOL_LIST,
                group);
        addField(serviceRequestBindingEditor);
        editorParentMap.put(serviceRequestBindingEditor, group);
    }

    private void addServiceResponseDataBinding(Group group) {
        serviceResponseBindingEditor = new SimpleComboBoxEditor("", "Response DataBinding:", FULL_PROTOCOL_LIST,
                group);
        addField(serviceResponseBindingEditor);
        editorParentMap.put(serviceResponseBindingEditor, group);
    }

    private IStatus validateProtocol() {
        if (currentCanUseProtoBuf == true) {
            return Status.OK_STATUS;
        }

        String newRequestDataBinding = getText(serviceRequestBindingEditor);
        String newResponseDataBinding = getText(serviceResponseBindingEditor);

        if ("protobuf".equalsIgnoreCase(newRequestDataBinding)
                || "protobuf".equalsIgnoreCase(newResponseDataBinding)) {
            return EclipseMessageUtils.createErrorStatus("ProtoBuf is not supported by current service.", null);
        }
        return Status.OK_STATUS;
    }

    private void addMessageProtocol(Group group) {
        String strArray[][] = new String[MessageProtocol.values().length][2];
        int index = 0;
        for (MessageProtocol protocol : MessageProtocol.values()) {
            strArray[index][0] = protocol.name();
            strArray[index][1] = protocol.name();
            index++;
        }
        messageProtocolEditor = new SimpleComboBoxEditor("", "Message Protocol:", strArray, group);
        addField(messageProtocolEditor);
        editorParentMap.put(messageProtocolEditor, group);
    }

    public void setElement(IAdaptable element) {
        try {
            if (element.getAdapter(IProject.class) instanceof IProject) {
                project = (IProject) element.getAdapter(IProject.class);
            }
        } catch (Exception exception) {
            logger.error(exception);
            UIUtil.showErrorDialog(exception);
        }
    }

    private String getText(StringFieldEditor stringFieldEditor) {
        return stringFieldEditor.getTextControl(editorParentMap.get(stringFieldEditor)).getText();
    }

    private String getText(SimpleComboBoxEditor simpleComboEditor) {
        return simpleComboEditor.getComboBoxControl(editorParentMap.get(simpleComboEditor)).getText();
    }

    @Override
    public boolean performOk() {
        try {
            // so we should collect all required information right now.
            final SOAClientEnvironment clientEnv = getCurrentSelectedService();
            if (clientEnv == null)
                // no service selected
                return true;
            final String serviceName = clientEnv.getServiceName();
            final String newServiceLocation = getText(serviceLocationEditor);
            final String newServiceBinding = getText(serviceBindingEditor);
            final String newMessageProtocol = getText(messageProtocolEditor);
            final String newRequestDataBinding = getText(serviceRequestBindingEditor);
            final String newResponseDataBinding = getText(serviceResponseBindingEditor);
            final String[] requiredServices = {};// serviceList.getItems();

            final ProjectInfo intfProjectInfo = GlobalRepositorySystem.instanceOf().getActiveRepositorySystem()
                    .getAssetRegistry().getProjectInfo(serviceName);
            final String implProjectName = intfProjectInfo.getImplementationProjectName();
            IStatus status = PropertiesUtil.validate(serviceName, implProjectName, newServiceLocation,
                    newServiceBinding);

            IStatus statusProtocol = validateProtocol();

            if (statusProtocol != Status.OK_STATUS) {
                setErrorMessage(status.getMessage());
                Throwable t = null;
                UIUtil.showErrorDialog(getShell(), "Validation Failed", status.getMessage(), t);
                return false;
            }

            if (status == Status.OK_STATUS) {
                setErrorMessage(null);
                final WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {

                    @Override
                    protected void execute(IProgressMonitor monitor)
                            throws CoreException, InvocationTargetException, InterruptedException {
                        monitor.beginTask(
                                "Modifying the properties and dependencies for SOA service -> " + serviceName,
                                ProgressUtil.PROGRESS_STEP * 15);
                        try {
                            PropertiesUtil.modifyServiceDependencies(project, clientEnv.getEnvironment(),
                                    serviceName, implProjectName, newServiceLocation, newServiceBinding,
                                    newMessageProtocol, newRequestDataBinding, newResponseDataBinding,
                                    requiredServices, monitor);
                        } catch (Exception e) {
                            throw new SOAResourceModifyFailedException(
                                    "Failed to modify dependencies and/or properties for SOA service -> "
                                            + serviceName,
                                    e);
                        } finally {
                            monitor.done();
                        }
                    }
                };
                new ProgressMonitorDialog(getControl().getShell()).run(true, true, operation);
            } else {
                setErrorMessage(status.getMessage());
                Throwable t = null;
                UIUtil.showErrorDialog(getShell(), "Validation Failed", status.getMessage(), t);
            }
        } catch (Exception e) {
            logger.error(e);
            UIUtil.showErrorDialog(e);
            return false;
        }
        return true;
    }

    @Override
    protected void checkState() {
        try {
            if (TurmericServiceUtils.isSOAImplProject(project)) {
                // if the underlying project is impl, we should skip the
                // validation.
                return;
            }
        } catch (CoreException e) {
            logger.error(e);
            UIUtil.showErrorDialog(e);
        }
        super.checkState();
        if (isValid() == false && isEnvEmpty == true) {
            setValid(true);
        }
    }

}