1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.enterprise.connectedapps.processor.containers; 17 18 import static com.google.android.enterprise.connectedapps.processor.CommonClassNames.SERVICE_CLASSNAME; 19 20 import com.google.android.enterprise.connectedapps.annotations.CrossProfileConfiguration; 21 import com.google.android.enterprise.connectedapps.processor.annotationdiscovery.AnnotationFinder; 22 import com.google.auto.value.AutoValue; 23 import com.google.common.collect.ImmutableCollection; 24 import com.google.common.collect.ImmutableSet; 25 import com.squareup.javapoet.ClassName; 26 import java.util.Optional; 27 import javax.annotation.processing.ProcessingEnvironment; 28 import javax.lang.model.element.Element; 29 import javax.lang.model.element.TypeElement; 30 31 /** A wrapper around basic information from a {@link CrossProfileConfiguration} annotation. */ 32 @AutoValue 33 public abstract class ValidatorCrossProfileConfigurationInfo { 34 configurationElement()35 public abstract TypeElement configurationElement(); 36 providerClassElements()37 public abstract ImmutableCollection<TypeElement> providerClassElements(); 38 serviceSuperclass()39 public abstract ClassName serviceSuperclass(); 40 serviceClass()41 public abstract Optional<TypeElement> serviceClass(); 42 connector()43 public abstract Optional<TypeElement> connector(); 44 createMultipleFromElement( ProcessingEnvironment processingEnvironment, TypeElement annotatedElement)45 public static ImmutableSet<ValidatorCrossProfileConfigurationInfo> createMultipleFromElement( 46 ProcessingEnvironment processingEnvironment, TypeElement annotatedElement) { 47 ImmutableSet<CrossProfileConfigurationAnnotationInfo> infos = 48 AnnotationFinder.extractCrossProfileConfigurationsAnnotationInfo( 49 annotatedElement, 50 processingEnvironment.getTypeUtils(), 51 processingEnvironment.getElementUtils()) 52 .configurations(); 53 ImmutableSet.Builder<ValidatorCrossProfileConfigurationInfo> configurations = 54 ImmutableSet.builder(); 55 56 if (infos.isEmpty()) { 57 configurations.add(createFromElement(processingEnvironment, annotatedElement)); 58 } else { 59 for (CrossProfileConfigurationAnnotationInfo info : infos) { 60 configurations.add(createFromAnnotationInfo(info, annotatedElement)); 61 } 62 } 63 64 return configurations.build(); 65 } 66 createFromElement( ProcessingEnvironment processingEnv, TypeElement annotatedElement)67 public static ValidatorCrossProfileConfigurationInfo createFromElement( 68 ProcessingEnvironment processingEnv, TypeElement annotatedElement) { 69 CrossProfileConfigurationAnnotationInfo annotationInfo = 70 extractFromCrossProfileConfigurationAnnotation(annotatedElement, processingEnv); 71 72 return createFromAnnotationInfo(annotationInfo, annotatedElement); 73 } 74 createFromAnnotationInfo( CrossProfileConfigurationAnnotationInfo annotationInfo, TypeElement annotatedElement)75 private static ValidatorCrossProfileConfigurationInfo createFromAnnotationInfo( 76 CrossProfileConfigurationAnnotationInfo annotationInfo, TypeElement annotatedElement) { 77 ClassName serviceSuperclass = 78 serviceSuperclassIsDefault(annotationInfo.serviceSuperclass()) 79 ? SERVICE_CLASSNAME 80 : ClassName.get(annotationInfo.serviceSuperclass()); 81 82 TypeElement serviceClass = 83 serviceClassIsDefault(annotationInfo.serviceClass()) ? null : annotationInfo.serviceClass(); 84 85 Optional<TypeElement> connector = 86 connectorIsDefault(annotationInfo.connector()) 87 ? Optional.empty() 88 : Optional.of(annotationInfo.connector()); 89 90 return new AutoValue_ValidatorCrossProfileConfigurationInfo( 91 annotatedElement, 92 ImmutableSet.copyOf(annotationInfo.providerClasses()), 93 serviceSuperclass, 94 Optional.ofNullable(serviceClass), 95 connector); 96 } 97 serviceSuperclassIsDefault(TypeElement serviceSuperclass)98 private static boolean serviceSuperclassIsDefault(TypeElement serviceSuperclass) { 99 // CrossProfileConfiguration.class is the default specified serviceSuperclass 100 return serviceSuperclass 101 .asType() 102 .toString() 103 .equals(CrossProfileConfiguration.class.getCanonicalName()); 104 } 105 serviceClassIsDefault(TypeElement serviceClass)106 private static boolean serviceClassIsDefault(TypeElement serviceClass) { 107 // CrossProfileConfiguration.class is the default specified serviceClass 108 return serviceClass 109 .asType() 110 .toString() 111 .equals(CrossProfileConfiguration.class.getCanonicalName()); 112 } 113 connectorIsDefault(TypeElement connector)114 private static boolean connectorIsDefault(TypeElement connector) { 115 // CrossProfileConfiguration.class is the default specified connector 116 return connector.asType().toString().equals(CrossProfileConfiguration.class.getCanonicalName()); 117 } 118 119 private static CrossProfileConfigurationAnnotationInfo extractFromCrossProfileConfigurationAnnotation( Element annotatedElement, ProcessingEnvironment processingEnv)120 extractFromCrossProfileConfigurationAnnotation( 121 Element annotatedElement, ProcessingEnvironment processingEnv) { 122 return AnnotationFinder.extractCrossProfileConfigurationAnnotationInfo( 123 annotatedElement, processingEnv.getTypeUtils(), processingEnv.getElementUtils()); 124 } 125 } 126