1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package davmail.exchange.dav;
20
21 import org.apache.log4j.Logger;
22
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.io.OutputStreamWriter;
26 import java.nio.charset.StandardCharsets;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Map;
30 import java.util.Set;
31
32
33
34
35
36 public class ExchangePropPatchMethod extends ExchangeDavMethod {
37 protected static final Logger LOGGER = Logger.getLogger(ExchangePropPatchMethod.class);
38 static final String TYPE_NAMESPACE = "urn:schemas-microsoft-com:datatypes";
39 final Set<PropertyValue> propertyValues;
40
41
42
43
44
45
46
47 public ExchangePropPatchMethod(String path, Set<PropertyValue> propertyValues) {
48 super(path);
49 this.propertyValues = propertyValues;
50 }
51
52 @Override
53 protected byte[] generateRequestContent() {
54 try {
55
56 int currentChar = 'e';
57 final Map<String, Integer> nameSpaceMap = new HashMap<>();
58 final Set<PropertyValue> setPropertyValues = new HashSet<>();
59 final Set<PropertyValue> deletePropertyValues = new HashSet<>();
60 for (PropertyValue propertyValue : propertyValues) {
61
62 if (!nameSpaceMap.containsKey(TYPE_NAMESPACE) && propertyValue.getTypeString() != null) {
63 nameSpaceMap.put(TYPE_NAMESPACE, currentChar++);
64 }
65
66 String namespaceUri = propertyValue.getNamespaceUri();
67 if (!nameSpaceMap.containsKey(namespaceUri)) {
68 nameSpaceMap.put(namespaceUri, currentChar++);
69 }
70 if (propertyValue.getXmlEncodedValue() == null) {
71 deletePropertyValues.add(propertyValue);
72 } else {
73 setPropertyValues.add(propertyValue);
74 }
75 }
76 ByteArrayOutputStream baos = new ByteArrayOutputStream();
77 OutputStreamWriter writer = new OutputStreamWriter(baos, StandardCharsets.UTF_8);
78 writer.write("<D:propertyupdate xmlns:D=\"DAV:\"");
79 for (Map.Entry<String, Integer> mapEntry : nameSpaceMap.entrySet()) {
80 writer.write(" xmlns:");
81 writer.write((char) mapEntry.getValue().intValue());
82 writer.write("=\"");
83 writer.write(mapEntry.getKey());
84 writer.write("\"");
85 }
86 writer.write(">");
87 if (!setPropertyValues.isEmpty()) {
88 writer.write("<D:set><D:prop>");
89 for (PropertyValue propertyValue : setPropertyValues) {
90 String typeString = propertyValue.getTypeString();
91 char nameSpaceChar = (char) nameSpaceMap.get(propertyValue.getNamespaceUri()).intValue();
92 writer.write('<');
93 writer.write(nameSpaceChar);
94 writer.write(':');
95 writer.write(propertyValue.getName());
96 if (typeString != null) {
97 writer.write(' ');
98 writer.write(nameSpaceMap.get(TYPE_NAMESPACE));
99 writer.write(":dt=\"");
100 writer.write(typeString);
101 writer.write("\"");
102 }
103 writer.write('>');
104 writer.write(propertyValue.getXmlEncodedValue());
105 writer.write("</");
106 writer.write(nameSpaceChar);
107 writer.write(':');
108 writer.write(propertyValue.getName());
109 writer.write('>');
110 }
111 writer.write("</D:prop></D:set>");
112 }
113 if (!deletePropertyValues.isEmpty()) {
114 writer.write("<D:remove><D:prop>");
115 for (PropertyValue propertyValue : deletePropertyValues) {
116 char nameSpaceChar = (char) nameSpaceMap.get(propertyValue.getNamespaceUri()).intValue();
117 writer.write('<');
118 writer.write(nameSpaceChar);
119 writer.write(':');
120 writer.write(propertyValue.getName());
121 writer.write("/>");
122 }
123 writer.write("</D:prop></D:remove>");
124 }
125 writer.write("</D:propertyupdate>");
126 writer.close();
127 return baos.toByteArray();
128 } catch (IOException e) {
129 throw new RuntimeException(e);
130 }
131 }
132
133 @Override
134 public String getName() {
135 return "PROPPATCH";
136 }
137
138 }