001/** 002 * Copyright (C) 2006-2025 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.tools.validator; 017 018import java.io.File; 019import java.util.Arrays; 020import java.util.List; 021import java.util.stream.Stream; 022 023import org.apache.xbean.finder.AnnotationFinder; 024import org.talend.sdk.component.api.exception.ComponentException; 025import org.talend.sdk.component.tools.ComponentValidator.Configuration; 026import org.talend.sdk.component.tools.validator.Validators.ValidatorHelper; 027 028import lombok.extern.slf4j.Slf4j; 029 030@Slf4j 031public class ExceptionValidator implements Validator { 032 033 private final Validators.ValidatorHelper helper; 034 035 private final Configuration configuration; 036 037 public ExceptionValidator(final ValidatorHelper helper, final Configuration configuration) { 038 this.helper = helper; 039 this.configuration = configuration; 040 } 041 042 @Override 043 public Stream<String> validate(final AnnotationFinder finder, final List<Class<?>> components) { 044 final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 045 final Stream<String> errorsException = helper 046 .componentClassFiles() 047 .flatMap(f -> streamClassesInDirectory(classLoader, null, f)) 048 .filter(ComponentException.class::isAssignableFrom) 049 .map(e -> e.getName() 050 + " inherits from ComponentException, this will lead to ClassNotFound errors in some environments. Use instead ComponentException directly!"); 051 if (configuration.isFailOnValidateExceptions()) { 052 return errorsException; 053 } else { 054 errorsException.forEach(e -> log.error(e)); 055 } 056 057 return Stream.empty(); 058 } 059 060 private Stream<Class> streamClassesInDirectory(final ClassLoader loader, final String pckg, final File classFile) { 061 if (classFile.isDirectory()) { 062 return Arrays 063 .stream(classFile.listFiles()) 064 .flatMap(f -> streamClassesInDirectory(loader, nextPackage(pckg, classFile.getName()), f)); 065 } 066 067 if (classFile.getName().endsWith(".class")) { 068 final String className = classFile.getName().substring(0, classFile.getName().lastIndexOf(".")); 069 final String completeName = pckg + className; 070 try { 071 return Stream.of(loader.loadClass(completeName)); 072 } catch (final Exception e) { 073 log.error("Could not load class : " + completeName + "=>" + e.getMessage()); 074 } 075 } 076 077 return Stream.empty(); 078 } 079 080 private String nextPackage(final String current, final String next) { 081 return current == null ? "" : current + next + "."; 082 } 083}