Java tutorial
/******************************************************************************* * 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.ui.wizards.project; import java.lang.reflect.InvocationTargetException; import java.util.Properties; import org.apache.log4j.Logger; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.IProgressService; import com.salesforce.ide.core.ForceIdeCorePlugin; import com.salesforce.ide.core.internal.utils.Constants; import com.salesforce.ide.core.internal.utils.DialogUtils; import com.salesforce.ide.core.internal.utils.ForceExceptionUtils; import com.salesforce.ide.core.internal.utils.Messages; import com.salesforce.ide.core.internal.utils.Utils; import com.salesforce.ide.core.project.ForceProject; import com.salesforce.ide.core.project.ForceProjectException; import com.salesforce.ide.core.remote.InsufficientPermissionsException; import com.salesforce.ide.core.remote.InvalidLoginException; import com.salesforce.ide.ui.internal.composite.BaseProjectComposite; import com.salesforce.ide.ui.internal.utils.UIConstants; import com.salesforce.ide.ui.internal.utils.UIMessages; import com.salesforce.ide.ui.internal.utils.UIUtils; import com.salesforce.ide.ui.packagemanifest.PackageManifestController; public class ProjectOrganizationPage extends BaseProjectCreatePage { private static final Logger logger = Logger.getLogger(ProjectOrganizationPage.class); protected static final String OTHER_LABEL_NAME = UIMessages .getString("ProjectCreateWizard.OrganizationPage.OtherEnvironment.label"); public static final String WIZARDPAGE_ID = "projectOrganizationWizardPage"; private ProjectOrganizationComposite projectOrganizationComposite = null; public ProjectOrganizationPage(ProjectCreateWizard projectCreateWizard) { super(WIZARDPAGE_ID, projectCreateWizard); } /** * Assemble connection page wizard. */ @Override public void createControl(Composite parent) { setWizardCosmetics(parent); projectOrganizationComposite = new ProjectOrganizationComposite(parent, SWT.NULL, this); setControl(projectOrganizationComposite); initialize(); UIUtils.setHelpContext(projectOrganizationComposite, this.getClass().getSimpleName()); } private void initialize() { initEnviornmentDefaults(); projectOrganizationComposite.getTxtProjectName().setFocus(); setComplete(false); if (Utils.isInternalMode() && Utils.hasDefaultProperties()) { setPropertyFileBasedProjectInputs(projectOrganizationComposite, "project"); setPropertyFileBasedOrgInputs(projectOrganizationComposite, "project"); validateUserInput(); if (isPageComplete()) { getProjectController().setCanComplete(true); } } } @Override protected void setPropertyFileBasedProjectInputs(BaseProjectComposite projectComposite, String prefix) { Properties props = Utils.getDefaultProperties(); if (props == null || props.isEmpty()) { return; } if (Utils.isNotEmpty(props.getProperty(prefix + ".name"))) { projectComposite.getTxtProjectName().setText(props.getProperty(prefix + ".name")); } if (logger.isDebugEnabled()) { logger.debug("Set default project properties from prop file"); } setPageComplete(true); } // set defaults and/or last used private void initEnviornmentDefaults() { Combo cmbEndpointServers = projectOrganizationComposite.getCmbEndpointServer(); Combo cmbEnvironment = projectOrganizationComposite.getCmbEnvironment(); // environment String lastEnvironmentSelected = ForceIdeCorePlugin.getPreferenceString(Constants.LAST_ENV_SELECTED); String selectedEndpointLabel = getSalesforceEndpoints().getDefaultEndpointLabel(); if (Utils.isNotEmpty(lastEnvironmentSelected) && (getSalesforceEndpoints().isValidEndpointLabel(lastEnvironmentSelected) || OTHER_LABEL_NAME.equals(lastEnvironmentSelected))) { selectCombo(cmbEnvironment, lastEnvironmentSelected); } else if (Utils.isNotEmpty(selectedEndpointLabel)) { selectCombo(cmbEnvironment, selectedEndpointLabel); } else { cmbEnvironment.select(0); } // server String lastServerSelected = ForceIdeCorePlugin.getPreferenceString(Constants.LAST_SERVER_SELECTED); if (Utils.isNotEmpty(lastServerSelected)) { selectCombo(cmbEndpointServers, lastServerSelected); } else { cmbEndpointServers.select(0); } // keep endpoint and protocol boolean lastKeepEndpointSelected = ForceIdeCorePlugin .getPreferenceBoolean(Constants.LAST_KEEP_ENDPOINT_SELECTED); projectOrganizationComposite.getChkBoxResetEndpoint().setSelection(lastKeepEndpointSelected); String username = ForceIdeCorePlugin.getPreferenceString(Constants.LAST_USERNAME_SELECTED); if (Utils.isNotEmpty(username)) { projectOrganizationComposite.setTxtUsername(username); } // set visibility of advanced server stuff projectOrganizationComposite.enableServerEntryControls(); } @Override public void setVisible(boolean visible) { if (visible) { setTitleAndDescription(UIMessages.getString("ProjectCreateWizard.OrganizationPage.title"), UIMessages.getString("ProjectCreateWizard.OrganizationPage.description")); } super.setVisible(visible); } // validate user input public void validateUserInput() { boolean valid = validateProjectSettings(projectOrganizationComposite); setPageComplete(valid); } // validates project and org settings protected boolean validateProjectSettings(BaseProjectComposite baseProjectComposite) { return validateProject(baseProjectComposite) && validateOrganization(baseProjectComposite); } // validates project settings protected boolean validateProject(BaseProjectComposite projectComposite) { String projectName = projectComposite.getTxtProjectNameString(); if (projectComposite.getTxtProjectName().getEnabled() && Utils.isEmpty(projectName)) { updateInfoStatus(UIMessages.getString(UIConstants.MSG_PROJECT_NAME_EMPTY)); return false; } if (Utils.containsInvalidChars(projectName)) { updateErrorStatus(UIMessages.getString("ProjectCreateWizard.OrganizationPage.InvalidChar.message")); return false; } IResource container = null; if (projectComposite.getTxtProjectName().getEnabled() && Utils.isNotEmpty(projectName)) { container = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(projectName)); if (container != null) { updateErrorStatus(UIMessages.getString(UIConstants.MSG_PROJECT_NAME_UNIQUE)); return false; } } updateInfoStatus(null); return true; } // saves valid user input public void saveUserInput() { ForceProject forceProject = getProjectModel().getForceProject(); if (forceProject == null) { forceProject = new ForceProject(); } // generic save of project and org stuff saveUserInput(forceProject, projectOrganizationComposite); saveEndpointInput(forceProject, projectOrganizationComposite, getSalesforceEndpoints()); // save to model to be worked on later String environment = projectOrganizationComposite.getCmbEnvironmentString(); getProjectModel().setEnvironment(environment); getProjectModel().setForceProject(forceProject); getProjectModel().setProjectName(projectOrganizationComposite.getTxtProjectNameString()); getProjectModel().clearConnections(); } @Override public IWizardPage getNextPage() { // only perform remote operations if org settings changed if (projectOrganizationComposite.isOrgModified()) { // reset modify flag projectOrganizationComposite.setOrgModified(false); // save updated input saveUserInput(); // invalidate packageCache.xml from previous org's PME load try { new PackageManifestController().clearCache(); } catch (ForceProjectException e) { logger.error("Unable to clear PME cache, '" + Constants.CACHE_FILENAME + "'", e); } // pre-load org's packages and enabled component types if (!prepareNextPage()) { return this; } } return super.getNextPage(); } protected boolean prepareNextPage() { try { projectWizard.getProjectProjectContentPage().enableServerContentOptions(); loadOrgDetails(); } catch (InvocationTargetException e) { // notify if connection failed projectWizard.getProjectProjectContentPage().disableServerContentOptions(); // reset finish ability setComplete(false); projectOrganizationComposite.setOrgModified(true); // cancel/prevent further project create operations for in InsufficientOrgPermissions exceptions if (e.getTargetException() instanceof InsufficientPermissionsException) { // log failure; option enabling occurs downstream logger.warn("Insufficient permissions to create project: " + ForceExceptionUtils.getRootCauseMessage(e)); InsufficientPermissionsException ex = (InsufficientPermissionsException) e.getTargetException(); // occurred during project create/update which determines message text ex.setShowUpdateCredentialsMessage(false); // show dialog DialogUtils.getInstance().presentInsufficientPermissionsDialog(ex); updateErrorStatus(Messages.getString("InsufficientPermissions.User.OrganizationSettings.message", new String[] { ex.getConnection().getUsername() })); return false; } else if (e.getTargetException() instanceof InvalidLoginException) { // log failure logger.warn("Unable to login: " + ForceExceptionUtils.getRootCauseMessage(e.getTargetException())); updateErrorStatus(UIMessages.getString( "ProjectCreateWizard.OrganizationPage.InvalidConnection.WithHost.message", new String[] { getProjectModel().getForceProject().getEndpointServer() })); DialogUtils.getInstance().abortMessage("Login Failed", UIMessages.getString( "ProjectCreateWizard.OrganizationPage.InvalidConnection.WithHostAndException.message", new String[] { getProjectModel().getForceProject().getEndpointServer(), ForceExceptionUtils.getRootExceptionMessage(e) })); return false; } else { // log failure; ask user what he/she wants to do logger.warn("Unable to load org details - package names and component enablement", ForceExceptionUtils.getRootCause(e)); // choose further project create direction String[] params = new String[] { getProjectModel().getForceProject().getUserName(), ForceExceptionUtils.getRootExceptionMessage(e) }; String message = UIMessages.getString( "ProjectCreateWizard.OrganizationPage.FetchOrgDetails.GenericError.message", params); updateErrorStatus(UIMessages.getString( "ProjectCreateWizard.OrganizationPage.FetchOrgDetails.GenericError.Status.message", new String[] { getProjectModel().getForceProject().getUserName() })); int action = createOfflineAbortRetryMessage("Unknown Error", message); switch (action) { case 0: /* create offline */ if (logger.isDebugEnabled()) { logger.debug("Continue offline project create"); } return true; case 1: /* abort */ if (logger.isDebugEnabled()) { logger.debug("Aborting connection validation in prep of project content selection page"); } return false; default: /* retry */ if (logger.isDebugEnabled()) { logger.debug("Retry connection validation"); } return prepareNextPage(); } } } catch (InterruptedException e) { logger.warn("Operation cancelled: " + e.getMessage()); } return true; } private int createOfflineAbortRetryMessage(String title, String message) { // retry is the default MessageDialog dialog = new MessageDialog(getShell(), title, null, message, MessageDialog.ERROR, new String[] { "Create Offline", IDialogConstants.ABORT_LABEL, IDialogConstants.RETRY_LABEL }, IDialogConstants.RETRY_ID); return dialog.open(); } private void loadOrgDetails() throws InvocationTargetException, InterruptedException { final IProgressService service = PlatformUI.getWorkbench().getProgressService(); service.run(false, false, new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException { monitor.beginTask("Fetching organization details...", 3); monitor.worked(1); try { // clear previous data, if applicable getProjectController().clearOrgDetails(); // get package names monitor.subTask("Fetching packages..."); getProjectController().loadRemotePackageNames(new SubProgressMonitor(monitor, 3)); monitor.worked(1); monitor.subTask("Preparing to fetch component metadata..."); getProjectController().prepareFileMetadataQueries(monitor); monitor.worked(1); monitor.beginTask("Fetching component metadata...", getProjectController().queriesCount() > 0 ? getProjectController().queriesCount() + 1 : IProgressMonitor.UNKNOWN); monitor.worked(1); getProjectController().loadFileMetadata(monitor); } catch (InterruptedException e) { logger.warn("Operation cancelled: " + e.getMessage()); } catch (Throwable e) { throw new InvocationTargetException(e); } finally { if (monitor != null) { monitor.done(); } } } }); } @Override public boolean canFlipToNextPage() { return isPageComplete(); } }