1 17 package org.alfresco.filesys.smb.server.repo; 18 19 import java.io.FileNotFoundException ; 20 import java.io.Serializable ; 21 import java.util.ArrayList ; 22 import java.util.Collections ; 23 import java.util.Date ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.Stack ; 27 import java.util.StringTokenizer ; 28 29 import org.alfresco.error.AlfrescoRuntimeException; 30 import org.alfresco.filesys.server.filesys.FileAttribute; 31 import org.alfresco.filesys.server.filesys.FileExistsException; 32 import org.alfresco.filesys.server.filesys.FileInfo; 33 import org.alfresco.filesys.server.filesys.FileName; 34 import org.alfresco.model.ContentModel; 35 import org.alfresco.service.cmr.dictionary.DictionaryService; 36 import org.alfresco.service.cmr.model.FileFolderService; 37 import org.alfresco.service.cmr.repository.ContentData; 38 import org.alfresco.service.cmr.repository.InvalidNodeRefException; 39 import org.alfresco.service.cmr.repository.MimetypeService; 40 import org.alfresco.service.cmr.repository.NodeRef; 41 import org.alfresco.service.cmr.repository.NodeService; 42 import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; 43 import org.alfresco.service.cmr.security.AccessStatus; 44 import org.alfresco.service.cmr.security.PermissionService; 45 import org.alfresco.service.namespace.QName; 46 import org.alfresco.util.SearchLanguageConversion; 47 import org.apache.commons.logging.Log; 48 import org.apache.commons.logging.LogFactory; 49 50 56 public class CifsHelper 57 { 58 private static Log logger = LogFactory.getLog(CifsHelper.class); 60 61 private DictionaryService dictionaryService; 63 private NodeService nodeService; 64 private FileFolderService fileFolderService; 65 private MimetypeService mimetypeService; 66 private PermissionService permissionService; 67 68 70 private boolean lockedFilesAsOffline; 71 72 75 public CifsHelper() 76 { 77 } 78 79 public void setDictionaryService(DictionaryService dictionaryService) 80 { 81 this.dictionaryService = dictionaryService; 82 } 83 84 public void setNodeService(NodeService nodeService) 85 { 86 this.nodeService = nodeService; 87 } 88 89 public void setFileFolderService(FileFolderService fileFolderService) 90 { 91 this.fileFolderService = fileFolderService; 92 } 93 94 public void setMimetypeService(MimetypeService mimetypeService) 95 { 96 this.mimetypeService = mimetypeService; 97 } 98 99 public void setPermissionService(PermissionService permissionService) 100 { 101 this.permissionService = permissionService; 102 } 103 104 109 public final void setMarkLockedFilesAsOffline(boolean ena) 110 { 111 lockedFilesAsOffline = ena; 112 } 113 114 119 public final boolean hasLockedFilesAsOffline() 120 { 121 return lockedFilesAsOffline; 122 } 123 124 130 public boolean isDirectory(NodeRef nodeRef) 131 { 132 QName nodeTypeQName = nodeService.getType(nodeRef); 133 if (dictionaryService.isSubClass(nodeTypeQName, ContentModel.TYPE_FOLDER)) 134 { 135 return true; 136 } 137 else if (dictionaryService.isSubClass(nodeTypeQName, ContentModel.TYPE_CONTENT)) 138 { 139 return false; 140 } 141 else 142 { 143 return false; 145 } 146 } 147 148 157 public FileInfo getFileInformation(NodeRef pathRootNodeRef, String path) throws FileNotFoundException 158 { 159 NodeRef nodeRef = getNodeRef(pathRootNodeRef, path); 161 162 FileInfo fileInfo = getFileInformation(nodeRef); 163 164 return fileInfo; 165 } 166 167 178 public FileInfo getFileInformation(NodeRef nodeRef) throws FileNotFoundException 179 { 180 org.alfresco.service.cmr.model.FileInfo fileFolderInfo = fileFolderService.getFileInfo(nodeRef); 182 183 FileInfo fileInfo = new FileInfo(); 185 186 int fileAttributes = 0; 188 fileInfo.setFileAttributes(fileAttributes); 189 190 if (fileFolderInfo.isFolder()) 191 { 192 fileAttributes |= FileAttribute.Directory; 194 fileInfo.setFileAttributes(fileAttributes); 195 } 196 else 197 { 198 Map <QName, Serializable > nodeProperties = fileFolderInfo.getProperties(); 199 200 202 ContentData contentData = (ContentData) nodeProperties.get(ContentModel.PROP_CONTENT); 203 long size = 0L; 204 if (contentData != null) 205 { 206 size = contentData.getSize(); 207 } 208 fileInfo.setSize(size); 209 210 212 if ( size > 0) 213 fileInfo.setAllocationSize((size + 512L) & 0xFFFFFFFFFFFFFE00L); 214 215 217 if ( hasLockedFilesAsOffline()) 218 { 219 String lockTypeStr = (String ) nodeProperties.get(ContentModel.PROP_LOCK_TYPE); 220 221 if ( lockTypeStr != null) 222 { 223 225 fileInfo.setFileAttributes(fileInfo.getFileAttributes() + FileAttribute.NTOffline); 226 } 227 } 228 } 229 230 Date createdDate = fileFolderInfo.getCreatedDate(); 232 if (createdDate != null) 233 { 234 long created = DefaultTypeConverter.INSTANCE.longValue(createdDate); 235 fileInfo.setCreationDateTime(created); 236 } 237 Date modifiedDate = fileFolderInfo.getModifiedDate(); 239 if (modifiedDate != null) 240 { 241 long modified = DefaultTypeConverter.INSTANCE.longValue(modifiedDate); 242 fileInfo.setModifyDateTime(modified); 243 fileInfo.setAccessDateTime(modified); 244 } 245 String name = fileFolderInfo.getName(); 247 if (name != null) 248 { 249 fileInfo.setFileName(name); 250 } 251 252 254 if ( permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED) 255 fileInfo.setFileAttributes(fileInfo.getFileAttributes() + FileAttribute.ReadOnly); 256 257 259 if ( fileInfo.getFileAttributes() == 0) 260 fileInfo.setFileAttributes(FileAttribute.NTNormal); 261 262 264 if (logger.isDebugEnabled()) 265 { 266 logger.debug("Fetched file info: \n" + 267 " info: " + fileInfo); 268 } 269 270 272 return fileInfo; 273 } 274 275 287 public NodeRef createNode(NodeRef rootNodeRef, String path, boolean isFile) throws FileExistsException 288 { 289 StringTokenizer tokenizer = new StringTokenizer (path, FileName.DOS_SEPERATOR_STR, false); 291 List <String > folderPathElements = new ArrayList <String >(10); 292 String name = null; 293 while (tokenizer.hasMoreTokens()) 294 { 295 String pathElement = tokenizer.nextToken(); 296 297 if (!tokenizer.hasMoreTokens()) 298 { 299 name = pathElement; 301 } 302 else 303 { 304 folderPathElements.add(pathElement); 306 } 307 } 308 NodeRef parentFolderNodeRef = rootNodeRef; 310 if (folderPathElements.size() > 0) 311 { 312 parentFolderNodeRef = fileFolderService.makeFolders( 313 rootNodeRef, 314 folderPathElements, 315 ContentModel.TYPE_FOLDER).getNodeRef(); 316 } 317 QName typeQName = isFile ? ContentModel.TYPE_CONTENT : ContentModel.TYPE_FOLDER; 319 try 320 { 321 NodeRef nodeRef = fileFolderService.create(parentFolderNodeRef, name, typeQName).getNodeRef(); 322 323 if (logger.isDebugEnabled()) 325 { 326 logger.debug("Created node: \n" + 327 " device root: " + rootNodeRef + "\n" + 328 " path: " + path + "\n" + 329 " is file: " + isFile + "\n" + 330 " new node: " + nodeRef); 331 } 332 return nodeRef; 333 } 334 catch (org.alfresco.service.cmr.model.FileExistsException e) 335 { 336 throw new FileExistsException(path); 337 } 338 } 339 340 private void addDescendents(List <NodeRef> pathRootNodeRefs, Stack <String > pathElements, List <NodeRef> results) 341 { 342 if (pathElements.isEmpty()) 343 { 344 results.addAll(pathRootNodeRefs); 347 return; 348 } 349 350 String pathElement = pathElements.pop(); 352 353 for (NodeRef pathRootNodeRef : pathRootNodeRefs) 355 { 356 if (results.contains(pathRootNodeRef)) 358 { 359 continue; 360 } 361 List <NodeRef> directDescendents = getDirectDescendents(pathRootNodeRef, pathElement); 363 addDescendents(directDescendents, pathElements, results); 365 } 366 367 pathElements.push(pathElement); 369 } 370 371 378 private List <NodeRef> getDirectDescendents(NodeRef pathRootNodeRef, String pathElement) 379 { 380 if (logger.isDebugEnabled()) 381 { 382 logger.debug("Getting direct descendents: \n" + 383 " Path Root: " + pathRootNodeRef + "\n" + 384 " Path Element: " + pathElement); 385 } 386 String escapedPathElement = SearchLanguageConversion.convertCifsToLucene(pathElement); 388 List <org.alfresco.service.cmr.model.FileInfo> childInfos = fileFolderService.search( 390 pathRootNodeRef, 391 escapedPathElement, 392 false); 393 List <NodeRef> results = new ArrayList <NodeRef>(childInfos.size()); 395 for (org.alfresco.service.cmr.model.FileInfo info : childInfos) 396 { 397 results.add(info.getNodeRef()); 398 } 399 return results; 401 } 402 403 416 public List <NodeRef> getNodeRefs(NodeRef pathRootNodeRef, String path) 417 { 418 StringTokenizer tokenizer = new StringTokenizer (path, FileName.DOS_SEPERATOR_STR, false); 421 String [] tokens = new String [tokenizer.countTokens()]; 422 int count = 0; 423 while(tokenizer.hasMoreTokens()) 424 { 425 tokens[count] = tokenizer.nextToken(); 426 count++; 427 } 428 Stack <String > pathElements = new Stack <String >(); 429 for (int i = tokens.length - 1; i >= 0; i--) 430 { 431 pathElements.push(tokens[i]); 432 } 433 434 List <NodeRef> pathRootNodeRefs = Collections.singletonList(pathRootNodeRef); 436 437 List <NodeRef> results = new ArrayList <NodeRef>(5); 439 440 addDescendents(pathRootNodeRefs, pathElements, results); 442 443 if (logger.isDebugEnabled()) 445 { 446 logger.debug("Retrieved node references for path: \n" + 447 " path root: " + pathRootNodeRef + "\n" + 448 " path: " + path + "\n" + 449 " results: " + results); 450 } 451 return results; 452 } 453 454 461 public NodeRef getNodeRef(NodeRef pathRootNodeRef, String path) throws FileNotFoundException 462 { 463 List <NodeRef> nodeRefs = getNodeRefs(pathRootNodeRef, path); 465 if (nodeRefs.size() == 0) 466 { 467 throw new FileNotFoundException (path); 468 } 469 else if (nodeRefs.size() > 1) 470 { 471 logger.warn("Multiple matching nodes: \n" + 472 " search root: " + pathRootNodeRef + "\n" + 473 " path: " + path); 474 } 475 NodeRef nodeRef = nodeRefs.get(0); 477 return nodeRef; 479 } 480 481 487 public void relinkNode(NodeRef tempNodeRef, NodeRef nodeToMoveRef, NodeRef newParentNodeRef, String newName) 488 throws FileNotFoundException , FileExistsException 489 { 490 org.alfresco.service.cmr.model.FileInfo tempFileInfo = fileFolderService.getFileInfo(tempNodeRef); 492 org.alfresco.service.cmr.model.FileInfo fileToMoveInfo = fileFolderService.getFileInfo(nodeToMoveRef); 493 494 String tempName = tempFileInfo.getName(); 496 497 try 498 { 499 fileFolderService.rename(tempNodeRef, newName); 501 fileFolderService.rename(nodeToMoveRef, tempName); 503 } 504 catch (org.alfresco.service.cmr.model.FileNotFoundException e) 505 { 506 throw new FileNotFoundException (e.getMessage()); 507 } 508 catch (org.alfresco.service.cmr.model.FileExistsException e) 509 { 510 throw new FileExistsException(e.getMessage()); 511 } 512 513 if (!tempFileInfo.isFolder() && !fileToMoveInfo.isFolder()) 514 { 515 ContentData oldContentData = tempFileInfo.getContentData(); 517 if (oldContentData == null) 518 { 519 String mimetype = mimetypeService.guessMimetype(tempName); 520 oldContentData = ContentData.setMimetype(null, mimetype); 521 } 522 523 ContentData newContentData = fileToMoveInfo.getContentData(); 524 525 527 String mimetype = mimetypeService.guessMimetype(newName); 528 newContentData = ContentData.setMimetype(newContentData, mimetype); 529 530 nodeService.setProperty(tempNodeRef, ContentModel.PROP_CONTENT, newContentData); 531 nodeService.setProperty(nodeToMoveRef, ContentModel.PROP_CONTENT, oldContentData); 532 } 533 } 534 535 543 public void move(NodeRef nodeToMoveRef, NodeRef newParentNodeRef, String newName) throws FileExistsException 544 { 545 try 546 { 547 fileFolderService.move(nodeToMoveRef, newParentNodeRef, newName); 548 } 549 catch (org.alfresco.service.cmr.model.FileExistsException e) 550 { 551 throw new FileExistsException(newName); 552 } 553 catch (Throwable e) 554 { 555 throw new AlfrescoRuntimeException("Move failed: \n" + 556 " node to move: " + nodeToMoveRef + "\n" + 557 " new parent: " + newParentNodeRef + "\n" + 558 " new name: " + newName, 559 e); 560 } 561 } 562 563 570 public String getFileName(NodeRef node) 571 { 572 String fname = null; 573 574 try 575 { 576 fname = (String ) nodeService.getProperty( node, ContentModel.PROP_NAME); 577 } 578 catch (InvalidNodeRefException ex) 579 { 580 } 581 582 return fname; 583 } 584 } 585 | Popular Tags |