/* * Copyright (C) 2012 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.motorola.studio.android.generatemenucode.model.codegenerators; import java.util.List; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.ExpressionStatement; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.SimpleName; import com.motorola.studio.android.generatecode.BasicCodeVisitor; /** * Visitor to collect information on activity/fragment class (about menu creation methods or variables). * It serves to avoid code duplication and fill the menu declared for this activity/fragment. */ public class CodeGeneratorBasedOnMenuVisitor extends BasicCodeVisitor { /* * Constants */ private static final String ACTIVITY_ON_CREATE_MENU_DECLARATION = "public boolean onCreateOptionsMenu(android.view.Menu)"; //$NON-NLS-1$ private static final String FRAGMENT_ON_CREATE_MENU_DECLARATION = "public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater)"; //$NON-NLS-1$ private static final String ACTIVITY_ON_CREATE_MENU = "onCreateOptionsMenu"; //$NON-NLS-1$ private static final String FRAGMENT_ON_CREATE_MENU = "onCreateOptionsMenu"; //$NON-NLS-1$ private static final String INFLATE_METHOD = "inflate"; /** * If type is fragment, there may be an inflated menu name. */ private String inflatedMenuName; /** * Visit method declaration, searching for instructions * onCreate for activity or fragment */ @Override public boolean visit(MethodDeclaration node) { //Fill Method information SimpleName name = node.getName(); if (name.getIdentifier().equals(ACTIVITY_ON_CREATE_MENU) || name.getIdentifier().equals(FRAGMENT_ON_CREATE_MENU)) { IMethodBinding binding = node.resolveBinding(); if (binding != null) { if (binding.toString().trim().contains(ACTIVITY_ON_CREATE_MENU_DECLARATION) || binding.toString().trim().contains(FRAGMENT_ON_CREATE_MENU_DECLARATION)) { visitMethodBodyToIdentifyMenu(node); } } } return super.visit(node); } /** * Visit method body from onCreateOptionsMenu declaration to the inflated menu * @param node */ protected void visitMethodBodyToIdentifyMenu(MethodDeclaration node) { //Navigate through statements... Block body = node.getBody(); if (body != null) { List<?> statements = body.statements(); if (statements != null) { for (Object statement : statements) { if ((statement != null) && (statement instanceof ExpressionStatement)) { Expression argumentExpression = ((ExpressionStatement) statement).getExpression(); if ((argumentExpression != null) && (argumentExpression instanceof MethodInvocation)) { String methodSimpleName = ((MethodInvocation) argumentExpression).getName().toString(); if ((methodSimpleName != null) && (methodSimpleName.equals(INFLATE_METHOD))) { if ((((MethodInvocation) argumentExpression).arguments() != null) && (((MethodInvocation) argumentExpression).arguments() .size() > 0)) { String menuBeingInflated = ((MethodInvocation) argumentExpression).arguments() .get(0).toString(); if ((menuBeingInflated != null) && (menuBeingInflated.indexOf('.') > 0)) { setInflatedMenuName(menuBeingInflated.substring( menuBeingInflated.lastIndexOf('.') + 1, menuBeingInflated.length())); } break; } } } } } } } } /** * @return the inflatedMenuName */ public String getInflatedMenuName() { return inflatedMenuName; } /** * @param inflatedMenuName the inflatedMenuName to set */ public void setInflatedMenuName(String inflatedMenuName) { this.inflatedMenuName = inflatedMenuName; } }