• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.google.android.enterprise.connectedapps.annotations.UncaughtExceptionsPolicy;
19 import com.google.android.enterprise.connectedapps.processor.SupportedTypes;
20 import com.google.auto.value.AutoValue;
21 import com.squareup.javapoet.ClassName;
22 import java.util.Optional;
23 import java.util.function.Function;
24 import javax.lang.model.element.TypeElement;
25 
26 /** Wrapper of the connectors specified for a connected app. */
27 @AutoValue
28 public abstract class ConnectorInfo {
29 
30   private static final String CROSS_PROFILE_CONNECTOR_QUALIFIED_NAME =
31       "com.google.android.enterprise.connectedapps.CrossProfileConnector";
32   private static final String CROSS_USER_CONNECTOR_QUALIFIED_NAME =
33       "com.google.android.enterprise.connectedapps.CrossUserConnector";
34   private static final String PROFILE_CONNECTOR_QUALIFIED_NAME =
35       "com.google.android.enterprise.connectedapps.ProfileConnector";
36   private static final String USER_CONNECTOR_QUALIFIED_NAME =
37       "com.google.android.enterprise.connectedapps.UserConnector";
38 
isProfileConnector(Context context, TypeElement connectorElement)39   public static boolean isProfileConnector(Context context, TypeElement connectorElement) {
40     return isConnectorOfType(context, connectorElement, PROFILE_CONNECTOR_QUALIFIED_NAME);
41   }
42 
isUserConnector(Context context, TypeElement connectorElement)43   public static boolean isUserConnector(Context context, TypeElement connectorElement) {
44     return isConnectorOfType(context, connectorElement, USER_CONNECTOR_QUALIFIED_NAME);
45   }
46 
isConnectorOfType( Context context, TypeElement connectorElement, String requiredType)47   private static boolean isConnectorOfType(
48       Context context, TypeElement connectorElement, String requiredType) {
49     return context
50         .types()
51         .isAssignable(
52             connectorElement.asType(), context.elements().getTypeElement(requiredType).asType());
53   }
54 
hasCrossProfileConnector()55   public boolean hasCrossProfileConnector() {
56     return profileConnector().isPresent();
57   }
58 
hasCrossUserConnector()59   public boolean hasCrossUserConnector() {
60     return userConnector().isPresent();
61   }
62 
profileConnector()63   public abstract Optional<ProfileConnectorInfo> profileConnector();
64 
userConnector()65   public abstract Optional<UserConnectorInfo> userConnector();
66 
connectorElement()67   public TypeElement connectorElement() {
68     return getElement(ProfileConnectorInfo::connectorElement, UserConnectorInfo::connectorElement);
69   }
70 
connectorClassName()71   public ClassName connectorClassName() {
72     return getElement(
73         ProfileConnectorInfo::connectorClassName, UserConnectorInfo::connectorClassName);
74   }
75 
serviceName()76   public ClassName serviceName() {
77     return getElement(ProfileConnectorInfo::serviceName, UserConnectorInfo::serviceName);
78   }
79 
supportedTypes()80   public SupportedTypes supportedTypes() {
81     return getElement(ProfileConnectorInfo::supportedTypes, UserConnectorInfo::supportedTypes);
82   }
83 
uncaughtExceptionsPolicy()84   public UncaughtExceptionsPolicy uncaughtExceptionsPolicy() {
85     return profileConnector()
86         .map(ProfileConnectorInfo::uncaughtExceptionsPolicy)
87         .orElse(UncaughtExceptionsPolicy.NOTIFY_RETHROW);
88   }
89 
90   /**
91    * Tries to get an element from {@link #profileConnector()} if present, or from {@link
92    * #userConnector()} otherwise.
93    *
94    * <p>Throws an exception if no connectors are specified, but this should not be possible (now and
95    * in the future).
96    */
getElement( Function<ProfileConnectorInfo, T> getFromProfileConnector, Function<UserConnectorInfo, T> getFromUserConnector)97   private <T> T getElement(
98       Function<ProfileConnectorInfo, T> getFromProfileConnector,
99       Function<UserConnectorInfo, T> getFromUserConnector) {
100     return profileConnector()
101         .map(getFromProfileConnector)
102         .orElseGet(
103             () ->
104                 userConnector()
105                     .map(getFromUserConnector)
106                     .orElseThrow(
107                         () -> new UnsupportedOperationException("No connectors specified")));
108   }
109 
invalid( Context context, TypeElement connector, SupportedTypes globalSupportedTypes)110   public static ConnectorInfo invalid(
111       Context context, TypeElement connector, SupportedTypes globalSupportedTypes) {
112     return noSpecificConnector(context, globalSupportedTypes, connector, connector);
113   }
114 
unspecified(Context context, SupportedTypes globalSupportedTypes)115   public static ConnectorInfo unspecified(Context context, SupportedTypes globalSupportedTypes) {
116     return noSpecificConnector(
117         context,
118         globalSupportedTypes,
119         context.elements().getTypeElement(CROSS_PROFILE_CONNECTOR_QUALIFIED_NAME),
120         context.elements().getTypeElement(CROSS_USER_CONNECTOR_QUALIFIED_NAME));
121   }
122 
noSpecificConnector( Context context, SupportedTypes globalSupportedTypes, TypeElement profileConnector, TypeElement userConnector)123   private static ConnectorInfo noSpecificConnector(
124       Context context,
125       SupportedTypes globalSupportedTypes,
126       TypeElement profileConnector,
127       TypeElement userConnector) {
128     return new AutoValue_ConnectorInfo(
129         Optional.of(ProfileConnectorInfo.create(context, profileConnector, globalSupportedTypes)),
130         Optional.of(UserConnectorInfo.create(context, userConnector, globalSupportedTypes)));
131   }
132 
forProfileConnector( Context context, TypeElement connectorElement, SupportedTypes globalSupportedTypes)133   public static ConnectorInfo forProfileConnector(
134       Context context, TypeElement connectorElement, SupportedTypes globalSupportedTypes) {
135     return new AutoValue_ConnectorInfo(
136         Optional.of(ProfileConnectorInfo.create(context, connectorElement, globalSupportedTypes)),
137         Optional.empty());
138   }
139 
forUserConnector( Context context, TypeElement connectorElement, SupportedTypes globalSupportedTypes)140   public static ConnectorInfo forUserConnector(
141       Context context, TypeElement connectorElement, SupportedTypes globalSupportedTypes) {
142     return new AutoValue_ConnectorInfo(
143         Optional.empty(),
144         Optional.of(UserConnectorInfo.create(context, connectorElement, globalSupportedTypes)));
145   }
146 }
147