Skip to content

Commit 5c9e15b

Browse files
committed
1 parent 7e5fafb commit 5c9e15b

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

gradle/dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ dependencies {
1010
compile 'commons-io:commons-io:2.5'
1111
compile 'org.apache.ant:ant:1.9.7'
1212
compile 'org.codehaus.plexus:plexus-utils:3.0.24'
13+
compile "org.apache.logging.log4j:log4j-core:2.11.0"
1314

1415
testCompile("org.spockframework:spock-core:1.0-groovy-2.4") {
1516
exclude module: 'groovy-all'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License") you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package com.github.jengelman.gradle.plugins.shadow.transformers
21+
22+
import com.github.jengelman.gradle.plugins.shadow.ShadowStats
23+
import com.github.jengelman.gradle.plugins.shadow.relocation.RelocateClassContext
24+
import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator
25+
import org.apache.commons.io.IOUtils
26+
import org.apache.commons.io.output.CloseShieldOutputStream
27+
import org.apache.logging.log4j.core.config.plugins.processor.PluginCache
28+
import org.apache.logging.log4j.core.config.plugins.processor.PluginEntry
29+
import org.apache.tools.zip.ZipOutputStream
30+
import org.gradle.api.file.FileTreeElement
31+
32+
import java.util.zip.ZipEntry
33+
34+
import static org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor.PLUGIN_CACHE_FILE;
35+
36+
/**
37+
* Modified from the maven equivalent to work with gradle
38+
*
39+
* @author Paul Nelson Baker
40+
* @see <a href="https://www.linkedin.com/in/paul-n-baker/">LinkedIn</a>
41+
* @see <a href="https://github.com/paul-nelson-baker/">GitHub</a>
42+
* @see <a href="https://github.com/edwgiz/maven-shaded-log4j-transformer">edwgiz/maven-shaded-log4j-transformer</a>
43+
* @see <a href="https://github.com/edwgiz/maven-shaded-log4j-transformer/blob/master/src/main/java/com/github/edwgiz/mavenShadePlugin/log4j2CacheTransformer/PluginsCacheFileTransformer.java">PluginsCacheFileTransformer.java</a>
44+
*/
45+
class Log4j2PluginsCacheFileTransformer implements Transformer {
46+
47+
private final List<File> temporaryFiles;
48+
private final List<Relocator> relocators;
49+
50+
public Log4j2PluginsCacheFileTransformer() {
51+
temporaryFiles = new ArrayList<>();
52+
relocators = new ArrayList<>();
53+
}
54+
55+
@Override
56+
boolean canTransformResource(FileTreeElement element) {
57+
return PLUGIN_CACHE_FILE == element.name
58+
}
59+
60+
@Override
61+
void transform(TransformerContext context) {
62+
def inputStream = context.is
63+
def temporaryFile = File.createTempFile("Log4j2Plugins", ".dat")
64+
temporaryFile.deleteOnExit()
65+
temporaryFiles.add(temporaryFile)
66+
IOUtils.copy(inputStream, new FileOutputStream(temporaryFile))
67+
def contextRelocators = context.relocators
68+
if (contextRelocators != null) {
69+
this.relocators.addAll(contextRelocators)
70+
}
71+
}
72+
73+
@Override
74+
boolean hasTransformedResource() {
75+
// This functionality matches the original plugin, however, I'm not clear what
76+
// the exact logic is. From what I can tell temporaryFiles should be never be empty
77+
// if anything has been performed.
78+
def hasTransformedMultipleFiles = temporaryFiles.size() > 1
79+
def hasAtLeastOneFileAndRelocator = !temporaryFiles.isEmpty() && !relocators.isEmpty()
80+
def hasTransformedResources = hasTransformedMultipleFiles || hasAtLeastOneFileAndRelocator
81+
return hasTransformedResources
82+
}
83+
84+
@Override
85+
void modifyOutputStream(ZipOutputStream jos) {
86+
PluginCache pluginCache = new PluginCache()
87+
pluginCache.loadCacheFiles(getUrlEnumeration())
88+
relocatePlugins(pluginCache)
89+
zipOutputStream.putNextEntry(new ZipEntry(PLUGIN_CACHE_FILE))
90+
pluginCache.writeCache(new CloseShieldOutputStream(zipOutputStream))
91+
temporaryFiles.clear()
92+
}
93+
94+
private Enumeration<URL> getUrlEnumeration() {
95+
def urls = temporaryFiles.collect({ it.toURL() }).asList()
96+
return Collections.enumeration(urls)
97+
}
98+
99+
private void relocatePlugins(PluginCache pluginCache) {
100+
for (Map<String, PluginEntry> currentMap : pluginCache.getAllCategories().values()) {
101+
pluginEntryLoop:
102+
for (PluginEntry currentPluginEntry : currentMap.values()) {
103+
String className = currentPluginEntry.getClassName();
104+
RelocateClassContext relocateClassContext = new RelocateClassContext(className, new ShadowStats());
105+
for (Relocator currentRelocator : relocators) {
106+
// If we have a relocator that can relocate our current entry...
107+
boolean canRelocateClass = currentRelocator.canRelocateClass(relocateClassContext);
108+
if (canRelocateClass) {
109+
// Then we perform that relocation and update the plugin entry to reflect the new value.
110+
String relocatedClassName = currentRelocator.relocateClass(relocateClassContext);
111+
currentPluginEntry.setClassName(relocatedClassName);
112+
continue pluginEntryLoop;
113+
}
114+
}
115+
}
116+
}
117+
}
118+
}

0 commit comments

Comments
 (0)