001/** 002 * Copyright (C) 2006-2024 Talend Inc. - www.talend.com 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.talend.sdk.component.runtime.manager.reflect; 017 018import static lombok.AccessLevel.PRIVATE; 019 020import java.lang.reflect.Constructor; 021import java.util.stream.Stream; 022 023import org.talend.sdk.component.api.configuration.Option; 024 025import lombok.NoArgsConstructor; 026 027@NoArgsConstructor(access = PRIVATE) 028public final class Constructors { 029 030 public static Constructor<?> findConstructor(final Class<?> type) { 031 return Stream 032 .of(type.getConstructors()) 033 // we select the constructor with arguments which uses @Option or no-arg 034 // constructor if no param construct 035 // is matching 036 .sorted((c1, c2) -> { 037 final int options1 = Stream 038 .of(c1.getParameters()) 039 .mapToInt(p -> p.isAnnotationPresent(Option.class) ? 1 : 0) 040 .sum(); 041 final int options2 = Stream 042 .of(c1.getParameters()) 043 .mapToInt(p -> p.isAnnotationPresent(Option.class) ? 1 : 0) 044 .sum(); 045 if (options1 == options2) { 046 final int paramCount1 = c1.getParameterCount(); 047 final int paramCount2 = c2.getParameterCount(); 048 return paramCount2 - paramCount1; 049 } 050 return options2 - options1; 051 052 }) 053 .findFirst() 054 .orElseThrow(() -> new IllegalArgumentException("No constructor usable in " + type.getName())); 055 } 056}