/** * Check if the file can be opened depending on any current file opens and the sharing mode of the * first file open * * @param params FileOpenParams * @return boolean */ public final boolean allowsOpen(FileOpenParams params) { // If the file is not currently open then allow the file open if (getOpenCount() == 0) return true; // Check the shared access mode if (getSharedAccess() == SharingMode.READWRITE && params.getSharedAccess() == SharingMode.READWRITE) return true; else if ((getSharedAccess() & SharingMode.READ) != 0 && params.isReadOnlyAccess()) return true; else if ((getSharedAccess() & SharingMode.WRITE) != 0 && params.isWriteOnlyAccess()) return true; // Sharing violation, do not allow the file open return false; }
@Override public void createDirectory(SrvSession sess, TreeConnection tree, FileOpenParams params) throws IOException { try { FileFilterMode.setClient(ClientHelper.getClient(sess)); try { diskInterface.createDirectory(sess, tree, params); } finally { FileFilterMode.clearClient(); } } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) { throw new AccessDeniedException("Unable to create directory " + params.getPath(), ade); } }
@Override public NetworkFile createFile(SrvSession sess, TreeConnection tree, FileOpenParams params) throws IOException { ContentContext tctx = (ContentContext) tree.getContext(); FileAccessToken token = null; if (tctx.hasStateCache()) { FileStateCache cache = tctx.getStateCache(); FileState fstate = tctx.getStateCache().findFileState(params.getPath(), true); token = cache.grantFileAccess(params, fstate, FileStatus.NotExist); if (logger.isDebugEnabled()) { logger.debug("create file created lock token:" + token); } } try { NetworkFile newFile = diskInterface.createFile(sess, tree, params); if (tctx.hasStateCache()) { FileState fstate = tctx.getStateCache().findFileState(params.getPath(), true); fstate.setProcessId(params.getProcessId()); fstate.setSharedAccess(params.getSharedAccess()); // Indicate that the file is open fstate.setFileStatus( newFile.isDirectory() ? FileStatus.DirectoryExists : FileStatus.FileExists); fstate.setAllocationSize(params.getAllocationSize()); if (newFile instanceof NodeRefNetworkFile) { NodeRefNetworkFile x = (NodeRefNetworkFile) newFile; x.setFileState(fstate); } if (newFile instanceof TempNetworkFile) { TempNetworkFile x = (TempNetworkFile) newFile; x.setFileState(fstate); } } if (newFile instanceof NodeRefNetworkFile) { NodeRefNetworkFile x = (NodeRefNetworkFile) newFile; x.setProcessId(params.getProcessId()); x.setAccessToken(token); } if (newFile instanceof TempNetworkFile) { TempNetworkFile x = (TempNetworkFile) newFile; x.setAccessToken(token); } return newFile; } catch (IOException ie) { if (logger.isDebugEnabled()) { logger.debug("create file exception caught", ie); } if (tctx.hasStateCache() && token != null) { FileStateCache cache = tctx.getStateCache(); FileState fstate = tctx.getStateCache().findFileState(params.getPath(), false); if (fstate != null && token != null) { if (logger.isDebugEnabled()) { logger.debug("create file release lock token:" + token); } cache.releaseFileAccess(fstate, token); } } throw ie; } }
@Override public NetworkFile openFile(SrvSession sess, TreeConnection tree, FileOpenParams params) throws IOException { ContentContext tctx = (ContentContext) tree.getContext(); String path = params.getPath(); FileAccessToken token = null; if (tctx.hasStateCache()) { if (!params.isDirectory()) { FileStateCache cache = tctx.getStateCache(); FileState fstate = tctx.getStateCache().findFileState(params.getPath(), true); token = cache.grantFileAccess(params, fstate, FileStatus.Unknown); if (logger.isDebugEnabled()) { logger.debug("open file created lock token:" + token); } } } try { NetworkFile openFile = diskInterface.openFile(sess, tree, params); if (openFile instanceof ContentNetworkFile) { ContentNetworkFile x = (ContentNetworkFile) openFile; x.setProcessId(params.getProcessId()); x.setAccessToken(token); if (tctx.hasStateCache()) { FileState fstate = tctx.getStateCache().findFileState(path, true); x.setFileState(fstate); fstate.setProcessId(params.getProcessId()); fstate.setSharedAccess(params.getSharedAccess()); fstate.setFileStatus(FileStatus.FileExists); } } if (openFile instanceof TempNetworkFile) { TempNetworkFile x = (TempNetworkFile) openFile; x.setAccessToken(token); // x.setProcessId( params.getProcessId()); if (tctx.hasStateCache()) { FileState fstate = tctx.getStateCache().findFileState(path, true); x.setFileState(fstate); fstate.setFileStatus(FileStatus.FileExists); fstate.setProcessId(params.getProcessId()); fstate.setSharedAccess(params.getSharedAccess()); } } if (openFile instanceof AlfrescoFolder) { AlfrescoFolder x = (AlfrescoFolder) openFile; // x.setProcessId( param.getProcessId()); if (tctx.hasStateCache()) { FileState fstate = tctx.getStateCache().findFileState(path, true); x.setFileState(fstate); fstate.setFileStatus(FileStatus.DirectoryExists); fstate.setProcessId(params.getProcessId()); fstate.setSharedAccess(params.getSharedAccess()); } } return openFile; } catch (IOException ie) { if (logger.isDebugEnabled()) { logger.debug("open file exception caught", ie); } if (tctx.hasStateCache() && token != null) { FileStateCache cache = tctx.getStateCache(); FileState fstate = tctx.getStateCache().findFileState(params.getPath(), false); if (fstate != null) { if (logger.isDebugEnabled()) { logger.debug("open file release lock token:" + token); } cache.releaseFileAccess(fstate, token); } } throw ie; } }
@Override public NetworkFile openFile(SrvSession sess, TreeConnection tree, FileOpenParams param) throws IOException { String path = param.getPath(); boolean truncate = param.isOverwrite(); if (logger.isDebugEnabled()) { int sharedAccess = param.getSharedAccess(); String strSharedAccess = SharingMode.getSharingModeAsString(sharedAccess); logger.debug( "openFile:" + path + ", isDirectory: " + param.isDirectory() + ", isStream: " + param.isStream() + ", readOnlyAccess: " + param.isReadOnlyAccess() + ", readWriteAccess: " + param.isReadWriteAccess() + ", writeOnlyAccess:" + param.isWriteOnlyAccess() + ", attributesOnlyAccess:" + param.isAttributesOnlyAccess() + ", sequentialAccessOnly:" + param.isSequentialAccessOnly() + ", writeThrough:" + param.isWriteThrough() + ", truncate:" + truncate + ", requestBatchOpLock:" + param.requestBatchOpLock() + ", requestExclusiveOpLock:" + param.requestExclusiveOpLock() + ", isDeleteOnClose:" + param.isDeleteOnClose() + ", allocationSize:" + param.getAllocationSize() + ", sharedAccess: " + strSharedAccess + ", openAction: " + param.getOpenAction() + param); } ContentContext tctx = (ContentContext) tree.getContext(); NodeRef rootNode = tctx.getRootNode(); DriverState driverState = getDriverState(sess); String[] paths = FileName.splitPath(path); String folder = paths[0]; String file = paths[1]; EvaluatorContext ctx = getEvaluatorContext(driverState, folder); OpenFileMode openMode = OpenFileMode.READ_ONLY; if (param.isAttributesOnlyAccess()) { openMode = OpenFileMode.ATTRIBUTES_ONLY; } else if (param.isReadWriteAccess()) { openMode = OpenFileMode.READ_WRITE; } else if (param.isWriteOnlyAccess()) { openMode = OpenFileMode.WRITE_ONLY; } else if (param.isReadOnlyAccess()) { openMode = OpenFileMode.READ_ONLY; } else if (param.isDeleteOnClose()) { if (logger.isDebugEnabled()) { logger.debug("open file has delete on close"); } openMode = OpenFileMode.DELETE; } try { Operation o = new OpenFileOperation(file, openMode, truncate, rootNode, path); Command c = ruleEvaluator.evaluate(ctx, o); Object ret = commandExecutor.execute(sess, tree, c); if (ret != null && ret instanceof NetworkFile) { NetworkFile x = (NetworkFile) ret; if (logger.isDebugEnabled()) { logger.debug("returning open file: for path:" + path + ", ret:" + ret); } return x; } else { // Error - contact broken logger.error( "contract broken - NetworkFile not returned. " + ret == null ? "Return value is null" : ret); return null; } } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) { throw new AccessDeniedException("Unable to open file " + param.getPath(), ade); } // return diskInterface.openFile(sess, tree, params); } // End of OpenFile
@Override public NetworkFile createFile(SrvSession sess, TreeConnection tree, FileOpenParams params) throws IOException { try { int attr = params.getAttributes(); if (logger.isDebugEnabled()) { int sharedAccess = params.getSharedAccess(); String strSharedAccess = SharingMode.getSharingModeAsString(sharedAccess); logger.debug( "createFile:" + params.getPath() + ", isDirectory: " + params.isDirectory() + ", isStream: " + params.isStream() + ", readOnlyAccess: " + params.isReadOnlyAccess() + ", readWriteAccess: " + params.isReadWriteAccess() + ", writeOnlyAccess:" + params.isWriteOnlyAccess() + ", attributesOnlyAccess:" + params.isAttributesOnlyAccess() + ", sequentialAccessOnly:" + params.isSequentialAccessOnly() + ", requestBatchOpLock:" + params.requestBatchOpLock() + ", requestExclusiveOpLock:" + params.requestExclusiveOpLock() + ", isDeleteOnClose:" + params.isDeleteOnClose() + ", sharedAccess: " + strSharedAccess + ", allocationSize: " + params.getAllocationSize() + ", isHidden:" + FileAttribute.isHidden(attr) + ", isSystem:" + FileAttribute.isSystem(attr)); } long creationDateTime = params.getCreationDateTime(); if (creationDateTime != 0) { logger.debug("creationDateTime is set:" + new Date(creationDateTime)); } ContentContext tctx = (ContentContext) tree.getContext(); NodeRef rootNode = tctx.getRootNode(); String[] paths = FileName.splitPath(params.getPath()); String folder = paths[0]; String file = paths[1]; DriverState driverState = getDriverState(sess); EvaluatorContext ctx = getEvaluatorContext(driverState, folder); Operation o = new CreateFileOperation( file, rootNode, params.getPath(), params.getAllocationSize(), FileAttribute.isHidden(attr)); Command c = ruleEvaluator.evaluate(ctx, o); Object ret = commandExecutor.execute(sess, tree, c); if (ret != null && ret instanceof NetworkFile) { return (NetworkFile) ret; } else { // Error - contact broken logger.error( "contract broken - NetworkFile not returned. " + ret == null ? "Return value is null" : ret); return null; } } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) { throw new AccessDeniedException("Unable to create file " + params.getPath(), ade); } }
/** * Create a network file for the specified file * * @param params FileOpenParams * @param fid int * @param stid int * @param did int * @param create boolean * @param dir boolean * @exception IOException * @exception FileNotFoundException */ public NetworkFile openFile( FileOpenParams params, int fid, int stid, int did, boolean create, boolean dir) throws IOException, FileNotFoundException { // Split the file name to get the name only String[] paths = FileName.splitPath(params.getPath()); String name = paths[1]; if (params.isStream()) name = name + params.getStreamName(); // Find, or create, the file state for the file/directory FileState fstate = m_stateCache.findFileState(params.getFullPath(), true); fstate.setExpiryTime(System.currentTimeMillis() + m_stateCache.getFileStateExpireInterval()); // Check if the file is a directory DBNetworkFile netFile = null; if (dir == false) { // Create the network file and associated file segment CachedNetworkFile cacheFile = createNetworkFile(fstate, params, name, fid, stid, did); netFile = cacheFile; // Check if the file is being opened for sequential access and the data has not yet been // loaded FileSegment fileSeg = cacheFile.getFileSegment(); if (create == true || params.isOverwrite() == true) { // Indicate that the file data is available, this is a new file or the existing file is // being // overwritten so there is no data to load. fileSeg.setStatus(FileSegmentInfo.Available); } else if (params.isSequentialAccessOnly() && fileSeg.isDataLoading() == false) { synchronized (cacheFile.getFileState()) { // Create the temporary file cacheFile.openFile(create); cacheFile.closeFile(); // Queue a file data load request if (fileSeg.isDataLoading() == false) queueFileRequest( new SingleFileRequest( FileRequest.LOAD, cacheFile.getFileId(), cacheFile.getStreamId(), fileSeg.getInfo(), cacheFile.getFullName(), fstate)); } // DEBUG if (Debug.EnableInfo && hasDebug()) Debug.println( "ObjIdLoader Queued file load, SEQUENTIAL access, file=" + cacheFile.getFullName()); } } else { // Create a placeholder network file for the directory netFile = new DirectoryNetworkFile(name, fid, did, m_stateCache.getFileStateProxy(fstate)); // Debug if (Debug.EnableInfo && hasDebug()) Debug.println("ObjIdLoader.openFile() DIR name=" + name + ", state=" + fstate); } // Return the network file return netFile; }
/** * Create a file segment to load/save the file data * * @param state FileState * @param params FileOpenParams * @param fname String * @param fid int * @param stid int * @param did int * @return CachedNetworkFile * @exception IOException */ private final CachedNetworkFile createNetworkFile( FileState state, FileOpenParams params, String fname, int fid, int stid, int did) throws IOException { // The file state is used to synchronize the creation of the file segment as there may be other // sessions opening the file at the same time. We have to be careful that only one thread // creates the // file segment. FileSegment fileSeg = null; CachedNetworkFile netFile = null; synchronized (state) { // Check if the file segment has been attached to the file state FileSegmentInfo fileSegInfo = (FileSegmentInfo) state.findAttribute(DBFileSegmentInfo); if (fileSegInfo == null) { // Check if we need to create a new temporary sub-drectory if (m_tempCount++ >= m_tempMax) createNewTempDirectory(); // Create a unique temporary file name StringBuffer tempName = new StringBuffer(); tempName.append(getTempFilePrefix()); tempName.append(fid); if (stid > 0) { tempName.append("_"); tempName.append(stid); // DEBUG if (Debug.EnableInfo && hasDebug()) Debug.println("## Temp file for stream ##"); } tempName.append(".tmp"); // Create a new file segment fileSegInfo = new FileSegmentInfo(); fileSeg = FileSegment.createSegment( fileSegInfo, tempName.toString(), m_curTempDir, params.isReadOnlyAccess() == false); // Add the segment to the file state cache state.addAttribute(DBFileSegmentInfo, fileSegInfo); // Check if the file is zero length, if so then set the file segment state to indicate it is // available DBFileInfo finfo = (DBFileInfo) state.findAttribute(FileState.FileInformation); if (finfo != null && finfo.getSize() == 0) fileSeg.setStatus(FileSegmentInfo.Available); } else { // Create the file segment to map to the existing temporary file fileSeg = new FileSegment(fileSegInfo, params.isReadOnlyAccess() == false); // Check if the temporary file exists, if not then create it File tempFile = new File(fileSeg.getTemporaryFile()); if (tempFile.exists() == false) { // Create the temporary file tempFile.createNewFile(); // Reset the file segment state to indicate a file load is required fileSeg.setStatus(FileSegmentInfo.Initial); } } // Create the new network file netFile = new CachedNetworkFile( fname, fid, stid, did, m_stateCache.getFileStateProxy(state), fileSeg, this); netFile.setGrantedAccess( params.isReadOnlyAccess() ? NetworkFile.READONLY : NetworkFile.READWRITE); netFile.setSequentialOnly(params.isSequentialAccessOnly()); netFile.setAttributes(params.getAttributes()); netFile.setFullName(params.getPath()); if (stid != 0) netFile.setStreamName(params.getStreamName()); } // Return the network file return netFile; }