/*
* Copyright (C) 2003-2007 eXo Platform SEA.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.wcm.connector.fckeditor;
import java.net.URLDecoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.annotation.security.RolesAllowed;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.ecm.connector.fckeditor.FCKUtils;
import org.exoplatform.ecm.utils.text.Text;
import org.exoplatform.services.cms.BasePath;
import org.exoplatform.services.cms.drives.DriveData;
import org.exoplatform.services.cms.drives.ManageDriveService;
import org.exoplatform.services.cms.impl.Utils;
import org.exoplatform.services.cms.link.LinkManager;
import org.exoplatform.services.cms.link.NodeFinder;
import org.exoplatform.services.cms.templates.TemplateService;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.resources.ResourceBundleService;
import org.exoplatform.services.rest.resource.ResourceContainer;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.Identity;
import org.exoplatform.services.security.IdentityRegistry;
import org.exoplatform.services.security.MembershipEntry;
import org.exoplatform.services.wcm.core.NodeLocation;
import org.exoplatform.services.wcm.core.NodetypeConstant;
import org.exoplatform.services.wcm.portal.PortalFolderSchemaHandler;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;
import org.exoplatform.services.wcm.webcontent.WebContentSchemaHandler;
import org.exoplatform.wcm.connector.BaseConnector;
import org.exoplatform.wcm.connector.FileUploadHandler;
import org.exoplatform.wcm.connector.handler.FCKFileHandler;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.apache.commons.lang.StringUtils;
/**
* Returns a list of drives/folders/documents in a specified location for a given user. Also, it processes the file uploading action.
*
* {{{{portalname}}}}: The name of portal.
* {{{{restcontextname}}}}: The context name of REST web application which is deployed to the "{{{{portalname}}}}" portal.
*
* @LevelAPI Provisional
* @anchor DriverConnector
*/
@Path("/wcmDriver/")
public class DriverConnector extends BaseConnector implements ResourceContainer {
/** The Constant FILE_TYPE_WEBCONTENT. */
public static final String FILE_TYPE_WEBCONTENT = "Web Contents";
/** The Constant FILE_TYPE_DMSDOC. */
public static final String FILE_TYPE_DMSDOC = "DMS Documents";
/** The Constant FILE_TYPE_MEDIAS. */
public static final String FILE_TYPE_MEDIAS = "Medias";
/** The Constant FILE_TYPE_MEDIAS. */
public static final String FILE_TYPE_ALL = "All";
/** The Constant FILE_TYPE_IMAGE. */
public static final String FILE_TYPE_IMAGE = "Image";
/** The Constant MEDIA_MIMETYPE. */
public static final String[] MEDIA_MIMETYPE = new String[]{"application", "image", "audio", "video"};
/** The Constant MEDIA_MIMETYPE. */
public static final String[] IMAGE_MIMETYPE = new String[]{"image"};
public static final String TYPE_FOLDER = "folder";
public static final String TYPE_EDITOR = "editor";
public static final String TYPE_CONTENT = "multi";
/** The log. */
private static final Log LOG = ExoLogger.getLogger(DriverConnector.class.getName());
/** The limit. */
private int limit;
/** The file number limit on client side. */
private int limitCountClient_ = 3;
/** The file number limit on server side. */
private int limitCountServer_ = 30;
private List<String> browsableContent =new ArrayList<String>();
private ResourceBundleService resourceBundleService=null;
private NodeFinder nodeFinder_ = null;
private LinkManager linkManager_ = null;
private String resourceBundleNames[];
private ResourceBundle sharedResourceBundle=null;
private Locale lang = Locale.ENGLISH;
/**
* Instantiates a new driver connector.
*
* @param params The init parameters.
*/
public DriverConnector(InitParams params) {
limit = Integer.parseInt(params.getValueParam("upload.limit.size").getValue());
if (params.getValueParam("upload.limit.count.client") != null) {
limitCountClient_ = Integer.parseInt(params.getValueParam("upload.limit.count.client").getValue());
}
if (params.getValueParam("upload.limit.count.server") != null) {
limitCountServer_ = Integer.parseInt(params.getValueParam("upload.limit.count.server").getValue());
}
if (params.getValueParam("exo.ecms.content.browsable") != null) {
browsableContent = Arrays.asList((params.getValueParam("exo.ecms.content.browsable").getValue()).split("\\s*,\\s*"));
}
}
/**
* Gets the maximum size of the uploaded file.
* @return The file size limit.
*/
public int getLimitSize() { return limit; }
/**
* Gets the maximum number of files uploaded from the client side.
* @return The maximum number of files uploaded on the client side.
*/
public int getMaxUploadCount() { return limitCountClient_; }
/**
* Returns a list of drives for the current user.
*
* @param lang The language of the drive name.
* @return The drives.
* @throws Exception The exception
*
* @anchor DriverConnector.getDrivers
*/
@GET
@Path("/getDrivers/")
@RolesAllowed("users")
public Response getDrivers(@QueryParam("lang") String lang) throws Exception {
ConversationState conversationState = ConversationState.getCurrent();
String userId = conversationState.getIdentity().getUserId();
List<DriveData> listDriver = getDriversByUserId(userId);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
Element rootElement = document.createElement("Connector");
document.appendChild(rootElement);
rootElement.setAttribute("isUpload", "false");
rootElement.appendChild(appendDrivers(document, generalDrivers(listDriver), "General Drives", lang));
rootElement.appendChild(appendDrivers(document, groupDrivers(listDriver), "Group Drives", lang));
rootElement.appendChild(appendDrivers(document, personalDrivers(listDriver, userId), "Personal Drives", lang));
CacheControl cacheControl = new CacheControl();
cacheControl.setNoCache(true);
cacheControl.setNoStore(true);
DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
return Response.ok(new DOMSource(document), MediaType.TEXT_XML)
.cacheControl(cacheControl)
.header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date()))
.build();
}
/**
* Returns all folders and files in a given location.
*
* @param driverName The drive name.
* @param currentFolder The current folder.
* @param currentPortal The current portal.
* @param repositoryName The repository name.
* @param workspaceName The workspace name.
* @param filterBy The type of filter.
* @return The folders and files.
* @throws Exception The exception
*
* @anchor DriverConnector.getFoldersAndFiles
*/
@GET
@Path("/getFoldersAndFiles/")
@RolesAllowed("users")
public Response getFoldersAndFiles(
@QueryParam("driverName") String driverName,
@QueryParam("currentFolder") String currentFolder,
@QueryParam("currentPortal") String currentPortal,
@QueryParam("repositoryName") String repositoryName,
@QueryParam("workspaceName") String workspaceName,
@QueryParam("filterBy") String filterBy,
@QueryParam("type") String type)
throws Exception {
try {
RepositoryService repositoryService = WCMCoreUtils.getService(RepositoryService.class);
ManageDriveService manageDriveService = WCMCoreUtils.getService(ManageDriveService.class);
SessionProvider sessionProvider = WCMCoreUtils.getUserSessionProvider();
ManageableRepository manageableRepository = repositoryService.getCurrentRepository();
DriveData drive = manageDriveService.getDriveByName(Text.escapeIllegalJcrChars(driverName));
workspaceName = drive.getWorkspace();
Session session = sessionProvider.getSession(workspaceName, manageableRepository);
String driverHomePath = drive.getHomePath();
String itemPath = driverHomePath
+ ((currentFolder != null && !"".equals(currentFolder) && !driverHomePath.endsWith("/")) ? "/" : "")
+ currentFolder;
ConversationState conversationState = ConversationState.getCurrent();
String userId = conversationState.getIdentity().getUserId();
itemPath = Utils.getPersonalDrivePath(itemPath, userId);
Node node = (Node)session.getItem(Text.escapeIllegalJcrChars(itemPath));
return buildXMLResponseForChildren(node,
null,
filterBy,
session,
currentPortal,
Text.escapeIllegalJcrChars(driverName), type);
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error("Error when perform getFoldersAndFiles: ", e);
}
}
DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
return Response.ok().header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date())).build();
}
/**
* Checks if the drive can upload a new file.
*
* @return Response containing the status indicating if upload is available.
* @throws Exception
* @anchor DriverConnector.checkUploadAvailable
*/
@GET
@Path("/uploadFile/checkUploadAvailable/")
@RolesAllowed("users")
public Response checkUploadAvailable() throws Exception {
CacheControl cacheControl = new CacheControl();
cacheControl.setNoCache(true);
DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
String msg = fileUploadHandler.getUploadingFileCount() < limitCountServer_ ? "uploadAvailable" : "uploadNotAvailable";
return Response.ok(createDOMResponse(msg), MediaType.TEXT_XML)
.cacheControl(cacheControl)
.header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date()))
.build();
}
/**
* Uploads a file.
*
* @param uploadId The Id of the uploaded file.
* @return The response.
* @throws Exception The exception
*
* @anchor DriverConnector.uploadFile
*/
@POST
@Path("/uploadFile/upload/")
@RolesAllowed("users")
public Response uploadFile(@Context HttpServletRequest servletRequest,
@QueryParam("uploadId") String uploadId) throws Exception {
//check if number of file uploading is greater than the limit
// if (fileUploadHandler.getUploadingFileCount() >= limitCountServer_) {
// CacheControl cacheControl = new CacheControl();
// cacheControl.setNoCache(true);
// DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
// return Response.ok(createDOMResponse("uploadNotAvailable"), MediaType.TEXT_XML)
// .cacheControl(cacheControl)
// .header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date()))
// .build();
// }
return fileUploadHandler.upload(servletRequest, uploadId, limit);
}
/**
* Check the status of uploading a file, such as aborting, deleting or progressing the file.
*
* @param repositoryName The repository name.
* @param workspaceName The workspace name.
* @param driverName The drive name.
* @param currentFolder The current folder.
* @param currentPortal The portal name.
* @param language The language file.
* @param fileName The file name.
* @return The response
* @throws Exception The exception
*
* @anchor DriverConnector.checkExistence
*/
@GET
@Path("/uploadFile/checkExistence/")
@RolesAllowed("users")
public Response checkExistence(
@QueryParam("repositoryName") String repositoryName,
@QueryParam("workspaceName") String workspaceName,
@QueryParam("driverName") String driverName,
@QueryParam("currentFolder") String currentFolder,
@QueryParam("currentPortal") String currentPortal,
@QueryParam("language") String language,
@QueryParam("fileName") String fileName) throws Exception {
try {
// Check file existence
Node currentFolderNode = getParentFolderNode(workspaceName,
Text.escapeIllegalJcrChars(driverName),
Text.escapeIllegalJcrChars(currentFolder));
if(StringUtils.isNotEmpty(fileName)) fileName = URLDecoder.decode(fileName, "UTF-8");
return fileUploadHandler.checkExistence(currentFolderNode, fileName);
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error("Error when perform processUpload: ", e);
}
}
DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
return Response.ok().header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date())).build();
}
/**
* Clean file name
*
* @param fileName original file name
* @return the response
*/
@GET
@Path("/uploadFile/cleanName")
@RolesAllowed("users")
public Response cleanName (@QueryParam("fileName") String fileName) throws Exception{
return fileUploadHandler.cleanName(fileName);
}
/**
* Controls the process of uploading a file, such as aborting, deleting or progressing the file.
*
* @param repositoryName The repository name.
* @param workspaceName The workspace name.
* @param driverName The drive name.
* @param currentFolder The current folder.
* @param currentPortal The current portal.
* @param userId The user identity.
* @param jcrPath The path of the file.
* @param action The action.
* @param language The language.
* @param fileName The file name.
* @param uploadId The Id of upload.
* @param existenceAction Checks if an action exists or not.
* @return The response.
* @throws Exception The exception
*
* @anchor DriverConnector.processUpload
*/
@GET
@Path("/uploadFile/control/")
@RolesAllowed("users")
public Response processUpload(
@QueryParam("repositoryName") String repositoryName,
@QueryParam("workspaceName") String workspaceName,
@QueryParam("driverName") String driverName,
@QueryParam("currentFolder") String currentFolder,
@QueryParam("currentPortal") String currentPortal,
@QueryParam("userId") String userId,
@QueryParam("jcrPath") String jcrPath,
@QueryParam("action") String action,
@QueryParam("language") String language,
@QueryParam("fileName") String fileName,
@QueryParam("uploadId") String uploadId,
@QueryParam("existenceAction") String existenceAction,
@QueryParam("srcAction") String srcAction) throws Exception {
try {
// Check upload status
if(StringUtils.isNotEmpty(fileName)) fileName = URLDecoder.decode(fileName, "UTF-8");
Response msgResponse = fileUploadHandler.checkStatus(uploadId, language);
if (msgResponse != null) return msgResponse;
if ((repositoryName != null) && (workspaceName != null) && (driverName != null)
&& (currentFolder != null)) {
ManageDriveService manageDriveService = WCMCoreUtils.getService(ManageDriveService.class);
workspaceName = workspaceName != null ? workspaceName :
manageDriveService.getDriveByName(Text.escapeIllegalJcrChars(driverName))
.getWorkspace();
Node currentFolderNode = getParentFolderNode(workspaceName,
Text.escapeIllegalJcrChars(driverName),
Text.escapeIllegalJcrChars(currentFolder));
fileName = Text.escapeIllegalJcrChars(fileName);
return createProcessUploadResponse(workspaceName,
currentFolderNode,
currentPortal,
userId,
Text.escapeIllegalJcrChars(jcrPath),
action,
language,
fileName,
uploadId,
existenceAction);
}
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error("Error when perform processUpload: ", e);
}
}
DateFormat dateFormat = new SimpleDateFormat(IF_MODIFIED_SINCE_DATE_FORMAT);
return Response.ok().header(LAST_MODIFIED_PROPERTY, dateFormat.format(new Date())).build();
}
/**
* Gets the drives by user Id.
*
* @param userId the user Id
*
* @return the drives by user Id
*
* @throws Exception the exception
*/
private List<DriveData> getDriversByUserId(String userId) throws Exception {
ManageDriveService driveService = WCMCoreUtils.getService(ManageDriveService.class);
List<String> userRoles = getMemberships(userId);
return driveService.getDriveByUserRoles(userId, userRoles);
}
/**
* Appends drives.
*
* @param document The document.
* @param driversList The drivers list.
* @param groupName The group name.
*
* @return The element.
*/
private Element appendDrivers(Document document,
List<DriveData> driversList,
String groupName,
String lang) throws Exception {
Element folders = document.createElement("Folders");
folders.setAttribute("name", resolveDriveLabel(groupName, lang));
folders.setAttribute("isUpload", "false");
for (DriveData driver : driversList) {
String repository = WCMCoreUtils.getRepository().getConfiguration().getName();
String workspace = driver.getWorkspace();
String path = driver.getHomePath();
String name = driver.getName();
Element folder = document.createElement("Folder");
NodeLocation nodeLocation = new NodeLocation(repository, workspace, path);
Node driveNode = NodeLocation.getNodeByLocation(nodeLocation);
if(driveNode == null) continue;
folder.setAttribute("name", name);
folder.setAttribute("label", resolveDriveLabel(name, lang));
folder.setAttribute("url", FCKUtils.createWebdavURL(driveNode));
folder.setAttribute("folderType", "exo:drive");
folder.setAttribute("path", path);
folder.setAttribute("repository", repository);
folder.setAttribute("workspace", workspace);
folder.setAttribute("isUpload", "true");
folder.setAttribute("hasFolderChild", String.valueOf(this.hasFolderChild(driveNode)));
folder.setAttribute("nodeTypeCssClass", Utils.getNodeTypeIcon(driveNode, "uiIcon16x16"));
folders.appendChild(folder);
}
return folders;
}
private String resolveDriveLabel(String name, String lang) {
if (resourceBundleService ==null) {
resourceBundleService = WCMCoreUtils.getService(ResourceBundleService.class);
resourceBundleNames = resourceBundleService.getSharedResourceBundleNames();
sharedResourceBundle = resourceBundleService.getResourceBundle(resourceBundleNames, this.lang);
}
try {
if(!this.lang.getLanguage().equals(lang)){
this.lang = new Locale(lang);
sharedResourceBundle = resourceBundleService.getResourceBundle(resourceBundleNames, this.lang);
}
return sharedResourceBundle.getString("ContentSelector.title." + name.replaceAll(" ", ""));
} catch (MissingResourceException e) {
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage());
}
}
return name;
}
/**
* Personal drivers.
*
* @param driveList the drive list
*
* @return the list< drive data>
* @throws Exception
*/
private List<DriveData> personalDrivers(List<DriveData> driveList, String userId) throws Exception {
List<DriveData> personalDrivers = new ArrayList<DriveData>();
NodeHierarchyCreator nodeHierarchyCreator = WCMCoreUtils.getService(NodeHierarchyCreator.class);
SessionProvider sessionProvider = WCMCoreUtils.getSystemSessionProvider();
Node userNode = nodeHierarchyCreator.getUserNode(sessionProvider, userId);
for(DriveData drive : driveList) {
String driveHomePath = Utils.getPersonalDrivePath(drive.getHomePath(), userId);
if(driveHomePath.startsWith(userNode.getPath())) {
drive.setHomePath(driveHomePath);
personalDrivers.add(drive);
}
}
Collections.sort(personalDrivers);
return personalDrivers;
}
/**
* Group drivers.
*
* @param driverList the driver list
* @return the list< drive data>
* @throws Exception the exception
*/
private List<DriveData> groupDrivers(List<DriveData> driverList) throws Exception {
ManageDriveService driveService = WCMCoreUtils.getService(ManageDriveService.class);
String currentUserId = ConversationState.getCurrent().getIdentity().getUserId();
List<String> userRoles = this.getMemberships(currentUserId);
return driveService.getGroupDrives(currentUserId, userRoles);
}
/**
* General drivers.
*
* @param driverList the driver list
*
* @return the list< drive data>
*
* @throws Exception the exception
*/
private List<DriveData> generalDrivers(List<DriveData> driverList) throws Exception {
List<DriveData> generalDrivers = new ArrayList<DriveData>();
NodeHierarchyCreator nodeHierarchyCreator = WCMCoreUtils.getService(NodeHierarchyCreator.class);
String userPath = nodeHierarchyCreator.getJcrPath(BasePath.CMS_USERS_PATH);
String groupPath = nodeHierarchyCreator.getJcrPath(BasePath.CMS_GROUPS_PATH);
for(DriveData drive : driverList) {
if((!drive.getHomePath().startsWith(userPath) && !drive.getHomePath().startsWith(groupPath))
|| drive.getHomePath().equals(userPath)) {
generalDrivers.add(drive);
}
}
return generalDrivers;
}
/**
* Gets the memberships.
*
* @param userId the user id
*
* @return the memberships
*
* @throws Exception the exception
*/
private List<String> getMemberships(String userId) throws Exception {
List<String> userMemberships = new ArrayList<String> ();
userMemberships.add(userId);
// here we must retrieve memberships of the user using the
// IdentityRegistry Service instead of Organization Service to
// allow JAAS based authorization
Collection<MembershipEntry> memberships = getUserMembershipsFromIdentityRegistry(userId);
if (memberships != null) {
for (MembershipEntry membership : memberships) {
String role = membership.getMembershipType() + ":" + membership.getGroup();
userMemberships.add(role);
}
}
return userMemberships;
}
/**
* this method retrieves memberships of the user having the given id using the
* IdentityRegistry service instead of the Organization service to allow JAAS
* based authorization
*
* @param authenticatedUser the authenticated user id
* @return a collection of MembershipEntry
*/
private static Collection<MembershipEntry> getUserMembershipsFromIdentityRegistry(String authenticatedUser) {
IdentityRegistry identityRegistry = WCMCoreUtils.getService(IdentityRegistry.class);
Identity currentUserIdentity = identityRegistry.getIdentity(authenticatedUser);
return currentUserIdentity.getMemberships();
}
private Response buildXMLResponseForChildren(Node node,
String command,
String filterBy,
Session session,
String currentPortal,
String nodeDriveName,
String type) throws Exception {
TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
Element rootElement = FCKUtils.createRootElement(command, node, folderHandler.getFolderType(node));
NodeList nodeList = rootElement.getElementsByTagName("CurrentFolder");
Element currentFolder = (Element) nodeList.item(0);
currentFolder.setAttribute("isUpload", "true");
Document document = rootElement.getOwnerDocument();
Element folders = document.createElement("Folders");
folders.setAttribute("isUpload", "true");
Element files = document.createElement("Files");
files.setAttribute("isUpload", "true");
Node sourceNode = null;
Node checkNode = null;
List<Node> childList = new ArrayList<Node>();
for (NodeIterator iterator = node.getNodes(); iterator.hasNext();) {
childList.add(iterator.nextNode());
}
Collections.sort(childList,new NodeTitleComparator());
for (Node child:childList) {
String fileType = null;
if (child.isNodeType(FCKUtils.EXO_HIDDENABLE))
continue;
if(TYPE_FOLDER.equals(type) && templateService.isManagedNodeType(child.getPrimaryNodeType().getName()))
continue;
if(child.isNodeType("exo:symlink") && child.hasProperty("exo:uuid")) {
LinkManager linkManager = WCMCoreUtils.getService(LinkManager.class);
sourceNode = linkManager.getTarget(child);
} else {
sourceNode = child;
}
checkNode = sourceNode != null ? sourceNode : child;
if (isFolder(checkNode, type)) {
// Get node name from node path to fix same name problem (ECMS-3586)
String nodePath = child.getPath();
Element folder = createFolderElement(document, checkNode, checkNode.getPrimaryNodeType().getName(),
nodePath.substring(nodePath.lastIndexOf("/") + 1, nodePath.length()), nodeDriveName, type);
folders.appendChild(folder);
}
if (FILE_TYPE_ALL.equals(filterBy)
&& (checkNode.isNodeType(NodetypeConstant.EXO_WEBCONTENT) || !isFolder(checkNode, type))) {
fileType = FILE_TYPE_ALL;
}
if (FILE_TYPE_WEBCONTENT.equals(filterBy)) {
if(checkNode.isNodeType(NodetypeConstant.EXO_WEBCONTENT)) {
fileType = FILE_TYPE_WEBCONTENT;
}
}
if (FILE_TYPE_MEDIAS.equals(filterBy) && isMediaType(checkNode)){
fileType = FILE_TYPE_MEDIAS;
}
if (FILE_TYPE_DMSDOC.equals(filterBy) && isDMSDocument(checkNode)) {
fileType = FILE_TYPE_DMSDOC;
}
if (FILE_TYPE_IMAGE.equals(filterBy) && isImageType(checkNode)) {
fileType = FILE_TYPE_IMAGE;
}
if (fileType != null) {
Element file = FCKFileHandler.createFileElement(document, fileType, checkNode, child, currentPortal, linkManager);
files.appendChild(file);
}
}
rootElement.appendChild(folders);
rootElement.appendChild(files);
return getResponse(document);
}
/**
* Checks if is folder and is not web content.
*
* @param checkNode the check node
*
* @return true, if is folder and is not web content
*
* @throws RepositoryException the repository exception
*/
private boolean isFolder(Node checkNode, String type) throws RepositoryException {
try {
if (isDocument(checkNode, type)) return false;
} catch (Exception e) {
if (LOG.isWarnEnabled()) {
LOG.warn(e.getMessage());
}
}
return
checkNode.isNodeType(NodetypeConstant.NT_UNSTRUCTURED)
|| checkNode.isNodeType(NodetypeConstant.NT_FOLDER)
|| checkNode.isNodeType(NodetypeConstant.EXO_TAXONOMY);
}
/**
* Check if specific node has child which is type of nt:folder or nt:unstructured.
*
* @param checkNode The node to be checked
* @return True if the folder has some child.
* @throws Exception
*/
private boolean hasFolderChild(Node checkNode) throws Exception {
return (Utils.hasChild(checkNode, NodetypeConstant.NT_UNSTRUCTURED)
|| Utils.hasChild(checkNode, NodetypeConstant.NT_FOLDER));
}
/**
* Checks if is dMS document.(not including free layout webcontent and media and article)
*
* @param node the node
*
* @return true, if is dMS document
*
* @throws Exception the exception
*/
private boolean isDMSDocument(Node node) throws Exception {
TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
List<String> dmsDocumentListTmp = templateService.getDocumentTemplates();
List<String> dmsDocumentList = new ArrayList<String>();
dmsDocumentList.addAll(dmsDocumentListTmp);
dmsDocumentList.remove(NodetypeConstant.EXO_WEBCONTENT);
for (String documentType : dmsDocumentList) {
if (node.getPrimaryNodeType().isNodeType(documentType)
&& !isMediaType(node)
&& !node.isNodeType(NodetypeConstant.EXO_WEBCONTENT)) {
return true;
}
}
return false;
}
/**
* Checks if specific node is document
*
* @param node specific Node
* @return true: is document, false: not document
* @throws RepositoryException
*/
private boolean isDocument(Node node, String type) throws RepositoryException {
TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
List<String> documentTypeList = templateService.getDocumentTemplates();
if (TYPE_EDITOR.equals(type) && browsableContent != null) {
for (String browsableDocument : browsableContent) {
documentTypeList.remove(browsableDocument);
}
}
for (String documentType : documentTypeList) {
if (node.getPrimaryNodeType().isNodeType(documentType)) {
return true;
}
}
return false;
}
/**
* Checks if is media type.
*
* @param node the node
*
* @return true, if is media type
*/
private boolean isMediaType(Node node){
String mimeType = "";
try {
mimeType = node.getNode("jcr:content").getProperty("jcr:mimeType").getString();
} catch (Exception e) {
return false;
}
for(String type: MEDIA_MIMETYPE) {
if(mimeType.contains(type)){
return true;
}
}
return false;
}
/**
* Checks if is image type.
*
* @param node the node
*
* @return true, if is image type
*/
private boolean isImageType(Node node){
String mimeType = "";
try {
mimeType = node.getNode("jcr:content").getProperty("jcr:mimeType").getString();
} catch (Exception e) {
return false;
}
for(String type: IMAGE_MIMETYPE) {
if(mimeType.contains(type)){
return true;
}
}
return false;
}
/* (non-Javadoc)
* @see org.exoplatform.wcm.connector.BaseConnector#getContentStorageType()
*/
@Override
protected String getContentStorageType() throws Exception {
return null;
}
/* (non-Javadoc)
* @see org.exoplatform.wcm.connector.BaseConnector#getRootContentStorage(javax.jcr.Node)
*/
@Override
protected Node getRootContentStorage(Node node) throws Exception {
try {
PortalFolderSchemaHandler folderSchemaHandler = webSchemaConfigService
.getWebSchemaHandlerByType(PortalFolderSchemaHandler.class);
return folderSchemaHandler.getImagesFolder(node);
} catch (Exception e) {
WebContentSchemaHandler webContentSchemaHandler = webSchemaConfigService
.getWebSchemaHandlerByType(WebContentSchemaHandler.class);
return webContentSchemaHandler.getImagesFolders(node);
}
}
/**
*
* @param workspaceName The workspace name.
* @param currentFolderNode The current folder.
* @param siteName The portal name.
* @param userId The user Id.
* @param jcrPath The path of the file.
* @param action The action.
* @param language The language.
* @param fileName The file name.
* @param uploadId The Id of upload.
* @param existenceAction Checks if an action exists.
* @return the response
* @throws Exception the exception
*/
protected Response createProcessUploadResponse(String workspaceName,
Node currentFolderNode,
String siteName,
String userId,
String jcrPath,
String action,
String language,
String fileName,
String uploadId,
String existenceAction) throws Exception {
if (FileUploadHandler.SAVE_ACTION.equals(action)) {
CacheControl cacheControl = new CacheControl();
cacheControl.setNoCache(true);
return fileUploadHandler.saveAsNTFile(currentFolderNode, uploadId, fileName, language, siteName, userId, existenceAction);
}else if(FileUploadHandler.SAVE_NEW_VERSION_ACTION.equals(action)){
CacheControl cacheControl = new CacheControl();
cacheControl.setNoCache(true);
return fileUploadHandler.saveAsNTFile(currentFolderNode, uploadId, fileName, language, siteName, userId, existenceAction,true);
}
return fileUploadHandler.control(uploadId, action);
}
/**
* Gets the parent folder node.
*
* @param workspaceName the workspace name
* @param driverName the driver name
* @param currentFolder the current folder
*
* @return the parent folder node
*
* @throws Exception the exception
*/
private Node getParentFolderNode(String workspaceName, String driverName, String currentFolder) throws Exception {
SessionProvider sessionProvider = WCMCoreUtils.getUserSessionProvider();
ManageableRepository manageableRepository = WCMCoreUtils.getRepository();
Session session = sessionProvider.getSession(workspaceName, manageableRepository);
ManageDriveService manageDriveService = WCMCoreUtils.getService(ManageDriveService.class);
DriveData driveData = manageDriveService.getDriveByName(driverName);
String parentPath = (driveData != null ? driveData.getHomePath() : "");
NodeHierarchyCreator nodeHierarchyCreator = WCMCoreUtils.getService(NodeHierarchyCreator.class);
if(driveData != null &&
driveData.getHomePath().startsWith(nodeHierarchyCreator.getJcrPath(BasePath.CMS_USERS_PATH) + "/${userId}")) {
parentPath = Utils.getPersonalDrivePath(driveData.getHomePath(),
ConversationState.getCurrent().getIdentity().getUserId());
};
parentPath += ((currentFolder != null && currentFolder.length() != 0) ? "/" : "") + currentFolder;
parentPath = parentPath.replace("//", "/");
//return result;
return getTargetNode(session, parentPath);
}
private Node getTargetNode(Session session, String path) throws Exception {
Node node = null;
if (linkManager_ == null) {
linkManager_ = WCMCoreUtils.getService(LinkManager.class);
}
if (nodeFinder_ == null) {
nodeFinder_ = WCMCoreUtils.getService(NodeFinder.class);
}
node = (Node)nodeFinder_.getItem(session, path, true);
return node;
}
private Element createFolderElement(Document document,
Node child,
String folderType,
String childName,
String nodeDriveName,
String type) throws Exception {
Element folder = document.createElement("Folder");
folder.setAttribute("name", childName.replaceAll("%", "%25"));
folder.setAttribute("title", Utils.getTitle(child).replaceAll("%", "%25"));
folder.setAttribute("url", FCKUtils.createWebdavURL(child));
folder.setAttribute("folderType", folderType);
if(TYPE_FOLDER.equals(type) || TYPE_CONTENT.equals(type)) {
boolean hasFolderChild = (getChildOfType(child, NodetypeConstant.NT_UNSTRUCTURED, type) != null)
|| (getChildOfType(child, NodetypeConstant.NT_FOLDER, type) != null);
folder.setAttribute("hasFolderChild", String.valueOf(hasFolderChild));
}else{
folder.setAttribute("hasFolderChild", String.valueOf(this.hasFolderChild(child)));
}
folder.setAttribute("path", child.getPath());
folder.setAttribute("isUpload", "true");
folder.setAttribute("nodeTypeCssClass", Utils.getNodeTypeIcon(child, "uiIcon16x16"));
if (nodeDriveName!=null && nodeDriveName.length()>0) folder.setAttribute("nodeDriveName", nodeDriveName);
return folder;
}
/**
* Check isFolder (skip all templateNodetype)
* @param node
* @param childType
* @return
* @throws Exception
*/
private Node getChildOfType(Node node, String childType, String type) throws Exception {
TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
if (node == null) {
return null;
}
NodeIterator iter = node.getNodes();
while (iter.hasNext()) {
Node child = iter.nextNode();
if (!isDocument(child, type) && child.isNodeType(childType)
&& !templateService.isManagedNodeType(child.getPrimaryNodeType().getName())
&& !"exo:thumbnails".equals(child.getPrimaryNodeType().getName()))
{
return child;
}
}
return null;
}
/**
* returns a DOMSource object containing given message
* @param message the message
* @return DOMSource object
* @throws Exception
*/
private DOMSource createDOMResponse(String message) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
Element rootElement = doc.createElement(message);
doc.appendChild(rootElement);
return new DOMSource(doc);
}
private static class NodeTitleComparator implements Comparator<Node>{
@Override
public int compare(Node node1, Node node2) {
try{
String titleNode1 = Utils.getTitle(node1);
String titleNode2 = Utils.getTitle(node2);
return titleNode1.compareToIgnoreCase(titleNode2) ;
}catch (Exception e) {
return 0;
}
}
}
}