1package org.robolectric.internal;
2
3import static java.nio.charset.StandardCharsets.UTF_8;
4
5import java.io.File;
6import java.io.FileInputStream;
7import java.io.IOException;
8import java.util.ArrayList;
9import java.util.Arrays;
10import java.util.Collections;
11import java.util.List;
12import javax.annotation.Nonnull;
13import org.robolectric.annotation.Config;
14import org.robolectric.res.Fs;
15import org.robolectric.res.FsFile;
16import org.robolectric.util.Util;
17
18public class BuckManifestFactory implements ManifestFactory {
19
20  private static final String BUCK_ROBOLECTRIC_RES_DIRECTORIES = "buck.robolectric_res_directories";
21  private static final String BUCK_ROBOLECTRIC_ASSETS_DIRECTORIES = "buck.robolectric_assets_directories";
22  private static final String BUCK_ROBOLECTRIC_MANIFEST = "buck.robolectric_manifest";
23
24  @Override
25  public ManifestIdentifier identify(Config config) {
26    String buckManifest = System.getProperty(BUCK_ROBOLECTRIC_MANIFEST);
27    FsFile manifestFile = Fs.fileFromPath(buckManifest);
28
29    String buckResDirs = System.getProperty(BUCK_ROBOLECTRIC_RES_DIRECTORIES);
30    String buckAssetsDirs = System.getProperty(BUCK_ROBOLECTRIC_ASSETS_DIRECTORIES);
31    String packageName = config.packageName();
32
33    final List<FsFile> buckResources = getDirectoriesFromProperty(buckResDirs);
34    final List<FsFile> buckAssets = getDirectoriesFromProperty(buckAssetsDirs);
35    final FsFile resDir = buckResources.size() == 0 ? null : buckResources.get(buckResources.size() - 1);
36    final FsFile assetsDir = buckAssets.size() == 0 ? null : buckAssets.get(buckAssets.size() - 1);
37    final List<ManifestIdentifier> libraries;
38
39    if (resDir == null && assetsDir == null) {
40      libraries = null;
41    } else {
42      libraries = new ArrayList<>();
43
44      for (int i = 0; i < buckResources.size() - 1; i++) {
45        libraries.add(new ManifestIdentifier((String) null, null, buckResources.get(i), null, null));
46      }
47
48      for (int i = 0; i < buckAssets.size() - 1; i++) {
49        libraries.add(new ManifestIdentifier(null, null, null, buckAssets.get(i), null));
50      }
51    }
52
53    return new ManifestIdentifier(packageName, manifestFile, resDir, assetsDir, libraries);
54  }
55
56  public static boolean isBuck() {
57    return System.getProperty(BUCK_ROBOLECTRIC_MANIFEST) != null;
58  }
59
60  @Nonnull
61  private List<FsFile> getDirectoriesFromProperty(String property) {
62    if (property == null) {
63      return Collections.emptyList();
64    }
65
66    List<String> dirs;
67    if (property.startsWith("@")) {
68      String filename = property.substring(1);
69      try {
70        dirs = Arrays.asList(
71            new String(Util.readBytes(new FileInputStream(filename)), UTF_8).split("\\n"));
72      } catch (IOException e) {
73        throw new RuntimeException("Cannot read file " + filename);
74      }
75    } else {
76      dirs = Arrays.asList(property.split(File.pathSeparator));
77    }
78
79    List<FsFile> files = new ArrayList<>();
80    for (String dir : dirs) {
81      files.add(Fs.fileFromPath(dir));
82    }
83    return files;
84  }
85}
86