Package org.cloudfoundry.ide.eclipse.server.ui.internal

Source Code of org.cloudfoundry.ide.eclipse.server.ui.internal.CloudApplicationUrlPart

/*******************************************************************************
* Copyright (c) 2013, 2014 Pivotal Software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*  Contributors:
*     Pivotal Software, Inc. - initial API and implementation
********************************************************************************/
package org.cloudfoundry.ide.eclipse.server.ui.internal;

import java.util.ArrayList;
import java.util.List;

import org.cloudfoundry.client.lib.domain.CloudDomain;
import org.cloudfoundry.ide.eclipse.server.core.internal.ApplicationUrlLookupService;
import org.cloudfoundry.ide.eclipse.server.core.internal.CloudApplicationURL;
import org.cloudfoundry.ide.eclipse.server.ui.internal.wizards.CloudUIEvent;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

/**
*
* Allows users to edit or add an application URL based on a list of existing
* URL Cloud domains.
* <p/>
* Application URL is defined by subdomain and domain segments. The UP part may
* keep track of a raw, unparsed URL , whether invalid or not, as the user has
* option to edit the full URL manually without necessarily specifying either a
* subdomain or domain.
* <p/>
* Any changes to the raw URL will be parsed into subdomain and domain segments
* if possible, based on a list of available domains for the account. If
* successfully parsed, any subdomain and domain controls will be updated as
* well. If not successfully parsed, at the very minimum any full URL controls
* will be kept up to date with the invalid URL.
* <p/>
* Any registered listeners are notified when there are changes to the URL, or
* any errors have occurred during validation or parsing of the URL.
*/
public class CloudApplicationUrlPart extends UIPart {

  protected final ApplicationUrlLookupService lookupService;

  /**
   * The current URL being edited, in raw form. Note that since URL value in
   * the UI needs to always be up to date but the URL itself may be invalid
   * and even not par
   */
  private String currentUrl;

  private Control validationSource;

  private Text subDomainText;

  private Text fullURLText;

  private Combo domainCombo;

  public CloudApplicationUrlPart(ApplicationUrlLookupService lookupService) {
    this.lookupService = lookupService;
  }

  /**
   * Note that the part will adapt the given parent into a 2 column parent
   * that does not grab vertically. This is to allow other two column controls
   * in the same parent to have the same column widths as the controls for the
   * URL part. Callers are responsible for creating an appropriate parent that
   * only contains the URL part, if they do not wish for other controls
   * outside this part to be affected.
   */
  public Composite createPart(Composite parent) {

    Composite subDomainComp = parent;
    GridLayoutFactory.fillDefaults().numColumns(2).applyTo(subDomainComp);
    GridDataFactory.fillDefaults().grab(true, false).applyTo(subDomainComp);

    Label label = new Label(subDomainComp, SWT.NONE);

    label.setText(Messages.CloudApplicationUrlPart_TEXT_SUBDOMAIN_LABEL);
    GridDataFactory.fillDefaults().grab(false, false).align(SWT.FILL, SWT.CENTER).applyTo(label);

    subDomainText = new Text(subDomainComp, SWT.BORDER);
    GridDataFactory.fillDefaults().grab(true, false).applyTo(subDomainText);

    subDomainText.addModifyListener(new ModifyListener() {

      public void modifyText(ModifyEvent arg0) {
        resolveUrlFromSubdomain(subDomainText);
      }
    });

    label = new Label(subDomainComp, SWT.NONE);
    label.setText(Messages.COMMONTXT_DOMAIN);
    GridDataFactory.fillDefaults().grab(false, false).align(SWT.FILL, SWT.CENTER).applyTo(label);

    domainCombo = new Combo(subDomainComp, SWT.BORDER | SWT.READ_ONLY);
    GridDataFactory.fillDefaults().grab(true, false).applyTo(domainCombo);
    domainCombo.setEnabled(true);
    domainCombo.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent event) {
        resolveUrlFromSubdomain(domainCombo);
      }
    });

    label = new Label(subDomainComp, SWT.NONE);

    label.setText(Messages.CloudApplicationUrlPart_TEXT_DEPLOYURL_LABEL);
    GridDataFactory.fillDefaults().grab(false, false).align(SWT.FILL, SWT.CENTER).applyTo(label);

    fullURLText = new Text(subDomainComp, SWT.BORDER);
    GridDataFactory.fillDefaults().grab(true, false).applyTo(fullURLText);

    fullURLText.addModifyListener(new ModifyListener() {

      public void modifyText(ModifyEvent arg0) {
        currentUrl = fullURLText.getText();
        validate(null, fullURLText);
      }
    });

    return subDomainComp;

  }
 
  public String getCurrentDomain() {
    if (isActive(domainCombo)) {
      int selectionIndex = domainCombo.getSelectionIndex();
      String[] domains = domainCombo.getItems();
      if (selectionIndex >= 0 && selectionIndex < domains.length) {
        return domains[selectionIndex];
      }
    }
    return null;
  }

  public void refreshDomains() {
    if (isActive(domainCombo)) {
      String existingSelection = getCurrentDomain();
      List<String> domains = getDomains();
      domainCombo.setItems(domains.toArray(new String[0]));
      updateDomainSelection(existingSelection);
    }
  }

  public void setUrl(String url) {
    // Update the current URL, whether valid or not
    currentUrl = url;

    setTextValue(fullURLText, currentUrl);
  }

  public void setSubdomain(String subdomain) {
    setTextValue(subDomainText, subdomain);
  }

  /**
   * Sets value in the given text control if the control is active , and there
   * is a change in the text control value. A null value will be set as an
   * empty String in the control (this serves as a way to "clear" the
   * control).
   * @param textControl where text needs to be set
   * @param value. If null, empty string will be set to clear the control
   */
  protected void setTextValue(Text textControl, String value) {
    if (value == null) {
      value = ""; //$NON-NLS-1$
    }
    // Only set value if change occurred to avoid unnecessary validation
    if (isActive(textControl) && !textControl.getText().equals(value)) {
      // Setting value will notify Control listener which then
      // triggers validation
      textControl.setText(value);
    }
  }

  protected void resolveUrlFromSubdomain(Control source) {
    String subdomain = subDomainText.getText();
    String domain = getCurrentDomain();

    CloudApplicationURL suggestedUrl = new CloudApplicationURL(subdomain, domain);

    validate(suggestedUrl, source);
  }

  protected boolean isActive(Control control) {
    return control != null && !control.isDisposed();
  }

  /**
   * Validate a given application URL. If no application URL is specified, a
   * raw URL will be validated instead, if available.
   *
   * <p/>
   * If the URL is valid, meaning it has valid subdomain and domain segments:
   *
   * <p/>
   * 1. UI controls will be updated ONLY if there have been changes to the
   * control values
   * <p/>
   * 2. If there are changes to values, or error occurred during validation,
   * an event will be fired to notify any registered listeners
   * <p/>
   * @param appUrl
   * @param status
   */
  protected void validate(CloudApplicationURL appUrl, Control source) {
    // Validation has already been requested by a control, therefore don't
    // start another
    // one to avoid recursive validations
    if (this.validationSource != null) {
      return;
    }

    this.validationSource = source;

    // If no Application URL is given with subdomain and domain values set,
    // attempt to parse the existing
    // current URL as it may have changed manually
    IStatus status = Status.OK_STATUS;
    if (appUrl == null) {

      if (currentUrl != null) {
        try {
          appUrl = lookupService.getCloudApplicationURL(currentUrl);
        }
        catch (CoreException ce) {
          status = ce.getStatus();
        }
      }
    }
    else {
      try {
        appUrl = lookupService.validateCloudApplicationUrl(appUrl);
      }
      catch (CoreException ce) {
        status = ce.getStatus();
      }
    }

    // Update the current URL regardless of whether the Application URL is
    // valid or not, to make sure UI controls are up-to-date
    if (appUrl != null) {
      currentUrl = appUrl.getUrl();
    }

    if (this.validationSource != fullURLText) {
      setTextValue(fullURLText, currentUrl);
    }

    if (this.validationSource != domainCombo) {
      String domain = appUrl != null ? appUrl.getDomain() : null;
      updateDomainSelection(domain);
    }

    if (this.validationSource != subDomainText) {
      String subDomain = appUrl != null ? appUrl.getSubdomain() : null;
      setTextValue(subDomainText, subDomain);
    }

    validationSource = null;

    notifyChange(new PartChangeEvent(currentUrl, status, CloudUIEvent.APPLICATION_URL_CHANGED));
  }

  /**
   *
   * @return non-null list of Domains.
   */
  protected List<String> getDomains() {
    List<String> domains = new ArrayList<String>();
    List<CloudDomain> cloudDomains = lookupService.getDomains();
    if (cloudDomains != null) {
      for (CloudDomain cldm : cloudDomains) {
        domains.add(cldm.getName());
      }
    }
    return domains;
  }

  protected void updateDomainSelection(String domain) {

    if (isActive(domainCombo)) {

      // If no domain is to be set, or it no longer exists in list of
      // domains (possibly because list of domains has been changed),
      // select
      // a default one
      if (getSelectionIndex(domain) < 0 && getCurrentDomain() == null) {
        List<String> domains = getDomains();

        if (!domains.isEmpty()) {
          domain = domains.get(0);
        }
      }

      if (domain != null) {
        int selectionIndex = getSelectionIndex(domain);

        if (selectionIndex > -1) {
          domainCombo.select(selectionIndex);
        }
      }
    }
  }

  protected int getSelectionIndex(String domain) {
    int selectionIndex = -1;
    String[] domains = domainCombo.getItems();
    if (domains != null) {
      for (int i = 0; i < domains.length; i++) {
        if (domains[i].equals(domain)) {
          selectionIndex = i;
          break;
        }
      }
    }
    return selectionIndex;
  }
}
TOP

Related Classes of org.cloudfoundry.ide.eclipse.server.ui.internal.CloudApplicationUrlPart

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.