Package org.playframework.playclipse.handlers

Source Code of org.playframework.playclipse.handlers.GoToViewHandler

/*
* Playclipse - Eclipse plugin for the Play! Framework
* Copyright 2009 Zenexity
*
* This file is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.playframework.playclipse.handlers;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import org.playframework.playclipse.FilesAccess;
import org.playframework.playclipse.Navigation;
import org.playframework.playclipse.PlayPlugin;

import cn.bran.japid.util.DirUtil;
import fr.zenexity.pdt.editors.EditorHelper;

/**
* Go to the view (template) corresponding to the current action
*/
public class GoToViewHandler extends AbstractHandler {
  static Pattern stringPattern = Pattern.compile("\"(.*)\"");
  static Pattern methodNamePattern = Pattern.compile("\\w+\\s*\\(");
  static Pattern renderJapidPattern = Pattern.compile("renderJapid\\s*\\(");
  static Pattern renderJapidWithPattern = Pattern.compile("renderJapidWith\\s*\\(\\s*\"(.*)\"");
  private IWorkbenchWindow window;

  /**
   * The constructor.
   */
  public GoToViewHandler() {
  }

//  @SuppressWarnings("restriction")
  @Override
  public Object execute(ExecutionEvent event) throws ExecutionException {
    window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
    EditorHelper editor = EditorHelper.getCurrent(event);
    IProject project = editor.getProject();
    IJavaProject jProject = JavaCore.create(project);
   
    if(editor != null) {
      String relativePath = ((IFileEditorInput) editor.textEditor.getEditorInput()).getFile().getProjectRelativePath().toString();
      if (relativePath.startsWith("app/japidviews/") && relativePath.endsWith(".java")) {
        // bran: if we are in the japid derived Java template code, let's switch back to the html view
        String jFile = DirUtil.mapJavaToSrc(relativePath);
        IFile f = project.getFile(jFile);
        try {
          FilesAccess.openFile(f);
        } catch (CoreException e) {
          PlayPlugin.showError(e);
        }
        return null;   
      }
    }
   
    boolean useJapid = true;

    String line;
    String viewName = null;
    String title = editor.getTitle();
    String controllerName = title.replace(".java", "");

    String packageName = "";
    IEditorInput editorInput = editor.textEditor.getEditorInput();
   
    ITextSelection selection = (ITextSelection) editor.textEditor.getSelectionProvider().getSelection();
    IJavaElement elem = JavaUI.getEditorInputJavaElement(editorInput);
    ICompilationUnit unit = null;
    if (elem instanceof ICompilationUnit) {
      unit = (ICompilationUnit) elem;
      try {
        IPackageDeclaration[] packs = unit.getPackageDeclarations();
        if (packs.length < 1) {
          info("This action can only apply to controllers.");
          return null;
        } else {
          packageName = packs[0].getElementName();
          if (!packageName.startsWith("controllers")) {
            info("This action can only apply to controllers.");
            return null;
          }
        }
       
        // get the class declaration line
        IType type = unit.getType(controllerName);
        ITypeHierarchy superTypes = type.newSupertypeHierarchy(null);
//        String name = JapidController.class.getName(); // this will require play.jar
        String name = "cn.bran.play.JapidController";
        IType japidController = jProject.findType(name);
        if (superTypes.contains(japidController)) {
          useJapid = true;
        }
        else {
          useJapid = false;
        }
       
//        String superclassName = type.getSuperclassName();
//        if (superclassName.toLowerCase().contains("japid")) {
//          useJapid = true;
//        }
       
        // current selected elem
            IJavaElement[] elements= unit.codeSelect(selection.getOffset(), selection.getLength());
            if (elements.length > 0) {
              // TODO extract the current selection to tell if the cursor in on renderJapidXXX line
              System.out.println(elements);
            }

      } catch (JavaModelException e) {
        e.printStackTrace();
      }
    } else {
      System.out.println(elem.getElementType() + ":" + elem.getElementName());
    }

    viewName = getEnclosingActionName(selection, unit);

    int lineNo = editor.getCurrentLineNo();
    line = editor.getLine(lineNo);
    if (line.contains("render")) {
      if (!line.contains("renderJapid")) {
        Pattern pt = Pattern.compile("\"(.*)\"");
        Matcher m = pt.matcher(line);
        if (m.find()) {
          // render classic groovy
          useJapid = false;
          // There is a custom view, by renderTemplate()
          viewName = "app/views/" + m.group().replace("\"", "");
        }
      } else {
        // render japid
        useJapid = true;
        if(line.contains("renderJapidWith")) {
          // explicit template name
          Matcher m = stringPattern.matcher(line);
          if (m.find()) {
            // There is a custom view
            // the template strin is the view name in relative to the japidviews directory
            viewName = "app/japidviews/" + m.group().replace("\"", "");
          }
          else {
            System.out.println("the first param of renderJapidWith is not a String. Strange....");
          }
        }
      }
    }
   
    if (viewName == null) {
      String string = "Use this command in a controller action body, or on a render...() line";
      info(string);
    } else {
      if (!viewName.startsWith("app")) {
       
        viewName = "app/" + (useJapid? "japidviews" : "views") + "/"
          + (packageName.equals("controllers") ? "" : packageName.substring(12).replace('.', '/') + "/")
          + controllerName + "/" + viewName + ".html";
      }
     
      (new Navigation(editor)).goToViewAbs(viewName);
    }
    return null;
  }

  /**
   * @param selection
   * @param unit
   */
  private String getEnclosingActionName(ITextSelection selection, ICompilationUnit unit) {
    IJavaElement selected;
    try {
      selected = unit.getElementAt(selection.getOffset());
      List<IJavaElement> path = getJavaElementsPath(selected);
      if (path.size() >= 7) {
        IJavaElement el = path.get(6);
        if (el.getElementType() == IJavaElement.METHOD) {
          IMethod sm = (IMethod)el;
          int flags = sm.getFlags();
          String actionMethodName = el.getElementName();
          if (/*Flags.isPublic(flags) &&*/ Flags.isStatic(flags)) {
            return actionMethodName;
          }
          else {
            info("The enclosig method " + actionMethodName + " is not public static, thus not a valid action method.");
          }
        }
      }
    }
    catch (JavaModelException e) {
      PlayPlugin.showError(e);
    }
    return null;
  }
 
  static void printAstPath(IJavaElement elem) {
    System.out.println(elem.getClass() + ":" + elem.getElementType() + ":" + elem.getElementName());
    IJavaElement parent = elem.getParent();
    if (parent != null) {
      printAstPath(parent);
    }
  }
 
  /**
   * the result pattern:
   *   {JavaModel, JavaProject, packageFragmentRoot, PackageFragment (package name),
   *   CompilationUnit (source file title), SouceType (class name}...
   * @param elem
   * @return
   */
  public static List<IJavaElement> getJavaElementsPath(IJavaElement elem) {
    List<IJavaElement> path = new ArrayList<IJavaElement>();
    if (elem == null)
      return path;
    path.add(elem);
    elem = elem.getParent();
    while (elem != null) {
      path.add(elem);
      elem = elem.getParent();
    }
    Collections.reverse(path);
    return path;
  }

  /**
   * @param window
   * @param string
   */
  private void info(String string) {
    MessageDialog.openInformation(window.getShell(), "Playclipse", string);
  }
}
TOP

Related Classes of org.playframework.playclipse.handlers.GoToViewHandler

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.