/* * Copyright (C) 2013 The Android Open Source Project * * 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 com.android.tools.idea.editors.navigation.macros; import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElementFactory; import com.intellij.psi.PsiMethod; import java.io.IOException; import java.io.InputStream; import java.util.IdentityHashMap; import java.util.Map; public class Macros { private static final String TEMPLATES_PACKAGE = /*"com.android.templates.".replace('.', '/')*/ ""; private static final String GENERAL_TEMPLATES = TEMPLATES_PACKAGE + "GeneralTemplates"; private static final String LISTENER_TEMPLATES = TEMPLATES_PACKAGE + "InstallListenerTemplates"; private static final String ACCESS_TEMPLATES = TEMPLATES_PACKAGE + "AccessTemplates"; private static final String LAUNCH_ACTIVITY_TEMPLATES = TEMPLATES_PACKAGE + "LaunchActivityTemplates"; public final PsiMethod defineAssignment; public final MultiMatch createIntent; public final MultiMatch installClickAndCallMacro; public final MultiMatch installItemClickAndCallMacro; public final MultiMatch installMenuItemOnGetMenuItemAndLaunchActivityMacro; public final MultiMatch defineInnerClassToLaunchActivityMacro; public final MultiMatch findViewById; public final MultiMatch findFragmentByTag; private static Map<Project, Macros> ourProjectToMacros = new IdentityHashMap<Project, Macros>(); private final Project myProject; private static PsiMethod[] getMethodsByName(String templateName, String methodName, Project project) { JavaPsiFacade facade = JavaPsiFacade.getInstance(project); final PsiElementFactory factory = facade.getElementFactory(); ClassLoader classLoader = Macros.class.getClassLoader(); try { InputStream inputStream = classLoader.getResourceAsStream("/navigationTemplates/" + templateName + ".java.template"); try { int available = inputStream.available(); byte[] buffer = new byte[available]; assert available == inputStream.read(buffer); String text = new String(buffer); int start = text.indexOf("{"); int end = text.lastIndexOf("}"); String body = text.substring(start + 1, end); PsiClass psiClass = factory.createClassFromText(body, null); //todo consider providing a context return psiClass.findMethodsByName(methodName, false); } finally { inputStream.close(); } } catch (IOException e) { throw new RuntimeException(e); } } public static Macros getInstance(Project project) { Macros result = ourProjectToMacros.get(project); if (result == null) { ourProjectToMacros.put(project, result = new Macros(project)); } return result; } public MultiMatch createMacro(String methodDefinition) { return MultiMatch.create(myProject, methodDefinition); } private Macros(Project project) { myProject = project; defineAssignment = getMethodsByName(GENERAL_TEMPLATES, "defineAssignment", project)[0]; PsiMethod defineInnerClassMacro = getMethodsByName(GENERAL_TEMPLATES, "defineInnerClass", project)[0]; PsiMethod installClickMacro = getMethodsByName(LISTENER_TEMPLATES, "installClickListener", project)[0]; PsiMethod installMenuItemClickMacro = getMethodsByName(LISTENER_TEMPLATES, "installMenuItemClick", project)[0]; PsiMethod installItemClickMacro = getMethodsByName(LISTENER_TEMPLATES, "installItemClickListener", project)[0]; PsiMethod getMenuItemMacro = getMethodsByName(ACCESS_TEMPLATES, "getMenuItem", project)[0]; PsiMethod launchActivityMacro = getMethodsByName(LAUNCH_ACTIVITY_TEMPLATES, "launchActivity", project)[0]; PsiMethod launchActivityMacro2 = getMethodsByName(LAUNCH_ACTIVITY_TEMPLATES, "launchActivity", project)[1]; createIntent = createMacro("void macro(Context context, Class activityClass) { new Intent(context, activityClass); }"); installClickAndCallMacro = new MultiMatch(installClickMacro); installItemClickAndCallMacro = new MultiMatch(installItemClickMacro); findViewById = createMacro("void findViewById(int $id) { findViewById(R.id.$id);}"); findFragmentByTag = createMacro("void findViewById(void $fragmentManager, int $tag) { $fragmentManager.findFragmentByTag($tag);}"); installMenuItemOnGetMenuItemAndLaunchActivityMacro = new MultiMatch(installMenuItemClickMacro); installMenuItemOnGetMenuItemAndLaunchActivityMacro.addSubMacro("$menuItem", getMenuItemMacro); installMenuItemOnGetMenuItemAndLaunchActivityMacro.addSubMacro("$f", launchActivityMacro); defineInnerClassToLaunchActivityMacro = new MultiMatch(defineInnerClassMacro); defineInnerClassToLaunchActivityMacro.addSubMacro("$f", launchActivityMacro2); } }