1 /*
2  * Copyright 2014 - 2020 Rafael Winterhalter
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  *     http://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 net.bytebuddy.implementation.auxiliary;
17
18 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19 import net.bytebuddy.ClassFileVersion;
20 import net.bytebuddy.build.HashCodeAndEqualsPlugin;
21 import net.bytebuddy.description.modifier.ModifierContributor;
22 import net.bytebuddy.description.modifier.SyntheticState;
23 import net.bytebuddy.description.type.TypeDescription;
24 import net.bytebuddy.dynamic.DynamicType;
25 import net.bytebuddy.implementation.MethodAccessorFactory;
26 import net.bytebuddy.utility.RandomString;
27
28 import java.lang.annotation.ElementType;
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 import java.lang.annotation.Target;
32
33 /**
34  * An auxiliary type that provides services to the instrumentation of another type. Implementations should provide
35  * meaningful {@code equals(Object)} and {@code hashCode()} implementations in order to avoid multiple creations
36  * of this type.
37  */

38 public interface AuxiliaryType {
39
40     /**
41      * The default type access of an auxiliary type. <b>This array must not be mutated</b>.
42      */

43     @SuppressFBWarnings(value = {"MS_MUTABLE_ARRAY""MS_OOI_PKGPROTECT"}, justification = "The array is not to be modified by contract")
44     ModifierContributor.ForType[] DEFAULT_TYPE_MODIFIER = {SyntheticState.SYNTHETIC};
45
46     /**
47      * Creates a new auxiliary type.
48      *
49      * @param auxiliaryTypeName     The fully qualified binary name for this auxiliary type. The type should be in
50      *                              the same package than the instrumented type this auxiliary type is providing services
51      *                              to in order to allow package-private access.
52      * @param classFileVersion      The class file version the auxiliary class should be written in.
53      * @param methodAccessorFactory A factory for accessor methods.
54      * @return A dynamically created type representing this auxiliary type.
55      */

56     DynamicType make(String auxiliaryTypeName, ClassFileVersion classFileVersion, MethodAccessorFactory methodAccessorFactory);
57
58     /**
59      * Representation of a naming strategy for an auxiliary type.
60      */

61     interface NamingStrategy {
62
63         /**
64          * Names an auxiliary type.
65          *
66          * @param instrumentedType The instrumented type for which an auxiliary type is registered.
67          * @return The fully qualified name for the given auxiliary type.
68          */

69         String name(TypeDescription instrumentedType);
70
71         /**
72          * A naming strategy for an auxiliary type which returns the instrumented type's name with a fixed extension
73          * and a random number as a suffix. All generated names will be in the same package as the instrumented type.
74          */

75         @HashCodeAndEqualsPlugin.Enhance
76         class SuffixingRandom implements NamingStrategy {
77
78             /**
79              * The suffix to append to the instrumented type for creating names for the auxiliary types.
80              */

81             private final String suffix;
82
83             /**
84              * An instance for creating random values.
85              */

86             @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.IGNORE)
87             private final RandomString randomString;
88
89             /**
90              * Creates a new suffixing random naming strategy.
91              *
92              * @param suffix The suffix to extend to the instrumented type.
93              */

94             public SuffixingRandom(String suffix) {
95                 this.suffix = suffix;
96                 randomString = new RandomString();
97             }
98
99             /**
100              * {@inheritDoc}
101              */

102             public String name(TypeDescription instrumentedType) {
103                 return instrumentedType.getName() + "$" + suffix + "$" + randomString.nextString();
104             }
105         }
106     }
107
108     /**
109      * A marker to indicate that an auxiliary type is part of the instrumented types signature. This information can be used to load a type before
110      * the instrumented type such that reflection on the instrumented type does not cause a {@link NoClassDefFoundError}.
111      */

112     @Retention(RetentionPolicy.CLASS)
113     @Target(ElementType.TYPE)
114     @interface SignatureRelevant {
115         /* empty */
116     }
117 }
118