KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > httpconnector > handlers > AbstractDocumentHandler


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.httpconnector.handlers;
17
18 import org.apache.avalon.framework.logger.Logger;
19 import org.apache.commons.fileupload.*;
20 import org.outerj.daisy.repository.*;
21 import org.outerj.daisy.repository.schema.RepositorySchema;
22 import org.outerj.daisy.repository.schema.FieldType;
23 import org.outerj.daisy.httpconnector.RequestHandler;
24 import org.outerj.daisy.httpconnector.HttpUtil;
25 import org.outerj.daisy.httpconnector.RequestWrapper;
26 import org.outerj.daisy.httpconnector.BadRequestException;
27 import org.outerx.daisy.x10.DocumentDocument;
28 import org.outerx.daisy.x10.PartDocument;
29 import org.outerx.daisy.x10.FieldDocument;
30 import org.outerx.daisy.x10.LinksDocument;
31 import org.mortbay.http.HttpResponse;
32 import org.mortbay.http.HttpRequest;
33
34 import javax.servlet.http.HttpServletRequest JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.Arrays JavaDoc;
39 import java.io.IOException JavaDoc;
40 import java.io.InputStream JavaDoc;
41
42 public abstract class AbstractDocumentHandler implements RequestHandler {
43     protected final Logger requestErrorLogger;
44     protected final int uploadThreshold;
45     protected final int uploadMaxSize;
46     protected final String JavaDoc uploadTempdir;
47
48     public AbstractDocumentHandler(Logger requestErrorLogger, int uploadThreshold, int uploadMaxSize, String JavaDoc uploadTempdir) {
49         this.requestErrorLogger = requestErrorLogger;
50         this.uploadThreshold = uploadThreshold;
51         this.uploadMaxSize = uploadMaxSize;
52         this.uploadTempdir = uploadTempdir;
53     }
54
55     /**
56      * Updates a Document object based on XML data and other uploaded data.
57      */

58     protected void updateDocument(Document document, DocumentDocument.Document documentXml, List JavaDoc uploadedItems,
59                                    HttpResponse response, Repository repository) throws RepositoryException, DocumentTypeInconsistencyException, IOException JavaDoc, BadRequestException {
60         //
61
// Handle the Parts
62
//
63

64         PartDocument.Part partsXml[] = documentXml.getParts().getPartArray();
65         Part parts[] = document.getParts().getArray();
66
67         // search for deleted parts and delete them
68
for (int i = 0; i < parts.length; i++) {
69             boolean found = false;
70             for (int j = 0; j < partsXml.length; j++) {
71                 if (partsXml[j].getTypeId() == parts[i].getTypeId())
72                     found = true;
73             }
74             if (!found)
75                 document.deletePart(parts[i].getTypeId());
76         }
77
78         // update other parts if needed
79
for (int i = 0; i < partsXml.length; i++) {
80             PartDocument.Part partXml = partsXml[i];
81             if (partXml.getDataRef() != null) {
82                 final FileItem item = getItemByName(uploadedItems, partXml.getDataRef());
83                 if (item == null) {
84                     throw new BadRequestException("Referred data item not present in uploaded data: " + partXml.getDataRef());
85                 }
86                 PartDataSource partDataSource = new PartDataSource() {
87                     public InputStream JavaDoc createInputStream() throws IOException JavaDoc {
88                         return item.getInputStream();
89                     }
90
91                     public long getSize() {
92                         return item.getSize();
93                     }
94                 };
95                 document.setPart(partXml.getTypeId(), partXml.getMimeType(), partDataSource);
96                 if (partXml.isSetFileName())
97                     document.setPartFileName(partXml.getTypeId(), partXml.getFileName());
98             } else {
99                 Part part = document.getPart(partXml.getTypeId());
100                 if (!partXml.getMimeType().equals(part.getMimeType()))
101                     document.setPartMimeType(partXml.getTypeId(), partXml.getMimeType());
102                 if ((!partXml.isSetFileName() && part.getFileName() != null) || (partXml.isSetFileName() && !partXml.getFileName().equals(part.getFileName())))
103                     document.setPartFileName(part.getTypeId(), partXml.getFileName());
104             }
105         }
106
107         //
108
// Handle the Fields
109
//
110

111         FieldDocument.Field fieldsXml[] = documentXml.getFields().getFieldArray();
112         Field[] fields = document.getFields().getArray();
113
114         // search for deleted fields and delete them
115
for (int i = 0; i < fields.length; i++) {
116             boolean found = false;
117             for (int j = 0; j < fieldsXml.length; j++) {
118                 if (fieldsXml[j].getTypeId() == fields[i].getTypeId())
119                     found = true;
120             }
121             if (!found)
122                 document.deleteField(fields[i].getTypeId());
123         }
124
125         // update the other fields if needed
126
RepositorySchema repositorySchema = repository.getRepositorySchema();
127         for (int i = 0; i < fieldsXml.length; i++) {
128             FieldDocument.Field fieldXml = fieldsXml[i];
129             FieldType fieldType = repositorySchema.getFieldTypeById(fieldXml.getTypeId(), false);
130             ValueType valueType = fieldType.getValueType();
131             Object JavaDoc value = FieldHelper.getFieldValueFromXml(valueType, fieldType.isMultiValue(), fieldXml);
132
133             if (document.hasField(fieldXml.getTypeId())) {
134                 Field field = document.getField(fieldXml.getTypeId());
135                 // only update if value has changed
136
if (!(fieldType.isMultiValue() ? Arrays.equals((Object JavaDoc[])field.getValue(), (Object JavaDoc[])value) : field.getValue().equals(value)))
137                     document.setField(fieldXml.getTypeId(), value);
138             } else {
139                 document.setField(fieldXml.getTypeId(), value);
140             }
141         }
142
143         //
144
// Handle the links
145
//
146
LinksDocument.Links.Link[] linksXml = documentXml.getLinks().getLinkArray();
147         Link[] links = document.getLinks().getArray();
148         boolean linksNeedUpdating = false;
149         if (linksXml.length != links.length) {
150             linksNeedUpdating = true;
151         } else {
152             for (int i = 0; i < linksXml.length; i++) {
153                 if (!linksXml[i].getTarget().equals(links[i].getTarget()) || !linksXml[i].getTitle().equals(links[i].getTitle())) {
154                     linksNeedUpdating = true;
155                     break;
156                 }
157             }
158         }
159
160         if (linksNeedUpdating) {
161             document.clearLinks();
162             for (int i = 0; i < linksXml.length; i++) {
163                 document.addLink(linksXml[i].getTitle(), linksXml[i].getTarget());
164             }
165         }
166
167         //
168
// Handle the custom fields
169
//
170
DocumentDocument.Document.CustomFields.CustomField[] customFieldsXml = documentXml.getCustomFields().getCustomFieldArray();
171         Map JavaDoc currentCustomFields = document.getCustomFields();
172         boolean customFieldsNeedUpdating = false;
173         if (currentCustomFields.size() != customFieldsXml.length) {
174             customFieldsNeedUpdating = true;
175         } else {
176             for (int i = 0; i < customFieldsXml.length; i++) {
177                 String JavaDoc value = (String JavaDoc)currentCustomFields.get(customFieldsXml[i].getName());
178                 if (value == null || !value.equals(customFieldsXml[i].getValue())) {
179                     customFieldsNeedUpdating = true;
180                     break;
181                 }
182             }
183         }
184         if (customFieldsNeedUpdating) {
185             document.clearCustomFields();
186             for (int i = 0; i < customFieldsXml.length; i++) {
187                 document.setCustomField(customFieldsXml[i].getName(), customFieldsXml[i].getValue());
188             }
189         }
190
191         //
192
// handle the collections
193
//
194

195         long[] collectionIds = documentXml.getCollectionIds().getCollectionIdArray();
196         boolean collectionsNeedUpdating = false;
197         if (document.getCollections().getArray().length != collectionIds.length) {
198             collectionsNeedUpdating = true;
199         } else {
200             for (int i = 0; i < collectionIds.length; i++) {
201                 if (!document.inCollection(collectionIds[i])) {
202                     collectionsNeedUpdating = true;
203                     break;
204                 }
205             }
206         }
207         if (collectionsNeedUpdating) {
208             CollectionManager collectionManager = repository.getCollectionManager();
209             document.clearCollections();
210             for (int i = 0; i < collectionIds.length; i++) {
211                 try {
212                     document.addToCollection(collectionManager.getCollection(collectionIds[i], false));
213                 } catch (CollectionNotFoundException e) {
214                     if (requestErrorLogger.isInfoEnabled())
215                         requestErrorLogger.info("A remote request to update a document referenced the non-existing collection " + collectionIds[i] + ", silently skipping this collection.");
216                 }
217             }
218         }
219
220         //
221
// Other document properties
222
//
223
if (!document.getName().equals(documentXml.getName()))
224             document.setName(documentXml.getName());
225         if (document.isPrivate() != documentXml.getPrivate())
226             document.setPrivate(documentXml.getPrivate());
227         if (document.isRetired() != documentXml.getRetired())
228             document.setRetired(documentXml.getRetired());
229         if (document.getDocumentTypeId() != documentXml.getTypeId())
230             document.changeDocumentType(documentXml.getTypeId());
231         if (document.getOwner() != documentXml.getOwner())
232             document.setOwner(documentXml.getOwner());
233         document.setNewVersionState(VersionState.fromString(documentXml.getNewVersionState().toString()));
234     }
235
236     /**
237      * Parses a multipart/form-data request and returns the list of items in it.
238      *
239      * <p>In case something is wrong, an error response is send to the client and
240      * null is returned.
241      */

242     protected List JavaDoc parseMultipartRequest(HttpRequest request, HttpResponse response) throws IOException JavaDoc, BadRequestException {
243         HttpServletRequest JavaDoc servletRequest = new RequestWrapper(request);
244         if (!FileUpload.isMultipartContent(servletRequest)) {
245             HttpUtil.sendCustomError("Expected multipart/form-data encoded content.", HttpResponse.__400_Bad_Request, response);
246             return null;
247         }
248
249         DiskFileUpload upload = new DiskFileUpload();
250         upload.setSizeThreshold(uploadThreshold);
251         upload.setSizeMax(uploadMaxSize);
252         if (uploadTempdir != null)
253             upload.setRepositoryPath(uploadTempdir);
254
255         try {
256             return upload.parseRequest(servletRequest);
257         } catch (FileUploadBase.SizeLimitExceededException e) {
258             throw new BadRequestException("Uploaded data exceeded the maximum allowed size.");
259         } catch (FileUploadException e) {
260             requestErrorLogger.error("Error handling multipart data.", e);
261             throw new BadRequestException("There was a problem handling the multipart data.");
262         }
263     }
264
265     protected FileItem getItemByName(List JavaDoc items, String JavaDoc name) {
266         Iterator JavaDoc itemsIt = items.iterator();
267         while (itemsIt.hasNext()) {
268             FileItem item = (FileItem)itemsIt.next();
269             if (item.getFieldName().equals(name))
270                 return item;
271         }
272         return null;
273     }
274 }
275
Popular Tags