/*
* $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;
}
}