1 package org.apache.maven.plugins.shade.relocation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.codehaus.plexus.util.SelectorUtils;
23
24 import java.util.Collection;
25 import java.util.LinkedHashSet;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.regex.Pattern;
29
30
31
32
33
34 public class SimpleRelocator
35 implements Relocator
36 {
37
38 private final String pattern;
39
40 private final String pathPattern;
41
42 private final String shadedPattern;
43
44 private final String shadedPathPattern;
45
46 private final Set<String> includes;
47
48 private final Set<String> excludes;
49
50 private final boolean rawString;
51
52 public SimpleRelocator( String patt, String shadedPattern, List<String> includes, List<String> excludes )
53 {
54 this( patt, shadedPattern, includes, excludes, false );
55 }
56
57 public SimpleRelocator( String patt, String shadedPattern, List<String> includes, List<String> excludes,
58 boolean rawString )
59 {
60 this.rawString = rawString;
61
62 if ( rawString )
63 {
64 this.pathPattern = patt;
65 this.shadedPathPattern = shadedPattern;
66
67 this.pattern = null;
68 this.shadedPattern = null;
69 }
70 else
71 {
72 if ( patt == null )
73 {
74 this.pattern = "";
75 this.pathPattern = "";
76 }
77 else
78 {
79 this.pattern = patt.replace( '/', '.' );
80 this.pathPattern = patt.replace( '.', '/' );
81 }
82
83 if ( shadedPattern != null )
84 {
85 this.shadedPattern = shadedPattern.replace( '/', '.' );
86 this.shadedPathPattern = shadedPattern.replace( '.', '/' );
87 }
88 else
89 {
90 this.shadedPattern = "hidden." + this.pattern;
91 this.shadedPathPattern = "hidden/" + this.pathPattern;
92 }
93 }
94
95 this.includes = normalizePatterns( includes );
96 this.excludes = normalizePatterns( excludes );
97 }
98
99 private static Set<String> normalizePatterns( Collection<String> patterns )
100 {
101 Set<String> normalized = null;
102
103 if ( patterns != null && !patterns.isEmpty() )
104 {
105 normalized = new LinkedHashSet<String>();
106
107 for ( String pattern : patterns )
108 {
109
110 String classPattern = pattern.replace( '.', '/' );
111
112 normalized.add( classPattern );
113
114 if ( classPattern.endsWith( "/*" ) )
115 {
116 String packagePattern = classPattern.substring( 0, classPattern.lastIndexOf( '/' ) );
117 normalized.add( packagePattern );
118 }
119 }
120 }
121
122 return normalized;
123 }
124
125 private boolean isIncluded( String path )
126 {
127 if ( includes != null && !includes.isEmpty() )
128 {
129 for ( String include : includes )
130 {
131 if ( SelectorUtils.matchPath( include, path, true ) )
132 {
133 return true;
134 }
135 }
136 return false;
137 }
138 return true;
139 }
140
141 private boolean isExcluded( String path )
142 {
143 if ( excludes != null && !excludes.isEmpty() )
144 {
145 for ( String exclude : excludes )
146 {
147 if ( SelectorUtils.matchPath( exclude, path, true ) )
148 {
149 return true;
150 }
151 }
152 }
153 return false;
154 }
155
156 public boolean canRelocatePath( String path )
157 {
158 if ( rawString )
159 {
160 return Pattern.compile( pathPattern ).matcher( path ).find();
161 }
162
163 if ( path.endsWith( ".class" ) )
164 {
165 path = path.substring( 0, path.length() - 6 );
166 }
167
168 if ( !isIncluded( path ) || isExcluded( path ) )
169 {
170 return false;
171 }
172
173
174 return path.startsWith( pathPattern ) || path.startsWith ( "/" + pathPattern );
175 }
176
177 public boolean canRelocateClass( String clazz )
178 {
179 return !rawString && clazz.indexOf( '/' ) < 0 && canRelocatePath( clazz.replace( '.', '/' ) );
180 }
181
182 public String relocatePath( String path )
183 {
184 if ( rawString )
185 {
186 return path.replaceAll( pathPattern, shadedPathPattern );
187 }
188 else
189 {
190 return path.replaceFirst( pathPattern, shadedPathPattern );
191 }
192 }
193
194 public String relocateClass( String clazz )
195 {
196 return clazz.replaceFirst( pattern, shadedPattern );
197 }
198 }