001// Copyright 2006, 2007, 2012 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.ioc.internal.services; 016 017/** 018 * Used by {@link org.apache.tapestry5.ioc.internal.services.PipelineBuilderImpl} to analyze service interface methods 019 * against filter interface methods to find the position of the extra service parameter (in the filter method). 020 */ 021public class FilterMethodAnalyzer 022{ 023 private final Class serviceInterface; 024 025 FilterMethodAnalyzer(Class serviceInterface) 026 { 027 this.serviceInterface = serviceInterface; 028 } 029 030 public int findServiceInterfacePosition(MethodSignature ms, MethodSignature fms) 031 { 032 if (ms.getReturnType() != fms.getReturnType()) return -1; 033 034 if (!ms.getName().equals(fms.getName())) return -1; 035 036 Class[] filterParameters = fms.getParameterTypes(); 037 int filterParameterCount = filterParameters.length; 038 Class[] serviceParameters = ms.getParameterTypes(); 039 040 if (filterParameterCount != (serviceParameters.length + 1)) return -1; 041 042 // TODO: check compatible exceptions! 043 044 // This needs work; it assumes the first occurance of the service interface 045 // in the filter interface method signature is the right match. That will suit 046 // most of the time. 047 048 boolean found = false; 049 int result = -1; 050 051 for (int i = 0; i < filterParameterCount; i++) 052 { 053 if (filterParameters[i] == serviceInterface) 054 { 055 result = i; 056 found = true; 057 break; 058 } 059 } 060 061 if (!found) return -1; 062 063 // Check that all the parameters before and after the service interface still 064 // match. 065 066 for (int i = 0; i < result; i++) 067 { 068 if (filterParameters[i] != serviceParameters[i]) return -1; 069 } 070 071 for (int i = result + 1; i < filterParameterCount; i++) 072 { 073 if (filterParameters[i] != serviceParameters[i - 1]) return -1; 074 } 075 076 return result; 077 } 078 079}