View Javadoc
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  package org.apache.maven.plugins.shade.relocation;
20  
21  import java.util.Arrays;
22  import java.util.Collections;
23  
24  import org.junit.Test;
25  
26  import static org.junit.Assert.assertEquals;
27  import static org.junit.Assert.assertFalse;
28  import static org.junit.Assert.assertTrue;
29  
30  /**
31   * Test for {@link SimpleRelocator}.
32   *
33   * @author Benjamin Bentmann
34   *
35   */
36  public class SimpleRelocatorTest {
37  
38      @Test
39      public void testNoNpeRelocateClass() {
40          new SimpleRelocator("foo", "bar", null, null, true).relocateClass("foo");
41      }
42  
43      @Test
44      public void testCanRelocatePath() {
45          SimpleRelocator relocator;
46  
47          relocator = new SimpleRelocator("org.foo", null, null, null);
48          assertTrue(relocator.canRelocatePath("org/foo/Class"));
49          assertTrue(relocator.canRelocatePath("org/foo/Class.class"));
50          assertTrue(relocator.canRelocatePath("org/foo/bar/Class"));
51          assertTrue(relocator.canRelocatePath("org/foo/bar/Class.class"));
52          assertFalse(relocator.canRelocatePath("com/foo/bar/Class"));
53          assertFalse(relocator.canRelocatePath("com/foo/bar/Class.class"));
54          assertFalse(relocator.canRelocatePath("org/Foo/Class"));
55          assertFalse(relocator.canRelocatePath("org/Foo/Class.class"));
56  
57          relocator = new SimpleRelocator(
58                  "org.foo", null, null, Arrays.asList("org.foo.Excluded", "org.foo.public.*", "org.foo.Public*Stuff"));
59          assertTrue(relocator.canRelocatePath("org/foo/Class"));
60          assertTrue(relocator.canRelocatePath("org/foo/Class.class"));
61          assertTrue(relocator.canRelocatePath("org/foo/excluded"));
62          assertFalse(relocator.canRelocatePath("org/foo/Excluded"));
63          assertFalse(relocator.canRelocatePath("org/foo/Excluded.class"));
64          assertFalse(relocator.canRelocatePath("org/foo/public"));
65          assertFalse(relocator.canRelocatePath("org/foo/public/Class"));
66          assertFalse(relocator.canRelocatePath("org/foo/public/Class.class"));
67          assertTrue(relocator.canRelocatePath("org/foo/publicRELOC/Class"));
68          assertTrue(relocator.canRelocatePath("org/foo/PrivateStuff"));
69          assertTrue(relocator.canRelocatePath("org/foo/PrivateStuff.class"));
70          assertFalse(relocator.canRelocatePath("org/foo/PublicStuff"));
71          assertFalse(relocator.canRelocatePath("org/foo/PublicStuff.class"));
72          assertFalse(relocator.canRelocatePath("org/foo/PublicUtilStuff"));
73          assertFalse(relocator.canRelocatePath("org/foo/PublicUtilStuff.class"));
74      }
75  
76      @Test
77      public void testCanRelocateClass() {
78          SimpleRelocator relocator;
79  
80          relocator = new SimpleRelocator("org.foo", null, null, null);
81          assertTrue(relocator.canRelocateClass("org.foo.Class"));
82          assertTrue(relocator.canRelocateClass("org.foo.bar.Class"));
83          assertFalse(relocator.canRelocateClass("com.foo.bar.Class"));
84          assertFalse(relocator.canRelocateClass("org.Foo.Class"));
85  
86          relocator = new SimpleRelocator(
87                  "org.foo", null, null, Arrays.asList("org.foo.Excluded", "org.foo.public.*", "org.foo.Public*Stuff"));
88          assertTrue(relocator.canRelocateClass("org.foo.Class"));
89          assertTrue(relocator.canRelocateClass("org.foo.excluded"));
90          assertFalse(relocator.canRelocateClass("org.foo.Excluded"));
91          assertFalse(relocator.canRelocateClass("org.foo.public"));
92          assertFalse(relocator.canRelocateClass("org.foo.public.Class"));
93          assertTrue(relocator.canRelocateClass("org.foo.publicRELOC.Class"));
94          assertTrue(relocator.canRelocateClass("org.foo.PrivateStuff"));
95          assertFalse(relocator.canRelocateClass("org.foo.PublicStuff"));
96          assertFalse(relocator.canRelocateClass("org.foo.PublicUtilStuff"));
97      }
98  
99      @Test
100     public void testCanRelocateRawString() {
101         SimpleRelocator relocator;
102 
103         relocator = new SimpleRelocator("org/foo", null, null, null, true);
104         assertTrue(relocator.canRelocatePath("(I)org/foo/bar/Class;"));
105 
106         relocator = new SimpleRelocator("^META-INF/org.foo.xml$", null, null, null, true);
107         assertTrue(relocator.canRelocatePath("META-INF/org.foo.xml"));
108     }
109 
110     // MSHADE-119, make sure that the easy part of this works.
111     @Test
112     public void testCanRelocateAbsClassPath() {
113         SimpleRelocator relocator = new SimpleRelocator("org.apache.velocity", "org.apache.momentum", null, null);
114         assertEquals(
115                 "/org/apache/momentum/mass.properties", relocator.relocatePath("/org/apache/velocity/mass.properties"));
116     }
117 
118     @Test
119     public void testCanRelocateAbsClassPathWithExcludes() {
120         SimpleRelocator relocator = new SimpleRelocator(
121                 "org/apache/velocity", "org/apache/momentum", null, Arrays.asList("org/apache/velocity/excluded/*"));
122         assertTrue(relocator.canRelocatePath("/org/apache/velocity/mass.properties"));
123         assertTrue(relocator.canRelocatePath("org/apache/velocity/mass.properties"));
124         assertFalse(relocator.canRelocatePath("/org/apache/velocity/excluded/mass.properties"));
125         assertFalse(relocator.canRelocatePath("org/apache/velocity/excluded/mass.properties"));
126     }
127 
128     @Test
129     public void testCanRelocateAbsClassPathWithIncludes() {
130         SimpleRelocator relocator = new SimpleRelocator(
131                 "org/apache/velocity", "org/apache/momentum", Arrays.asList("org/apache/velocity/included/*"), null);
132         assertFalse(relocator.canRelocatePath("/org/apache/velocity/mass.properties"));
133         assertFalse(relocator.canRelocatePath("org/apache/velocity/mass.properties"));
134         assertTrue(relocator.canRelocatePath("/org/apache/velocity/included/mass.properties"));
135         assertTrue(relocator.canRelocatePath("org/apache/velocity/included/mass.properties"));
136     }
137 
138     @Test
139     public void testRelocatePath() {
140         SimpleRelocator relocator;
141 
142         relocator = new SimpleRelocator("org.foo", null, null, null);
143         assertEquals("hidden/org/foo/bar/Class.class", relocator.relocatePath("org/foo/bar/Class.class"));
144 
145         relocator = new SimpleRelocator("org.foo", "private.stuff", null, null);
146         assertEquals("private/stuff/bar/Class.class", relocator.relocatePath("org/foo/bar/Class.class"));
147     }
148 
149     @Test
150     public void testRelocateClass() {
151         SimpleRelocator relocator;
152 
153         relocator = new SimpleRelocator("org.foo", null, null, null);
154         assertEquals("hidden.org.foo.bar.Class", relocator.relocateClass("org.foo.bar.Class"));
155 
156         relocator = new SimpleRelocator("org.foo", "private.stuff", null, null);
157         assertEquals("private.stuff.bar.Class", relocator.relocateClass("org.foo.bar.Class"));
158     }
159 
160     @Test
161     public void testRelocateRawString() {
162         SimpleRelocator relocator;
163 
164         relocator = new SimpleRelocator("Lorg/foo", "Lhidden/org/foo", null, null, true);
165         assertEquals("(I)Lhidden/org/foo/bar/Class;", relocator.relocatePath("(I)Lorg/foo/bar/Class;"));
166 
167         relocator = new SimpleRelocator("^META-INF/org.foo.xml$", "META-INF/hidden.org.foo.xml", null, null, true);
168         assertEquals("META-INF/hidden.org.foo.xml", relocator.relocatePath("META-INF/org.foo.xml"));
169     }
170 
171     @Test
172     public void testRelocateMavenFiles() {
173         SimpleRelocator relocator = new SimpleRelocator(
174                 "META-INF/maven",
175                 "META-INF/shade/maven",
176                 null,
177                 Collections.singletonList("META-INF/maven/com.foo.bar/artifactId/pom.*"));
178         assertFalse(relocator.canRelocatePath("META-INF/maven/com.foo.bar/artifactId/pom.properties"));
179         assertFalse(relocator.canRelocatePath("META-INF/maven/com.foo.bar/artifactId/pom.xml"));
180         assertTrue(relocator.canRelocatePath("META-INF/maven/com/foo/bar/artifactId/pom.properties"));
181         assertTrue(relocator.canRelocatePath("META-INF/maven/com/foo/bar/artifactId/pom.xml"));
182         assertTrue(relocator.canRelocatePath("META-INF/maven/com-foo-bar/artifactId/pom.properties"));
183         assertTrue(relocator.canRelocatePath("META-INF/maven/com-foo-bar/artifactId/pom.xml"));
184     }
185 
186     private static final String sourceFile = "package org.apache.maven.hello;\n" + "package org.objectweb.asm;\n"
187             + "\n"
188             + "import foo.bar.Bar;\n"
189             + "import zot.baz.Baz;\n"
190             + "import org.apache.maven.exclude1.Ex1;\n"
191             + "import org.apache.maven.exclude1.a.b.Ex1AB;\n"
192             + "import org.apache.maven.sub.exclude2.Ex2;\n"
193             + "import org.apache.maven.sub.exclude2.c.d.Ex2CD;\n"
194             + "import org.apache.maven.In;\n"
195             + "import org.apache.maven.e.InE;\n"
196             + "import org.apache.maven.f.g.InFG;\n"
197             + "import java.io.IOException;\n"
198             + "\n"
199             + "/**\n"
200             + " * Also check out {@link org.apache.maven.hello.OtherClass} and {@link\n"
201             + " * org.apache.maven.hello.YetAnotherClass}\n"
202             + " */\n"
203             + "public class MyClass {\n"
204             + "  private org.apache.maven.exclude1.x.X myX;\n"
205             + "  private org.apache.maven.h.H h;\n"
206             + "  private String ioInput;\n"
207             + "\n"
208             + "  /** Javadoc, followed by default visibility method with fully qualified return type */\n"
209             + "  org.apache.maven.MyReturnType doSomething( org.apache.maven.Bar bar, org.objectweb.asm.sub.Something something) {\n"
210             + "    org.apache.maven.Bar bar;\n"
211             + "    org.objectweb.asm.sub.Something something;\n"
212             + "    String io, val;\n"
213             + "    String noRelocation = \"NoWordBoundaryXXXorg.apache.maven.In\";\n"
214             + "    String relocationPackage = \"org.apache.maven.In\";\n"
215             + "    String relocationPath = \"org/apache/maven/In\";\n"
216             + "  }\n"
217             + "}\n";
218 
219     private static final String relocatedFile = "package com.acme.maven.hello;\n" + "package aj.org.objectweb.asm;\n"
220             + "\n"
221             + "import foo.bar.Bar;\n"
222             + "import zot.baz.Baz;\n"
223             + "import org.apache.maven.exclude1.Ex1;\n"
224             + "import org.apache.maven.exclude1.a.b.Ex1AB;\n"
225             + "import org.apache.maven.sub.exclude2.Ex2;\n"
226             + "import org.apache.maven.sub.exclude2.c.d.Ex2CD;\n"
227             + "import com.acme.maven.In;\n"
228             + "import com.acme.maven.e.InE;\n"
229             + "import com.acme.maven.f.g.InFG;\n"
230             + "import java.io.IOException;\n"
231             + "\n"
232             + "/**\n"
233             + " * Also check out {@link com.acme.maven.hello.OtherClass} and {@link\n"
234             + " * com.acme.maven.hello.YetAnotherClass}\n"
235             + " */\n"
236             + "public class MyClass {\n"
237             + "  private org.apache.maven.exclude1.x.X myX;\n"
238             + "  private com.acme.maven.h.H h;\n"
239             + "  private String ioInput;\n"
240             + "\n"
241             + "  /** Javadoc, followed by default visibility method with fully qualified return type */\n"
242             + "  com.acme.maven.MyReturnType doSomething( com.acme.maven.Bar bar, aj.org.objectweb.asm.sub.Something something) {\n"
243             + "    com.acme.maven.Bar bar;\n"
244             + "    aj.org.objectweb.asm.sub.Something something;\n"
245             + "    String io, val;\n"
246             + "    String noRelocation = \"NoWordBoundaryXXXorg.apache.maven.In\";\n"
247             + "    String relocationPackage = \"com.acme.maven.In\";\n"
248             + "    String relocationPath = \"com/acme/maven/In\";\n"
249             + "  }\n"
250             + "}\n";
251 
252     @Test
253     public void testRelocateSourceWithExcludesRaw() {
254         SimpleRelocator relocator = new SimpleRelocator(
255                 "org.apache.maven",
256                 "com.acme.maven",
257                 Arrays.asList("foo.bar", "zot.baz"),
258                 Arrays.asList("irrelevant.exclude", "org.apache.maven.exclude1", "org.apache.maven.sub.exclude2"),
259                 true);
260         assertEquals(sourceFile, relocator.applyToSourceContent(sourceFile));
261     }
262 
263     @Test
264     public void testRelocateSourceWithExcludes() {
265         // Main relocator with in-/excludes
266         SimpleRelocator relocator = new SimpleRelocator(
267                 "org.apache.maven",
268                 "com.acme.maven",
269                 Arrays.asList("foo.bar", "zot.baz"),
270                 Arrays.asList("irrelevant.exclude", "org.apache.maven.exclude1", "org.apache.maven.sub.exclude2"));
271         // Make sure not to replace variables 'io' and 'ioInput', package 'java.io'
272         SimpleRelocator ioRelocator = new SimpleRelocator("io", "shaded.io", null, null);
273         // Check corner case which was not working in PR #100
274         SimpleRelocator asmRelocator = new SimpleRelocator("org.objectweb.asm", "aj.org.objectweb.asm", null, null);
275         // Make sure not to replace 'foo' package by path-like 'shaded/foo'
276         SimpleRelocator fooRelocator = new SimpleRelocator("foo", "shaded.foo", null, Arrays.asList("foo.bar"));
277         assertEquals(
278                 relocatedFile,
279                 fooRelocator.applyToSourceContent(asmRelocator.applyToSourceContent(
280                         ioRelocator.applyToSourceContent(relocator.applyToSourceContent(sourceFile)))));
281     }
282 }