1 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 ; 35 import java.util.List ; 36 import java.util.Iterator ; 37 import java.util.Map ; 38 import java.util.Arrays ; 39 import java.io.IOException ; 40 import java.io.InputStream ; 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 uploadTempdir; 47 48 public AbstractDocumentHandler(Logger requestErrorLogger, int uploadThreshold, int uploadMaxSize, String uploadTempdir) { 49 this.requestErrorLogger = requestErrorLogger; 50 this.uploadThreshold = uploadThreshold; 51 this.uploadMaxSize = uploadMaxSize; 52 this.uploadTempdir = uploadTempdir; 53 } 54 55 58 protected void updateDocument(Document document, DocumentDocument.Document documentXml, List uploadedItems, 59 HttpResponse response, Repository repository) throws RepositoryException, DocumentTypeInconsistencyException, IOException , BadRequestException { 60 64 PartDocument.Part partsXml[] = documentXml.getParts().getPartArray(); 65 Part parts[] = document.getParts().getArray(); 66 67 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 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 createInputStream() throws IOException { 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 111 FieldDocument.Field fieldsXml[] = documentXml.getFields().getFieldArray(); 112 Field[] fields = document.getFields().getArray(); 113 114 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 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 value = FieldHelper.getFieldValueFromXml(valueType, fieldType.isMultiValue(), fieldXml); 132 133 if (document.hasField(fieldXml.getTypeId())) { 134 Field field = document.getField(fieldXml.getTypeId()); 135 if (!(fieldType.isMultiValue() ? Arrays.equals((Object [])field.getValue(), (Object [])value) : field.getValue().equals(value))) 137 document.setField(fieldXml.getTypeId(), value); 138 } else { 139 document.setField(fieldXml.getTypeId(), value); 140 } 141 } 142 143 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 DocumentDocument.Document.CustomFields.CustomField[] customFieldsXml = documentXml.getCustomFields().getCustomFieldArray(); 171 Map 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 value = (String )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 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 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 242 protected List parseMultipartRequest(HttpRequest request, HttpResponse response) throws IOException , BadRequestException { 243 HttpServletRequest 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 items, String name) { 266 Iterator 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 |