Skip to content

Commit 1b41243

Browse files
authored
Fix cached streams (#427)
1 parent 9662fce commit 1b41243

File tree

4 files changed

+101
-50
lines changed

4 files changed

+101
-50
lines changed

AndroidSDKCore/src/main/java/com/leanplum/Var.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,12 @@ private static <T> Var<T> define(
111111
var.cacheComputedValues();
112112
VarCache.registerVariable(var);
113113
if (Constants.Kinds.FILE.equals(var.kind)) {
114-
VarCache.registerFile(var.stringValue,
115-
var.defaultValue() == null ? null : var.defaultValue().toString(),
116-
var.defaultStream(), var.isResource, var.hash, var.size);
114+
if (var.isResource) {
115+
VarCache.registerFile(var.stringValue, var::defaultStream, var.hash, var.size);
116+
} else {
117+
String defaultVal = var.defaultValue() == null ? null : var.defaultValue().toString();
118+
VarCache.registerFile(var.stringValue, defaultVal, var::defaultStream);
119+
}
117120
}
118121
var.update();
119122
} catch (Throwable t) {

AndroidSDKCore/src/main/java/com/leanplum/internal/ActionArg.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,14 @@ public static ActionArg<String> fileArgNamed(String name, String defaultFilename
6969
defaultFilename = "";
7070
}
7171
ActionArg<String> arg = argNamed(name, defaultFilename, Constants.Kinds.FILE);
72-
VarCache.registerFile(arg.defaultValue, arg.defaultValue,
73-
arg.defaultStream(), false, null, 0);
72+
VarCache.registerFile(arg.defaultValue, arg.defaultValue, arg::defaultStream);
7473
return arg;
7574
}
7675

7776
public static ActionArg<String> assetArgNamed(String name, String defaultFilename) {
7877
ActionArg<String> arg = argNamed(name, defaultFilename, Constants.Kinds.FILE);
7978
arg.isAsset = true;
80-
VarCache.registerFile(arg.defaultValue, arg.defaultValue,
81-
arg.defaultStream(), false, null, 0);
79+
VarCache.registerFile(arg.defaultValue, arg.defaultValue, arg::defaultStream);
8280
return arg;
8381
}
8482

AndroidSDKCore/src/main/java/com/leanplum/internal/VarCache.java

Lines changed: 75 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
public class VarCache {
6060
private static final Map<String, Var<?>> vars = new ConcurrentHashMap<>();
6161
private static final Map<String, Object> fileAttributes = new HashMap<>();
62-
private static final Map<String, InputStream> fileStreams = new HashMap<>();
62+
private static final Map<String, StreamProvider> fileStreams = new HashMap<>();
6363

6464
/**
6565
* The default values set by the client. This is not thread-safe so traversals should be
@@ -122,42 +122,77 @@ private static Object traverse(Object collection, Object key, boolean autoInsert
122122
return null;
123123
}
124124

125-
public static boolean registerFile(
126-
String stringValue, String defaultValue,
127-
InputStream defaultStream, boolean isResource, String resourceHash, int resourceSize) {
128-
if (Constants.isDevelopmentModeEnabled) {
129-
if (!Constants.isNoop()) {
130-
if (defaultStream == null) {
131-
return false;
132-
}
133-
Map<String, Object> variationAttributes = new HashMap<>();
134-
Map<String, Object> attributes = new HashMap<>();
135-
if (isResource) {
136-
attributes.put(Constants.Keys.HASH, resourceHash);
137-
attributes.put(Constants.Keys.SIZE, resourceSize);
138-
} else {
139-
if (Constants.hashFilesToDetermineModifications && Util.isSimulator()) {
140-
HashResults result = FileManager.fileMD5HashCreateWithPath(defaultStream);
141-
if (result != null) {
142-
attributes.put(Constants.Keys.HASH, result.hash);
143-
attributes.put(Constants.Keys.SIZE, result.size);
144-
}
145-
} else {
146-
int size = FileManager.getFileSize(
147-
FileManager.fileValue(stringValue, defaultValue, null));
148-
attributes.put(Constants.Keys.SIZE, size);
149-
}
150-
}
151-
variationAttributes.put("", attributes);
152-
fileAttributes.put(stringValue, variationAttributes);
153-
fileStreams.put(stringValue, defaultStream);
154-
maybeUploadNewFiles();
125+
@FunctionalInterface
126+
public interface StreamProvider {
127+
InputStream openStream();
128+
}
129+
130+
private static boolean isStreamAvailable(StreamProvider stream) {
131+
if (stream == null)
132+
return false;
133+
134+
try {
135+
InputStream is = stream.openStream();
136+
if (is != null) {
137+
is.close();
138+
return true;
155139
}
156-
return true;
140+
} catch (Throwable ignore) {
157141
}
158142
return false;
159143
}
160144

145+
public static void registerFile(
146+
String stringValue, StreamProvider defaultStream, String hash, int size) {
147+
148+
if (!isStreamAvailable(defaultStream)
149+
|| !Constants.isDevelopmentModeEnabled
150+
|| Constants.isNoop()) {
151+
return;
152+
}
153+
154+
Map<String, Object> attributes = new HashMap<>();
155+
attributes.put(Constants.Keys.HASH, hash);
156+
attributes.put(Constants.Keys.SIZE, size);
157+
158+
Map<String, Object> variationAttributes = new HashMap<>();
159+
variationAttributes.put("", attributes);
160+
161+
fileStreams.put(stringValue, defaultStream);
162+
fileAttributes.put(stringValue, variationAttributes);
163+
maybeUploadNewFiles();
164+
}
165+
166+
public static void registerFile(
167+
String stringValue, String defaultValue, StreamProvider defaultStream) {
168+
169+
if (!isStreamAvailable(defaultStream)
170+
|| !Constants.isDevelopmentModeEnabled
171+
|| Constants.isNoop()) {
172+
return;
173+
}
174+
175+
Map<String, Object> variationAttributes = new HashMap<>();
176+
Map<String, Object> attributes = new HashMap<>();
177+
178+
if (Constants.hashFilesToDetermineModifications && Util.isSimulator()) {
179+
HashResults result = FileManager.fileMD5HashCreateWithPath(defaultStream.openStream());
180+
if (result != null) {
181+
attributes.put(Constants.Keys.HASH, result.hash);
182+
attributes.put(Constants.Keys.SIZE, result.size);
183+
}
184+
} else {
185+
int size = FileManager.getFileSize(
186+
FileManager.fileValue(stringValue, defaultValue, null));
187+
attributes.put(Constants.Keys.SIZE, size);
188+
}
189+
190+
variationAttributes.put("", attributes);
191+
fileStreams.put(stringValue, defaultStream);
192+
fileAttributes.put(stringValue, variationAttributes);
193+
maybeUploadNewFiles();
194+
}
195+
161196
private static void updateValues(String name, String[] nameComponents, Object value, String kind,
162197
Map<String, Object> values, Map<String, String> kinds) {
163198
Object valuesPtr = values;
@@ -461,8 +496,8 @@ private static void fileVariableFinish() {
461496
!overrideFile.equals(var.defaultValue())) {
462497
Map<String, Object> variationAttributes = CollectionUtil.uncheckedCast(fileAttributes.get
463498
(overrideFile));
464-
InputStream stream = fileStreams.get(overrideFile);
465-
if (variationAttributes != null && stream != null) {
499+
StreamProvider streamProvider = fileStreams.get(overrideFile);
500+
if (variationAttributes != null && streamProvider != null) {
466501
var.setOverrideResId(getResIdFromPath(var.stringValue()));
467502
}
468503
}
@@ -692,7 +727,12 @@ static void maybeUploadNewFiles() {
692727
Log.e("Unable to upload files.\n" + Log.getStackTraceString(e));
693728
fileData.add(new JSONObject());
694729
}
695-
streams.add(fileStreams.get(name));
730+
InputStream is = null;
731+
StreamProvider streamProvider = fileStreams.get(name);
732+
if (streamProvider != null) {
733+
is = streamProvider.openStream();
734+
}
735+
streams.add(is);
696736
}
697737
}
698738

AndroidSDKCore/src/main/java/com/leanplum/internal/http/UploadOperation.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,16 @@ public boolean uploadFiles(
6767

6868
// Main file writing loop
6969
for (int i = 0; i < filesToUpload.size(); i++) {
70+
File file = filesToUpload.get(i);
7071

71-
File fileToUpload = filesToUpload.get(i);
72-
InputStream is = (i < streams.size()) ? streams.get(i) : new FileInputStream(fileToUpload);
72+
InputStream is;
73+
if (i < streams.size()) {
74+
is = streams.get(i);
75+
} else {
76+
is = new FileInputStream(file);
77+
}
7378

74-
if (!writeFile(writer, fileToUpload, is, i)) {
79+
if (!writeFile(writer, file.getName(), file.getPath(), is, i)) {
7580
return false;
7681
}
7782
}
@@ -101,12 +106,17 @@ private void writeEnd(DataOutputStream writer) throws IOException {
101106
writer.writeBytes(endOfRequest);
102107
}
103108

104-
private boolean writeFile(DataOutputStream writer, File file, InputStream is, int i)
109+
private boolean writeFile(
110+
DataOutputStream writer,
111+
String fileName,
112+
String filePath,
113+
InputStream is,
114+
int i)
105115
throws IOException {
106116

107-
writeFileHeader(writer, file.getName(), i);
117+
writeFileHeader(writer, fileName, i);
108118

109-
if (!writeFileContent(writer, file, is)) {
119+
if (!writeFileContent(writer, filePath, is)) {
110120
return false;
111121
}
112122

@@ -129,7 +139,7 @@ private void writeFileHeader(DataOutputStream writer, String fileName, int i) th
129139
writer.writeBytes(fileHeader);
130140
}
131141

132-
private boolean writeFileContent(DataOutputStream writer, File file, InputStream is)
142+
private boolean writeFileContent(DataOutputStream writer, String filePath, InputStream is)
133143
throws IOException {
134144
// Read in the actual file
135145
byte[] buffer = new byte[4096];
@@ -139,7 +149,7 @@ private boolean writeFileContent(DataOutputStream writer, File file, InputStream
139149
writer.write(buffer, 0, bytesRead);
140150
}
141151
} catch (NullPointerException e) {
142-
Log.d("Unable to read file while uploading " + file);
152+
Log.d("Unable to read file while uploading " + filePath);
143153
return false;
144154
} finally {
145155
if (is != null) {

0 commit comments

Comments
 (0)