Package org.pdtextensions.core.ui.actions

Source Code of org.pdtextensions.core.ui.actions.GenerateGettersHandler$InvalidElementException

/*******************************************************************************
* This file is part of the PDT Extensions eclipse plugin.
*
* (c) Robert Gruendler <r.gruendler@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
******************************************************************************/
package org.pdtextensions.core.ui.actions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.IMember;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.core.SourceType;
import org.eclipse.dltk.ui.DLTKPluginImages;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.php.core.compiler.PHPFlags;
import org.eclipse.php.internal.core.PHPCoreConstants;
import org.eclipse.php.internal.core.PHPCorePlugin;
import org.eclipse.php.internal.core.ast.nodes.ASTNode;
import org.eclipse.php.internal.core.ast.nodes.ASTParser;
import org.eclipse.php.internal.core.ast.nodes.Block;
import org.eclipse.php.internal.core.ast.nodes.ClassDeclaration;
import org.eclipse.php.internal.core.ast.nodes.Program;
import org.eclipse.php.internal.core.ast.nodes.Statement;
import org.eclipse.php.internal.core.format.FormatterUtils;
import org.eclipse.php.internal.ui.actions.SelectionHandler;
import org.eclipse.php.internal.ui.editor.PHPStructuredEditor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.texteditor.ITextEditor;
import org.pdtextensions.core.ui.dialog.GetterSetterDialog;
import org.pdtextensions.core.ui.util.GetterSetterUtil;
import org.pdtextensions.core.util.PDTFormatterUtils;


/**
*
* Generates getters for private fields.
*
* @author Robert Gruendler <r.gruendler@gmail.com>
*
*/
@SuppressWarnings("restriction")
public class GenerateGettersHandler extends SelectionHandler implements IHandler {
 
  private IEditorPart editorPart;
  private PHPStructuredEditor textEditor;
  private IDocument document;
 
    private Map options;
  private SourceType type;
  private String lineDelim;
  private boolean insertFirst = false;
  private IModelElement insertAfter = null;
 
 
  @SuppressWarnings("rawtypes")
  private static class GetterSetterContentProvider implements ITreeContentProvider {

    private Map fields;
    private static final Object[] EMPTY = new Object[0];
   
    public GetterSetterContentProvider(Map fields) {

      this.fields = fields;
    }

    @Override
    public void dispose() {
      fields.clear();
      fields = null;     
    }

    @Override
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
           
    }

    @Override
    public Object[] getElements(Object inputElement) {

      return fields.keySet().toArray();
     

    }

    @Override
    public Object[] getChildren(Object parentElement) {
     
      if (parentElement instanceof IField) {
         
          Object[] elems = (Object[]) fields.get(parentElement);

          for (Object elem : elems) {
              GetterSetterEntry entry = (GetterSetterEntry) elem;
          }
        return elems;
      }
     
      return EMPTY;
    }

    @Override
    public Object getParent(Object element) {

      if (element instanceof IMember) {
        return ((IMember) element).getDeclaringType();
      }
      if (element instanceof GetterSetterEntry)
        return ((GetterSetterEntry) element).field;
     
      return null;
    }

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

    }
  }
 
  private class GetterSetterLabelProvider extends LabelProvider {

   
    @Override
    public Image getImage(Object element) {
     
      if (element instanceof GetterSetterEntry) {       
        return DLTKUIPlugin.getImageDescriptorRegistry().get(DLTKPluginImages.DESC_FIELD_PUBLIC);
      } else if (element instanceof IField){
        return DLTKUIPlugin.getImageDescriptorRegistry().get(DLTKPluginImages.DESC_FIELD_PRIVATE);
       
      }
      return super.getImage(element);

    }
    @Override
    public String getText(Object element) {

      if (element instanceof GetterSetterEntry) {
        GetterSetterEntry entry = (GetterSetterEntry) element;
        return entry.getName();
      } else if (element instanceof IField){
        return GetterSetterUtil.getFieldName(((IField)element));
       
      }
     
      return super.getText(element);
    }
  }
 
  protected Object exitMessage()
  {
      final Shell p = DLTKUIPlugin.getActiveWorkbenchShell();
      MessageDialog.openInformation(p, "Getter/Setter generation unavailable", "No fields to generate getters/setters found.");
      return null;
  }
 
  @SuppressWarnings("rawtypes")
  @Override
  public Object execute(ExecutionEvent event) throws ExecutionException {

    IModelElement element = getCurrentModelElement(event);
   
    if (element == null) {     
        return exitMessage();
    }
   
    if (!(element instanceof SourceType)) {     
      while(element.getParent() != null) {       
        element = element.getParent();       
        if (element instanceof SourceType) {
          break;
        }
      }
    }
   
    if (element == null || !(element instanceof SourceType)) {
      return exitMessage();
    }
   
    type = (SourceType) element;
   
    try {

      if (type.getFields().length == 0) {
          return exitMessage();
      }

      initialize(event, element);
     
      Map fields = getFields();     
      final Shell p = DLTKUIPlugin.getActiveWorkbenchShell();
      GetterSetterContentProvider cp = new GetterSetterContentProvider(fields);
      GetterSetterDialog dialog = new GetterSetterDialog(p, new GetterSetterLabelProvider(), cp, type);
     
      dialog.setContainerMode(true);
      dialog.setInput(type);
      dialog.setTitle("Generate Getters and Setters");
     
      if (fields.size() == 0) {
          return exitMessage();
      }
     
      if (dialog.open() == Window.OK) {
       
        List<GetterSetterEntry> entries = new ArrayList<GetterSetterEntry>();       
        Object[] dialogResult = dialog.getResult();
       
        for (Object o : dialogResult) {         
          if (o instanceof GetterSetterEntry) {       
            entries.add((GetterSetterEntry) o);           
          }
        }
       
        insertFirst = false;
        insertAfter = null;
       
        if (dialog.insertAsFirstMember())
          insertFirst = true;
        else if (dialog.insertAsLastMember()) {
        } else insertAfter = dialog.getInsertionPoint();
       
        generate(entries, dialog.getModifier(), dialog.doGenerateComments(), dialog.hasFluentInterface());
       
      }
     
     
    } catch (Exception e) {
      e.printStackTrace();
    }

    return null;
  }
 
 
  private void generate(final List<GetterSetterEntry> entries, final int modifier, final boolean generateComments, final boolean fluent) throws Exception {

    ISourceModule source = type.getSourceModule();     
    String name = type.getElementName().replace("$", "");     
    StringBuffer buffer = new StringBuffer(name);     
    buffer.replace(0, 1, Character.toString(Character.toUpperCase(name.charAt(0))));     
    name = buffer.toString();     
         
    ASTParser parser = ASTParser.newParser(source);
    parser.setSource(document.get().toCharArray());
   
    Program program = parser.createAST(new NullProgressMonitor());     
//    program.recordModifications();   
//    AST ast = program.getAST();   

    ISourceRange range = type.getSourceRange();   
    ASTNode node = program.getElementAt(range.getOffset());

    if (!(node instanceof ClassDeclaration)) {
      return ;       
    }
   
    char indentChar = FormatterUtils
        .getFormatterCommonPrferences().getIndentationChar(document);
    String indent = String.valueOf(indentChar);
   
    ClassDeclaration clazz = (ClassDeclaration) node;
    Block body = clazz.getBody();
    List<Statement> bodyStatements = body.statements();
       

    int end = bodyStatements.get(bodyStatements.size()-1).getEnd();
   
    if (insertFirst) {
      end = bodyStatements.get(0).getStart() - 1;
    } else if (insertAfter != null) {
     
      boolean found = false;
     
      for (IMethod method : type.getMethods()) {       
        if (method == insertAfter) {
          ISourceRange r = method.getSourceRange();
          end = r.getOffset() + r.getLength();
          found = true;
        }
      }
     
      if (!found) {       
        for (IField field : type.getFields()) {
          ISourceRange r = field.getSourceRange();
          end = r.getOffset() + r.getLength() + 1;
        }
      }
    }
   
    lineDelim = TextUtilities.getDefaultLineDelimiter(document);
    String methods = "";
   
    int i = 0;
    for (GetterSetterEntry entry : entries) {
     
      String code = "";
     
      if (!entry.isGetter) {
        code = GetterSetterUtil.getSetterStub(entry.field,
            entry.getIdentifier(), entry.getType(), generateComments, modifier, indent, fluent);
       
      } else {
        code = GetterSetterUtil.getGetterStub(entry.field,
            entry.getIdentifier(), generateComments, modifier, indent);       
      }   
     
      code = lineDelim + code;
      String formatted = indentPattern(code, indent, lineDelim);
     
      if (i++ == 0) {
        formatted = lineDelim + formatted;
      }
     
      methods+= formatted;

     
    }           
   
    document.replace(end, 0, methods);
    PDTFormatterUtils.format(document, new Region(end, methods.length()), type.getScriptProject().getProject());
  }
 
  private String indentPattern(String originalPattern, String indentation,
      String lineDelim) {
   
    String delimPlusIndent = lineDelim + indentation;
    String indentedPattern = originalPattern.replaceAll(lineDelim,delimPlusIndent) + delimPlusIndent;

    return indentedPattern;
  }
 


  @SuppressWarnings({ "unchecked", "rawtypes" })
  private void setupOptions() {

    options = new HashMap(PHPCorePlugin.getOptions());
   
    IScopeContext[] contents = new IScopeContext[] {
        new ProjectScope(type
            .getScriptProject()
            .getProject()),
            InstanceScope.INSTANCE, DefaultScope.INSTANCE };
   
    for (int i = 0; i < contents.length; i++) {
     
      IScopeContext scopeContext = contents[i];
      IEclipsePreferences inode = scopeContext.getNode(PHPCorePlugin.ID);
     
      if (inode != null) {
       
        if (!options.containsKey(PHPCoreConstants.FORMATTER_USE_TABS)) {
         
          String useTabs = inode.get(PHPCoreConstants.FORMATTER_USE_TABS,null);
          if (useTabs != null) {
            options.put(PHPCoreConstants.FORMATTER_USE_TABS, useTabs);
          }
        }
       
        if (!options.containsKey(PHPCoreConstants.FORMATTER_INDENTATION_SIZE)) {
         
          String size = inode.get(PHPCoreConstants.FORMATTER_INDENTATION_SIZE,null);
         
          if (size != null) {
            options.put(PHPCoreConstants.FORMATTER_INDENTATION_SIZE,size);
          }
        }
      }
    }
  }
 
 
  private void initialize(ExecutionEvent event, IModelElement element) throws InvalidElementException {
   
    editorPart = HandlerUtil.getActiveEditor(event);
    textEditor = null;
    if (editorPart instanceof PHPStructuredEditor)
      textEditor = (PHPStructuredEditor) editorPart;
    else {
      Object o = editorPart.getAdapter(ITextEditor.class);
      if (o != null)
        textEditor = (PHPStructuredEditor) o;
    }
   
    document = textEditor.getDocument();
   
    setupOptions();

  }
 
 
  @SuppressWarnings({ "rawtypes", "unchecked" })
  private Map getFields() throws ModelException {
   
    IField[] fields = type.getFields();
    Map result = new LinkedHashMap();
    for (int i = 0; i < fields.length; i++) {
               
      IField field = fields[i];
     
      int flags = field.getFlags();
      if (PHPFlags.isStatic(flags) || PHPFlags.isConstant(flags)) {
          continue;
      }
     
      String name = field.getElementName().replace("$", "");
            String getter = "get" + name.toLowerCase();
            String setter = "set" + name.toLowerCase();
     
      List l = new ArrayList(2);
      List<GetterSetterEntry> entries = new ArrayList<GetterSetterEntry>();
     
      boolean getterExists = false;
      boolean setterExists = false;
     
            for (IMethod method : type.getMethods()) {
                String methodName = method.getElementName().toLowerCase();
                if (methodName.startsWith("get")) {
                    getterExists = methodName.equals(getter);   
                } else if (methodName.startsWith("set")) {
                    setterExists = methodName.equals(setter);   
                }
            }
     
            if (!getterExists) {
                entries.add(new GetterSetterEntry(field, true));
            }
           
            if (!setterExists) {
                entries.add(new GetterSetterEntry(field, false));
            }
           
            if (!getterExists || !setterExists) {
                l.addAll(entries);   
            }
           
      if (!l.isEmpty())
        result.put(field, l.toArray(new GetterSetterEntry[l.size()]));

    }

    return result;
   
  }
 
  private class InvalidElementException extends Exception {

    private static final long serialVersionUID = 1L;
   
  }
 
  public static class GetterSetterEntry {
   
   
    public final IField field;
    public final boolean isGetter;
    private String name = null;
    private String identifier = null;
    private String type = null;
    private String raw = null;
   
    public GetterSetterEntry(IField field, boolean isGetterEntry) {
   
      this.field = field;
      this.isGetter = isGetterEntry;
    }
   
    public String getIdentifier() {
     
      if (identifier != null)
        return identifier;
     
      if (isGetter)
        return identifier = GetterSetterUtil.getGetterName(field);
      else return identifier = GetterSetterUtil.getSetterName(field);
     
    }
   
    public String getType() {

      if (type != null)
        return type;
     
      return type = GetterSetterUtil.getTypeReference(field);
     
    }
   
    public String getName() {

      if (name != null)
        return name;
     
      if (isGetter) {
        return name = String.format("%s()", getIdentifier());
      } else {
          String elemName = field.getElementName();
          String type = getType();
          String param = "";
          if (type != null && type != "") {            
              param += type +" ";
          }
          param += elemName;
        return name = String.format("%s(%s)", getIdentifier(), param);
      }
    }


    public String getRawFieldName() {

      if (raw != null)
        return raw;
     
      return raw = field.getElementName().replace("$", "");
     
    }
   
  }
}
TOP

Related Classes of org.pdtextensions.core.ui.actions.GenerateGettersHandler$InvalidElementException

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.