TypedSource.java :  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » corext » refactoring » Java Open Source

Java Open Source » IDE Eclipse » jdt 
jdt » org » eclipse » jdt » internal » corext » refactoring » TypedSource.java
/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IImportContainer;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;

import org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgUtils;
import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
import org.eclipse.jdt.internal.corext.util.Strings;

/**
 * A tuple used to keep source of an element and its type.
 * @see IJavaElement
 * @see org.eclipse.jdt.core.ISourceReference
 */
public class TypedSource {

  private static class SourceTuple {

    private SourceTuple(ICompilationUnit unit) {
      this.unit= unit;
    }
    private ICompilationUnit unit;
    private CompilationUnit node;
  }

  private final String fSource;
  private final int fType;

  private TypedSource(String source, int type){
    Assert.isNotNull(source);
    Assert.isTrue(canCreateForType(type));
    fSource= source;
    fType= type;
  }

  public static TypedSource create(String source, int type) {
    if (source == null || ! canCreateForType(type))
      return null;
    return new TypedSource(source, type);
  }

  public String getSource() {
    return fSource;
  }

  public int getType() {
    return fType;
  }

  /* (non-Javadoc)
   * @see java.lang.Object#equals(java.lang.Object)
   */
  public boolean equals(Object other) {
    if (! (other instanceof TypedSource))
      return false;

    TypedSource ts= (TypedSource)other;
    return ts.getSource().equals(getSource()) && ts.getType() == getType();
  }

  /* (non-Javadoc)
   * @see java.lang.Object#hashCode()
   */
  public int hashCode() {
    return getSource().hashCode() ^ (97 * getType());
  }

  private static boolean canCreateForType(int type){
    return     type == IJavaElement.FIELD
        ||   type == IJavaElement.TYPE
        ||   type == IJavaElement.IMPORT_CONTAINER
        ||   type == IJavaElement.IMPORT_DECLARATION
        ||   type == IJavaElement.INITIALIZER
        ||   type == IJavaElement.METHOD
        ||   type == IJavaElement.PACKAGE_DECLARATION;
  }


  public static void sortByType(TypedSource[] typedSources){
    Arrays.sort(typedSources, createTypeComparator());
  }

  public static Comparator createTypeComparator() {
    return new Comparator(){
      public int compare(Object arg0, Object arg1) {
        return ((TypedSource)arg0).getType() - ((TypedSource)arg1).getType();
      }
    };
  }
  public static TypedSource[] createTypedSources(IJavaElement[] javaElements) throws CoreException {
    //Map<ICompilationUnit, List<IJavaElement>>
    Map grouped= ReorgUtils.groupByCompilationUnit(Arrays.asList(javaElements));
    List result= new ArrayList(javaElements.length);
    for (Iterator iter= grouped.keySet().iterator(); iter.hasNext();) {
      ICompilationUnit cu= (ICompilationUnit) iter.next();
      for (Iterator iterator= ((List) grouped.get(cu)).iterator(); iterator.hasNext();) {
        SourceTuple tuple= new SourceTuple(cu);
        TypedSource[] ts= createTypedSources((IJavaElement) iterator.next(), tuple);
        if (ts != null)
          result.addAll(Arrays.asList(ts));
      }
    }
    return (TypedSource[]) result.toArray(new TypedSource[result.size()]);
  }

  private static TypedSource[] createTypedSources(IJavaElement elem, SourceTuple tuple) throws CoreException {
    if (! ReorgUtils.isInsideCompilationUnit(elem))
      return null;
    if (elem.getElementType() == IJavaElement.IMPORT_CONTAINER)
      return createTypedSourcesForImportContainer(tuple, (IImportContainer)elem);
    else if (elem.getElementType() == IJavaElement.FIELD)
      return new TypedSource[] {create(getFieldSource((IField)elem, tuple), elem.getElementType())};
    return new TypedSource[] {create(getSourceOfDeclararationNode(elem, tuple.unit), elem.getElementType())};
  }

  private static TypedSource[] createTypedSourcesForImportContainer(SourceTuple tuple, IImportContainer container) throws JavaModelException, CoreException {
    IJavaElement[] imports= container.getChildren();
    List result= new ArrayList(imports.length);
    for (int i= 0; i < imports.length; i++) {
      result.addAll(Arrays.asList(createTypedSources(imports[i], tuple)));
    }
    return (TypedSource[]) result.toArray(new TypedSource[result.size()]);
  }

  private static String getFieldSource(IField field, SourceTuple tuple) throws CoreException {
    if (Flags.isEnum(field.getFlags())) {
      String source= field.getSource();
      if (source != null)
        return source;
    } else {
      if (tuple.node == null) {
        ASTParser parser= ASTParser.newParser(AST.JLS3);
        parser.setSource(tuple.unit);
        tuple.node= (CompilationUnit) parser.createAST(null);
      }
      FieldDeclaration declaration= ASTNodeSearchUtil.getFieldDeclarationNode(field, tuple.node);
      if (declaration.fragments().size() == 1)
        return getSourceOfDeclararationNode(field, tuple.unit);
      VariableDeclarationFragment declarationFragment= ASTNodeSearchUtil.getFieldDeclarationFragmentNode(field, tuple.node);
      IBuffer buffer= tuple.unit.getBuffer();
      StringBuffer buff= new StringBuffer();
      buff.append(buffer.getText(declaration.getStartPosition(), ((ASTNode) declaration.fragments().get(0)).getStartPosition() - declaration.getStartPosition()));
      buff.append(buffer.getText(declarationFragment.getStartPosition(), declarationFragment.getLength()));
      buff.append(";"); //$NON-NLS-1$
      return buff.toString();
    }
    return ""; //$NON-NLS-1$
  }

  private static String getSourceOfDeclararationNode(IJavaElement elem, ICompilationUnit cu) throws JavaModelException, CoreException {
    Assert.isTrue(elem.getElementType() != IJavaElement.IMPORT_CONTAINER);
    if (elem instanceof ISourceReference) {
      ISourceReference reference= (ISourceReference) elem;
      String source= reference.getSource();
      if (source != null)
        return Strings.trimIndentation(source, cu.getJavaProject(), false);
    }
    return ""; //$NON-NLS-1$
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.