Package com.salesforce.ide.core.internal.components

Source Code of com.salesforce.ide.core.internal.components.ComponentController

/*******************************************************************************
* Copyright (c) 2014 Salesforce.com, inc..
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Salesforce.com, inc. - initial API and implementation
******************************************************************************/
package com.salesforce.ide.core.internal.components;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.SortedSet;

import javax.xml.bind.JAXBException;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import com.salesforce.ide.core.ForceIdeCorePlugin;
import com.salesforce.ide.core.factories.FactoryException;
import com.salesforce.ide.core.internal.context.ContainerDelegate;
import com.salesforce.ide.core.internal.controller.Controller;
import com.salesforce.ide.core.internal.utils.Constants;
import com.salesforce.ide.core.internal.utils.Messages;
import com.salesforce.ide.core.internal.utils.PackageManifestDocumentUtils;
import com.salesforce.ide.core.internal.utils.Utils;
import com.salesforce.ide.core.model.Component;
import com.salesforce.ide.core.model.ComponentList;
import com.salesforce.ide.core.model.ProjectPackageList;
import com.salesforce.ide.core.project.ForceProject;
import com.salesforce.ide.core.project.ForceProjectException;
import com.salesforce.ide.core.project.MarkerUtils;
import com.salesforce.ide.core.remote.Connection;
import com.salesforce.ide.core.remote.ForceConnectionException;
import com.salesforce.ide.core.remote.ForceRemoteException;
import com.salesforce.ide.core.remote.InsufficientPermissionsException;
import com.salesforce.ide.core.remote.metadata.DeployResultExt;
import com.salesforce.ide.core.remote.metadata.FileMetadataExt;
import com.salesforce.ide.core.remote.registries.DescribeObjectRegistry;
import com.salesforce.ide.core.services.ServiceException;
import com.salesforce.ide.core.services.ServiceTimeoutException;
import com.sforce.soap.metadata.FileProperties;

public class ComponentController extends Controller {
    private static final Logger logger = Logger.getLogger(ComponentController.class);

    protected DeployResultExt deployResultHandler = null;

    public ComponentController(ComponentModel componentWizardModel) throws ForceProjectException {
        super();
        model = componentWizardModel;
        init();
    }

    @Override
    public void init() throws ForceProjectException {
        getComponentWizardModel().setComponentFactory(ContainerDelegate.getInstance().getFactoryLocator().getComponentFactory());
        getComponentWizardModel().initComponent();
    }

    public ComponentModel getComponentWizardModel() {
        return (ComponentModel) model;
    }

    public void setComponentWizardModel(ComponentModel componentWizardModel) {
        this.model = componentWizardModel;
    }

    public void setResources(IFolder folder, IProject project) {
        getComponentWizardModel().setFolder(folder);
        getComponentWizardModel().setProject(project);
    }

    public String getComponentType() {
        return getComponentWizardModel().getComponent().getComponentType();
    }

    public Component getComponent() {
        return getComponentWizardModel().getComponent();
    }

    public DeployResultExt getDeployResultExt() {
        return deployResultHandler;
    }

    public void setDeployResultExt(DeployResultExt deployResultExt) {
        this.deployResultHandler = deployResultExt;
    }

    public Component getNewComponentByComponentType(String componentType) throws FactoryException {
        return ContainerDelegate.getInstance().getFactoryLocator().getComponentFactory().getComponentByComponentType(componentType);
    }

    public IFile getComponentResoruce() {
        return getComponentWizardModel().getComponent().getFileResource();
    }

    public void clean() {
        model = null;
    }

    public boolean isComponentEnabled() throws ForceConnectionException, ForceRemoteException, InterruptedException,
    FactoryException {
        if (getComponentWizardModel().getProject() == null) {
            logger.error("Unable to check " + getComponentWizardModel().getComponent().getDisplayName()
                + " permissions - project is null");
            return false;
        }
        ForceProject forceProject = ContainerDelegate.getInstance().getServiceLocator().getProjectService().getForceProject(getComponentWizardModel().getProject());

        Connection connection = ContainerDelegate.getInstance().getFactoryLocator().getConnectionFactory().getConnection(forceProject);
        boolean componentEnabled =
                ContainerDelegate.getInstance().getServiceLocator().getMetadataService().isComponentTypeEnabled(connection,
                    getComponentWizardModel().getComponentType());
        if (logger.isDebugEnabled()) {
            logger.debug(getComponentWizardModel().getComponent().getDisplayName() + " "
                    + (componentEnabled ? "are" : "are not") + " enabled");
        }

        return componentEnabled;
    }

    public boolean isNameUnique(IProgressMonitor monitor) throws ForceConnectionException, FactoryException,
    ServiceException, ForceRemoteException, InterruptedException {
        return (isNameUniqueLocalCheck() && isNameUniqueRemoteCheck(monitor));
    }

    public boolean isNameUniqueLocalCheck() {
        final Component componentToCheck = getComponent();
        final String dirPath =
                (componentToCheck != null) ? (new StringBuffer(Constants.SOURCE_FOLDER_NAME).append(File.separator)
                        .append(componentToCheck.getDefaultFolder())).toString() : null;

                        final String fileName =
                                (componentToCheck != null) ? (new StringBuffer(componentToCheck.getName()).append(".")
                                        .append(componentToCheck.getFileExtension())).toString() : null;

                                        final String componentName_Absolute =
                                                (dirPath != null && fileName != null) ? (new StringBuffer(dirPath).append(fileName)).toString() : null;

                                                if (logger.isInfoEnabled()) {
                                                    logger.info("Ensure local uniqueness for '"
                                                            + (Utils.isEmpty(componentName_Absolute) ? "" : componentName_Absolute.toString()) + "'");
                                                }

                                                return (!componentToCheck.isCaseSensitive()) ? checkInFolder(dirPath, fileName) : true;
    }

    protected boolean checkInFolder(final String dirPath, final String fileName) {
        IFolder folder = getSourceFolder(dirPath.toString());
        if (folder != null && folder.exists()) {
            IResource[] folderMembers = null;
            try {
                folderMembers = folder.members();
            } catch (CoreException e) {
                String logMessage = generateLogMessageFromCoreException(e);
                logger.warn("Unable to get contents for folder '" + folder.getProjectRelativePath().toPortableString()
                    + "': " + logMessage, e);
                return true;
            }

            if (Utils.isNotEmpty(folderMembers)) {
                for (IResource folderMember : folderMembers) {
                    if (folderMember.getType() == IResource.FILE
                            && folderMember.getName().equalsIgnoreCase(fileName.toString())) {
                        logger.warn("Component resource '" + fileName.toString() + "' already exists in project");
                        return false;
                    }
                }
            }
        }

        return true;
    }

    protected String generateLogMessageFromCoreException(CoreException e) {
        String logMessage = Utils.generateCoreExceptionLog(e);
        return logMessage;
    }

    protected IFolder getSourceFolder(final String path) {
        return getComponentWizardModel().getProject().getFolder(path);
    }

    public boolean isNameUniqueRemoteCheck(IProgressMonitor monitor) throws InsufficientPermissionsException,
    ForceConnectionException, ForceRemoteException, InterruptedException, FactoryException {
        if (!isProjectOnlineEnabled()) {
            logger.warn("Remote unique name check aborted - project is not online enabled");
            return true;
        }

        StringBuffer strBuff = new StringBuffer();
        final Component component = getComponent();

        strBuff.append(component.getDefaultFolder()).append("/").append(component.getName()).append(".").append(
            component.getFileExtension());

        if (logger.isDebugEnabled()) {
            logger.debug("Ensure remote uniqueness for '" + strBuff.toString() + "'");
        }

        component.setFilePath(strBuff.toString());

        return checkIfComponentExistsOnServer(monitor, component);
    }

    /**
     * @return true if it doesn't exist on server
     */
    protected boolean checkIfComponentExistsOnServer(IProgressMonitor monitor, final Component component)
            throws ForceConnectionException, ForceRemoteException, InterruptedException, FactoryException,
            InsufficientPermissionsException {
        final FileMetadataExt listMetadataRetrieveResult = fireListMetadataQuery(monitor, component);
        boolean notFoundOnServer = true;
        if (listMetadataRetrieveResult.hasFileProperties()) {
            final FileProperties[] fileProps = listMetadataRetrieveResult.getFileProperties();
            for (FileProperties fp : fileProps) {
                if (fp.getFullName().equalsIgnoreCase(component.getName())) {
                    notFoundOnServer=false;
                    break;
                }
            }
        }
        return notFoundOnServer;
    }

    protected FileMetadataExt fireListMetadataQuery(IProgressMonitor monitor, final Component component)
            throws ForceConnectionException, ForceRemoteException, InterruptedException, FactoryException,
            InsufficientPermissionsException {
        final FileMetadataExt listMetadataRetrieveResult =
                ContainerDelegate.getInstance().getServiceLocator().getMetadataService().listMetadata(
                    ContainerDelegate.getInstance().getFactoryLocator().getConnectionFactory().getConnection(getComponentWizardModel().getProject()), component, monitor);
        return listMetadataRetrieveResult;
    }

    protected boolean isProjectOnlineEnabled() {
        return ContainerDelegate.getInstance().getServiceLocator().getProjectService().isManagedOnlineProject(getComponentWizardModel().getProject());
    }

    @Override
    public void finish(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException, IOException,
    ForceConnectionException, ForceRemoteException, FactoryException, CoreException, ServiceException,
    JAXBException, Exception {
        if (getComponentWizardModel() == null || getComponentWizardModel().getProject() == null) {
            logger.error("Component model and/or project cannot be null");
            throw new IllegalArgumentException("Component model and/or project cannot be null");
        }

        if (logger.isDebugEnabled()) {
            logger.debug("***   C R E A T E   C O M P O N E N T   ***");
        }

        monitorWorkCheck(monitor, "Creating new " + getComponentWizardModel().getDisplayName() + "...");

        // create and load components from user input including metadata, if applicable
        ComponentList components = getComponentWizardModel().getLoadedComponents();

        if (Utils.isEmpty(components)) {
            logger.error("Unable to create component.");
            Utils.openError(new Exception("Unable to create component.  Component is null."),
                "Unable to create component", null);
            return;
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Creating " + components.get(0).getFullDisplayName());
        }

        // prepare container to perform save and deploy ops
        ProjectPackageList projectPackageList = ContainerDelegate.getInstance().getServiceLocator().getProjectService().getProjectPackageListInstance();
        projectPackageList.setProject(getComponentWizardModel().getProject());
        projectPackageList.addComponents(components, false);

        // perform pre-save actions
        preSaveProcess(getComponentWizardModel(), monitor);

        // save to f/s - enables offline work
        monitorSubTask(monitor, "Saving " + getComponentWizardModel().getDisplayName() + " to project...");
        projectPackageList.saveResources(new String[] { getComponentWizardModel().getComponent().getComponentType() },
            monitor);
        monitorWorkCheck(monitor);

        // commit to server
        monitorSubTask(monitor, "Saving " + getComponentWizardModel().getDisplayName() + " to server...");
        deploy(projectPackageList, monitor);

        // performing post-save actions
        postSaveProcess(getComponentWizardModel(), monitor);
    }

    /**
     * Override this method to perform actions before saving component to server and project.
     *
     * @param componentWizardModel
     * @param monitor
     */
    protected void preSaveProcess(ComponentModel componentWizardModel, IProgressMonitor monitor)
            throws InvocationTargetException, InterruptedException, IOException {
        // test for remote uniqueness
        try {
            if (logger.isInfoEnabled()) {
                logger.info("Validating name uniquness of " + getComponentWizardModel().getDisplayName());
            }
            if (isProjectOnlineEnabled() && !isNameUniqueRemoteCheck(monitor)) {
                logger.warn("Found remote instance of " + getComponentWizardModel().getDisplayName());
                StringBuffer strBuff = new StringBuffer("Found existing ");
                strBuff.append(getComponentWizardModel().getDisplayName()).append(" instance named '").append(
                    getComponentWizardModel().getName()).append(
                            "' in source organization.\n\nOverwrite remote instance?");
                boolean ovewrite = Utils.openConfirm("Duplicate Component Found", strBuff.toString());
                if (!ovewrite) {
                    logger.warn("User cancelled new component operation - will not overwrite remote instance");
                    throw new InterruptedException(
                            "User cancelled new component operation - will not overwrite remote instance");
                }
            }
        } catch (InterruptedException e) {
            throw e;
        } catch (Exception e) {
            logger.error("Unable to test remote uniqueness", e);
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Saving newly created component(s)");
        }
    }

    /**
     * Override this method to perform actions after saving component to server and project
     *
     * @param componentWizardModel
     * @param monitor
     */
    protected void postSaveProcess(final ComponentModel componentWizardModel, final IProgressMonitor monitor)
            throws InvocationTargetException, InterruptedException, IOException {
        // manually update cache inserting new component in appropriate stanza
        Job updateCacheJob = new Job("Update list metadata cache") {
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                // set cache, may not exists
                URL cacheUrl = Utils.getCacheUrl(getProject());
                Document packageManifestCache = Utils.loadDocument(cacheUrl);
                if (packageManifestCache != null) {
                    Node componentTypeNode =
                            PackageManifestDocumentUtils.addComponentTypeNode(packageManifestCache,
                                componentWizardModel.getComponentType());

                    PackageManifestDocumentUtils.addMemberNode(componentTypeNode, componentWizardModel.getName());

                    try {
                        Utils.saveDocument(packageManifestCache, cacheUrl.getPath());
                    } catch (Exception e) {
                        logger.warn("Unable to update cache with new component "
                                + componentWizardModel.getDisplayName(), e);
                        return new Status(Status.INFO, ForceIdeCorePlugin.PLUGIN_ID, Status.INFO,
                            "Unable to update cache with new component " + componentWizardModel.getDisplayName(), e);
                    }

                    if (logger.isDebugEnabled()) {
                        logger.debug("Added new component " + componentWizardModel.getDisplayName() + " to cache");
                        logger.debug("Updated cache...");
                        PackageManifestDocumentUtils.log(packageManifestCache);
                    }
                } else {
                    logger.warn("Unable to update cache with new component " + componentWizardModel.getDisplayName()
                        + " - cache is not found");
                    return new Status(Status.INFO, ForceIdeCorePlugin.PLUGIN_ID, Status.INFO,
                        "Unable to update cache with new component " + componentWizardModel.getDisplayName()
                        + " - cache is not found", null);
                }

                return Status.OK_STATUS;
            }

        };

        // perform now
        updateCacheJob.setSystem(true);
        updateCacheJob.schedule();
    }

    protected void deploy(ProjectPackageList projectPackageList, IProgressMonitor monitor)
            throws ForceConnectionException, FactoryException, InterruptedException, CoreException, IOException,
            ServiceException, ForceRemoteException, InvocationTargetException, Exception {

        if (!isProjectOnlineEnabled()) {
            logger.warn("Remote save aborted - project is not online enabled");
            // TODO: apply dirty marker to file?
            ComponentList components = projectPackageList.getAllComponents();
            for (Component component : components) {
                if (!component.isPackageManifest()) {
                    MarkerUtils.getInstance().applyDirty(component.getFileResource(),
                        Messages
                        .getString("Markers.OfflineOnlySavedLocally.message"));
                }
            }
            return;
        }

        // compile and save new component
        try {
            deployResultHandler = ContainerDelegate.getInstance().getServiceLocator().getPackageDeployService().deploy(projectPackageList, monitor);
        } catch (ServiceTimeoutException ex) {
            deployResultHandler =
                    ContainerDelegate.getInstance().getServiceLocator().getPackageDeployService().handleDeployServiceTimeoutException(ex,
                        "create new " + getComponent().getDisplayName(), monitor);
        }

        if (deployResultHandler == null) {
            logger.error("Unable to finalize new component creation - deploy result is null");
            return;
        }

        ContainerDelegate.getInstance().getServiceLocator().getProjectService().handleDeployResult(projectPackageList, deployResultHandler, true, monitor);
    }

    // get all object names
    public SortedSet<String> getObjectNames(boolean refresh) throws ForceConnectionException, ForceRemoteException {
        IProject project = getComponentWizardModel().getProject();

        if (project == null) {
            return null;
        }

        Connection connection = ContainerDelegate.getInstance().getFactoryLocator().getConnectionFactory().getConnection(project);
        DescribeObjectRegistry describeObjectRegistry = ContainerDelegate.getInstance().getFactoryLocator().getConnectionFactory().getDescribeObjectRegistry();
        return describeObjectRegistry.getCachedDescribeSObjectNames(connection, project.getName(), refresh);
    }

    @Override
    public void dispose() {

    }
}
TOP

Related Classes of com.salesforce.ide.core.internal.components.ComponentController

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.