|
23 | 23 | import java.util.List; |
24 | 24 |
|
25 | 25 | import org.bson.BsonArray; |
| 26 | +import org.bson.BsonBinary; |
26 | 27 | import org.bson.BsonDocument; |
| 28 | +import org.bson.BsonJavaScriptWithScope; |
27 | 29 | import org.bson.BsonValue; |
28 | 30 |
|
29 | 31 | class InPlaceApplyProcessor implements BsonPatchProcessor { |
@@ -58,7 +60,8 @@ public void copy(List<String> fromPath, List<String> toPath) { |
58 | 60 | BsonValue parentNode = getParentNode(fromPath, Operation.COPY); |
59 | 61 | String field = fromPath.get(fromPath.size() - 1).replaceAll("\"", ""); |
60 | 62 | BsonValue valueNode = parentNode.isArray() ? parentNode.asArray().get(Integer.parseInt(field)) : parentNode.asDocument().get(field); |
61 | | - add(toPath, valueNode); |
| 63 | + BsonValue valueToCopy = valueNode != null ? cloneBsonValue(valueNode) : null; |
| 64 | + add(toPath, valueToCopy); |
62 | 65 | } |
63 | 66 |
|
64 | 67 | @Override |
@@ -238,4 +241,26 @@ private int arrayIndex(String s, int max, boolean allowNoneExisting) { |
238 | 241 | private boolean isNullOrEmpty(String string) { |
239 | 242 | return string == null || string.length() == 0; |
240 | 243 | } |
| 244 | + |
| 245 | + private static BsonValue cloneBsonValue(BsonValue from) { |
| 246 | + BsonValue to; |
| 247 | + switch (from.getBsonType()) { |
| 248 | + case DOCUMENT: |
| 249 | + to = from.asDocument().clone(); |
| 250 | + break; |
| 251 | + case ARRAY: |
| 252 | + to = from.asArray().clone(); |
| 253 | + break; |
| 254 | + case BINARY: |
| 255 | + to = new BsonBinary(from.asBinary().getType(), from.asBinary().getData().clone()); |
| 256 | + break; |
| 257 | + case JAVASCRIPT_WITH_SCOPE: |
| 258 | + to = new BsonJavaScriptWithScope(from.asJavaScriptWithScope().getCode(), from.asJavaScriptWithScope().getScope().clone()); |
| 259 | + break; |
| 260 | + default: |
| 261 | + to = from; // assume that from is immutable |
| 262 | + } |
| 263 | + return to; |
| 264 | + } |
| 265 | + |
241 | 266 | } |
0 commit comments