diff options
3 files changed, 52 insertions, 9 deletions
diff --git a/src/test/java/com/google/devtools/build/android/resources/RClassGeneratorTest.java b/src/test/java/com/google/devtools/build/android/resources/RClassGeneratorTest.java index 9767c9a276..fd87c45506 100644 --- a/src/test/java/com/google/devtools/build/android/resources/RClassGeneratorTest.java +++ b/src/test/java/com/google/devtools/build/android/resources/RClassGeneratorTest.java @@ -15,6 +15,7 @@ package com.google.devtools.build.android.resources; import static com.google.common.truth.Truth.assertThat; +import com.android.SdkConstants; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; @@ -28,6 +29,7 @@ import java.lang.reflect.Modifier; import java.net.URL; import java.net.URLClassLoader; import java.nio.charset.StandardCharsets; +import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; @@ -120,6 +122,38 @@ public class RClassGeneratorTest { } @Test + public void checkFileWriteThrowsOnExisting() throws Exception { + checkFileWriteThrowsOnExisting(SdkConstants.FN_COMPILED_RESOURCE_CLASS); + } + + @Test + public void checkInnerFileWriteThrowsOnExisting() throws Exception { + checkFileWriteThrowsOnExisting("R$string.class"); + } + + private void checkFileWriteThrowsOnExisting(String existingFile) throws Exception { + ResourceSymbols symbolValues = + createSymbolFile("R.txt", "int string ok 0x7f100001"); + ResourceSymbols symbolsInLibrary = + createSymbolFile("lib.R.txt", "int string ok 0x1"); + + Path out = temp.resolve("classes"); + String packageName = "com"; + Path packageFolder = out.resolve(packageName); + Files.createDirectories(packageFolder); + + RClassGenerator writer = RClassGenerator.with(out, symbolValues.asInitializers(), false); + Files.write(packageFolder.resolve(existingFile), new byte[0]); + + try { + writer.write(packageName, symbolsInLibrary.asInitializers()); + } catch (FileAlreadyExistsException e) { + return; + } + throw new Exception("Expected to throw a FileAlreadyExistsException"); + } + + @Test public void emptyIntArrays() throws Exception { boolean finalFields = true; // Make sure we parse an empty array the way the R.txt writes it. @@ -145,7 +179,7 @@ public class RClassGeneratorTest { finalFields ); } - + static final Matcher<Throwable> NUMBER_FORMAT_EXCEPTION = new BaseMatcher<Throwable>() { @Override diff --git a/src/tools/android/java/com/google/devtools/build/android/GenerateRobolectricResourceSymbolsAction.java b/src/tools/android/java/com/google/devtools/build/android/GenerateRobolectricResourceSymbolsAction.java index 0857fe37fd..4f33dd490d 100644 --- a/src/tools/android/java/com/google/devtools/build/android/GenerateRobolectricResourceSymbolsAction.java +++ b/src/tools/android/java/com/google/devtools/build/android/GenerateRobolectricResourceSymbolsAction.java @@ -33,6 +33,7 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -43,7 +44,7 @@ import java.util.logging.Level; import java.util.logging.Logger; /** - * This action generates consistant ids R.class files for use in robolectric tests. + * This action generates consistent ids R.class files for use in robolectric tests. */ public class GenerateRobolectricResourceSymbolsAction { @@ -51,11 +52,11 @@ public class GenerateRobolectricResourceSymbolsAction { Logger.getLogger(GenerateRobolectricResourceSymbolsAction.class.getName()); private static final class WriteLibraryRClass implements Callable<Boolean> { - private final Entry<String, ListenableFuture<ResourceSymbols>> librarySymbolEntry; + private final Entry<String, Collection<ListenableFuture<ResourceSymbols>>> librarySymbolEntry; private final RClassGenerator generator; private WriteLibraryRClass( - Entry<String, ListenableFuture<ResourceSymbols>> librarySymbolEntry, + Entry<String, Collection<ListenableFuture<ResourceSymbols>>> librarySymbolEntry, RClassGenerator generator) { this.librarySymbolEntry = librarySymbolEntry; this.generator = generator; @@ -63,8 +64,14 @@ public class GenerateRobolectricResourceSymbolsAction { @Override public Boolean call() throws Exception { + List<ResourceSymbols> resourceSymbolsList = new ArrayList<>(); + for (final ListenableFuture<ResourceSymbols> resourceSymbolsReader : + librarySymbolEntry.getValue()) { + resourceSymbolsList.add(resourceSymbolsReader.get()); + } + generator.write( - librarySymbolEntry.getKey(), librarySymbolEntry.getValue().get().asInitializers()); + librarySymbolEntry.getKey(), ResourceSymbols.merge(resourceSymbolsList).asInitializers()); return true; } } @@ -152,8 +159,8 @@ public class GenerateRobolectricResourceSymbolsAction { libraries.add(library); } List<ListenableFuture<Boolean>> writeSymbolsTask = new ArrayList<>(); - for (final Entry<String, ListenableFuture<ResourceSymbols>> librarySymbolEntry : - ResourceSymbols.loadFrom(libraries, executorService, null).entries()) { + for (final Entry<String, Collection<ListenableFuture<ResourceSymbols>>> librarySymbolEntry : + ResourceSymbols.loadFrom(libraries, executorService, null).asMap().entrySet()) { writeSymbolsTask.add( executorService.submit(new WriteLibraryRClass(librarySymbolEntry, generator))); } diff --git a/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java b/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java index ea09b5bbd3..81a55e09de 100644 --- a/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java +++ b/src/tools/android/java/com/google/devtools/build/android/resources/RClassGenerator.java @@ -13,6 +13,8 @@ // limitations under the License. package com.google.devtools.build.android.resources; +import static java.nio.file.StandardOpenOption.CREATE_NEW; + import com.android.SdkConstants; import com.android.resources.ResourceType; import com.google.common.base.Splitter; @@ -116,7 +118,7 @@ public class RClassGenerator { Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC); } classWriter.visitEnd(); - Files.write(rClassFile, classWriter.toByteArray()); + Files.write(rClassFile, classWriter.toByteArray(), CREATE_NEW); // Now generate the R$inner.class files. for (Map.Entry<ResourceType, Map<String, FieldInitializer>> entry : initializersToWrite) { writeInnerClass(entry.getValue(), packageDir, rClassName, entry.getKey().toString()); @@ -151,7 +153,7 @@ public class RClassGenerator { innerClassWriter.visitEnd(); Path innerFile = packageDir.resolve("R$" + innerClass + ".class"); - Files.write(innerFile, innerClassWriter.toByteArray()); + Files.write(innerFile, innerClassWriter.toByteArray(), CREATE_NEW); } private String writeInnerClassHeader( |