1 package org.jahia.services.htmleditors.fckeditor; 2 3 import java.io.File ; 4 import java.io.IOException ; 5 import java.io.PrintWriter ; 6 import java.text.Collator ; 7 import java.util.Collections ; 8 import java.util.Iterator ; 9 import java.util.LinkedList ; 10 import java.util.List ; 11 12 import javax.servlet.ServletException ; 13 import javax.servlet.http.HttpServletRequest ; 14 import javax.servlet.http.HttpServletResponse ; 15 import javax.transaction.Status ; 16 17 import org.apache.commons.fileupload.DiskFileUpload; 18 import org.apache.commons.fileupload.FileItem; 19 import org.apache.commons.fileupload.FileUploadException; 20 import org.apache.commons.lang.StringEscapeUtils; 21 import org.jahia.params.ParamBean; 22 import org.jahia.services.webdav.DAVFileAccess; 23 import org.jahia.services.webdav.JahiaWebdavBaseService; 24 25 44 45 public class FCKeditorWebDAVConnector extends FCKeditorBaseConnector 46 { 47 private static class FileEntry implements Comparable 48 { 49 String name; 50 int size; 51 52 FileEntry(String fileName, int fileSize) 53 { 54 name = fileName; 55 size = fileSize; 56 } 57 58 63 public int compareTo(Object theO) 64 { 65 return COLLATOR.compare(name, ((FileEntry)theO).name); 66 } 67 68 } 69 70 private static class UploadResult 71 { 72 String newFileName; 73 String returnValue; 74 75 UploadResult(String retValue, String newName) 76 { 77 returnValue = retValue; 78 newFileName = newName; 79 } 80 81 } 82 83 static final Collator COLLATOR = Collator.getInstance(); 84 85 protected static String getExtension(String fileName) 86 { 87 return fileName.lastIndexOf(".") != -1 ? fileName.substring(fileName 88 .lastIndexOf(".") + 1) : ""; 89 } 90 91 protected static String getNameWithoutExtension(String fileName) 92 { 93 return fileName.lastIndexOf(".") != -1 ? fileName.substring(0, fileName 94 .lastIndexOf(".")) : fileName; 95 } 96 97 protected String createFolder(DAVFileAccess fileAccess, 98 String currentFolderStr, HttpServletRequest request, ParamBean jParams) 99 { 100 String retValue = "110"; if (fileAccess.hasPermission(DAVFileAccess.WRITE) 102 && fileAccess.isWriteable()) 103 { 104 String newFolderStr = request.getParameter("NewFolderName"); 105 String normalizedName = DAVFileAccess.normalizeDirName(newFolderStr); 106 DAVFileAccess existingDir = JahiaWebdavBaseService.getInstance() 107 .getDAVFileAccess(jParams, currentFolderStr + "/" + normalizedName); 108 if (existingDir != null && existingDir.isValid()) 109 { 110 retValue = existingDir.isCollection() ? "101" : "102"; 113 } 114 else 115 { 116 retValue = fileAccess.createCollection(newFolderStr) != null ? "0" 117 : "110"; 118 } 119 } 120 else 121 { 122 retValue = "103"; } 124 125 return retValue; 126 } 127 128 137 public void doGet(HttpServletRequest request, HttpServletResponse response) 138 throws ServletException , IOException 139 { 140 ParamBean jParams = getJahiaParamBean(request, response); 141 String rootUrl = getRootPathForSite(jParams); 142 String rootFolder = getRootFolderName(jParams); 143 144 String command = request.getParameter("Command"); 145 String type = request.getParameter("Type"); 146 String currentFolder = request.getParameter("CurrentFolder"); 147 String currentResource = request.getParameter("CurrentResource"); 148 149 if (logger.isDebugEnabled()) 150 logger.debug("Start performing FCKeditor command " + command 151 + " for resource type " + type + " and current folder " + currentFolder 152 + " and current resource " + currentResource); 153 154 StringBuffer outBuffer = new StringBuffer (1024); 155 outBuffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); 156 157 try 158 { 159 if ("GetStartFolders".equals(command)) 160 { 161 currentFolder = getStartFolder(rootUrl, rootFolder, currentResource, 164 jParams); 165 } 166 167 DAVFileAccess fileAccess = JahiaWebdavBaseService.getInstance() 168 .getDAVFileAccess(jParams, currentFolder); 169 170 boolean doRollback = false; 171 172 if (fileAccess != null 173 && fileAccess.getTransactionStatus() == Status.STATUS_NO_TRANSACTION) 174 fileAccess.beginTransaction(); 175 176 while (!fileAccess.isValid() && currentFolder.length() > 1 177 && currentFolder.lastIndexOf('/', currentFolder.length() - 2) > 0) 178 { 179 currentFolder = currentFolder.substring(0, currentFolder.lastIndexOf( 180 '/', currentFolder.length() - 2)) 181 + "/"; 182 183 fileAccess = JahiaWebdavBaseService.getInstance().getDAVFileAccess( 184 jParams, currentFolder); 185 } 186 187 outBuffer.append("<Connector command=\"").append(command).append( 188 "\" resourceType=\"").append(type).append("\">").append( 189 "<RootFolder path=\"").append(StringEscapeUtils.escapeXml(rootFolder)) 190 .append("\"/>").append("<CurrentFolder path=\"").append( 191 StringEscapeUtils.escapeXml(currentFolder)).append("\" url=\"") 192 .append(StringEscapeUtils.escapeXml(rootUrl + currentFolder)).append( 193 "\" root=\"").append(StringEscapeUtils.escapeXml(rootFolder)).append( 194 "\"/>"); 195 196 if ("GetFolders".equals(command)) 197 { 198 List resourceList = fileAccess != null 199 && fileAccess.hasPermission(DAVFileAccess.READ) ? fileAccess 200 .getChildren() : Collections.EMPTY_LIST; 201 202 getFolders(resourceList, rootFolder, jParams, outBuffer); 203 } 204 else if ("GetFoldersAndFiles".equals(command)) 205 { 206 List resourceList = fileAccess != null 207 && fileAccess.hasPermission(DAVFileAccess.READ) ? fileAccess 208 .getChildren() : Collections.EMPTY_LIST; 209 210 getFolders(resourceList, rootFolder, jParams, outBuffer); 211 getFiles(resourceList, type, rootFolder, jParams, outBuffer); 212 } 213 else if ("CreateFolder".equals(command)) 214 { 215 String retValue = createFolder(fileAccess, currentFolder, request, 216 jParams); 217 218 outBuffer.append("<Error number=\"").append(retValue).append("\"/>"); 219 220 if ("110".equals(retValue)) 221 doRollback = true; 222 } 223 224 outBuffer.append("</Connector>"); 225 226 if (doRollback) 227 fileAccess.rollbackTransaction(); 228 else 229 fileAccess.commitTransaction(); 230 } 231 catch (Exception ex) 232 { 233 logger.error("Error executing FCKeditor command " + command, ex); 234 } 235 finally 236 { 237 releaseResources(); 238 } 239 240 if (logger.isDebugEnabled()) 241 logger.debug("FCKeditor command result: " + outBuffer.toString()); 242 243 response.setContentType("text/xml; charset=UTF-8"); 244 response.setHeader("Cache-Control", "no-cache"); 245 PrintWriter out = response.getWriter(); 246 out.print(outBuffer.toString()); 247 out.flush(); 248 out.close(); 249 } 250 251 259 public void doPost(HttpServletRequest request, HttpServletResponse response) 260 throws ServletException , IOException 261 { 262 String commandStr = request.getParameter("Command"); 263 String typeStr = request.getParameter("Type"); 264 String currentFolderStr = request.getParameter("CurrentFolder"); 265 266 if (logger.isDebugEnabled()) 267 logger.debug("Start performing FCKeditor command " + commandStr 268 + " for resource type " + typeStr + " and current folder " 269 + currentFolderStr); 270 271 String retVal = "0"; 272 String newName = ""; 273 274 if (!commandStr.equals("FileUpload")) 275 { 276 retVal = "203"; 277 } 278 else 279 { 280 ParamBean jParams = getJahiaParamBean(request, response); 281 DAVFileAccess fileAccess = JahiaWebdavBaseService.getInstance() 282 .getDAVFileAccess(jParams, currentFolderStr); 283 284 if (fileAccess != null 285 && fileAccess.getTransactionStatus() == Status.STATUS_NO_TRANSACTION) 286 fileAccess.beginTransaction(); 287 288 try 289 { 290 UploadResult result = uploadFile(fileAccess, request, jParams); 291 retVal = result.returnValue; 292 newName = result.newFileName; 293 294 fileAccess.commitTransaction(); 295 } 296 catch (Exception ex) 297 { 298 logger 299 .error( 300 "Error while uploading file. Failed to process FCKeditor FileUpload command", 301 ex); 302 retVal = "203"; 303 304 if (fileAccess != null) 305 fileAccess.rollbackTransaction(); 306 } 307 finally 308 { 309 releaseResources(); 310 } 311 } 312 if (logger.isDebugEnabled()) 313 logger.debug("FCKeditor command result: " + retVal); 314 315 response.setContentType("text/html; charset=UTF-8"); 316 response.setHeader("Cache-Control", "no-cache"); 317 PrintWriter out = response.getWriter(); 318 out.print("<script type=\"text/javascript\">"); 319 out.print("window.parent.frames['frmUpload'].OnUploadCompleted("); 320 out.print(retVal); 321 out.print(",'"); 322 out.print(newName.length() > 0 ? newName.replaceAll("\'", "\\\\'") : ""); 323 out.print("');"); 324 out.print("</script>"); 325 out.flush(); 326 out.close(); 327 } 328 329 protected void getFiles(List resourceList, String typeStr, String rootFolder, 330 ParamBean jParams, StringBuffer buffer) 331 { 332 buffer.append("<Files>"); 333 List fileList = new LinkedList (); 334 335 for (Iterator iter = resourceList.iterator(); iter.hasNext();) 337 { 338 DAVFileAccess currentElement = (DAVFileAccess)iter.next(); 339 if (!currentElement.isCollection() 340 && currentElement.hasPermission(DAVFileAccess.READ) 341 && resourceTypeMatches(currentElement, typeStr) 342 && !skipFile(currentElement, rootFolder, jParams)) 343 { 344 fileList.add(new FileEntry(currentElement.getName(), 345 (int)(currentElement.getContentLength() / 1024))); 346 } 347 } 348 349 if (fileList.size() > 0) 351 Collections.sort(fileList); 352 353 for (Iterator iter = fileList.iterator(); iter.hasNext();) 355 { 356 FileEntry currentElement = (FileEntry)iter.next(); 357 buffer.append("<File name=\"").append( 358 StringEscapeUtils.escapeXml(currentElement.name)).append("\" size=\"") 359 .append(currentElement.size).append("\"/>"); 360 } 361 362 buffer.append("</Files>"); 363 } 364 365 protected void getFolders(List resourceList, String rootFolder, 366 ParamBean jParams, StringBuffer buffer) 367 { 368 buffer.append("<Folders>"); 369 List folderNames = new LinkedList (); 370 371 for (Iterator iter = resourceList.iterator(); iter.hasNext();) 373 { 374 DAVFileAccess currentElement = (DAVFileAccess)iter.next(); 375 if (currentElement.isCollection() 376 && currentElement.hasPermission(DAVFileAccess.READ) 377 && !skipFolder(currentElement, rootFolder, jParams)) 378 { 379 folderNames.add(currentElement.getName()); 380 } 381 } 382 383 if (folderNames.size() > 0) 385 Collections.sort(folderNames, COLLATOR); 386 387 for (Iterator iter = folderNames.iterator(); iter.hasNext();) 389 { 390 buffer.append("<Folder name=\"").append( 391 StringEscapeUtils.escapeXml((String )iter.next())).append("\"/>"); 392 } 393 394 buffer.append("</Folders>"); 395 } 396 397 protected String getRootFolderName(ParamBean jParams) 398 { 399 return "/"; 400 } 401 402 protected String getRootPathForSite(ParamBean jParams) 403 { 404 return new StringBuffer (32).append(jParams.getRequest().getContextPath()) 405 .append("/webdav/site/").append(jParams.getSiteKey()).toString(); 406 } 407 408 protected String getStartFolder(String rootPath, String rootFolder, 409 String currentResource, ParamBean jParams) 410 { 411 String currentFolder = rootFolder; 412 413 if (currentResource != null) 416 { 417 currentResource = currentResource.trim(); 418 if (currentResource.startsWith(rootPath + rootFolder)) 419 { 420 String relativeResource = currentResource 421 .substring((rootPath + rootFolder).length()); 422 423 if (relativeResource.charAt(relativeResource.length() - 1) != '/') 424 { 425 if (relativeResource.lastIndexOf('/') > 0) 426 { 427 relativeResource = relativeResource.substring(0, relativeResource 428 .lastIndexOf('/')) 429 + "/"; 430 } 431 else 432 { 433 relativeResource = ""; 434 } 435 } 436 437 currentFolder = rootFolder + relativeResource; 438 } 439 } 440 441 return currentFolder; 442 } 443 444 protected boolean resourceTypeMatches(DAVFileAccess resource, 445 String resourceType) 446 { 447 boolean matches = true; 448 if (resourceType != null && resourceType.length() > 0) 449 { 450 matches = false; 451 String contentType = resource.getContentType(); 452 if (contentType != null) 453 { 454 if ("Image".equals(resourceType)) 455 { 456 matches = contentType.regionMatches(true, 0, "image/", 0, "image/" 458 .length()); 459 } 460 else if ("File".equals(resourceType)) 461 { 462 matches = !contentType.regionMatches(true, 0, "image/", 0, "image/" 464 .length()); 465 } 466 else if ("Flash".equals(resourceType)) 467 { 468 matches = contentType.regionMatches(true, 0, 470 "application/x-shockwave-flash", 0, "application/x-shockwave-flash" 471 .length()); 472 } 473 else 474 matches = true; 475 } 476 } 477 478 return matches; 479 } 480 481 491 protected boolean skipFile(DAVFileAccess file, String rootFolder, 492 ParamBean jParams) 493 { 494 return false; 495 } 496 497 507 protected boolean skipFolder(DAVFileAccess folder, String rootFolder, 508 ParamBean jParams) 509 { 510 return false; 511 } 512 513 protected UploadResult uploadFile(DAVFileAccess currentDavDir, 514 HttpServletRequest request, ParamBean jParams) 515 throws FileUploadException, IOException 516 { 517 String retVal = "0"; 518 String newName = ""; 519 520 DiskFileUpload upload = new DiskFileUpload(); 522 523 File tmpDir = new File (jParams.settings().getTmpContentDiskPath()); 525 if (!tmpDir.exists()) 526 tmpDir.mkdir(); 527 528 upload.setRepositoryPath(tmpDir.getPath()); 529 upload.setSizeMax(jParams.settings().getJahiaFileUploadMaxSize()); 531 upload.setHeaderEncoding("UTF-8"); 533 534 List items = upload.parseRequest(request); 536 FileItem uploadedFile = null; 537 538 Iterator iter = items.iterator(); 540 while (iter.hasNext()) 541 { 542 FileItem item = (FileItem)iter.next(); 543 if (!item.isFormField() && "NewFile".equals(item.getFieldName())) 544 { 545 uploadedFile = item; 546 break; 547 } 548 } 549 550 if (uploadedFile.getSize() == 0) 551 { 552 return new UploadResult("202", ""); 554 } 555 556 String [] pathParts = uploadedFile.getName().replace('\\', '/').split("/"); 559 String fileName = pathParts[pathParts.length - 1]; 560 String fileNameWithoutExt = getNameWithoutExtension(fileName); 561 String fileExtension = getExtension(fileName); 562 String normalizedName = DAVFileAccess.normalizeFileName(fileName); 564 DAVFileAccess existingFile = JahiaWebdavBaseService 565 .getInstance() 566 .getDAVFileAccess(jParams, currentDavDir.getPath() + "/" + normalizedName); 567 int counter = 1; 568 while (existingFile != null && existingFile.isValid()) 571 { 572 newName = new StringBuffer (32).append(fileNameWithoutExt).append("(") 573 .append(counter).append(")").append(".").append(fileExtension) 574 .toString(); 575 normalizedName = DAVFileAccess.normalizeFileName(newName); 576 retVal = "201"; 577 existingFile = JahiaWebdavBaseService.getInstance().getDAVFileAccess( 578 jParams, currentDavDir.getPath() + "/" + normalizedName); 579 counter++; 580 } 581 582 String contentType = uploadedFile.getContentType() != null ? uploadedFile 585 .getContentType() : getServletContext().getMimeType(fileName); 586 587 currentDavDir 589 .uploadFile(newName.length() > 0 ? newName : fileName, uploadedFile 590 .getInputStream(), contentType, uploadedFile.getSize(), false); 591 592 uploadedFile.delete(); 594 595 return new UploadResult(retVal, newName); 596 } 597 598 } 599 | Popular Tags |