Skip to content

Commit daaa2d4

Browse files
committed
Add abstraction for use of ObjectFactory in Gradle.
1 parent c99b196 commit daaa2d4

7 files changed

Lines changed: 223 additions & 12 deletions

File tree

byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/AbstractByteBuddyTask.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ public List<Transformation> getTransformations() {
124124
* @param closure The closure to configure the transformation.
125125
*/
126126
public void transformation(Closure<Transformation> closure) {
127-
transformations.add((Transformation) getProject().configure(getProject().getObjects().newInstance(Transformation.class, getProject()), closure));
127+
Transformation transformation = ObjectFactory.newInstance(getProject(), Transformation.class, getProject());
128+
transformations.add((Transformation) getProject().configure(transformation == null
129+
? new Transformation(getProject())
130+
: transformation, closure));
128131
}
129132

130133
/**
@@ -133,7 +136,10 @@ public void transformation(Closure<Transformation> closure) {
133136
* @param action The action to configure the transformation.
134137
*/
135138
public void transformation(Action<Transformation> action) {
136-
Transformation transformation = getProject().getObjects().newInstance(Transformation.class, getProject());
139+
Transformation transformation = ObjectFactory.newInstance(getProject(), Transformation.class, getProject());
140+
if (transformation == null) {
141+
transformation = new Transformation(getProject());
142+
}
137143
action.execute(transformation);
138144
transformations.add(transformation);
139145
}
@@ -373,7 +379,10 @@ protected void doApply(Plugin.Engine.Source source, Plugin.Engine.Target target)
373379
try {
374380
@SuppressWarnings("unchecked")
375381
Class<? extends Plugin> plugin = (Class<? extends Plugin>) Class.forName(line);
376-
Transformation transformation = getProject().getObjects().newInstance(Transformation.class, getProject());
382+
Transformation transformation = ObjectFactory.newInstance(getProject(), Transformation.class, getProject());;
383+
if (transformation == null) {
384+
transformation = new Transformation(getProject());
385+
}
377386
transformation.setPlugin(plugin);
378387
transformations.add(transformation);
379388
} catch (ClassNotFoundException exception) {

byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/AbstractByteBuddyTaskExtension.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,11 @@ public List<Transformation> getTransformations() {
150150
* @param closure The closure to configure the transformation.
151151
*/
152152
public void transformation(Closure<Transformation> closure) {
153-
transformations.add((Transformation) project.configure(project.getObjects().newInstance(Transformation.class, project), closure));
153+
Transformation transformation = ObjectFactory.newInstance(project, Transformation.class, project);
154+
if (transformation == null) {
155+
transformation = new Transformation(project);
156+
}
157+
transformations.add((Transformation) project.configure(transformation, closure));
154158
}
155159

156160
/**
@@ -159,7 +163,10 @@ public void transformation(Closure<Transformation> closure) {
159163
* @param action The action to configure the transformation.
160164
*/
161165
public void transformation(Action<Transformation> action) {
162-
Transformation transformation = project.getObjects().newInstance(Transformation.class, project);
166+
Transformation transformation = ObjectFactory.newInstance(project, Transformation.class, project);
167+
if (transformation == null) {
168+
transformation = new Transformation(project);
169+
}
163170
action.execute(transformation);
164171
transformations.add(transformation);
165172
}

byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/ByteBuddyJarTask.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ public class ByteBuddyJarTask extends AbstractByteBuddyTask {
6060
*/
6161
@Inject
6262
public ByteBuddyJarTask(Project project) {
63-
project.getObjects().newInstance(ByteBuddyJarTaskExtension.class, project).configure(this);
63+
ByteBuddyJarTaskExtension extension = ObjectFactory.newInstance(project, ByteBuddyJarTaskExtension.class, project);
64+
if (extension == null) {
65+
extension = new ByteBuddyJarTaskExtension(project);
66+
}
67+
extension.configure(this);
6468
}
6569

6670
/**

byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/ByteBuddyPlugin.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,13 @@ public void execute(JavaPlugin plugin) {
104104
String name = sourceSet.getName().equals(SourceSet.MAIN_SOURCE_SET_NAME)
105105
? "byteBuddy"
106106
: (sourceSet.getName() + "ByteBuddy");
107-
AbstractByteBuddyTaskExtension<?> extension = project.getObjects().newInstance(DISPATCHER.toExtension(), project);
107+
108+
AbstractByteBuddyTaskExtension<?> extension = ObjectFactory.newInstance(project,
109+
DISPATCHER.getExtensionType(),
110+
project);
111+
if (extension == null) {
112+
extension = DISPATCHER.toExtension(project);
113+
}
108114
extension.resolve(configuration.getTargetCompatibility());
109115
project.getExtensions().add(name, extension);
110116
project.afterEvaluate(DISPATCHER.toAction(name, sourceSet));
@@ -121,12 +127,20 @@ public void execute(JavaPlugin plugin) {
121127
*/
122128
protected interface Dispatcher<T extends AbstractByteBuddyTask, S extends AbstractByteBuddyTaskExtension<T>> {
123129

130+
/**
131+
* Returns the Byte Buddy extension type.
132+
*
133+
* @return The Byte Buddy extension type.
134+
*/
135+
Class<S> getExtensionType();
136+
124137
/**
125138
* Creates a Byte Buddy extension instance.
126139
*
140+
* @param project The current Gradle project.
127141
* @return An appropriate Byte Buddy extension instance.
128142
*/
129-
Class<S> toExtension();
143+
S toExtension(Project project);
130144

131145
/**
132146
* Creates a Byte Buddy task configuration.
@@ -150,10 +164,17 @@ enum ForLegacyGradle implements Dispatcher<ByteBuddySimpleTask, ByteBuddySimpleT
150164
/**
151165
* {@inheritDoc}
152166
*/
153-
public Class<ByteBuddySimpleTaskExtension> toExtension() {
167+
public Class<ByteBuddySimpleTaskExtension> getExtensionType() {
154168
return ByteBuddySimpleTaskExtension.class;
155169
}
156170

171+
/**
172+
* {@inheritDoc}
173+
*/
174+
public ByteBuddySimpleTaskExtension toExtension(Project project) {
175+
return new ByteBuddySimpleTaskExtension(project);
176+
}
177+
157178
/**
158179
* {@inheritDoc}
159180
*/
@@ -191,10 +212,17 @@ protected ForApi6CapableGradle(Method getDestinationDirectory, Method setDestina
191212
/**
192213
* {@inheritDoc}
193214
*/
194-
public Class<ByteBuddyTaskExtension> toExtension() {
215+
public Class<ByteBuddyTaskExtension> getExtensionType() {
195216
return ByteBuddyTaskExtension.class;
196217
}
197218

219+
/**
220+
* {@inheritDoc}
221+
*/
222+
public ByteBuddyTaskExtension toExtension(Project project) {
223+
return new ByteBuddyTaskExtension(project);
224+
}
225+
198226
/**
199227
* {@inheritDoc}
200228
*/

byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/ByteBuddySimpleTask.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ public class ByteBuddySimpleTask extends AbstractByteBuddyTask {
6060
*/
6161
@Inject
6262
public ByteBuddySimpleTask(Project project) {
63-
project.getObjects().newInstance(ByteBuddySimpleTaskExtension.class, project).configure(this);
63+
ByteBuddySimpleTaskExtension extension = ObjectFactory.newInstance(project, ByteBuddySimpleTaskExtension.class, project);
64+
if (extension == null) {
65+
extension = new ByteBuddySimpleTaskExtension(project);
66+
}
67+
extension.configure(this);
6468
}
6569

6670
/**

byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/ByteBuddyTask.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ public abstract class ByteBuddyTask extends AbstractByteBuddyTask {
5757
*/
5858
@Inject
5959
public ByteBuddyTask(Project project) {
60-
project.getObjects().newInstance(ByteBuddyTaskExtension.class, project).configure(this);
60+
ByteBuddyTaskExtension extension = ObjectFactory.newInstance(project, ByteBuddyTaskExtension.class, project);
61+
if (extension == null) {
62+
extension = new ByteBuddyTaskExtension(project);
63+
}
64+
extension.configure(this);
6165
}
6266

6367
/**
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* Copyright 2014 - Present 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.build.gradle;
17+
18+
import net.bytebuddy.utility.nullability.AlwaysNull;
19+
import net.bytebuddy.utility.nullability.MaybeNull;
20+
import org.gradle.api.Project;
21+
22+
import java.lang.reflect.InvocationTargetException;
23+
import java.lang.reflect.Method;
24+
25+
/**
26+
* A object factory for Gradle that uses the {@code org.gradle.api.model.ObjectFactory} API if available.
27+
*/
28+
public class ObjectFactory {
29+
30+
/**
31+
* The dispatcher to use.
32+
*/
33+
private static final Dispatcher DISPATCHER;
34+
35+
/*
36+
* Resolves the dispatcher for the current Gradle version.
37+
*/
38+
static {
39+
Dispatcher dispatcher;
40+
try {
41+
dispatcher = new Dispatcher.ForApi4CapableGradle(Project.class.getMethod("getObjects"),
42+
Class.forName("org.gradle.api.model.ObjectFactory").getMethod("newInstance", Class.class, Object[].class));
43+
} catch (Throwable ignored) {
44+
dispatcher = Dispatcher.ForLegacyGradle.INSTANCE;
45+
}
46+
DISPATCHER = dispatcher;
47+
}
48+
49+
/**
50+
* A private constructor that is not supposed to be invoked.
51+
*/
52+
private ObjectFactory() {
53+
throw new UnsupportedOperationException("This class is a utility class and not supposed to be instantiated");
54+
}
55+
56+
/**
57+
* Returns a new instance of the supplied class by invoking a constructor or returns {@code null} if the feature
58+
* is not available.
59+
*
60+
* @param project The Gradle project to use.
61+
* @param type The type of the class to be instantiated.
62+
* @param argument The arguments to supply.
63+
* @param <T> The type of the created class.
64+
* @return The created instance or {@code null} if the feature is not available.
65+
*/
66+
@SuppressWarnings("unchecked")
67+
@MaybeNull
68+
public static <T> T newInstance(Project project, Class<T> type, Object... argument) {
69+
return (T) DISPATCHER.newInstance(project, type, argument);
70+
}
71+
72+
/**
73+
* A dispatcher for using the {@code org.gradle.api.model.ObjectFactory} if available.
74+
*/
75+
protected interface Dispatcher {
76+
77+
/**
78+
* Returns a new instance of the supplied class by invoking a constructor or returns {@code null} if the feature
79+
* is not available.
80+
*
81+
* @param project The Gradle project to use.
82+
* @param type The type of the class to be instantiated.
83+
* @param argument The arguments to supply.
84+
* @return The created instance or {@code null} if the feature is not available.
85+
*/
86+
@MaybeNull
87+
Object newInstance(Project project, Class<?> type, Object... argument);
88+
89+
/**
90+
* A dispatcher for a legacy version of Gradle that does not support the object factory API.
91+
*/
92+
enum ForLegacyGradle implements Dispatcher {
93+
94+
/**
95+
* The singleton instance.
96+
*/
97+
INSTANCE;
98+
99+
/**
100+
* {@inheritDoc}
101+
*/
102+
@AlwaysNull
103+
public Object newInstance(Project project, Class<?> type, Object... argument) {
104+
return null;
105+
}
106+
}
107+
108+
/**
109+
* A dispatcher for a Gradle version that supports the object factory API.
110+
*/
111+
class ForApi4CapableGradle implements Dispatcher {
112+
113+
/**
114+
* The {@code org.gradle.api.Project#getObjects()} method.
115+
*/
116+
private final Method getObjects;
117+
118+
/**
119+
* The {@code org.gradle.api.model.ObjectFactory#newInstance} method.
120+
*/
121+
private final Method newInstance;
122+
123+
/**
124+
* Creates a new dispatcher.
125+
*
126+
* @param getObjects The {@code org.gradle.api.Project#getObjects()} method.
127+
* @param newInstance The {@code org.gradle.api.model.ObjectFactory#newInstance} method.
128+
*/
129+
protected ForApi4CapableGradle(Method getObjects, Method newInstance) {
130+
this.getObjects = getObjects;
131+
this.newInstance = newInstance;
132+
}
133+
134+
/**
135+
* {@inheritDoc}
136+
*/
137+
public Object newInstance(Project project, Class<?> type, Object... argument) {
138+
try {
139+
return newInstance.invoke(getObjects.invoke(project), argument);
140+
} catch (IllegalAccessException e) {
141+
throw new IllegalStateException(e);
142+
} catch (InvocationTargetException e) {
143+
Throwable cause = e.getCause();
144+
if (cause instanceof RuntimeException) {
145+
throw (RuntimeException) cause;
146+
} else if (cause instanceof Error) {
147+
throw (Error) cause;
148+
} else {
149+
throw new RuntimeException(e);
150+
}
151+
}
152+
}
153+
}
154+
}
155+
}

0 commit comments

Comments
 (0)