001/** 002 * Copyright (C) 2006-2020 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.server.service; 017 018import static java.util.Optional.ofNullable; 019import static java.util.stream.Collectors.toList; 020 021import java.util.Collection; 022import java.util.Map; 023import java.util.function.BiFunction; 024import java.util.function.Function; 025import java.util.stream.Stream; 026 027import javax.annotation.PostConstruct; 028import javax.enterprise.context.ApplicationScoped; 029 030import org.talend.sdk.component.runtime.manager.reflect.parameterenricher.ValidationParameterEnricher; 031import org.talend.sdk.component.server.front.model.PropertyValidation; 032 033@ApplicationScoped 034public class PropertyValidationService { 035 036 private Function<Map<String, String>, PropertyValidation> propertyValidationCreator; 037 038 @PostConstruct 039 private void initMapper() { 040 // precompute the mapping of validations to centralize the convention - note: can be moved to impl for setters 041 // part 042 final Collection<BiFunction<Object, Map<String, String>, Boolean>> validationSetters = 043 Stream.of(PropertyValidation.class.getDeclaredFields()).map(f -> { 044 // we need boolean, int, string, collection<string> 045 final Function<String, Object> valueConverter; 046 if (Integer.class == f.getType()) { 047 valueConverter = v -> Double.valueOf(v).intValue(); 048 } else if (Boolean.class == f.getType()) { 049 valueConverter = Boolean::parseBoolean; 050 } else if (Collection.class == f.getType()) { 051 valueConverter = s -> Stream.of(s.split(",")).collect(toList()); 052 } else { 053 valueConverter = s -> s; 054 } 055 if (!f.isAccessible()) { 056 f.setAccessible(true); 057 } 058 return (BiFunction<Object, Map<String, String>, Boolean>) (instance, 059 meta) -> ofNullable(meta.get(ValidationParameterEnricher.META_PREFIX + f.getName())) 060 .map(valueConverter) 061 .map(val -> { 062 try { 063 f.set(instance, val); 064 } catch (IllegalAccessException e) { 065 throw new IllegalStateException(e); 066 } 067 return true; 068 }) 069 .orElse(false); 070 }).collect(toList()); 071 propertyValidationCreator = config -> { 072 final PropertyValidation validation = new PropertyValidation(); 073 if (validationSetters.stream().filter(s -> s.apply(validation, config)).count() == 0) { 074 return null; 075 } 076 return validation; 077 }; 078 } 079 080 public PropertyValidation map(final Map<String, String> meta) { 081 return propertyValidationCreator.apply(meta); 082 } 083}