Package org.springframework.ide.eclipse.beans.ui.navigator

Source Code of org.springframework.ide.eclipse.beans.ui.navigator.BeansNavigatorContentProvider$ModelJob

/*******************************************************************************
* Copyright (c) 2007, 2009 Spring IDE Developers
* 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:
*     Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.beans.ui.navigator;

import java.util.LinkedHashSet;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IType;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.navigator.CommonNavigator;
import org.eclipse.ui.navigator.ICommonContentExtensionSite;
import org.eclipse.ui.navigator.ICommonContentProvider;
import org.eclipse.ui.progress.IProgressConstants;
import org.springframework.ide.eclipse.beans.core.BeansCorePlugin;
import org.springframework.ide.eclipse.beans.core.model.IBeansConfig;
import org.springframework.ide.eclipse.beans.core.model.IBeansConfigSet;
import org.springframework.ide.eclipse.beans.core.model.IBeansImport;
import org.springframework.ide.eclipse.beans.core.model.IBeansProject;
import org.springframework.ide.eclipse.beans.core.model.IImportedBeansConfig;
import org.springframework.ide.eclipse.beans.ui.BeansUIImages;
import org.springframework.ide.eclipse.beans.ui.BeansUIPlugin;
import org.springframework.ide.eclipse.beans.ui.model.BeansModelContentProvider;
import org.springframework.ide.eclipse.beans.ui.model.BeansModelLabelDecorator;
import org.springframework.ide.eclipse.core.SpringCore;
import org.springframework.ide.eclipse.core.SpringCoreUtils;
import org.springframework.ide.eclipse.core.io.ZipEntryStorage;
import org.springframework.ide.eclipse.core.java.JdtUtils;
import org.springframework.ide.eclipse.core.model.ILazyInitializedModelElement;
import org.springframework.ide.eclipse.core.model.IModelElement;
import org.springframework.ide.eclipse.core.model.IResourceModelElement;
import org.springframework.ide.eclipse.core.model.ISourceModelElement;
import org.springframework.ide.eclipse.core.model.ISpringProject;
import org.springframework.ide.eclipse.core.model.ModelChangeEvent;
import org.springframework.ide.eclipse.ui.SpringUIUtils;

/**
* This class is a content provider for the {@link CommonNavigator} which knows about the beans core model's
* {@link IModelElement} elements.
* @author Torsten Juergeleit
* @author Christian Dupuis
*/
public class BeansNavigatorContentProvider extends BeansModelContentProvider implements ICommonContentProvider {

  private String providerID;

  @Override
  public Object[] getElements(Object inputElement) {
    if (BeansUIPlugin.PROJECT_EXPLORER_CONTENT_PROVIDER_ID.equals(providerID)) {
      return SpringCoreUtils.getSpringProjects().toArray();
    }
    return super.getElements(inputElement);
  }

  @Override
  public boolean hasChildren(Object element) {
    return getChildren(element).length > 0;
  }

  @Override
  public Object[] getChildren(final Object parentElement) {
    if (parentElement instanceof ISpringProject) {
      IBeansProject beansProject = BeansCorePlugin.getModel().getProject(
          ((ISpringProject) parentElement).getProject());
      if (beansProject != null
          && (!beansProject.getConfigs().isEmpty() || !beansProject.getConfigSets().isEmpty())) {
        return new Object[] { beansProject };
      }
    }
    // check for lazy loading and/or long running elements; if a element is
    // marked to be long-running, execute the call to super.getChildren()
    // asynchronous and refresh the underlying viewer with the given parent
    // element (use parent because IBeansConfigSets need to be updated as
    // well)
    else if (parentElement instanceof ILazyInitializedModelElement
        && !((ILazyInitializedModelElement) parentElement).isInitialized()) {
      triggerDeferredElementLoading(parentElement, ((IModelElement) parentElement).getElementParent());
      return IModelElement.NO_CHILDREN;
    }
    else if (parentElement instanceof IBeansImport) {
      return getImportChildren(parentElement);
    }
    return super.getChildren(parentElement);
  }

  protected Object[] getImportChildren(final Object parentElement) {
    Set<IImportedBeansConfig> importedBeansConfigs = ((IBeansImport) parentElement).getImportedBeansConfigs();
    Set<Object> importedFiles = new LinkedHashSet<Object>();
    for (IBeansConfig bc : importedBeansConfigs) {
      if (bc.isElementArchived()) {
        importedFiles.add(new ZipEntryStorage(bc));
      }
      else {
        importedFiles.add(bc.getElementResource());
      }
    }
    return importedFiles.toArray(new Object[importedFiles.size()]);
  }

  @Override
  protected Object[] getConfigSetChildren(IBeansConfigSet configSet) {
    Set<ISourceModelElement> children = new LinkedHashSet<ISourceModelElement>();
    for (final IBeansConfig config : configSet.getConfigs()) {
      if (config instanceof ILazyInitializedModelElement
          && !((ILazyInitializedModelElement) config).isInitialized()) {
        triggerDeferredElementLoading(config, configSet);
        continue;
      }
      getConfigChildren(children, config);
    }
    return children.toArray();
  }

  @Override
  protected Object[] getJavaTypeChildren(IType type) {
    // Prevent showing the Java -> Bean reference node in Spring Explorer
    if (BeansUIPlugin.SPRING_EXPLORER_CONTENT_PROVIDER_ID.equals(providerID)) {
      return IModelElement.NO_CHILDREN;
    }
    return super.getJavaTypeChildren(type);
  }

  private void triggerDeferredElementLoading(final Object config, final Object parent) {
    // first check if a matching job is already scheduled
    synchronized (getClass()) {
      Job[] buildJobs = Job.getJobManager().find(ModelJob.MODEL_CONTENT_FAMILY);
      for (int i = 0; i < buildJobs.length; i++) {
        Job curr = buildJobs[i];
        if (curr instanceof ModelJob) {
          ModelJob job = (ModelJob) curr;
          if (job.isCoveredBy(config, parent)) {
            return;
          }
        }
      }
    }
    Job job = new ModelJob(config, parent, this);
    job.setPriority(Job.INTERACTIVE);
    job.setProperty(IProgressConstants.ICON_PROPERTY, BeansUIImages.DESC_OBJS_SPRING);
    job.schedule();
  }

  private Object[] superGetChildren(Object parentElement) {
    return super.getChildren(parentElement);
  }

  @Override
  public synchronized void elementChanged(ModelChangeEvent event) {

    IModelElement element = event.getElement();
    if (element instanceof IBeansProject) {
      IProject project = ((IBeansProject) element).getProject();
      if (BeansUIPlugin.PROJECT_EXPLORER_CONTENT_PROVIDER_ID.equals(providerID)) {
        refreshViewerForElement(project);
        refreshViewerForElement(JdtUtils.getJavaProject(project));
      }
      else if (BeansUIPlugin.SPRING_EXPLORER_CONTENT_PROVIDER_ID.equals(providerID)) {
        refreshViewerForElement(SpringCore.getModel().getProject(project));
      }
      else {
        super.elementChanged(event);
      }
    }
    else if (element instanceof IBeansConfig) {
      IBeansConfig config = (IBeansConfig) element;

      // For a changed Spring beans config in the Eclipse Project Explorer
      // refresh all corresponding bean classes
      if (BeansUIPlugin.PROJECT_EXPLORER_CONTENT_PROVIDER_ID.equals(providerID)) {
        refreshBeanClasses(config);
      }

      // In order to refresh the meta data contributions we need refresh
      // the entire project
      refreshViewerForElement(config.getElementParent());
    }
    else {
      super.elementChanged(event);
    }
  }

  /**
   * Refreshes the config file and all bean classes of a given beans config
   */
  protected void refreshBeanClasses(IBeansConfig config) {
    Set<String> classes = config.getBeanClasses();
    for (String clazz : classes) {
      IType type = JdtUtils.getJavaType(config.getElementResource().getProject(), clazz);
      if (type != null) {
        refreshViewerForElement(type);
      }
    }
  }

  public void init(ICommonContentExtensionSite config) {
    providerID = config.getExtension().getId();
  }

  public void saveState(IMemento memento) {
  }

  public void restoreState(IMemento memento) {
  }

  @Override
  public String toString() {
    return String.valueOf(providerID);
  }

  /**
   * Internal {@link Job} that handles loading of {@link IBeansConfig} as Eclipse progress
   */
  private static class ModelJob extends Job {

    public static final Object MODEL_CONTENT_FAMILY = new Object();

    private final Object config;

    private final Object parent;

    private final BeansNavigatorContentProvider contentProvider;

    public ModelJob(Object config, Object parent, BeansNavigatorContentProvider contentProvider) {
      super("Initializing Spring Project '"
          + ((IResourceModelElement) config).getElementResource().getFullPath().toString().substring(1) + "'");
      this.config = config;
      this.parent = parent;
      this.contentProvider = contentProvider;
    }

    @Override
    protected IStatus run(IProgressMonitor monitor) {
      synchronized (getClass()) {
        if (monitor.isCanceled()) {
          return Status.CANCEL_STATUS;
        }
        Job[] buildJobs = Job.getJobManager().find(MODEL_CONTENT_FAMILY);
        for (int i = 0; i < buildJobs.length; i++) {
          Job curr = buildJobs[i];
          if (curr != this && curr instanceof ModelJob) {
            ModelJob job = (ModelJob) curr;
            if (job.isCoveredBy(this)) {
              curr.cancel();
            }
          }
        }
      }
      if (config instanceof IBeansProject) {
        IBeansProject bp = (IBeansProject) config;
        monitor = new SubProgressMonitor(monitor, bp.getConfigs().size());
        monitor.beginTask("Initializing Spring Project '"
            + ((IResourceModelElement) config).getElementResource().getFullPath().toString() + "'", bp
            .getConfigs().size());
        for (IBeansConfig beansConfig : bp.getConfigs()) {
          monitor.setTaskName("Loading '" + beansConfig.getElementName() + "'");
          beansConfig.getBeans();
          monitor.worked(1);
        }
      }
      else {
        monitor.beginTask("Loading '"
            + ((IResourceModelElement) config).getElementResource().getFullPath().toString() + "'", 1);
        contentProvider.superGetChildren(config);
      }
      SpringUIUtils.getStandardDisplay().asyncExec(new Runnable() {
        public void run() {
          contentProvider.refreshViewerForElement(config);
          contentProvider.refreshViewerForElement(parent);
          if (parent instanceof IBeansProject) {
            contentProvider.refreshViewerForElement(SpringCore.getModel().getProject(
                ((IBeansProject) parent).getProject()));
          }
          if (BeansUIPlugin.PROJECT_EXPLORER_CONTENT_PROVIDER_ID.equals(contentProvider.providerID)
              && config instanceof IResourceModelElement) {
            contentProvider.refreshViewerForElement(((IResourceModelElement) config).getElementResource());
          }
          BeansModelLabelDecorator.update();
        }
      });
      monitor.worked(1);
      monitor.done();
      return Status.OK_STATUS;
    }

    public boolean isCoveredBy(ModelJob other) {
      return other.parent.equals(parent) && other.config.equals(config);
    }

    public boolean isCoveredBy(Object otherConfig, Object otherParent) {
      return otherParent.equals(parent) && otherConfig.equals(config);
    }

    @Override
    public boolean belongsTo(Object family) {
      return MODEL_CONTENT_FAMILY == family;
    }
  }

}
TOP

Related Classes of org.springframework.ide.eclipse.beans.ui.navigator.BeansNavigatorContentProvider$ModelJob

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.