package org.openedit.entermedia; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.openedit.data.SearcherManager; import org.openedit.repository.BaseRepository; import org.openedit.repository.ContentItem; import org.openedit.repository.InputStreamItem; import org.openedit.repository.Repository; import org.openedit.repository.RepositoryException; import com.openedit.users.User; import com.openedit.users.UserManager; public class FtpRepository extends BaseRepository { protected SearcherManager fieldSearcherManager; protected UserManager fieldUserManager; // for getting the FTP user private static final Log log = LogFactory.getLog(FtpRepository.class); protected FTPClient fieldFTPClient; public FTPClient getFTPClient() { if (fieldFTPClient == null) { fieldFTPClient = new FTPClient(); } return fieldFTPClient; } public void setFTPClient(FTPClient inFTPClient) { fieldFTPClient = inFTPClient; } public ContentItem get(String inPath) throws RepositoryException { String path = inPath.substring(getPath().length()); if (path.length() == 0) { path = "/"; } String url = getExternalPath() + path; FtpContentItem item = new FtpContentItem(); item.setPath(inPath); item.setAbsolutePath(path); return item; } protected String makeRemotePath(String inPath) { String path = inPath.toString(); if (path.startsWith(getPath())) { //chop off the repo path. add 1 b/c repo path doesn't include trailing slash path = path.substring(getPath().length() + 1); } return path; } protected void checkConnection() throws Exception { if (!isConnected()) { boolean connect = connect(); if (!connect) { throw new RepositoryException("Cannot connect to server: " + getExternalPath()); } } } public void copy(ContentItem inSource, ContentItem inDestination) throws RepositoryException { try { checkConnection(); String path = inDestination.getAbsolutePath().substring(1); makeDirs(path); boolean success = getFTPClient().storeFile(path, inSource.getInputStream()); if (!success) log.info("Failed to store " + path); } catch (Exception e) { throw new RepositoryException(e); } } public void deleteOldVersions(String inPath) throws RepositoryException { // TODO Auto-generated method stub } public boolean doesExist(String inPath) throws RepositoryException { return false; /* try { checkConnection(); String path = makeRemotePath(inPath); FTPFile[] files = getFTPClient().listFiles(path); int num = files.length; if (num == 0) return false; else if (num == 1) return true; else { throw new Exception("Individual file list returned multiple matches:" + inPath); } } catch (Exception e) { throw new RepositoryException(e); } */ } public List getChildrenNames(String inParent) throws RepositoryException { log.info("trying to get filenames"); try { if (!isConnected()) { boolean connect = connect(); if (!connect) { log.info("unable to connect to server: " + getExternalPath()); return null; } } getFTPClient().changeWorkingDirectory(inParent); FTPFile[] files = getFTPClient().listFiles(); List filenames = new ArrayList(); for (int i = 0; i < files.length; i++) { FTPFile file = files[i]; String filename = file.getName(); filenames.add(filename); } return filenames; } catch (Exception e) { throw new RepositoryException(e); } } public ContentItem getLastVersion(String inPath) throws RepositoryException { // TODO Auto-generated method stub return null; } public ContentItem getStub(String inPath) throws RepositoryException { return get(inPath); } public List getVersions(String inPath) throws RepositoryException { // TODO Auto-generated method stub return null; } public void move(ContentItem inSource, ContentItem inDestination) throws RepositoryException { // TODO Auto-generated method stub } public void move(ContentItem inSource, Repository inSourceRepository, ContentItem inDestination) throws RepositoryException { // TODO Auto-generated method stub } /* Given a path to a file, make all the intermediate directories * */ protected void makeDirs(String inPath) throws IOException { if (inPath.contains("/")) { String[] components = inPath.split("/"); String path = components[0]; for (int i = 1; i < components.length; i++) { getFTPClient().makeDirectory(path); path += "/" + components[i]; } } } public void remove(ContentItem inPath) throws RepositoryException { try { checkConnection(); String path = inPath.getAbsolutePath().substring(1); boolean success = getFTPClient().deleteFile(path); if (!success) { throw new RepositoryException("Couldn't put file: " + inPath.getPath()); } } catch (Exception e) { throw new RepositoryException(e); } } class FtpContentItem extends InputStreamItem { protected Boolean existed; public InputStream getInputStream() throws RepositoryException { try { return getFTPClient().retrieveFileStream(getAbsolutePath().substring(1)); } catch (IOException e) { throw new RepositoryException(e); } } public boolean exists() { try { checkConnection(); String path = getAbsolutePath().substring(1); FTPFile[] files = getFTPClient().listFiles(path); if (files == null || files.length == 0) { return false; } return true; } catch (Exception e) { throw new RepositoryException(e); } } public boolean isFolder() { if (getAbsolutePath().endsWith("/")) { return true; } return false; } } public boolean isConnected() { return getFTPClient().isConnected(); } public SearcherManager getSearcherManager() { return fieldSearcherManager; } public void setSearcherManager(SearcherManager inSearcherManager) { fieldSearcherManager = inSearcherManager; } public UserManager getUserManager() { return fieldUserManager; } public void setUserManager(UserManager inUserManager) { fieldUserManager = inUserManager; } /* public Data getConfiguration() { Searcher configsearcher = getSearcherManager().getSearcher("system", "ftp"); Data config = (Data) configsearcher.searchById(getPath()); if (config == null) { config = configsearcher.createNewData(); config.setId(getPath()); configsearcher.saveData(config, null); } return config; } */ public void disconnect() throws IOException { if (isConnected()) { getFTPClient().disconnect(); } } public boolean connect() throws Exception { try { if (isConnected()) { return true; } boolean connected = false; String serverName = getExternalPath(); String subdir = null; if (serverName.indexOf(':') > -1) { String[] parts = serverName.split(":"); if (parts.length > 0) { serverName = parts[0]; } if (parts.length > 1) { subdir = parts[1]; } } getFTPClient().connect(serverName); log.info("trying to connect to : " + serverName); String ftpuser = getUserName(); User user = getUserManager().getUser(ftpuser); if (user == null) { log.info("No user found -trying anonymous login"); connected = getFTPClient().login("anonymous", "anonymous"); } else { connected = getFTPClient().login(ftpuser, getUserManager().decryptPassword(user)); } if (connected) { //getFTPClient().enterLocalPassiveMode(); log.info("Connected to " + serverName); if (subdir != null) { log.info("Changing working directory to " + subdir); getFTPClient().changeWorkingDirectory(subdir); } getFTPClient().setFileType(FTP.BINARY_FILE_TYPE); } log.info(getFTPClient().getReplyString()); return connected; } catch (IOException e) { return false; } } public String getUserName() { return getProperty("username"); } public void setUserName(String userName) { setProperty("username", userName); } @Override public void put(ContentItem inContent) throws RepositoryException { // TODO Auto-generated method stub } }