Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 4603b4552d672ca281fc562482369d600108e170 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12











                                                                            
                                                              






                                                
                                              







                             

                                                

                       
                                 
 
                                                                                                      

                                                                            
 
                          







                                                                       
                           




                              
                                                    





                                         
                                                   












                                                          
                                                                 


























                                                               
                         





































































                                                                                                                 
 
/***************************************************************************
 * Copyright (c) 2004-2007 Eike Stepper, Germany.
 * 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:
 *    Eike Stepper - initial API and implementation
 **************************************************************************/
package org.eclipse.emf.internal.cdo.util;

import org.eclipse.net4j.internal.util.om.trace.ContextTracer;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.internal.cdo.bundle.OM;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * TODO Handle generic types and type parameters
 * 
 * @author Eike Stepper
 */
public final class PackageClosure
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_MODEL, PackageClosure.class);

  private static final Set<EPackage> EMPTY_CLOSURE = Collections.emptySet();

  private PackageClosure()
  {
  }

  public static Set<EPackage> calculate(Collection<EPackage> ePackages)
  {
    // Optimize no packages
    if (ePackages.isEmpty())
    {
      return EMPTY_CLOSURE;
    }

    // Optimize 1 package
    if (ePackages.size() == 1)
    {
      return calculate(ePackages.iterator().next());
    }

    // Handle >1 packages
    Set<EPackage> result = new HashSet();
    for (EPackage ePackage : ePackages)
    {
      Set<EPackage> packages = calculate(ePackage);
      result.addAll(packages);
    }

    return result;
  }

  /**
   * TODO Handle Ecore generics
   */
  public static Set<EPackage> calculate(EPackage ePackage)
  {
    if (TRACER.isEnabled())
    {
      TRACER.trace("Package closure for " + ePackage.getNsURI());
    }

    Set<EClass> visited = new HashSet();

    List<EClassifier> classifiers = ePackage.getEClassifiers();
    for (EClassifier classifier : classifiers)
    {
      handleEClassifier(classifier, visited);
    }

    Set<EPackage> result = new HashSet();
    for (EClass eClass : visited)
    {
      final EPackage p = eClass.getEPackage();
      if (p != null)
      {
        if (result.add(p))
        {
          if (TRACER.isEnabled())
          {
            TRACER.trace("Found package " + p.getNsURI());
          }
        }
      }
      else
      {
        String msg = "Package == null for " + eClass.getName();
        OM.LOG.warn(msg);
        if (TRACER.isEnabled())
        {
          TRACER.trace(msg);
        }
      }
    }

    return result;
  }

  private static void handleEClassifier(EClassifier classifier, Set<EClass> visited)
  {
    if (classifier instanceof EClass)
    {
      EClass eClass = (EClass)classifier;
      if (visited.add(eClass))
      {
        if (TRACER.isEnabled())
        {
          TRACER.trace("Found class " + eClass.getName());
        }

        handleEStructuralFeatures(eClass.getEStructuralFeatures(), visited);
        handleEOperations(eClass.getEOperations(), visited);
        handleESuperTypes(eClass.getESuperTypes(), visited);
      }
    }
  }

  private static void handleEStructuralFeatures(List<EStructuralFeature> structuralFeatures, Set<EClass> visited)
  {
    for (EStructuralFeature structuralFeature : structuralFeatures)
    {
      handleEClassifier(structuralFeature.getEType(), visited);
    }
  }

  private static void handleEOperations(List<EOperation> operations, Set<EClass> visited)
  {
    for (EOperation operation : operations)
    {
      handleEClassifier(operation.getEType(), visited);
      handleEParameters(operation.getEParameters(), visited);
      handleEExceptions(operation.getEExceptions(), visited);
    }
  }

  private static void handleEParameters(List<EParameter> parameters, Set<EClass> visited)
  {
    for (EParameter parameter : parameters)
    {
      handleEClassifier(parameter.getEType(), visited);
    }
  }

  private static void handleEExceptions(List<EClassifier> exceptions, Set<EClass> visited)
  {
    for (EClassifier exception : exceptions)
    {
      handleEClassifier(exception, visited);
    }
  }

  private static void handleESuperTypes(List<EClass> superTypes, Set<EClass> visited)
  {
    for (EClass superType : superTypes)
    {
      handleEClassifier(superType, visited);
    }
  }
}

Back to the top