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