1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.client.bindings.spi.atompub;
20
21 import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_ATOM_ID;
22 import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_ATOM_TITLE;
23 import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_ATOM_UPDATED;
24 import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_CONTENT;
25 import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_CONTENT_BASE64;
26 import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_CONTENT_FILENAME;
27 import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_CONTENT_MEDIATYPE;
28
29 import java.io.BufferedInputStream;
30 import java.io.ByteArrayInputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.OutputStream;
34 import java.util.GregorianCalendar;
35 import java.util.TimeZone;
36
37 import javax.xml.stream.XMLStreamException;
38 import javax.xml.stream.XMLStreamWriter;
39
40 import org.apache.chemistry.opencmis.commons.PropertyIds;
41 import org.apache.chemistry.opencmis.commons.data.ContentStream;
42 import org.apache.chemistry.opencmis.commons.data.ObjectData;
43 import org.apache.chemistry.opencmis.commons.data.PropertyData;
44 import org.apache.chemistry.opencmis.commons.data.PropertyString;
45 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
46 import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
47 import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
48 import org.apache.chemistry.opencmis.commons.impl.Base64;
49 import org.apache.chemistry.opencmis.commons.impl.DateTimeHelper;
50 import org.apache.chemistry.opencmis.commons.impl.XMLConstants;
51 import org.apache.chemistry.opencmis.commons.impl.XMLConverter;
52 import org.apache.chemistry.opencmis.commons.impl.XMLUtils;
53 import org.apache.chemistry.opencmis.commons.impl.dataobjects.BulkUpdateImpl;
54
55
56
57
58 public class AtomEntryWriter {
59
60 private static final int BUFFER_SIZE = 64 * 1024;
61
62 private final CmisVersion cmisVersion;
63 private final ObjectData object;
64 private final ContentStream contentStream;
65 private final InputStream stream;
66 private final TypeDefinition typeDef;
67 private final BulkUpdateImpl bulkUpdate;
68
69
70
71
72 public AtomEntryWriter(ObjectData object, CmisVersion cmisVersion) {
73 this(object, cmisVersion, null);
74 }
75
76
77
78
79 public AtomEntryWriter(ObjectData object, CmisVersion cmisVersion, ContentStream contentStream) {
80 if ((object == null) || (object.getProperties() == null)) {
81 throw new CmisInvalidArgumentException("Object and properties must not be null!");
82 }
83
84 if ((contentStream != null) && (contentStream.getMimeType() == null)) {
85 throw new CmisInvalidArgumentException("Media type must be set if a stream is present!");
86 }
87
88 this.object = object;
89 this.cmisVersion = cmisVersion;
90 this.contentStream = contentStream;
91 if (contentStream != null && contentStream.getStream() != null) {
92 InputStream in = contentStream.getStream();
93
94
95 if (!(in instanceof BufferedInputStream) && !(in instanceof ByteArrayInputStream)) {
96 stream = new BufferedInputStream(in, BUFFER_SIZE);
97 } else {
98 stream = in;
99 }
100 } else {
101 stream = null;
102 }
103 this.typeDef = null;
104 this.bulkUpdate = null;
105 }
106
107
108
109
110 public AtomEntryWriter(TypeDefinition type, CmisVersion cmisVersion) {
111 if (type == null) {
112 throw new CmisInvalidArgumentException("Type must not be null!");
113 }
114
115 this.typeDef = type;
116 this.cmisVersion = cmisVersion;
117 this.object = null;
118 this.contentStream = null;
119 this.stream = null;
120 this.bulkUpdate = null;
121 }
122
123
124
125
126 public AtomEntryWriter(BulkUpdateImpl bulkUpdate) {
127 if (bulkUpdate == null) {
128 throw new CmisInvalidArgumentException("Bulk update data must not be null!");
129 }
130
131 this.bulkUpdate = bulkUpdate;
132 this.typeDef = null;
133 this.cmisVersion = CmisVersion.CMIS_1_1;
134 this.object = null;
135 this.contentStream = null;
136 this.stream = null;
137 }
138
139
140
141
142 public void write(OutputStream out) throws XMLStreamException, IOException {
143 XMLStreamWriter writer = XMLUtils.createWriter(out);
144
145 XMLUtils.startXmlDocument(writer);
146
147 writer.writeStartElement(XMLConstants.PREFIX_ATOM, "entry", XMLConstants.NAMESPACE_ATOM);
148
149 writer.writeNamespace(XMLConstants.PREFIX_ATOM, XMLConstants.NAMESPACE_ATOM);
150 writer.writeNamespace(XMLConstants.PREFIX_CMIS, XMLConstants.NAMESPACE_CMIS);
151 writer.writeNamespace(XMLConstants.PREFIX_RESTATOM, XMLConstants.NAMESPACE_RESTATOM);
152 if (contentStream != null && contentStream.getFileName() != null) {
153 writer.writeNamespace(XMLConstants.PREFIX_APACHE_CHEMISTY, XMLConstants.NAMESPACE_APACHE_CHEMISTRY);
154 }
155
156
157 XMLUtils.write(writer, XMLConstants.PREFIX_ATOM, XMLConstants.NAMESPACE_ATOM, TAG_ATOM_ID,
158 "urn:uuid:00000000-0000-0000-0000-00000000000");
159
160
161 XMLUtils.write(writer, XMLConstants.PREFIX_ATOM, XMLConstants.NAMESPACE_ATOM, TAG_ATOM_TITLE, getTitle());
162
163
164 XMLUtils.write(writer, XMLConstants.PREFIX_ATOM, XMLConstants.NAMESPACE_ATOM, TAG_ATOM_UPDATED,
165 new GregorianCalendar(DateTimeHelper.GMT));
166
167
168 if (stream != null) {
169 writer.writeStartElement(XMLConstants.PREFIX_RESTATOM, TAG_CONTENT, XMLConstants.NAMESPACE_RESTATOM);
170
171 XMLUtils.write(writer, XMLConstants.PREFIX_RESTATOM, XMLConstants.NAMESPACE_RESTATOM,
172 TAG_CONTENT_MEDIATYPE, contentStream.getMimeType());
173
174 if (contentStream.getFileName() != null) {
175 XMLUtils.write(writer, XMLConstants.PREFIX_APACHE_CHEMISTY, XMLConstants.NAMESPACE_APACHE_CHEMISTRY,
176 TAG_CONTENT_FILENAME, contentStream.getFileName());
177 }
178
179 writer.writeStartElement(XMLConstants.PREFIX_RESTATOM, TAG_CONTENT_BASE64, XMLConstants.NAMESPACE_RESTATOM);
180 writeContent(writer);
181 writer.writeEndElement();
182
183 writer.writeEndElement();
184 }
185
186
187 if (object != null) {
188 XMLConverter.writeObject(writer, cmisVersion, XMLConstants.NAMESPACE_RESTATOM, object);
189 }
190
191
192 if (typeDef != null) {
193 XMLConverter.writeTypeDefinition(writer, cmisVersion, XMLConstants.NAMESPACE_RESTATOM, typeDef);
194 }
195
196
197 if (bulkUpdate != null) {
198 XMLConverter.writeBulkUpdate(writer, XMLConstants.NAMESPACE_RESTATOM, bulkUpdate);
199 }
200
201
202 writer.writeEndElement();
203
204
205 XMLUtils.endXmlDocument(writer);
206 }
207
208
209
210 private String getTitle() {
211 String result = "";
212
213 if (object != null) {
214 PropertyData<?> nameProperty = object.getProperties().getProperties().get(PropertyIds.NAME);
215 if (nameProperty instanceof PropertyString) {
216 result = ((PropertyString) nameProperty).getFirstValue();
217 }
218 }
219
220 if (typeDef != null) {
221 if (typeDef.getDisplayName() != null) {
222 result = typeDef.getDisplayName();
223 }
224 }
225
226 if (bulkUpdate != null) {
227 result = "Bulk Update Properties";
228 }
229
230 return result;
231 }
232
233 private void writeContent(XMLStreamWriter writer) throws XMLStreamException, IOException {
234 @SuppressWarnings("resource")
235 Base64.InputStream b64stream = new Base64.InputStream(stream, Base64.ENCODE);
236
237 char[] buffer = new char[BUFFER_SIZE];
238 int pos = 0;
239 int b;
240 while ((b = b64stream.read()) > -1) {
241 buffer[pos++] = (char) (b & 0xFF);
242 if (pos == buffer.length) {
243 writer.writeCharacters(buffer, 0, buffer.length);
244 pos = 0;
245 }
246 }
247 if (pos > 0) {
248 writer.writeCharacters(buffer, 0, pos);
249 }
250 }
251 }