1 20 package org.openi.web.controller.admin; 21 22 import org.apache.log4j.Logger; 23 import org.openi.project.DirectoryLister; 24 import org.openi.project.ProjectContext; 25 import org.openi.security.Permission; 26 import org.openi.util.*; 27 import org.openi.xml.*; 28 import org.openi.xml.BeanStorage; 29 import org.springframework.validation.BindException; 30 import org.springframework.validation.Errors; 31 import org.springframework.web.servlet.ModelAndView; 32 import org.springframework.web.servlet.mvc.SimpleFormController; 33 import java.io.*; 34 import java.util.*; 35 import javax.servlet.http.HttpServletRequest ; 36 import javax.servlet.http.HttpServletResponse ; 37 import javax.servlet.http.HttpSession ; 38 39 40 46 public class ManageFilesFormController extends SimpleFormController { 47 public static final String NEW_FOLDER_VIEW = "newFolderConfirmView"; 48 public static final String RENAME_FOLDER_FILE_VIEW = "renameFileConfirmView"; 49 public static final String DELETE_FOLDERFILE_VIEW = "manageFilesConfirmView"; 50 public static final String MAIN_VIEW = "manageFilesFormView"; 51 public static final String EDIT_FILE_VIEW = "editFileFormView"; 52 53 private static Logger logger = Logger.getLogger(ManageFilesFormController.class); 54 private ProjectContext context = null; 55 private Folder root = null; 56 private String xslTemplate; 57 private List editableFileTypes; 58 59 68 protected Object formBackingObject(HttpServletRequest request) 69 throws Exception { 70 context = (ProjectContext) request.getSession() 71 .getAttribute("projectContext"); 72 73 Map model; 74 75 try { 76 model = new HashMap(); 77 78 List modules; 79 modules = context.getProjectSubDirs(); 80 81 85 Folder folder; 86 folder = DirectoryLister.buildFolderList(context.getProjectDirectory(), 87 modules, true); 88 89 setupEditableFlag(folder); 90 91 root = folder; 92 93 BeanStorage store = new BeanStorage(); 94 String folderXML = store.toXmlString(folder); 95 96 if ((getXslTemplate() == null) || (getXslTemplate() == "")) { 97 throw new IOException( 98 "xsl template file is not configured properly"); 99 } 100 101 String xsl = Util.getFileContents(this.getServletContext() 102 .getRealPath(getXslTemplate())); 103 String result = XMLTransformer.transform(xsl, folderXML); 104 model.put("FolderXML", result); 105 106 return model; 107 } catch (Exception e) { 108 logger.error("Exception:", e); 109 throw e; 110 } 111 } 112 113 private void setupEditableFlag(Folder folder) { 114 if (folder != null) { 115 Collection children = folder.getChildren(); 116 if (children != null) { 117 Iterator iter = children.iterator(); 118 while (iter.hasNext()) { 119 Object item = iter.next(); 120 if (item instanceof FileItem) { 121 FileItem fileItem = (FileItem) item; 122 fileItem.setType(isEditableFile(fileItem.getPath()) ? 123 "text" : ""); 124 } else if (item instanceof Folder) 125 setupEditableFlag((Folder) item); 126 } 127 } 128 } 129 } 130 131 private boolean isEditableFile(String name ) { 132 if( editableFileTypes == null || name == null || "".equals(name)) 133 return false; 134 int index = name.lastIndexOf("."); 135 if(index <= 0) 136 return false; 137 138 139 String extension = name.substring(index); 140 if(editableFileTypes.contains(extension.toLowerCase())) 141 return true; 142 else 143 return false; 144 } 145 146 156 protected ModelAndView onSubmit(HttpServletRequest request, 157 HttpServletResponse response, Object command, BindException errors) 158 throws Exception { 159 try { 160 String action = request.getParameter("action"); 161 162 if ("Rename".equals(action)) { 163 return handleRename(request, response, command, errors); 164 } else if ("Delete".equals(action)) { 165 return handleDelete(request, response, command, errors); 166 } else if ("Create".equals(action)) { 167 return handleCreate(request, response, command, errors); 168 } else if ("Cancel".equals(action)) { 169 return handleCancel(request, response, command, errors); 170 } else if ("Save".equals(action)) { 171 return handleSaveFile(request, response, command, errors); 172 } else { 173 Enumeration params = request.getParameterNames(); 174 175 while (params.hasMoreElements()) { 176 String param = params.nextElement().toString(); 177 String path = null; 178 String theaction = null; 179 String actionpath = null; 180 181 if (param.startsWith("newaction::")) { 182 theaction = "new"; 183 actionpath = "newaction::"; 184 } else if (param.startsWith("deleteaction::")) { 185 theaction = "delete"; 186 actionpath = "deleteaction::"; 187 } else if(param.startsWith("editaction::")) { 188 theaction = "edit"; 189 actionpath = "editaction::"; 190 } else if (param.startsWith("renameaction::")) { 191 theaction = "rename"; 192 actionpath = "renameaction::"; 193 } 194 195 if (theaction != null) { 196 path = param.substring(actionpath.length()); 197 198 int index = path.endsWith(".x") ? path.lastIndexOf(".x") : -1; 199 200 if (index == -1) { 201 index = path.endsWith(".y")? path.lastIndexOf(".y"): -1; 202 } 203 204 if (index != -1) { 205 path = path.substring(0, index); 206 } 207 208 return handleClick(theaction, path, request, response, 209 command, errors); 210 } 211 } 212 } 213 214 return super.onSubmit(request, response, command, errors); 215 } catch (Exception e) { 216 logger.error("Exception:", e); 217 throw e; 218 } 219 } 220 221 232 protected ModelAndView handleClick(String action, String path, 233 HttpServletRequest request, HttpServletResponse response, 234 Object command, BindException errors) throws Exception { 235 Map model = (Map) command; 236 String fullpath = context.resolvePathWithProjectDir(path); 237 238 File dir = new File(fullpath); 239 String view = DELETE_FOLDERFILE_VIEW; 240 241 if (!dir.exists()) { 242 logger.info(path + " does not exist"); 243 errors.reject("pathdoesnotexist.message"); 244 } 245 246 if (!context.isPathBeneathProjectDir(fullpath)) { 247 errors.reject("outsideProjectDirError.message"); 248 } 249 250 if ("delete".equals(action)) { 251 view = DELETE_FOLDERFILE_VIEW; 252 253 List files = new LinkedList(); 254 List folders = new LinkedList(); 255 256 if (dir.isFile()) { 257 logger.info("File is about to delete"); 258 files.add(path); 259 } else if (dir.isDirectory()) { 260 folders.add(path); 261 262 Folder folder = Folder.findChildFolder(path, root); 264 265 if (folder != null) { 266 logger.info("Found folder:" + folder.getDisplayName()); 267 268 if ((folder.getChildren() != null) 269 && (folder.getChildren().size() > 0)) { 270 Folder.buildChildList(folder, folders, files); 271 } else { 272 files = null; 273 } 274 } else { 275 errors.reject("direrror.message"); 278 } 279 } 280 281 model.put("foldersList", folders); 282 model.put("filesList", files); 283 model.put("selectedPath", path); 284 } else if ("new".equals(action)) { 285 view = NEW_FOLDER_VIEW; 286 model.put("selectedPath", path); 287 } else if ("rename".equals(action)) { 288 view = RENAME_FOLDER_FILE_VIEW; 289 model.put("selectedPath", path); 290 path = path.substring(0, path.length() - dir.getName().length() - 1); 291 model.put("parentPath", path); 292 model.put("fileType", dir.isDirectory() ? "dir" : "file"); 293 model.put("fileName", dir.getName()); 294 } else if ("edit".equals(action)) { 295 File file = new File(fullpath); 296 if(!file.isFile() || ! isEditableFile(path)) { 297 errors.reject("notAEditableFile.message"); 298 } else { 299 model.put("textContent", Util.getFileContents(fullpath)); 300 model.put("selectedPath", path); 301 view = EDIT_FILE_VIEW; 302 } 303 } 304 305 if (errors.hasErrors()) { 306 return showForm(request, errors, MAIN_VIEW, model); 307 } else { 308 return new ModelAndView(view, "model", model); 309 } 310 } 311 312 322 protected ModelAndView handleCreate(HttpServletRequest request, 323 HttpServletResponse response, Object command, BindException errors) 324 throws Exception { 325 326 Map model = (Map) command; 327 328 String folderName = request.getParameter("folderName"); 329 String selectedPath = request.getParameter("selectedPath"); 330 logger.info("Creating folder:" + folderName + " on " + selectedPath); 331 model.put("selectedPath", selectedPath); 332 333 if ((selectedPath == null) || (selectedPath == "")) { 334 logger.info("Empty folder name"); 335 errors.reject("emptyFolderName.message"); 336 } else if (!context.isPathBeneathProjectDir( 337 context.resolvePathWithProjectDir(selectedPath))) { 338 errors.reject("outsideProjectDirError.message"); 339 } else if (!validateName(folderName, true)) { 340 errors.reject("invalidNameError.message"); 341 } else { 342 File file = new File(context.resolvePathWithProjectDir(selectedPath + "/" + folderName)); 343 if (file.exists()) { 344 errors.reject("alreadyExists.message"); 345 } else if (!context.addSubFolder(selectedPath, folderName)) { 346 logger.info("Could not create folder:" + folderName); 347 errors.reject("createError.message"); 348 } 349 } 350 351 if (errors.hasErrors()) { 352 model.put("selectedPath", selectedPath); 353 model.put("folderName", folderName); 354 355 return showForm(request, errors, NEW_FOLDER_VIEW, model); 356 } else { 357 return new ModelAndView(getSuccessView()); 358 } 359 } 360 361 371 protected ModelAndView handleDelete(HttpServletRequest request, 372 HttpServletResponse response, Object command, BindException errors) 373 throws Exception { 374 375 Map model = (Map) command; 376 String path = request.getParameter("selectedPath"); 377 String [] files = request.getParameterValues("filesList"); 378 379 if ((path == null) || (path == "")) { 380 errors.reject("selectFile.message"); 381 } 382 383 if (!context.isPathBeneathProjectDir(context.resolvePathWithProjectDir( 384 path))) { 385 errors.reject("outsideProjectDirError.message"); 386 } else { 387 if (!context.removeFileFolder(path)) { 388 errors.reject("fileDeleteError"); 389 } 390 } 391 392 if (errors.hasErrors()) { 393 model.put("filesList", files); 394 model.put("foldersList", request.getParameterValues("foldersList")); 395 model.put("selectedPath", path); 396 397 return showForm(request, errors, DELETE_FOLDERFILE_VIEW, model); 398 } else { 399 return new ModelAndView(getSuccessView()); 400 } 401 } 402 403 412 protected ModelAndView handleRename(HttpServletRequest request, 413 HttpServletResponse response, Object command, BindException errors) 414 throws Exception { 415 Map model = (Map) command; 416 String path = request.getParameter("selectedPath"); 417 String newname = request.getParameter("folderName"); 418 419 if (!context.isPathBeneathProjectDir(context.resolvePathWithProjectDir( 420 path))) { 421 errors.reject("outsideProjectDirError.message"); 422 } else { 423 if ((newname == null) || (newname == "")) { 424 errors.reject("emptyFolderName.message"); 425 } else { 426 File file = new File(context.resolvePathWithProjectDir(path)); 427 428 if (!file.exists()) { 429 errors.reject("pathdoesnotexist.message"); 430 } else if (!validateName(newname, file.isDirectory())) { 431 errors.reject("invalidNameError.message"); 432 } else { 433 newname = newname.replace(' ', '_'); 434 File newfile = new File(file.getParentFile().getPath() 435 + "/" + newname); 436 437 if (newfile.exists()) { 438 errors.reject("alreadyExists.message"); 439 } else if (!context.renameFileFolder(path, newname)) { 440 errors.reject("renameError.message"); 441 } 442 } 443 } 444 } 445 446 if (errors.hasErrors()) { 447 model.put("selectedPath", path); 448 449 File dir = new File(path); 450 path = path.substring(0, path.length() - dir.getName().length() - 1); 451 model.put("parentPath", path); 452 model.put("fileType", dir.isDirectory() ? "dir" : "file"); 453 model.put("fileName", newname); 454 455 return showForm(request, errors, RENAME_FOLDER_FILE_VIEW, model); 456 } else { 457 return new ModelAndView(getSuccessView()); 458 } 459 } 460 461 470 protected ModelAndView handleSaveFile(HttpServletRequest request, 471 HttpServletResponse response, 472 Object command, BindException errors) throws 473 Exception { 474 475 476 String path = request.getParameter("selectedPath"); 477 String content = request.getParameter("textContent"); 478 479 if (!context.isPathBeneathProjectDir(context.resolvePathWithProjectDir( 480 path))) { 481 errors.reject("outsideProjectDirError.message"); 482 } else { 483 if (content == null) { 484 logger.debug("content is null"); 485 errors.reject("nullFileContent.message"); 486 } else { 487 File file = new File(context.resolvePathWithProjectDir(path)); 488 489 if (!file.exists()) { 490 logger.debug("path does not exists"); 491 errors.reject("pathdoesnotexist.message"); 492 } else { 493 context.saveTextFileContent(path, content); 494 } 495 } 496 } 497 return new ModelAndView(getSuccessView()); 498 } 499 500 510 protected ModelAndView handleCancel(HttpServletRequest request, 511 HttpServletResponse response, Object command, BindException errors) 512 throws Exception { 513 return new ModelAndView(getSuccessView()); 515 } 516 517 private boolean validateName(String name, boolean isFolder) { 518 if ((name == null) || ("".equals(name))) { 519 return false; 520 } 521 522 if (name.indexOf("..") != -1) { 523 return false; 524 } 525 526 if (((name.indexOf("/") != -1) || (name.indexOf("\\") != -1))) { 529 return false; 530 } 531 boolean alphaContained = false; 532 for (int i = 0; i < name.length(); i++) { 533 char c = name.charAt(i); 534 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { 535 alphaContained = true; 536 break; 537 } 538 } 539 540 return alphaContained; 541 } 542 543 549 public void setXslTemplate(String xslTemplate) { 550 this.xslTemplate = xslTemplate; 551 } 552 553 public void setEditableFileTypes(List editableFileTypes) { 554 this.editableFileTypes = editableFileTypes; 555 } 556 557 public String getXslTemplate() { 558 return xslTemplate; 559 } 560 561 public List getEditableFileTypes() { 562 return editableFileTypes; 563 } 564 565 566 570 public Folder getFolderRoot() { 571 return this.root; 572 } 573 } 574 | Popular Tags |