Skip to content

Commit 7cc865a

Browse files
committedMar 27, 2020
Use UUID for indexers with names that exceed the file name length.
Fixes #4106.
1 parent cbbb254 commit 7cc865a

File tree

2 files changed

+89
-6
lines changed

2 files changed

+89
-6
lines changed
 

‎annotation/compiler/src/main/java/com/bumptech/glide/annotation/compiler/IndexerGenerator.java

+18-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.lang.annotation.Annotation;
99
import java.util.ArrayList;
1010
import java.util.List;
11+
import java.util.UUID;
1112
import javax.lang.model.element.Modifier;
1213
import javax.lang.model.element.TypeElement;
1314

@@ -46,6 +47,7 @@
4647
*/
4748
final class IndexerGenerator {
4849
private static final String INDEXER_NAME_PREFIX = "GlideIndexer_";
50+
private static final int MAXIMUM_FILE_NAME_LENGTH = 255;
4951
private final ProcessorUtil processorUtil;
5052

5153
IndexerGenerator(ProcessorUtil processorUtil) {
@@ -79,7 +81,7 @@ TypeSpec generate(List<TypeElement> types) {
7981
}
8082
}
8183

82-
private static TypeSpec generate(
84+
private TypeSpec generate(
8385
List<TypeElement> libraryModules, Class<? extends Annotation> annotation) {
8486
AnnotationSpec.Builder annotationBuilder = AnnotationSpec.builder(Index.class);
8587

@@ -88,15 +90,25 @@ private static TypeSpec generate(
8890
annotationBuilder.addMember(value, "$S", ClassName.get(childModule).toString());
8991
}
9092

91-
StringBuilder indexerName =
93+
StringBuilder indexerNameBuilder =
9294
new StringBuilder(INDEXER_NAME_PREFIX + annotation.getSimpleName() + "_");
9395
for (TypeElement element : libraryModules) {
94-
indexerName.append(element.getQualifiedName().toString().replace(".", "_"));
95-
indexerName.append("_");
96+
indexerNameBuilder.append(element.getQualifiedName().toString().replace(".", "_"));
97+
indexerNameBuilder.append("_");
98+
}
99+
indexerNameBuilder =
100+
new StringBuilder(indexerNameBuilder.substring(0, indexerNameBuilder.length() - 1));
101+
String indexerName = indexerNameBuilder.toString();
102+
// If the indexer name has too many packages/modules, it can exceed the file name length
103+
// allowed by the file system, which can break compilation. To avoid that, fall back to a
104+
// deterministic UUID.
105+
if (indexerName.length() >= (MAXIMUM_FILE_NAME_LENGTH - INDEXER_NAME_PREFIX.length())) {
106+
indexerName =
107+
INDEXER_NAME_PREFIX
108+
+ UUID.nameUUIDFromBytes(indexerName.getBytes()).toString().replace("-", "_");
96109
}
97-
indexerName = new StringBuilder(indexerName.substring(0, indexerName.length() - 1));
98110

99-
return TypeSpec.classBuilder(indexerName.toString())
111+
return TypeSpec.classBuilder(indexerName)
100112
.addAnnotation(annotationBuilder.build())
101113
.addModifiers(Modifier.PUBLIC)
102114
.build();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.bumptech.glide.annotation.compiler;
2+
3+
import static com.google.testing.compile.Compiler.javac;
4+
5+
import com.bumptech.glide.annotation.compiler.test.CompilationProvider;
6+
import com.google.testing.compile.Compilation;
7+
import com.google.testing.compile.CompilationSubject;
8+
import com.google.testing.compile.JavaFileObjects;
9+
import java.io.File;
10+
import java.io.IOException;
11+
import javax.tools.JavaFileObject;
12+
import org.junit.Before;
13+
import org.junit.Rule;
14+
import org.junit.Test;
15+
import org.junit.rules.TemporaryFolder;
16+
import org.junit.runner.RunWith;
17+
import org.junit.runners.JUnit4;
18+
19+
/**
20+
* Makes sure that we can handle indexers based on long package or file names, or many modules.
21+
*
22+
* <p>See #4106.
23+
*/
24+
@RunWith(JUnit4.class)
25+
public class OverlyLongFileNameTest implements CompilationProvider {
26+
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
27+
private Compilation compilation;
28+
private static final String FILE_NAME_LONGER_THAN_255_CHARS =
29+
"SomeReallyReallyRidiculouslyLongFileNameOrPackageNameIGuessThatExceedsTwoHundredAndFiftyFive"
30+
+ "CharactersThoughThatsOnlyAroundOneHundredCharactersWhichMeansINeedToKeepTypingToGetTo"
31+
+ "TwoHundredAndFiftyFiveSomehowThankfullyOnlyLikeFiftyToGoNowMaybeButNotQuiteYet"
32+
+ "SomewhereAroundNowIsProbablyGood";
33+
34+
@Before
35+
public void setUp() {
36+
compilation =
37+
javac()
38+
.withProcessors(new GlideAnnotationProcessor())
39+
.compile(
40+
JavaFileObjects.forSourceLines(
41+
FILE_NAME_LONGER_THAN_255_CHARS,
42+
"package com.bumptech.glide.test;",
43+
"import com.bumptech.glide.annotation.GlideModule;",
44+
"import com.bumptech.glide.module.LibraryGlideModule;",
45+
"@GlideModule",
46+
"public final class "
47+
+ FILE_NAME_LONGER_THAN_255_CHARS
48+
+ " extends LibraryGlideModule {}"));
49+
}
50+
51+
@Test
52+
public void compilingLongClassAndOrPackageNameShouldSucceed() throws IOException {
53+
CompilationSubject.assertThat(compilation).succeededWithoutWarnings();
54+
for (JavaFileObject file : compilation.generatedFiles()) {
55+
temporaryFolder.create();
56+
String actualFileName = new File(file.getName()).getName();
57+
if (!actualFileName.startsWith(FILE_NAME_LONGER_THAN_255_CHARS)) {
58+
try {
59+
temporaryFolder.newFile(actualFileName).createNewFile();
60+
} catch (IOException e) {
61+
throw new RuntimeException("Failed to create: " + actualFileName, e);
62+
}
63+
}
64+
}
65+
}
66+
67+
@Override
68+
public Compilation getCompilation() {
69+
return compilation;
70+
}
71+
}

0 commit comments

Comments
 (0)
Please sign in to comment.