/* * $Id: IWSlideServiceBean.java,v 1.69 2009/05/20 14:18:49 valdas Exp $ * Created on 23.10.2004 * * Copyright (C) 2004 Idega Software hf. All Rights Reserved. * * This software is the proprietary information of Idega hf. * Use is subject to license terms. */ package com.idega.slide.business; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.servlet.http.HttpSession; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HostConfiguration; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.HttpURL; import org.apache.commons.httpclient.HttpsURL; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.URIException; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.slide.common.Domain; import org.apache.slide.common.NamespaceAccessToken; import org.apache.slide.security.Security; import org.apache.slide.webdav.WebdavServlet; import org.apache.webdav.lib.Ace; import org.apache.webdav.lib.PropertyName; import org.apache.webdav.lib.WebdavFile; import org.apache.webdav.lib.WebdavResource; import org.apache.webdav.lib.WebdavResources; import org.apache.webdav.lib.WebdavState; import org.apache.webdav.lib.properties.AclProperty; import org.apache.webdav.lib.util.WebdavStatus; import org.springframework.beans.factory.annotation.Autowired; import com.idega.business.IBOLookupException; import com.idega.business.IBORuntimeException; import com.idega.business.IBOServiceBean; import com.idega.idegaweb.IWMainApplication; import com.idega.io.ZipInstaller; import com.idega.servlet.filter.RequestResponseProvider; import com.idega.slide.authentication.AuthenticationBusiness; import com.idega.slide.bean.WorkerInfo; import com.idega.slide.schema.SlideSchemaCreator; import com.idega.slide.util.AccessControlEntry; import com.idega.slide.util.AccessControlList; import com.idega.slide.util.IWSlideConstants; import com.idega.slide.util.WebdavExtendedResource; import com.idega.slide.util.WebdavLocalResource; import com.idega.slide.util.WebdavOutputStream; import com.idega.slide.util.WebdavRootResource; import com.idega.slide.webdavservlet.DomainConfig; import com.idega.slide.webdavservlet.WebdavExtendedServlet; import com.idega.util.CoreConstants; import com.idega.util.CoreUtil; import com.idega.util.FileUtil; import com.idega.util.IOUtil; import com.idega.util.IWTimestamp; import com.idega.util.ListUtil; import com.idega.util.StringHandler; import com.idega.util.StringUtil; import com.idega.util.expression.ELUtil; /** * <p> * This is the main bean for accessing system wide information about the slide * store. * </p> * * Last modified: $Date: 2009/05/20 14:18:49 $ by $Author: valdas $ * * @author <a href="mailto:gummi@idega.com">Gudmundur Agust Saemundsson</a>,<a * href="mailto:tryggvi@idega.com">Tryggvi Larusson</a> * @version $Revision: 1.69 $ */ public class IWSlideServiceBean extends IBOServiceBean implements IWSlideService, IWSlideChangeListener { private static final long serialVersionUID = -4520443825572949293L; // listeners and caching private List<IWSlideChangeListener> iwSlideChangeListeners = null; private IWSlideChangeListener[] iwSlideChangeListenersArray = null; private Map<String, List<String>> childPathsCacheMap = new HashMap<String, List<String>>(); private Map<String, List<String>> childPathsExcludingFolderAndHiddenFilesCacheMap = new HashMap<String, List<String>>(); private Map<String, List<String>> childFolderPathsCacheMap = new HashMap<String, List<String>>(); protected static final String FILE_SERVER_URI = CoreConstants.WEBDAV_SERVLET_URI + CoreConstants.PATH_FILES_ROOT; protected static final String USER_SERVLET_URI = CoreConstants.WEBDAV_SERVLET_URI + "/users"; protected static final String PATH_BLOCK_HOME = CoreConstants.PATH_FILES_ROOT + "/cms"; protected static final String PATH_USERS_HOME_FOLDERS = CoreConstants.PATH_FILES_ROOT + "/users"; protected static final String PATH_GROUPS_HOME_FOLDERS = CoreConstants.PATH_FILES_ROOT + "/groups"; protected static final String FOLDER_NAME_PUBLIC = "/public"; protected static final String FOLDER_NAME_SHARED = "/shared"; protected static final String FOLDER_NAME_DROPBOX = "/dropbox"; protected Map<String, String> lastUniqueFileNameScopeMap = new HashMap<String, String>(); protected String lastGlobalUniqueFileName = null; private Security security = null; private static final Logger LOGGER = Logger.getLogger(IWSlideServiceBean.class.getName()); private Map<String, WorkerInfo> queue = new HashMap<String, WorkerInfo>(); @Autowired private IWSimpleSlideService simpleSlideService; public IWSlideServiceBean() { super(); } /** * <p> * Gets the URI for the root of the slide repository. The repository is by * default mapped on '/content' under the web application.<br/> This method * returns the context path for the application so if it is e.g. mapped * under '/cms' this method returns '/cms/content'. If the webapplication is * mapped on '/' the method returns '/content' * </p> * * @param path * @return */ @Override public String getWebdavServerURI() { String appContext = getIWMainApplication().getApplicationContextURI(); if (appContext.endsWith(CoreConstants.SLASH)) { appContext = appContext.substring(0, appContext.lastIndexOf(CoreConstants.SLASH)); } return appContext + CoreConstants.WEBDAV_SERVLET_URI; } /** * <p> * Gets the URL from with a path in the filesystem (e.g.) if the given path * is '/files/public/myfile.pdf' then this method returns * 'http://[hostname]:[port]/[contextpath]/content/files/public/myfile.pdf' * </p> * * @param path * @return */ @Override public HttpURL getWebdavServerURL(String path) { return getWebdavServerURL(null, path); } @Override public HttpURL getWebdavServerURL() { return getWebdavServerURL(null, null); } @Override public HttpURL getWebdavServerURL(UsernamePasswordCredentials credential) { return getWebdavServerURL(credential, null); } @Override public HttpURL getWebdavServerURL(UsernamePasswordCredentials credential, String path) { return getWebdavServerURL(credential, path, getWebdavServerURI(), Boolean.TRUE); } /** * Gets the root url for the webdav server with authentication * * @return */ private HttpURL getWebdavServerURL(UsernamePasswordCredentials credential, String path, String servletPath, boolean addSessionId) { try { String server = getIWApplicationContext().getDomain().getURL(); if (server == null) { return null; } int port = 80; boolean https = false; if (server.endsWith(CoreConstants.SLASH)) { server = server.substring(0, server.lastIndexOf(CoreConstants.SLASH)); } if (server.startsWith("http://")) { server = server.substring(7, server.length()); } if (server.startsWith("https://")) { if (getIWMainApplication().getSettings().getBoolean("slide.allow.local.https")) { // https protocol when to slide is only enabled when this property is set https = true; } server = server.substring(8, server.length()); } if (server.indexOf(CoreConstants.COLON) != -1) { String sPort = server.substring(server.indexOf(CoreConstants.COLON) + 1, server.length()); port = Integer.parseInt(sPort); server = server.substring(0, server.indexOf(CoreConstants.COLON)); } String rootPath = servletPath; String realPath = rootPath; if (path != null) { realPath = rootPath + path; } HttpURL hrl = https ? new HttpsURL(server, port, realPath) : new HttpURL(server, port, realPath); if (credential != null) { hrl.setUserinfo(credential.getUserName(), credential.getPassword()); } return hrl; } catch (URIException e) { throw new IBORuntimeException(e); } } /** * Gets resource for the webdav server with authentication * * @return */ @Override public WebdavFile getWebdavFile(UsernamePasswordCredentials credentials, String path) { try { return new WebdavFile(getWebdavServerURL(credentials, path)); } catch (HttpException e) { throw new IBORuntimeException(e); } } /** * Gets the root resource for the webdav server with authentication * * @return */ @Override public WebdavFile getWebdavFile(UsernamePasswordCredentials credentials) { return getWebdavFile(credentials, null); } /** * Gets the root resource for the webdav server without any authentication * * @return */ @Override public WebdavFile getWebdavFile() { return getWebdavFile(null, null); } /** * * @return * @throws RemoteException * @throws IBOLookupException */ @Override public UsernamePasswordCredentials getRootUserCredentials() throws IBOLookupException, RemoteException { return getAuthenticationBusiness().getRootUserCredentials(); } /** * Auto creates the Slide sql schema structure */ @Override public void createSlideSchemas() { try { new SlideSchemaCreator().createSchemas(); } catch (Exception e) { e.printStackTrace(); } } /** * <p> * Returns the WebdavResource for the "/" or root of the WebDav server. * </p> * * @param credentials * @return * @throws HttpException * @throws IOException * @throws RemoteException */ @Override public WebdavResource getWebdavExternalRootResource(UsernamePasswordCredentials credentials) throws HttpException, IOException, RemoteException { return getWebdavExtendedResource(null, credentials, Boolean.FALSE); } @Override public WebdavResource getWebdavResource(String path, UsernamePasswordCredentials credentials) throws HttpException, IOException, RemoteException { return getWebdavExtendedResource(path, credentials); } @Override public WebdavExtendedResource getWebdavExtendedResource(String path, UsernamePasswordCredentials credentials) throws HttpException, IOException, RemoteException { return getWebdavExtendedResource(path, credentials, Boolean.TRUE); } private boolean isLocalResourceEnabled() { return IWMainApplication.getDefaultIWMainApplication().getSettings().getBoolean("local_slide_resource", Boolean.TRUE); } @Override public WebdavExtendedResource getWebdavExtendedResource(String path, UsernamePasswordCredentials credentials, boolean localResource) throws HttpException, IOException, RemoteException, RemoteException { HttpURL url = getWebdavServerURL(credentials, getPath(path), getWebdavServerURI(), localResource); if (url == null) { throw new IOException("[IWSlideService] WebdavServerURL could not be retrieved for " + path + ", using credentials: " + credentials); } WebdavExtendedResource resource = null; if (localResource && isLocalResourceEnabled()) { if (!Domain.isInitialized()) { DomainConfig domainConfig = ELUtil.getInstance().getBean(DomainConfig.SPRING_BEAN_IDENTIFIER); domainConfig.initialize(); } HttpSession currentSession = getCurrentSession(); if (currentSession != null) { url.setQuery(CoreConstants.PARAMETER_SESSION_ID.toLowerCase(), currentSession.getId()); } try { resource = new WebdavLocalResource(getHttpClient(url, credentials)); resource.setHttpURL(url); } catch (Exception e) { e.printStackTrace(); } } if (resource == null) { resource = new WebdavExtendedResource(url); } return resource; } @SuppressWarnings("deprecation") private HttpClient getHttpClient(HttpURL url, UsernamePasswordCredentials credentials) throws Exception { HttpSession currentSession = getCurrentSession(); HttpState state = new WebdavState(); AuthScope authScope = new AuthScope(url.getHost(), url.getPort()); state.setCredentials(authScope, credentials); if (currentSession != null) { IWTimestamp iwExpires = new IWTimestamp(System.currentTimeMillis()); iwExpires.setMinute(iwExpires.getMinute() + 30); Date expires = new Date(iwExpires.getTimestamp().getTime()); boolean secure = url instanceof HttpsURL; Cookie cookie = new Cookie(url.getHost(), CoreConstants.PARAMETER_SESSION_ID, currentSession.getId(), CoreConstants.SLASH, expires, secure); state.addCookie(cookie); } HttpClient client = new HttpClient(new MultiThreadedHttpConnectionManager()); client.setState(state); HostConfiguration hostConfig = client.getHostConfiguration(); hostConfig.setHost(url); Credentials hostCredentials = null; if (credentials == null) { String userName = url.getUser(); if (userName != null && userName.length() > 0) { hostCredentials = new UsernamePasswordCredentials(userName, url.getPassword()); } } if (hostCredentials != null) { HttpState clientState = client.getState(); clientState.setCredentials(null, url.getHost(), hostCredentials); clientState.setAuthenticationPreemptive(true); } return client; } private HttpSession getCurrentSession() { try { RequestResponseProvider requestProvider = ELUtil.getInstance().getBean(RequestResponseProvider.class); return requestProvider.getRequest().getSession(Boolean.FALSE); } catch (Exception e) {} return null; } /** * Returns the WebdavResource at the given path and authenticated as root */ @Override public WebdavResource getWebdavResourceAuthenticatedAsRoot(String path) throws HttpException, IOException { return getWebdavResource(path, getRootUserCredentials()); } /** * Returns the WebdavResource at path "/" and authenticated as root */ @Override public WebdavResource getWebdavResourceAuthenticatedAsRoot() throws HttpException, IOException { return getWebdavResourceAuthenticatedAsRoot(null); } private WebdavResource getWebdavExternalResourceAuthenticatedAsRoot(String path) throws HttpException, IOException { return getWebdavExtendedResource(path, getRootUserCredentials(), Boolean.FALSE); } @Override public WebdavResource getWebdavExternalResourceAuthenticatedAsRoot() throws HttpException, IOException { return getWebdavExternalResourceAuthenticatedAsRoot(null); } /** * <p> * Gets the URI from with a path in the filesystem (e.g.) if the given path * is '/files/public/myfile.pdf' then this method returns * '/[contextpath]/content/files/public/myfile.pdf' * </p> * * @param path * @return */ @Override public String getURI(String path) throws RemoteException { if (path.startsWith(CoreConstants.WEBDAV_SERVLET_URI)) { // to avoid /content/content/ path = path.substring(CoreConstants.WEBDAV_SERVLET_URI.length()); } return getWebdavServerURI() + ((path.startsWith(CoreConstants.SLASH)) ? CoreConstants.EMPTY : CoreConstants.SLASH) + path; } @Override public String getPath(String uri) throws RemoteException { String uriPrefix = getWebdavServerURI(); if (uri == null) { return null; } else { return ((uri.startsWith(uriPrefix)) ? uri.substring(uriPrefix .length()) : uri); } } @Override public boolean getExistence(String path) throws HttpException, IOException { if (path == null) { return false; } try { return getSimpleSlideService().checkExistance(path); } catch (Exception e) {} try { String pathToCheck = ((path.startsWith(getWebdavServerURI())) ? path : getURI(path)); Enumeration<?> prop = getWebdavExternalResourceAuthenticatedAsRoot().propfindMethod(pathToCheck, WebdavResource.DISPLAYNAME); return !(prop == null || !prop.hasMoreElements()); } catch (HttpException e) { if (e.getReasonCode() == WebdavStatus.SC_NOT_FOUND) { return false; } else { throw e; } } } @Override public boolean generateUserFolders(String loginName) throws HttpException, IOException { if (StringUtil.isEmpty(loginName)) { return false; } AuthenticationBusiness ab = getAuthenticationBusiness(); String userPath = ab.getUserPath(loginName); if (!getExistence(userPath)) { WebdavResource user = getWebdavResourceAuthenticatedAsRoot(userPath); user.mkcolMethod(); user.close(); } if (!getExistence(getUserHomeFolderPath(loginName))) { WebdavResource rootFolder = getWebdavResourceAuthenticatedAsRoot(); String userFolderPath = getURI(getUserHomeFolderPath(loginName)); rootFolder.mkcolMethod(userFolderPath); rootFolder.mkcolMethod(userFolderPath + FOLDER_NAME_DROPBOX); rootFolder.mkcolMethod(userFolderPath + FOLDER_NAME_PUBLIC); rootFolder.close(); try { updateUserFolderPrivileges(loginName); } catch (IOException e) { e.printStackTrace(); return false; } } return true; } @Override public void updateUserFolderPrivileges(String loginName) throws IOException, IOException { String userFolderPath = getURI(getUserHomeFolderPath(loginName)); AuthenticationBusiness aBusiness = getAuthenticationBusiness(); String userPrincipal = aBusiness.getUserURI(loginName); // user folder AccessControlList userFolderList = getAccessControlList(userFolderPath); // should be 'all' for the user himself List<AccessControlEntry> userFolderUserACEs = userFolderList.getAccessControlEntriesForUsers(); AccessControlEntry usersPositiveAce = null; AccessControlEntry usersNegativeAce = null; boolean madeChangesToUserFolderList = false; // Find the ace for (Iterator<AccessControlEntry> iter = userFolderUserACEs.iterator(); iter.hasNext();) { AccessControlEntry ace = iter.next(); if (ace.getPrincipal().equals(userPrincipal) && !ace.isInherited()) { if (ace.isNegative()) { usersNegativeAce = ace; } else { usersPositiveAce = ace; } } } if (usersPositiveAce == null) { usersPositiveAce = new AccessControlEntry(userPrincipal, false, false, false, null, AccessControlEntry.PRINCIPAL_TYPE_USER); userFolderList.add(usersPositiveAce); } if (!usersPositiveAce.containsPrivilege(IWSlideConstants.PRIVILEGE_ALL)) { if (usersNegativeAce != null && usersNegativeAce.containsPrivilege(IWSlideConstants.PRIVILEGE_ALL)) { // do nothing becuse this is not ment to reset permissions but // to set them in the first // first place and update for legacy reasons. If Administrator // has closed someones user folder // for some reason, this is not supposed to reset that. } else { usersPositiveAce.addPrivilege(IWSlideConstants.PRIVILEGE_ALL); madeChangesToUserFolderList = true; // temporary at least: usersPositiveAce.setInherited(false); usersPositiveAce.setInheritedFrom(null); // temporary ends } } if (madeChangesToUserFolderList) { storeAccessControlList(userFolderList); } // dropbox updateUsersDropboxPrivileges(userFolderPath); // public folder updateUsersPublicFolderPrivileges(userFolderPath); } /** * @param userFolderPath * @throws HttpException * @throws IOException */ private void updateUsersDropboxPrivileges(String userFolderPath)throws HttpException, IOException { // dropbox AccessControlList dropboxList = getAccessControlList(userFolderPath + FOLDER_NAME_DROPBOX); // should be 'write' for authenticated List<AccessControlEntry> publicFolderStandardACEs = dropboxList.getAccessControlEntriesForUsers(); String principalAuthenticated = IWSlideConstants.SUBJECT_URI_AUTHENTICATED; AccessControlEntry prAuthenticatedPositiveAce = null; AccessControlEntry prAuthenticatedNegativeAce = null; boolean madeChangesToPublicFolderList = false; // Find the ace for (Iterator<AccessControlEntry> iter = publicFolderStandardACEs.iterator(); iter.hasNext();) { AccessControlEntry ace = iter.next(); if (ace.getPrincipal().equals(principalAuthenticated) && !ace.isInherited()) { if (ace.isNegative()) { prAuthenticatedNegativeAce = ace; } else { prAuthenticatedPositiveAce = ace; } } } if (prAuthenticatedPositiveAce == null) { prAuthenticatedPositiveAce = new AccessControlEntry(principalAuthenticated, false, false, false, null, AccessControlEntry.PRINCIPAL_TYPE_STANDARD); dropboxList.add(prAuthenticatedPositiveAce); } if (!prAuthenticatedPositiveAce.containsPrivilege(IWSlideConstants.PRIVILEGE_WRITE)) { if (prAuthenticatedNegativeAce != null && prAuthenticatedNegativeAce.containsPrivilege(IWSlideConstants.PRIVILEGE_WRITE)) { // do nothing becuse this is not ment to reset permissions but // to set them in the first // first place and update for legacy reasons. } else { prAuthenticatedPositiveAce.addPrivilege(IWSlideConstants.PRIVILEGE_WRITE); madeChangesToPublicFolderList = true; // temporary at least: prAuthenticatedPositiveAce.setInherited(false); prAuthenticatedPositiveAce.setInheritedFrom(null); // temporary ends } } if (madeChangesToPublicFolderList) { storeAccessControlList(dropboxList); } } /** * @param userFolderPath * @throws HttpException * @throws IOException */ private void updateUsersPublicFolderPrivileges(String userFolderPath) throws HttpException, IOException { // public folder AccessControlList publicFolderList = getAccessControlList(userFolderPath + FOLDER_NAME_PUBLIC); // should be 'read' for everyone (and preferably nothing set for 'write') List<AccessControlEntry> publicFolderStandardACEs = publicFolderList.getAccessControlEntriesForUsers(); String principalEveryone = IWSlideConstants.SUBJECT_URI_ALL; AccessControlEntry prEveryonePositiveAce = null; AccessControlEntry prEveryoneNegativeAce = null; boolean madeChangesToPublicFolderList = false; // Find the ace for (Iterator<AccessControlEntry> iter = publicFolderStandardACEs.iterator(); iter.hasNext();) { AccessControlEntry ace = iter.next(); if (ace.getPrincipal().equals(principalEveryone) && !ace.isInherited()) { if (ace.isNegative()) { prEveryoneNegativeAce = ace; } else { prEveryonePositiveAce = ace; } } } if (prEveryonePositiveAce == null) { prEveryonePositiveAce = new AccessControlEntry(principalEveryone, false, false, false, null, AccessControlEntry.PRINCIPAL_TYPE_STANDARD); publicFolderList.add(prEveryonePositiveAce); } if (!prEveryonePositiveAce.containsPrivilege(IWSlideConstants.PRIVILEGE_READ)) { if (prEveryoneNegativeAce != null && prEveryoneNegativeAce.containsPrivilege(IWSlideConstants.PRIVILEGE_READ)) { // do nothing becuse this is not ment to reset permissions but // to set them in the first // first place and update for legacy reasons. } else { prEveryonePositiveAce.addPrivilege(IWSlideConstants.PRIVILEGE_READ); madeChangesToPublicFolderList = true; // temporary at least: prEveryonePositiveAce.setInherited(false); prEveryonePositiveAce.setInheritedFrom(null); // temporary ends } } if (madeChangesToPublicFolderList) { storeAccessControlList(publicFolderList); } } @Override public AccessControlList getAccessControlList(String path) throws HttpException, IOException { WebdavResource resource = getWebdavResourceAuthenticatedAsRoot(path); return getAccessControlList(path, new WebdavRootResource(resource)); } /** * @param path * @param rResource * @return * @throws RemoteException * @throws HttpException * @throws IOException */ @Override public AccessControlList getAccessControlList(String path, WebdavRootResource rResource) throws HttpException, IOException { String thePath = null; if (path != null) { thePath = getPath(path); } AccessControlList acl = new AccessControlList(getWebdavServerURI(), thePath); AclProperty aclProperty = null; if (thePath != null) { aclProperty = rResource.aclfindMethod(getURI(thePath)); } else { aclProperty = rResource.aclfindMethod(); } if (aclProperty != null) { Ace[] aclProperties = aclProperty.getAces(); if (aclProperties != null) { acl.setAces(aclProperties); } } return acl; } @Override public boolean storeAccessControlList(AccessControlList acl) throws HttpException, IOException { WebdavResource rResource = getWebdavExtendedResource(null, getRootUserCredentials(), Boolean.TRUE); return storeAccessControlList(acl, new WebdavRootResource(rResource)); } /** * @param acl * @param rResource * @return * @throws RemoteException * @throws HttpException * @throws IOException */ @Override public boolean storeAccessControlList(AccessControlList acl, WebdavRootResource rResource) throws HttpException, IOException { String resourceURI = getURI(acl.getResourcePath()); Ace[] aces = acl.getAces(); return rResource.aclMethod(resourceURI, aces); } /** * @return * @throws IBOLookupException */ @Override public AuthenticationBusiness getAuthenticationBusiness() throws IBOLookupException { return (AuthenticationBusiness) getServiceInstance(AuthenticationBusiness.class); } /** * @param loginName * @return */ @Override public String getUserHomeFolderPath(String loginName) { return PATH_USERS_HOME_FOLDERS + CoreConstants.SLASH + loginName; } /** * @param scope * This parameter can be null and then the file name will be * unique over the whole web. If one needs unique name within a * module or a folder one can set some (unique) string as a scope * parameter */ @Override public synchronized String createUniqueFileName(String scope) { IWTimestamp timestamp = new IWTimestamp(); String minuteString = "yyyyMMdd-HHmm"; String name = timestamp.getDateString(minuteString); String lastName = null; if (scope != null && !"".equals(scope)) { lastName = this.lastUniqueFileNameScopeMap.get(scope); } else { lastName = this.lastGlobalUniqueFileName; } if (!(lastName == null || !lastName.startsWith(name))) { if (lastName.length() == minuteString.length()) { name += "-1"; } else { String counter = lastName.substring(minuteString.length() + 1); name += "-" + (Integer.parseInt(counter) + 1); } } if (scope != null) { this.lastUniqueFileNameScopeMap.put(scope, name); } this.lastGlobalUniqueFileName = name; return name; } @Override public Security getSecurityHelper() { if (this.security == null) { NamespaceAccessToken token = (NamespaceAccessToken) getIWApplicationContext().getApplicationAttribute(WebdavServlet.ATTRIBUTE_NAME); this.security = token.getSecurityHelper(); } return this.security; } /** * Creates all the folders in path * * @param path * Path with all the folders to create. Should hold all the * folders after Server URI (Typically /cms/content/) * @throws HttpException * @throws RemoteException * @throws IOException * @return true if it needed to create the folders */ @Override public boolean createAllFoldersInPath(String path, UsernamePasswordCredentials credentials) throws HttpException, RemoteException, IOException { boolean create = !getExistence(path); if (create) { if (isLocalResourceEnabled() && getSimpleSlideService().createStructure(path)) { return true; } WebdavResource rootResource = getWebdavExternalRootResource(credentials); StringBuffer createPath = new StringBuffer(getWebdavServerURI()); StringTokenizer st = new StringTokenizer(path, CoreConstants.SLASH); while (st.hasMoreTokens()) { createPath.append(CoreConstants.SLASH).append(st.nextToken()); rootResource.mkcolMethod(createPath.toString()); } } return true; } /** * Creates all the folders in path with credentatials of the * root/administrator user. * * @param path * Path with all the folders to create. Should hold all the * folders after Server URI (Typically /cms/content/) * @throws HttpException * @throws RemoteException * @throws IOException * @return true if it needed to create the folders */ @Override public boolean createAllFoldersInPathAsRoot(String path) throws HttpException, RemoteException, IOException { return createAllFoldersInPath(path, getRootUserCredentials()); } /** * Creates the parent folder if needed and uploads the content of the string * as a utf8 encoded file of the contenttype/mimetype you specify * */ @Override public boolean uploadFileAndCreateFoldersFromStringAsRoot( String parentPath, String fileName, String fileContentString, String contentType) { return uploadFileAndCreateFoldersFromStringAsRoot(parentPath, fileName, fileContentString, contentType, false); } /** * Creates the parent folder if needed and uploads the content of the string * as a utf8 encoded file of the contenttype/mimetype you specify * */ @Override public boolean uploadFileAndCreateFoldersFromStringAsRoot(String parentPath, String fileName, String fileContentString, String contentType, boolean deletePredecessor) { InputStream stream = null; try { stream = StringHandler.getStreamFromString(fileContentString); return uploadFileAndCreateFoldersFromStringAsRoot(parentPath, fileName, stream, contentType, deletePredecessor); } catch (Exception e) { e.printStackTrace(); } finally { IOUtil.closeInputStream(stream); } return false; } String createFoldersAndPreparedUploadPath(String uploadPath, boolean checkSlashes) { if (checkSlashes) { if (!uploadPath.startsWith(CoreConstants.SLASH)) { uploadPath = CoreConstants.SLASH.concat(uploadPath); } if (!uploadPath.endsWith(CoreConstants.SLASH)) { uploadPath.concat(CoreConstants.SLASH); } } try { if (uploadPath.startsWith(CoreConstants.WEBDAV_SERVLET_URI)) { // to avoid /content/content/ if (createAllFoldersInPathAsRoot(uploadPath.substring(CoreConstants.WEBDAV_SERVLET_URI.length()))) { return uploadPath; } } else { if (createAllFoldersInPathAsRoot(uploadPath)) { return uploadPath; } } } catch (Exception e) { e.printStackTrace(); } return null; } @Override public boolean uploadFile(String uploadPath, String fileName, String contentType, InputStream fileInputStream) { return uploadFile(uploadPath, fileName, contentType, fileInputStream, true); } /** * Synchronized for now because it doesn't seem to be thread safe (deadlock) * * @param uploadPath * @param fileName * @param contentType * @param fileInputStream * @param closeStream * @return */ private boolean uploadFile(String uploadPath, String fileName, String contentType, InputStream stream, boolean closeStream) { if (StringUtil.isEmpty(uploadPath) || StringUtil.isEmpty(fileName) || stream == null) { LOGGER.warning("Unable to upload file: invalid parameters provided: upload path: " + uploadPath + ", file name: " + fileName + ", stream: " + stream); return false; } ByteArrayOutputStream tmp = null; byte[] memory = null; if (IWMainApplication.getDefaultIWMainApplication().getSettings().getBoolean("slide.copy_stream_for_upload", true)) { try { tmp = new ByteArrayOutputStream(); FileUtil.streamToOutputStream(stream, tmp); memory = tmp.toByteArray(); } catch (Exception e) { } finally { if (memory != null && closeStream) IOUtil.close(stream); IOUtil.close(tmp); } } boolean success = false; stream = memory == null ? stream : new ByteArrayInputStream(memory); UploadWorker uw = new UploadWorker(this, uploadPath, fileName, contentType, stream, closeStream); try { Thread uploader = new Thread(uw); uploader.run(); // We want "synchronous" execution success = uw.isWorkFinishedSuccessfully(); } catch (Throwable t) { LOGGER.log(Level.WARNING, "Error while uploading: ".concat(uploadPath).concat(fileName), t); } finally { removeFromQueue(uploadPath, uw.getWorkId()); if (success && closeStream) IOUtil.close(stream); } if (success) return Boolean.TRUE; try { stream = memory == null ? stream : new ByteArrayInputStream(memory); success = CoreUtil.doWriteFileToRepository(uploadPath, fileName, stream); if (success) { getLogger().info("Wrote file " + fileName + " to " + uploadPath + " using files system"); } else { getLogger().warning("Failed to write file " + fileName + " to " + uploadPath + " using files system"); } return success; } catch (IOException e) { String message = "Error writing to the repository (" + uploadPath + fileName + ") using files system"; LOGGER.log(Level.WARNING, message, e); CoreUtil.sendExceptionNotification(message, e); return false; } finally { if (closeStream) IOUtil.close(stream); } } boolean isBusyWorker(String path, String workId) { WorkerInfo info = null; synchronized (queue) { info = queue.get(path); } if (info == null) { info = new WorkerInfo(); synchronized (queue) { queue.put(path, info); } } info.addToQueue(workId); boolean busy = Boolean.TRUE; if (WebdavExtendedServlet.isLocked()) { return Boolean.TRUE; // Slide is being used via HTTP } else if (info.isQueueEmpty()) { busy = Boolean.FALSE; // The first attempt to change repository } else if (info.isFirstInAQueue(workId)) { busy = Boolean.FALSE; // If the work id is the first and a lock is unlocked, worker can proceed } else if (info.isLockedByCurrentThread()) { return Boolean.FALSE; // Current thread has locked, worker can proceed } if (!busy) { // 1. Check if not working on the parent folder (or some sibling folder) currently WorkerInfo parentFolderActivity = getParentFolderActivityInfo(path); if (parentFolderActivity != null) { if (parentFolderActivity.isActive()) { return Boolean.TRUE; } } // 2. Check if not working on the descendant folder currently List<WorkerInfo> descendantFolders = getDescendantFoldersActivityInfo(path); if (!ListUtil.isEmpty(descendantFolders)) { for (WorkerInfo descendantFolder: descendantFolders) { if (descendantFolder.isActive()) { return Boolean.TRUE; } } } // 3. Checking if Slide is being used via HTTP again if (WebdavExtendedServlet.isLocked()) { return Boolean.TRUE; } } if (!busy) { synchronized (queue) { info.lock(); return Boolean.FALSE; } } return Boolean.TRUE; } private List<WorkerInfo> getDescendantFoldersActivityInfo(String uploadPath) { Set<String> currentActivities = null; synchronized (queue) { currentActivities = queue.keySet(); } if (ListUtil.isEmpty(currentActivities)) { return null; } List<WorkerInfo> descendantFolders = new ArrayList<WorkerInfo>(); for (String folderActivity: currentActivities) { if (folderActivity.startsWith(uploadPath) && !folderActivity.equals(uploadPath)) { WorkerInfo descendantFolder = queue.get(folderActivity); if (descendantFolder != null) { descendantFolders.add(descendantFolder); } } } return descendantFolders; } private WorkerInfo getParentFolderActivityInfo(String uploadPath) { if (uploadPath.endsWith(CoreConstants.SLASH)) { uploadPath = uploadPath.substring(0, uploadPath.length() - 1); } if (uploadPath.indexOf(CoreConstants.SLASH) == -1) { return null; } String parentFolder = uploadPath.substring(0, uploadPath.lastIndexOf(CoreConstants.SLASH)); if (!parentFolder.endsWith(CoreConstants.SLASH)) { parentFolder = parentFolder.concat(CoreConstants.SLASH); } synchronized (queue) { return queue.get(parentFolder); } } void removeFromQueue(String path, String workId) { synchronized (queue) { WorkerInfo info = queue.get(path); if (info != null) { info.removeFromQueue(workId); if (info.isQueueEmpty()) { queue.remove(path); } } } } /** * * Creates the parent folder if needed and uploads the content of the file * to Slide and sets the contenttype/mimetype you specify */ @Override public boolean uploadFileAndCreateFoldersFromStringAsRoot(String parentPath, String fileName, InputStream fileInputStream, String contentType, boolean deletePredecessor) { return uploadFileAndCreateFoldersFromStringAsRoot(parentPath, fileName, fileInputStream, contentType, deletePredecessor, Boolean.TRUE); } @Override public boolean uploadFileAndCreateFoldersFromStringAsRoot(String parentPath, String fileName, InputStream fileInputStream, String contentType, boolean deletePredecessor, boolean useSlideAPI) { if (useSlideAPI && uploadFile(parentPath, fileName, contentType, fileInputStream, false)) { // Trying with Slide API firstly return true; } // Using old way to do it try { parentPath = createFoldersAndPreparedUploadPath(parentPath, false); if (parentPath == null) { return false; } String filePath = parentPath + fileName; WebdavResource rootResource = getWebdavExternalResourceAuthenticatedAsRoot(); String fixedURL = getURI(filePath); // delete previous versions if (deletePredecessor) { if (!rootResource.deleteMethod(fixedURL)) { rootResource.deleteMethod(filePath); } } // Conflict fix: uri for creating but path for updating // Note! This is a patch to what seems to be a bug in WebDav // Apparently in version below works in some cases and the other in // other cases. // Seems to be connected to creating files in folders created in // same tomcat session or similar // not quite clear... // update or create if (!rootResource.putMethod(fixedURL, fileInputStream)) { rootResource.putMethod(filePath, fileInputStream); } if (contentType != null) { // use the object PropertyName, do not use // proppatchMethod(String, String, String, boolean) // where only the property name is set but not the namespace // "DAV:" // The namespace is needed later in the method // StandardRDBMSAdapter#createRevisionDescriptor(Connection // connection, Uri uri, NodeRevisionDescriptor // revisionDescriptor) // first parameter is the namespace, second parameter is the // name of the property (e.g. "getcontenttype") PropertyName propertyName = new PropertyName("DAV:", WebdavResource.GETCONTENTTYPE); if (!rootResource.proppatchMethod(fixedURL, propertyName, contentType, true)) { rootResource.proppatchMethod(filePath, propertyName, contentType, true); } } rootResource.close(); // log(rootResource.getStatusMessage()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * Uploads the supplied string as a file with the content type "text/xml" * * @param parentPath * @param fileName * @param fileContentString * @param contentType * @return */ @Override public boolean uploadXMLFileAndCreateFoldersFromStringAsRoot( String parentPath, String fileName, String fileContentString) { return uploadFileAndCreateFoldersFromStringAsRoot(parentPath, fileName, fileContentString, "text/xml", false); } /** * Uploads the supplied string as a file with the content type "text/xml" * * @param parentPath * @param fileName * @param fileContentString * @param contentType * @param deletePredecessor * @return */ @Override public boolean uploadXMLFileAndCreateFoldersFromStringAsRoot( String parentPath, String fileName, String fileContentString, boolean deletePredecessor) { return uploadFileAndCreateFoldersFromStringAsRoot(parentPath, fileName, fileContentString, "text/xml", deletePredecessor); } /** * @return Returns the array of IWSlideChangeListeners. */ @Override public IWSlideChangeListener[] getIWSlideChangeListeners() { return this.iwSlideChangeListenersArray; } /** * @param iwSlideChangeListeners * The iwSlideChangeListeners to set. Overwrites the current list */ @Override public void setIWSlideChangeListeners(List<IWSlideChangeListener> iwSlideChangeListeners) { this.iwSlideChangeListeners = iwSlideChangeListeners; this.iwSlideChangeListenersArray = iwSlideChangeListeners.toArray(new IWSlideChangeListener[0]); } /** * Add a listener that get's notified whenever content changes in Slide, * filter the event yourself by event.getURI() for example * * @param iwSlideChangeListener */ @Override public void addIWSlideChangeListeners(IWSlideChangeListener iwSlideChangeListener) { if (this.iwSlideChangeListeners == null) { this.iwSlideChangeListeners = new ArrayList<IWSlideChangeListener>(); } if (!this.iwSlideChangeListeners.contains(iwSlideChangeListener)) { this.iwSlideChangeListeners.add(iwSlideChangeListener); // update the array, for speed optimization this.iwSlideChangeListenersArray = this.iwSlideChangeListeners.toArray(new IWSlideChangeListener[0]); } } /** * * @param folderURI * @return the count of "real" child resources, excluding folders and hidden * files */ @Override public int getChildCountExcludingFoldersAndHiddenFiles(String folderURI) { List<String> children = getChildPathsExcludingFoldersAndHiddenFiles(folderURI); if (children != null) { return children.size(); } return 0; } /** * * @param folderURI * @return the count of folder resources under the sepcified path, excluding * files and hidden files */ @Override public int getChildFolderCount(String folderURI) { List<String> children = getChildFolderPaths(folderURI); if (children != null) { return children.size(); } return 0; } /** * * @param folderURI * @return the count of ALL child resources, including folders and hidden * files */ @Override public int getChildCount(String folderURI) { List<String> children = getChildPaths(folderURI); if (children != null) { return children.size(); } return 0; } @Override public boolean isHiddenFile(String fileName) { if (fileName != null) { return fileName.startsWith(CoreConstants.DOT) || fileName.startsWith("Thumbs.db"); } return false; } /** * * @param folderURI * @return the count of "real" child resources, excluding folders and hidden * files */ @Override public List<String> getChildPathsExcludingFoldersAndHiddenFiles(String folderURI) { Map<String, List<String>> cache = getChildPathsCacheMap(); List<String> paths = cache.get(folderURI); if (paths == null) { try { // TODO optimize by using a dasl search! WebdavResource resource = getWebdavResourceAuthenticatedAsRoot(folderURI); if (resource.isCollection()) { WebdavResources children = resource.getChildResources(); WebdavResource[] resources = children.listResources(); if (resources.length > 0) { paths = new ArrayList<String>(); for (int i = 0; i < resources.length; i++) { WebdavResource wResource = resources[i]; String path = wResource.getPath(); String fileName = path.substring(path.lastIndexOf(CoreConstants.SLASH) + 1); if (!resources[i].isCollection() && !isHiddenFile(fileName)) { paths.add(wResource.getPath()); } } cache.put(folderURI, paths); } } } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return paths; } /** * * @param folderURI * @return the paths of folder resources under the specified path, excluding * files and hidden files */ @Override public List<String> getChildFolderPaths(String folderURI) { Map<String, List<String>>cache = getChildFolderPathsCacheMap(); List<String> paths = cache.get(folderURI); if (paths == null) { try { // TODO optimize by using a dasl search! WebdavResource resource = getWebdavResourceAuthenticatedAsRoot(folderURI); if (resource.isCollection()) { WebdavResources children = resource.getChildResources(); WebdavResource[] resources = children.listResources(); if (resources.length > 0) { paths = new ArrayList<String>(); for (int i = 0; i < resources.length; i++) { WebdavResource wResource = resources[i]; if (resources[i].isCollection()) { paths.add(wResource.getPath()); } } cache.put(folderURI, paths); } } } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return paths; } /** * * @param folderURI * @return the path of ALL child resources, including folders and hidden * files. Null if no children */ @Override public List<String> getChildPaths(String folderURI) { Map<String, List<String>> cache = getChildPathsCacheMap(); List<String> paths = cache.get(folderURI); if (paths == null) { try { // TODO optimize by using a dasl search! WebdavResource resource = getWebdavResourceAuthenticatedAsRoot(folderURI); if (resource.isCollection()) { WebdavResources children = resource.getChildResources(); WebdavResource[] resources = children.listResources(); if (resources.length > 0) { paths = new ArrayList<String>(); for (int i = 0; i < resources.length; i++) { WebdavResource wResource = resources[i]; paths.add(wResource.getPath()); } cache.put(folderURI, paths); } } } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return paths; } /** * Takes the URI and splits it by each "/" and invalidates child counts and * childpath caches for each folder * * @param URI */ @Override public void invalidateCacheForAllFoldersInURIPath(String URI) { // rip the URI apart and then rebuild it from ground up, invalidating // each folders cache // must end with a "/" if (!URI.endsWith(CoreConstants.SLASH)) { URI += CoreConstants.SLASH; } StringBuffer createPath = new StringBuffer(); StringTokenizer st = new StringTokenizer(URI, CoreConstants.SLASH); while (st.hasMoreTokens()) { if (!createPath.toString().startsWith(CoreConstants.SLASH)) { createPath.append(CoreConstants.SLASH); } createPath.append(st.nextToken()).append(CoreConstants.SLASH); // clear from maps String path = createPath.toString(); getChildFolderPathsCacheMap().remove(path); getChildPathsCacheMap().remove(path); getChildPathsExcludingFolderAndHiddenFilesCacheMap().remove(path); } } /** * @return Returns the childFolderPathsCacheMap. */ @Override public Map<String, List<String>> getChildFolderPathsCacheMap() { return this.childFolderPathsCacheMap; } /** * @param childFolderPathsCacheMap * The childFolderPathsCacheMap to set. */ @Override public void setChildFolderPathsCacheMap(Map<String, List<String>> childFolderPathsCacheMap) { this.childFolderPathsCacheMap = childFolderPathsCacheMap; } /** * @param <K> * @param <V> * @return Returns the childPathsCacheMap. */ @Override public Map<String, List<String>> getChildPathsCacheMap() { return this.childPathsCacheMap; } /** * @param childPathsCacheMap * The childPathsCacheMap to set. */ @Override public void setChildPathsCacheMap(Map<String, List<String>> childPathsCacheMap) { this.childPathsCacheMap = childPathsCacheMap; } /** * @return Returns the childPathsExcludingFolderAndHiddenFilesCacheMap. */ @Override public Map<String, List<String>> getChildPathsExcludingFolderAndHiddenFilesCacheMap() { return this.childPathsExcludingFolderAndHiddenFilesCacheMap; } /** * @param childPathsExcludingFolderAndHiddenFilesCacheMap * The childPathsExcludingFolderAndHiddenFilesCacheMap to set. */ @Override public void setChildPathsExcludingFolderAndHiddenFilesCacheMap(Map<String, List<String>> childPathsExcludingFolderAndHiddenFilesCacheMap) { this.childPathsExcludingFolderAndHiddenFilesCacheMap = childPathsExcludingFolderAndHiddenFilesCacheMap; } /* * (non-Javadoc) * * @see com.idega.slide.business.IWSlideChangeListener#onSlideChange(org.apache.slide.event.ContentEvent) */ @Override public void onSlideChange(IWContentEvent contentEvent) { // get the url changing and invalidate String URI = contentEvent.getContentEvent().getUri(); invalidateCacheForAllFoldersInURIPath(URI); } /** * Gets the parent path of the resource * * @param resource * @return */ @Override public String getParentPath(WebdavResource resource) { String path = resource.getPath(); return getParentPath(path); } @Override public String getParentPath(String path) { String parentPath = null; if (path != null) { int index = path.lastIndexOf(CoreConstants.SLASH); if (index == 0) { parentPath = CoreConstants.EMPTY; } else { parentPath = path.substring(0, index); } } else { return null; } return parentPath; } /** * Uploads zip file's contents to slide. Note: only *.zip file allowed! * * @param zipInputStream: * a stream to read the file and its content from * @param uploadPath: * a path in slide where to store files (for example: * "/files/public/") * @return result: success (true) or failure (false) while uploading file */ @Override public boolean uploadZipFileContents(ZipInputStream zipInputStream, String uploadPath) { boolean result = (uploadPath == null || CoreConstants.EMPTY .equals(uploadPath)) ? false : true; // Checking if // parameters are valid if (!result) { LOGGER.warning("Invalid upload path!"); return result; } result = zipInputStream == null ? false : true; if (!result) { LOGGER.warning("ZipInputStream is closed!"); return result; } ZipEntry entry = null; ZipInstaller zip = new ZipInstaller(); ByteArrayOutputStream memory = null; InputStream is = null; String pathToFile = null; String fileName = null; try { while ((entry = zipInputStream.getNextEntry()) != null && result) { if (!entry.isDirectory()) { pathToFile = CoreConstants.EMPTY; fileName = StringHandler.removeCharacters(entry.getName(), CoreConstants.SPACE, CoreConstants.UNDER); fileName = StringHandler.removeCharacters(fileName, CoreConstants.BRACKET_LEFT, CoreConstants.EMPTY); fileName = StringHandler.removeCharacters(fileName, CoreConstants.BRACKET_RIGHT, CoreConstants.EMPTY); int lastSlash = fileName.lastIndexOf(CoreConstants.SLASH); if (lastSlash != -1) { pathToFile = fileName.substring(0, lastSlash + 1); fileName = fileName.substring(lastSlash + 1, fileName .length()); } if (!fileName.startsWith(CoreConstants.DOT)) { // If not a system file memory = new ByteArrayOutputStream(); zip.writeFromStreamToStream(zipInputStream, memory); is = new ByteArrayInputStream(memory.toByteArray()); result = uploadFile(uploadPath + pathToFile, fileName, null, is); memory.close(); is.close(); } } zip.closeEntry(zipInputStream); } } catch (IOException e) { LOGGER.log(Level.WARNING, "Error uploading zip file to: " + uploadPath, e); return false; } finally { zip.closeEntry(zipInputStream); } return result; } /** * Gets an inputstream for reading the file on the given path as ROOT * * @throws IOException * @throws */ @Override public InputStream getInputStream(String path) throws IOException { InputStream stream = null; IWSimpleSlideService simpleSlideService = getSimpleSlideService(); if (simpleSlideService != null) stream = simpleSlideService.getInputStream(path); try { if (!IOUtil.isStreamValid(stream)) { IOUtil.close(stream); WebdavResource resource = getWebdavExternalResourceAuthenticatedAsRoot(path); stream = getInputStream(resource); } } catch (Exception e) { getLogger().log(Level.WARNING, "Error getting stream to " + path, e); } if (stream != null) return stream; File tmp = CoreUtil.getFileFromRepository(path.concat("_1.0")); if (tmp != null && tmp.exists()) stream = new FileInputStream(tmp); return stream; } @Override public InputStream getInputStream(WebdavResource resource) throws IOException, RemoteException { if (resource == null) { LOGGER.warning("Provided WebdavResource is undefined!"); return null; } if (!resource.exists()) { LOGGER.warning("Provided WebdavResource does not exist at: " + resource.getPath()); return null; } try { if (resource instanceof WebdavLocalResource) { InputStream stream = resource.getMethodData(); if (IOUtil.isStreamValid(stream)) { return stream; } IOUtil.close(stream); String path = resource.getPath(); resource = getWebdavExternalResourceAuthenticatedAsRoot(resource.getPath()); if (resource == null) { LOGGER.warning("InputStream from local resource '" + path + "' was invalid, tried to load resource via HTTP and it failed!"); return null; } } return resource.getMethodData(); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error getting input stream from: " + resource.getPath()); return null; } } IWSimpleSlideService getSimpleSlideService() { if (simpleSlideService == null) { ELUtil.getInstance().autowire(this); } return simpleSlideService; } @Override public OutputStream getOutputStream(File file) throws IOException { return getOutputStream(file.getAbsolutePath()); } /** * Gets an outputstream for writing to the file on the given path * * @throws IOException * @throws */ @Override public OutputStream getOutputStream(String path) throws IOException { WebdavResource resource = getWebdavResourceAuthenticatedAsRoot(path); return new WebdavOutputStream(resource); } /** * Gets a file representation for the given path as root * * @throws RemoteException */ @Override public File getFile(String path) throws URIException, RemoteException { WebdavFile file = null; try { file = new WebdavFile(getWebdavServerURL(getRootUserCredentials(), path)); } catch (IBOLookupException e) { e.printStackTrace(); } return file; } @Override public boolean deleteAsRootUser(String path) throws RemoteException { if (getSimpleSlideService().delete(path)) { return true; } try { WebdavResource resource = getWebdavResourceAuthenticatedAsRoot(path); return resource.deleteMethod(); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error deleting: " + path, e); return false; } } @Override public boolean delete(String path, UsernamePasswordCredentials credentials) throws RemoteException { try { WebdavResource resource = getWebdavResource(path, credentials); resource.deleteMethod(); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error deleting: " + path, e); return false; } return true; } }