/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 freemarker.ext.beans;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import freemarker.template.ObjectWrapperAndUnwrapper;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

Stores the non-varargs methods for a OverloadedMethods object.
/** * Stores the non-varargs methods for a {@link OverloadedMethods} object. */
class OverloadedFixArgsMethods extends OverloadedMethodsSubset { OverloadedFixArgsMethods(boolean bugfixed) { super(bugfixed); } @Override Class[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) { return memberDesc.getParamTypes(); } @Override void afterWideningUnwrappingHints(Class[] paramTypes, int[] paramNumericalTypes) { // Do nothing } @Override MaybeEmptyMemberAndArguments getMemberAndArguments(List tmArgs, BeansWrapper unwrapper) throws TemplateModelException { if (tmArgs == null) { // null is treated as empty args tmArgs = Collections.EMPTY_LIST; } final int argCount = tmArgs.size(); final Class[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount(); if (unwrappingHintsByParamCount.length <= argCount) { return EmptyMemberAndArguments.WRONG_NUMBER_OF_ARGUMENTS; } Class[] unwarppingHints = unwrappingHintsByParamCount[argCount]; if (unwarppingHints == null) { return EmptyMemberAndArguments.WRONG_NUMBER_OF_ARGUMENTS; } Object[] pojoArgs = new Object[argCount]; int[] typeFlags = getTypeFlags(argCount); if (typeFlags == ALL_ZEROS_ARRAY) { typeFlags = null; } Iterator it = tmArgs.iterator(); for (int i = 0; i < argCount; ++i) { Object pojo = unwrapper.tryUnwrapTo( (TemplateModel) it.next(), unwarppingHints[i], typeFlags != null ? typeFlags[i] : 0); if (pojo == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) { return EmptyMemberAndArguments.noCompatibleOverload(i + 1); } pojoArgs[i] = pojo; } MaybeEmptyCallableMemberDescriptor maybeEmtpyMemberDesc = getMemberDescriptorForArgs(pojoArgs, false); if (maybeEmtpyMemberDesc instanceof CallableMemberDescriptor) { CallableMemberDescriptor memberDesc = (CallableMemberDescriptor) maybeEmtpyMemberDesc; if (bugfixed) { if (typeFlags != null) { // Note that overloaded method selection has already accounted for overflow errors when the method // was selected. So this forced conversion shouldn't cause such corruption. Except, conversion from // BigDecimal is allowed to overflow for backward-compatibility. forceNumberArgumentsToParameterTypes(pojoArgs, memberDesc.getParamTypes(), typeFlags); } } else { BeansWrapper.coerceBigDecimals(memberDesc.getParamTypes(), pojoArgs); } return new MemberAndArguments(memberDesc, pojoArgs); } else { return EmptyMemberAndArguments.from((EmptyCallableMemberDescriptor) maybeEmtpyMemberDesc, pojoArgs); } } }