Package org.eclipse.jst.jsp.ui.internal.java.refactoring

Source Code of org.eclipse.jst.jsp.ui.internal.java.refactoring.BasicRefactorSearchRequestor

/*******************************************************************************
* Copyright (c) 2004, 2010 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.jst.jsp.ui.internal.java.refactoring;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.search.SearchDocument;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jst.jsp.core.internal.java.search.JSPSearchSupport;
import org.eclipse.jst.jsp.core.internal.java.search.JavaSearchDocumentDelegate;
import org.eclipse.jst.jsp.ui.internal.JSPUIMessages;
import org.eclipse.jst.jsp.ui.internal.Logger;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.osgi.util.NLS;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;

/**
* <p>After a search is run with this {@link SearchRequestor} {@link #getChanges(RefactoringParticipant)}
* can be called to get any new {@link Change}s that need to be created as a result of the search.  If
* {@link Change}s are already existing for the documents found then new {@link Change}s will not be
* created for them, but the needed {@link TextEdit}s will be added to the existing {@link Change}s.</p>
*/
public class BasicRefactorSearchRequestor extends SearchRequestor {
  /** The type being renamed (the old type)*/
  IJavaElement fElement = null;
  /** The new name of the type being renamed*/
  private String fNewName = ""; //$NON-NLS-1$
  /** maps a JSPSearchDocument path -> MultiTextEdit for the java file*/
  private HashMap fSearchDocPath2JavaEditMap = null;
 
  public BasicRefactorSearchRequestor(IJavaElement element, String newName) {
    this.fNewName = newName;
    this.fElement = element;
    this.fSearchDocPath2JavaEditMap = new HashMap();
  }
 
  public IJavaElement getElement() {
    return this.fElement;
  }

  /**
   * @return the new name for the Type
   */
  public String getNewName() {
    return this.fNewName;
  }
 
  /**
   * @see org.eclipse.jdt.core.search.SearchRequestor#acceptSearchMatch(org.eclipse.jdt.core.search.SearchMatch)
   */
  public void acceptSearchMatch(SearchMatch javaMatch) throws CoreException {
   
    String matchDocumentPath = javaMatch.getResource().getFullPath().toString();
    SearchDocument searchDoc = JSPSearchSupport.getInstance().getSearchDocument(matchDocumentPath);
 
    if (searchDoc != null && searchDoc instanceof JavaSearchDocumentDelegate) {
 
      String renameText = getRenameText((JavaSearchDocumentDelegate)searchDoc, javaMatch);
     
      //if rename text is null then don't create an edit for it
      if(renameText != null) {
        // add it for the correct document
        addJavaEdit(searchDoc.getPath(), new ReplaceEdit(javaMatch.getOffset(), javaMatch.getLength(), renameText));
      }
    }
  }
 
  /**
   * @param searchDoc
   * @return the rename text or <code>null</code> if no edit should be created for the given match.
   * Such a case would be a match where nothing needs to be edited.
   */
  protected String getRenameText(JavaSearchDocumentDelegate searchDoc, SearchMatch javaMatch) {
    return getNewName();
  }

  /**
   * Adds to the multi edit for a give java document.
   * @param javaDocument
   * @param javaEdit
   */
  private void addJavaEdit(String searchDocPath, ReplaceEdit javaEdit) {
   
    Object o = this.fSearchDocPath2JavaEditMap.get(searchDocPath);
    if(o != null) {

      MultiTextEdit multi = (MultiTextEdit)o;
      multi.addChild(javaEdit);
    }
    else {
      // use a multi edit so doc position offsets get updated automatically
      // when adding multiple child edits
      MultiTextEdit multi = new MultiTextEdit();
      multi.addChild(javaEdit);
      this.fSearchDocPath2JavaEditMap.put(searchDocPath, multi);
    }
  }
 
  /**
   * <p>This function is not safe because it does not check for existing {@link Change}s that
   * new {@link Change}s created by this method may conflict with.  These conflicts can
   * cause indeterminate results when applied to documents.  Long story short, don't
   * use this method any more.</p>
   *
   * @return all JSP changes for the search matches for the given Type, they may conflict
   * with already existing {@link Change}s
   *
   * @see #getChanges(RefactoringParticipant)
   *
   * @deprecated
   */
  public Change[] getChanges() {
   
    JSPSearchSupport support = JSPSearchSupport.getInstance();
    List changes = new ArrayList();
    Iterator keys = fSearchDocPath2JavaEditMap.keySet().iterator();
    String searchDocPath = null;
    SearchDocument delegate = null;
   
    while(keys.hasNext()) {
      // create on the fly
      searchDocPath = (String)keys.next();
      MultiTextEdit javaEdit = (MultiTextEdit)fSearchDocPath2JavaEditMap.get(searchDocPath);
      delegate = support.getSearchDocument(searchDocPath);
     
      if(delegate != null && delegate instanceof JavaSearchDocumentDelegate) {
        JavaSearchDocumentDelegate javaDelegate = (JavaSearchDocumentDelegate)delegate;
        changes.add(createChange(javaDelegate, javaDelegate.getJspTranslation().getJspEdit(javaEdit)));
      }
    }
    return (Change[])changes.toArray(new Change[changes.size()]);
  }
 
  /**
   * Gets new {@link Change}s created as a result of this {@link SearchRequestor}.
   * Any existing {@link TextChange}s that had new edits added to them will not be
   * returned.
   *
   * @param participant {@link RefactoringParticipant} to determine if there are already existing
   * {@link TextChange}s for the documents that this {@link SearchRequestor} found.
   * If existing
   * {@link TextChange}s are found then they will be used for any new edits, else new {@link TextChange}s
   * will be created.
   *
   * @return Any new {@link TextChange}s created by this {@link SearchRequestor}.  If edits were
   * added to existing {@link TextChange}s then those existing {@link TextChange}s will not be
   * returned in this array.
   */
  public Change[] getChanges(RefactoringParticipant participant) {
   
    JSPSearchSupport support = JSPSearchSupport.getInstance();
    List changes = new ArrayList();
    Iterator keys = fSearchDocPath2JavaEditMap.keySet().iterator();
    String searchDocPath = null;
    SearchDocument delegate = null;
   
    while(keys.hasNext()) {
      // create on the fly
      searchDocPath = (String)keys.next();
      MultiTextEdit javaEdit = (MultiTextEdit)fSearchDocPath2JavaEditMap.get(searchDocPath);
      delegate = support.getSearchDocument(searchDocPath);
     
      if(delegate != null && delegate instanceof JavaSearchDocumentDelegate) {
        JavaSearchDocumentDelegate javaDelegate = (JavaSearchDocumentDelegate)delegate;
        Change change = createChange(javaDelegate, javaDelegate.getJspTranslation().getJspEdit(javaEdit), participant);
        changes.add(change);
      }
    }
    return (Change[])changes.toArray(new Change[changes.size()]);
  }
 
  /**
   * <p>This method is not safe because it does not take into consideration already existing
   * {@link Change}s and thus conflicts could occur that when applied create indeterminate
   * results in the target documents</p>
   *
   * @see #createChange(JavaSearchDocumentDelegate, TextEdit, RefactoringParticipant)
   *
   * @deprecated
   */
  private Change createChange(JavaSearchDocumentDelegate searchDoc, TextEdit edit) {
   
    IDocument doc = searchDoc.getJspTranslation().getJspDocument();
    String file = searchDoc.getFile().getName();
    String description = getDescription();
    try {
      // document lines are 0 based
      String lineNumber = Integer.toString(doc.getLineOfOffset(edit.getOffset()) + 1);
      description += " " + NLS.bind(JSPUIMessages.BasicRefactorSearchRequestor_1, new String[]{file, lineNumber}); //$NON-NLS-1$
    }
    catch (BadLocationException e) {
      Logger.logException(e);
    }
    return new JSPRenameChange(searchDoc.getFile(), doc, edit, description);
  }
 
  /**
   * </p>If a {@link TextChange} does not already exist for the given {@link JavaSearchDocumentDelegate}
   * then a new one will be created with the given {@link TextEdit}.  Otherwise the given {@link TextEdit}
   * will be added to a new group and added to the existing change and <code>null</code> will be returned.</p>
   *
   * @param searchDoc the {@link JavaSearchDocumentDelegate} that the <code>edit</code> will be applied to
   * @param edit the {@link TextEdit} that needs to be added to a new {@link TextChange} or appended to an
   * existing one
   * @param participant the {@link RefactoringParticipant} that knows about the existing {@link TextChange}s
   * @return a new {@link Change} if there was not one already existing for the document in question,
   * else <code>null</code>
   */
  private Change createChange(JavaSearchDocumentDelegate searchDoc, TextEdit edit, RefactoringParticipant participant) {
    IDocument doc = searchDoc.getJspTranslation().getJspDocument();
    String description = getDescription();
   
    TextChange existingChange = participant.getTextChange(searchDoc.getFile());
    TextChange change = null;
    if(existingChange != null) {
      try {
        existingChange.addEdit(edit);
      }catch (MalformedTreeException e) {
        Logger.logException("MalformedTreeException while adding edit " + //$NON-NLS-1$
            edit + " to existing change " + change, e); //$NON-NLS-1$
      }
     
      TextEditGroup group = new TextEditGroup(description, edit);
      existingChange.addTextEditGroup(group);
    } else {
      change = new JSPRenameChange(searchDoc.getFile(), doc, edit, searchDoc.getFile().getName());
      TextEditGroup group = new TextEditGroup(description, edit);
      change.addTextEditGroup(group);
    }
   
    return change;
  }
 
  // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3205
  // only relevant for IType refactorings
  protected boolean isFullyQualified(String matchText) {
    if(getElement() instanceof IType) {
      String pkg = ((IType)getElement()).getPackageFragment().getElementName();
      return matchText.startsWith(pkg);
    }
    return false;
  }

  /**
   * Subclasses should override to better describe the change.
   * @return
   */
  protected String getDescription() {
    return ""; //$NON-NLS-1$
  }
}
TOP

Related Classes of org.eclipse.jst.jsp.ui.internal.java.refactoring.BasicRefactorSearchRequestor

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.