/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.vfs2.provider.smb; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import jcifs.smb.NtlmPasswordAuthentication; import jcifs.smb.SmbException; import jcifs.smb.SmbFile; import jcifs.smb.SmbFileInputStream; import jcifs.smb.SmbFileOutputStream; import org.apache.commons.vfs2.FileName; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.FileTypeHasNoContentException; import org.apache.commons.vfs2.RandomAccessContent; import org.apache.commons.vfs2.UserAuthenticationData; import org.apache.commons.vfs2.provider.AbstractFileName; import org.apache.commons.vfs2.provider.AbstractFileObject; import org.apache.commons.vfs2.provider.UriParser; import org.apache.commons.vfs2.util.RandomAccessMode; import org.apache.commons.vfs2.util.UserAuthenticatorUtils; /** * A file in an SMB file system. * CHECKSTYLE:OFF * * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> */ public class SmbFileObject extends AbstractFileObject implements FileObject { // private final String fileName; private SmbFile file; protected SmbFileObject(final AbstractFileName name, final SmbFileSystem fileSystem) throws FileSystemException { super(name, fileSystem); // this.fileName = UriParser.decode(name.getURI()); } /** * Attaches this file object to its file resource. */ @Override protected void doAttach() throws Exception { // Defer creation of the SmbFile to here if (file == null) { file = createSmbFile(getName()); } } @Override protected void doDetach() throws Exception { // file closed through content-streams file = null; } private SmbFile createSmbFile(FileName fileName) throws MalformedURLException, SmbException, FileSystemException { SmbFileName smbFileName = (SmbFileName) fileName; String path = smbFileName.getUriWithoutAuth(); UserAuthenticationData authData = null; SmbFile file; NtlmPasswordAuthentication auth; try { authData = UserAuthenticatorUtils.authenticate(getFileSystem().getFileSystemOptions(), SmbFileProvider.AUTHENTICATOR_TYPES); auth = new NtlmPasswordAuthentication( UserAuthenticatorUtils.toString( UserAuthenticatorUtils.getData( authData, UserAuthenticationData.DOMAIN, UserAuthenticatorUtils.toChar(smbFileName.getDomain()))), UserAuthenticatorUtils.toString( UserAuthenticatorUtils.getData( authData, UserAuthenticationData.USERNAME, UserAuthenticatorUtils.toChar(smbFileName.getUserName()))), UserAuthenticatorUtils.toString( UserAuthenticatorUtils.getData( authData, UserAuthenticationData.PASSWORD, UserAuthenticatorUtils.toChar(smbFileName.getPassword())))); file = new SmbFile(path, auth); } finally { UserAuthenticatorUtils.cleanup(authData); } if (file.isDirectory() && !file.toString().endsWith("/")) { file = new SmbFile(path + "/", auth); } return file; } /** * Determines the type of the file, returns null if the file does not * exist. */ @Override protected FileType doGetType() throws Exception { if (!file.exists()) { return FileType.IMAGINARY; } else if (file.isDirectory()) { return FileType.FOLDER; } else if (file.isFile()) { return FileType.FILE; } throw new FileSystemException("vfs.provider.smb/get-type.error", getName()); } /** * Lists the children of the file. Is only called if {@link #doGetType} * returns {@link FileType#FOLDER}. */ @Override protected String[] doListChildren() throws Exception { // VFS-210: do not try to get listing for anything else than directories if (!file.isDirectory()) { return null; } return UriParser.encode(file.list()); } /** * Determines if this file is hidden. */ @Override protected boolean doIsHidden() throws Exception { return file.isHidden(); } /** * Deletes the file. */ @Override protected void doDelete() throws Exception { file.delete(); } @Override protected void doRename(FileObject newfile) throws Exception { file.renameTo(createSmbFile(newfile.getName())); } /** * Creates this file as a folder. */ @Override protected void doCreateFolder() throws Exception { file.mkdir(); file = createSmbFile(getName()); } /** * Returns the size of the file content (in bytes). */ @Override protected long doGetContentSize() throws Exception { return file.length(); } /** * Returns the last modified time of this file. */ @Override protected long doGetLastModifiedTime() throws Exception { return file.getLastModified(); } /** * Creates an input stream to read the file content from. */ @Override protected InputStream doGetInputStream() throws Exception { try { return new SmbFileInputStream(file); } catch (SmbException e) { if (e.getNtStatus() == SmbException.NT_STATUS_NO_SUCH_FILE) { throw new org.apache.commons.vfs2.FileNotFoundException(getName()); } else if (file.isDirectory()) { throw new FileTypeHasNoContentException(getName()); } throw e; } } /** * Creates an output stream to write the file content to. */ @Override protected OutputStream doGetOutputStream(boolean bAppend) throws Exception { return new SmbFileOutputStream(file, bAppend); } /** * random access */ @Override protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception { return new SmbFileRandomAccessContent(file, mode); } }