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 static java.util.stream.Stream.of; 019 020import java.io.File; 021import java.lang.annotation.Annotation; 022import java.lang.reflect.Parameter; 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.LinkedHashSet; 026import java.util.List; 027import java.util.ResourceBundle; 028import java.util.Set; 029import java.util.stream.Stream; 030 031import org.apache.xbean.finder.AnnotationFinder; 032import org.talend.sdk.component.api.component.Icon; 033import org.talend.sdk.component.api.service.asyncvalidation.AsyncValidation; 034import org.talend.sdk.component.api.service.completion.DynamicValues; 035import org.talend.sdk.component.api.service.completion.Suggestions; 036import org.talend.sdk.component.api.service.dependency.DynamicDependencies; 037import org.talend.sdk.component.api.service.healthcheck.HealthCheck; 038import org.talend.sdk.component.api.service.schema.DiscoverSchema; 039import org.talend.sdk.component.api.service.update.Update; 040import org.talend.sdk.component.runtime.manager.ParameterMeta; 041import org.talend.sdk.component.runtime.manager.reflect.ParameterModelService; 042import org.talend.sdk.component.tools.ComponentValidator.Configuration; 043import org.talend.sdk.component.tools.spi.ValidationExtension; 044 045public class Validators { 046 047 private final List<Validator> validators; 048 049 private Validators(final List<Validator> validators) { 050 this.validators = validators; 051 } 052 053 public interface ValidatorHelper { 054 055 boolean isService(Parameter parameter); 056 057 ResourceBundle findResourceBundle(final Class<?> component); 058 059 String validateFamilyI18nKey(final Class<?> clazz, final String... keys); 060 061 List<ParameterMeta> buildOrGetParameters(final Class<?> c); 062 063 String validateIcon(final Icon annotation, final Collection<String> errors); 064 065 ParameterModelService getParameterModelService(); 066 067 Stream<File> componentClassFiles(); 068 } 069 070 public Set<String> validate(final AnnotationFinder finder, final List<Class<?>> components) { 071 final Set<String> errors = new LinkedHashSet<>(); 072 073 this.validators 074 .stream() 075 .flatMap((Validator validator) -> validator.validate(finder, components)) 076 .forEach(errors::add); 077 return errors; 078 } 079 080 public static Validators build(final Configuration configuration, final ValidatorHelper helper, 081 final Iterable<ValidationExtension> extensions, final File sourceRoot) { 082 083 final List<Validator> activeValidators = new ArrayList<>(); 084 085 if (configuration.isValidateSerializable()) { 086 activeValidators.add(new SerializationValidator()); 087 } 088 089 if (configuration.isValidateInternationalization()) { 090 InternationalizationValidator intern = new InternationalizationValidator(helper, sourceRoot, 091 configuration.isValidatePlaceholder(), configuration.isValidateInternationalizationAutoFix()); 092 activeValidators.add(intern); 093 } 094 095 if (configuration.isValidateHttpClient()) { 096 activeValidators.add(new HttpValidator()); 097 } 098 099 if (configuration.isValidateModel()) { 100 final ModelValidator modelValidator = new ModelValidator(configuration.isValidateComponent(), helper); 101 activeValidators.add(modelValidator); 102 } 103 104 if (configuration.isValidateMetadata()) { 105 final MetadataValidator metaValidator = new MetadataValidator(helper); 106 activeValidators.add(metaValidator); 107 } 108 109 if (configuration.isValidateDataStore()) { 110 final DataStoreValidator validator = new DataStoreValidator(helper); 111 activeValidators.add(validator); 112 } 113 114 if (configuration.isValidateDataSet()) { 115 final DatasetValidator validator = new DatasetValidator(helper); 116 activeValidators.add(validator); 117 final DatasetDiscoveryValidator discoveryValidator = new DatasetDiscoveryValidator(helper); 118 activeValidators.add(discoveryValidator); 119 } 120 121 if (configuration.isValidateActions()) { 122 final ActionValidator validator = new ActionValidator(helper); 123 activeValidators.add(validator); 124 } 125 126 if (configuration.isValidateDocumentation()) { 127 activeValidators.add(new DocumentationValidator()); 128 } 129 130 if (configuration.isValidateLayout()) { 131 final LayoutValidator validator = new LayoutValidator(helper); 132 activeValidators.add(validator); 133 } 134 if (configuration.isValidateOptionNames()) { 135 activeValidators.add(new OptionNameValidator()); 136 activeValidators.add(new OptionParameterValidator()); 137 } 138 139 if (configuration.isValidateLocalConfiguration()) { 140 final LocalConfigurationValidator validator = new LocalConfigurationValidator(helper, configuration); 141 activeValidators.add(validator); 142 } 143 if (configuration.isValidateOutputConnection()) { 144 activeValidators.add(new OutputConnectionValidator()); 145 } 146 if (configuration.isValidateNoFinalOption()) { 147 activeValidators.add(new NoFinalOptionValidator()); 148 } 149 if (configuration.isValidateWording()) { 150 if (configuration.isValidateDocumentation()) { 151 activeValidators.add(new DocumentationWordingValidator()); 152 } 153 } 154 155 if (configuration.isValidateExceptions()) { 156 final ExceptionValidator validator = new ExceptionValidator(helper, configuration); 157 activeValidators.add(validator); 158 } 159 160 if (configuration.isValidateFamily()) { 161 final FamilyValidator validator = new FamilyValidator(helper); 162 activeValidators.add(validator); 163 } 164 if (extensions != null) { 165 extensions.forEach((ValidationExtension ext) -> { 166 final ExtensionValidator validator = new ExtensionValidator(ext, helper); 167 activeValidators.add(validator); 168 }); 169 } 170 if (configuration.isValidateRecord()) { 171 activeValidators.add(new RecordValidator()); 172 } 173 if (configuration.isValidateSchema()) { 174 activeValidators.add(new SchemaValidator()); 175 } 176 if (configuration.isValidateFixedSchema()) { 177 activeValidators.add(new FixedSchemaValidator()); 178 } 179 180 return new Validators(activeValidators); 181 182 }; 183 184 public static Stream<Class<? extends Annotation>> getActionsStream() { 185 return of(AsyncValidation.class, DynamicValues.class, HealthCheck.class, DiscoverSchema.class, 186 Suggestions.class, Update.class, DynamicDependencies.class); 187 } 188 189 public static Stream<ParameterMeta> flatten(final Collection<ParameterMeta> options) { 190 return options 191 .stream() 192 .flatMap((ParameterMeta it) -> Stream 193 .concat(Stream.of(it), it.getNestedParameters().isEmpty() ? Stream.empty() 194 : Validators.flatten(it.getNestedParameters()))); 195 } 196}