-
-
Notifications
You must be signed in to change notification settings - Fork 468
Expand file tree
/
Copy pathHint.java
More file actions
166 lines (138 loc) · 5.02 KB
/
Hint.java
File metadata and controls
166 lines (138 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package io.sentry;
import io.sentry.util.AutoClosableReentrantLock;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class Hint {
private static final @NotNull Map<String, Class<?>> PRIMITIVE_MAPPINGS;
static {
PRIMITIVE_MAPPINGS = new HashMap<>();
PRIMITIVE_MAPPINGS.put("boolean", Boolean.class);
PRIMITIVE_MAPPINGS.put("char", Character.class);
PRIMITIVE_MAPPINGS.put("byte", Byte.class);
PRIMITIVE_MAPPINGS.put("short", Short.class);
PRIMITIVE_MAPPINGS.put("int", Integer.class);
PRIMITIVE_MAPPINGS.put("long", Long.class);
PRIMITIVE_MAPPINGS.put("float", Float.class);
PRIMITIVE_MAPPINGS.put("double", Double.class);
}
private final @NotNull Map<String, Object> internalStorage = new HashMap<String, Object>();
private final @NotNull List<Attachment> attachments = new ArrayList<>();
private final @NotNull AutoClosableReentrantLock lock = new AutoClosableReentrantLock();
private @Nullable Attachment screenshot = null;
private @Nullable Attachment viewHierarchy = null;
private @Nullable Attachment threadDump = null;
private @Nullable ReplayRecording replayRecording = null;
public static @NotNull Hint withAttachment(@Nullable Attachment attachment) {
@NotNull final Hint hint = new Hint();
hint.addAttachment(attachment);
return hint;
}
public static @NotNull Hint withAttachments(@Nullable List<Attachment> attachments) {
@NotNull final Hint hint = new Hint();
hint.addAttachments(attachments);
return hint;
}
public void set(@NotNull String name, @Nullable Object hint) {
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
internalStorage.put(name, hint);
}
}
public @Nullable Object get(@NotNull String name) {
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
return internalStorage.get(name);
}
}
@SuppressWarnings("unchecked")
public <T extends Object> @Nullable T getAs(@NotNull String name, @NotNull Class<T> clazz) {
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
Object hintValue = internalStorage.get(name);
if (clazz.isInstance(hintValue)) {
return (T) hintValue;
} else if (isCastablePrimitive(hintValue, clazz)) {
return (T) hintValue;
} else {
return null;
}
}
}
public void remove(@NotNull String name) {
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
internalStorage.remove(name);
}
}
public void addAttachment(@Nullable Attachment attachment) {
if (attachment != null) {
attachments.add(attachment);
}
}
public void addAttachments(@Nullable List<Attachment> attachments) {
if (attachments != null) {
this.attachments.addAll(attachments);
}
}
public @NotNull List<Attachment> getAttachments() {
return new ArrayList<>(attachments);
}
public void replaceAttachments(@Nullable List<Attachment> attachments) {
clearAttachments();
addAttachments(attachments);
}
public void clearAttachments() {
attachments.clear();
}
/**
* Clears all attributes added via {@link #set(String, Object)} Note: SDK internal attributes are
* being kept. This is useful to avoid leaking any objects (e.g. Android activities) being
* referenced.
*/
@ApiStatus.Internal
public void clear() {
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
final Iterator<Map.Entry<String, Object>> iterator = internalStorage.entrySet().iterator();
while (iterator.hasNext()) {
final Map.Entry<String, Object> entry = iterator.next();
if (entry.getKey() == null || !entry.getKey().startsWith("sentry:")) {
iterator.remove();
}
}
}
}
public void setScreenshot(@Nullable Attachment screenshot) {
this.screenshot = screenshot;
}
public @Nullable Attachment getScreenshot() {
return screenshot;
}
public void setViewHierarchy(final @Nullable Attachment viewHierarchy) {
this.viewHierarchy = viewHierarchy;
}
public @Nullable Attachment getViewHierarchy() {
return viewHierarchy;
}
public void setThreadDump(final @Nullable Attachment threadDump) {
this.threadDump = threadDump;
}
public @Nullable Attachment getThreadDump() {
return threadDump;
}
@Nullable
public ReplayRecording getReplayRecording() {
return replayRecording;
}
public void setReplayRecording(final @Nullable ReplayRecording replayRecording) {
this.replayRecording = replayRecording;
}
private boolean isCastablePrimitive(@Nullable Object hintValue, @NotNull Class<?> clazz) {
Class<?> nonPrimitiveClass = PRIMITIVE_MAPPINGS.get(clazz.getCanonicalName());
return hintValue != null
&& clazz.isPrimitive()
&& nonPrimitiveClass != null
&& nonPrimitiveClass.isInstance(hintValue);
}
}