Java tutorial
/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * 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. * * * Copyright 2006 - 2013 Pentaho Corporation. All rights reserved. */ package org.pentaho.platform.repository2.unified.jcr; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.jcr.AccessDeniedException; import javax.jcr.Item; import javax.jcr.ItemExistsException; import javax.jcr.Node; import javax.jcr.PathNotFoundException; import javax.jcr.Property; import javax.jcr.PropertyIterator; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.lock.Lock; import org.pentaho.platform.api.locale.IPentahoLocale; import org.pentaho.platform.api.repository2.unified.IRepositoryAccessVoterManager; import org.pentaho.platform.api.repository2.unified.IRepositoryDefaultAclHandler; import org.pentaho.platform.api.repository2.unified.IRepositoryFileData; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.RepositoryFileAcl; import org.pentaho.platform.api.repository2.unified.RepositoryFilePermission; import org.pentaho.platform.api.repository2.unified.RepositoryFileTree; import org.pentaho.platform.api.repository2.unified.RepositoryRequest; import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; import org.pentaho.platform.api.repository2.unified.VersionSummary; import org.pentaho.platform.api.repository2.unified.data.node.DataNode; import org.pentaho.platform.api.repository2.unified.data.node.NodeRepositoryFileData; import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.repository2.messages.Messages; import org.pentaho.platform.repository2.unified.IRepositoryFileAclDao; import org.pentaho.platform.repository2.unified.IRepositoryFileDao; import org.pentaho.platform.repository2.unified.ServerRepositoryPaths; import org.springframework.extensions.jcr.JcrCallback; import org.springframework.extensions.jcr.JcrTemplate; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * CRUD operations against JCR. Note that there is no access control in this class (implicit or explicit). * * @author mlowery */ public class JcrRepositoryFileDao implements IRepositoryFileDao { // ~ Static fields/initializers // ====================================================================================== // ~ Instance fields // ================================================================================================= private JcrTemplate jcrTemplate; private List<ITransformer<IRepositoryFileData>> transformers; private ILockHelper lockHelper; private IDeleteHelper deleteHelper; private IPathConversionHelper pathConversionHelper; private IRepositoryFileAclDao aclDao; private IRepositoryDefaultAclHandler defaultAclHandler; private IRepositoryAccessVoterManager accessVoterManager; // ~ Constructors // ==================================================================================================== public JcrRepositoryFileDao(final JcrTemplate jcrTemplate, final List<ITransformer<IRepositoryFileData>> transformers, final ILockHelper lockHelper, final IDeleteHelper deleteHelper, final IPathConversionHelper pathConversionHelper, final IRepositoryFileAclDao aclDao, final IRepositoryDefaultAclHandler defaultAclHandler) { super(); Assert.notNull(jcrTemplate); Assert.notNull(transformers); this.jcrTemplate = jcrTemplate; this.transformers = transformers; this.lockHelper = lockHelper; this.deleteHelper = deleteHelper; this.pathConversionHelper = pathConversionHelper; this.aclDao = aclDao; this.defaultAclHandler = defaultAclHandler; } public JcrRepositoryFileDao(final JcrTemplate jcrTemplate, final List<ITransformer<IRepositoryFileData>> transformers, final ILockHelper lockHelper, final IDeleteHelper deleteHelper, final IPathConversionHelper pathConversionHelper, final IRepositoryFileAclDao aclDao, final IRepositoryDefaultAclHandler defaultAclHandler, final IRepositoryAccessVoterManager accessVoterManager) { this(jcrTemplate, transformers, lockHelper, deleteHelper, pathConversionHelper, aclDao, defaultAclHandler); this.accessVoterManager = accessVoterManager; } // ~ Methods // ========================================================================================================= private RepositoryFile internalCreateFolder(final Session session, final Serializable parentFolderId, final RepositoryFile folder, final RepositoryFileAcl acl, final String versionMessage) throws RepositoryException { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } // Get repository file info and acl info of parent if (parentFolderId != null) { RepositoryFile parentRepositoryFile = getFileById(parentFolderId); if (parentRepositoryFile != null) { RepositoryFileAcl parentAcl = aclDao.getAcl(parentRepositoryFile.getId()); // Invoke accessVoterManager to see if we have access to perform this operation if (!accessVoterManager.hasAccess(parentRepositoryFile, RepositoryFilePermission.WRITE, parentAcl, PentahoSessionHolder.getSession())) { return null; } } } PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, parentFolderId); Node folderNode = JcrRepositoryFileUtils.createFolderNode(session, pentahoJcrConstants, parentFolderId, folder); // create a temporary folder object with correct path for default acl purposes. String path = JcrRepositoryFileUtils.getAbsolutePath(session, pentahoJcrConstants, folderNode); RepositoryFile tmpFolder = new RepositoryFile.Builder(folder).path(path).build(); // we must create the acl during checkout JcrRepositoryFileAclUtils.createAcl(session, pentahoJcrConstants, folderNode.getIdentifier(), acl == null ? defaultAclHandler.createDefaultAcl(tmpFolder) : acl); session.save(); if (folder.isVersioned()) { JcrRepositoryFileUtils.checkinNearestVersionableNodeIfNecessary(session, pentahoJcrConstants, folderNode, versionMessage); } JcrRepositoryFileUtils.checkinNearestVersionableFileIfNecessary(session, pentahoJcrConstants, parentFolderId, Messages.getInstance().getString("JcrRepositoryFileDao.USER_0001_VER_COMMENT_ADD_FOLDER", //$NON-NLS-1$ folder.getName(), (parentFolderId == null ? "root" : parentFolderId.toString()))); //$NON-NLS-1$ return JcrRepositoryFileUtils.nodeToFile(session, pentahoJcrConstants, pathConversionHelper, lockHelper, folderNode); } private RepositoryFile internalCreateFile(final Serializable parentFolderId, final RepositoryFile file, final IRepositoryFileData content, final RepositoryFileAcl acl, final String versionMessage) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } /* * PPP-3049: Changed the Assert.notNull(content) to code that creates a file with a single blank when the assert * WOULD have been triggered. */ Assert.notNull(file); Assert.isTrue(!file.isFolder()); // Get repository file info and acl info of parent if (parentFolderId != null) { RepositoryFile parentRepositoryFile = getFileById(parentFolderId); if (parentRepositoryFile != null) { RepositoryFileAcl parentAcl = aclDao.getAcl(parentRepositoryFile.getId()); // Invoke accessVoterManager to see if we have access to perform this operation if (!accessVoterManager.hasAccess(parentRepositoryFile, RepositoryFilePermission.WRITE, parentAcl, PentahoSessionHolder.getSession())) { return null; } } } // Assert.notNull(content); DataNode emptyDataNode = new DataNode(file.getName()); emptyDataNode.setProperty(" ", "content"); //$NON-NLS-1$ //$NON-NLS-2$ final IRepositoryFileData emptyContent = new NodeRepositoryFileData(emptyDataNode); return (RepositoryFile) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, parentFolderId); Node fileNode = JcrRepositoryFileUtils.createFileNode(session, pentahoJcrConstants, parentFolderId, file, content == null ? emptyContent : content, findTransformerForWrite(content == null ? emptyContent.getClass() : content.getClass())); // create a tmp file with correct path for default acl creation purposes. String path = JcrRepositoryFileUtils.getAbsolutePath(session, pentahoJcrConstants, fileNode); RepositoryFile tmpFile = new RepositoryFile.Builder(file).path(path).build(); // we must create the acl during checkout aclDao.createAcl(fileNode.getIdentifier(), acl == null ? defaultAclHandler.createDefaultAcl(tmpFile) : acl); session.save(); if (file.isVersioned()) { JcrRepositoryFileUtils.checkinNearestVersionableNodeIfNecessary(session, pentahoJcrConstants, fileNode, versionMessage, file.getCreatedDate(), false); } JcrRepositoryFileUtils.checkinNearestVersionableFileIfNecessary(session, pentahoJcrConstants, parentFolderId, Messages.getInstance().getString("JcrRepositoryFileDao.USER_0002_VER_COMMENT_ADD_FILE", //$NON-NLS-1$ file.getName(), (parentFolderId == null ? "root" : parentFolderId.toString()))); //$NON-NLS-1$ return JcrRepositoryFileUtils.nodeToFile(session, pentahoJcrConstants, pathConversionHelper, lockHelper, fileNode); } }); } private RepositoryFile internalUpdateFile(final Session session, final PentahoJcrConstants pentahoJcrConstants, final RepositoryFile file, final IRepositoryFileData content, final String versionMessage) throws RepositoryException { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(file); Assert.isTrue(!file.isFolder()); Assert.notNull(content); // Get repository file info and acl info of parent RepositoryFileAcl acl = aclDao.getAcl(file.getId()); // Invoke accessVoterManager to see if we have access to perform this operation if (!accessVoterManager.hasAccess(file, RepositoryFilePermission.WRITE, acl, PentahoSessionHolder.getSession())) { return null; } lockHelper.addLockTokenToSessionIfNecessary(session, pentahoJcrConstants, file.getId()); JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, file.getId()); JcrRepositoryFileUtils.updateFileNode(session, pentahoJcrConstants, file, content, findTransformerForWrite(content.getClass())); session.save(); JcrRepositoryFileUtils.checkinNearestVersionableFileIfNecessary(session, pentahoJcrConstants, file.getId(), versionMessage, file.getCreatedDate() != null ? file.getCreatedDate() : new java.util.Date(), true); lockHelper.removeLockTokenFromSessionIfNecessary(session, pentahoJcrConstants, file.getId()); return JcrRepositoryFileUtils.nodeIdToFile(session, pentahoJcrConstants, pathConversionHelper, lockHelper, file.getId()); } private RepositoryFile internalUpdateFolder(final Session session, final PentahoJcrConstants pentahoJcrConstants, final RepositoryFile folder, final String versionMessage) throws RepositoryException { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(folder); Assert.isTrue(folder.isFolder()); lockHelper.addLockTokenToSessionIfNecessary(session, pentahoJcrConstants, folder.getId()); JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, folder.getId()); JcrRepositoryFileUtils.updateFolderNode(session, pentahoJcrConstants, folder); session.save(); JcrRepositoryFileUtils.checkinNearestVersionableFileIfNecessary(session, pentahoJcrConstants, folder.getId(), versionMessage); lockHelper.removeLockTokenFromSessionIfNecessary(session, pentahoJcrConstants, folder.getId()); return JcrRepositoryFileUtils.nodeIdToFile(session, pentahoJcrConstants, pathConversionHelper, lockHelper, folder.getId()); } protected ITransformer<IRepositoryFileData> findTransformerForRead(final String contentType, final Class<? extends IRepositoryFileData> clazz) { for (ITransformer<IRepositoryFileData> transformer : transformers) { if (transformer.canRead(contentType, clazz)) { return transformer; } } throw new IllegalArgumentException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0001_NO_TRANSFORMER")); //$NON-NLS-1$ } protected ITransformer<IRepositoryFileData> findTransformerForWrite( final Class<? extends IRepositoryFileData> clazz) { for (ITransformer<IRepositoryFileData> transformer : transformers) { if (transformer.canWrite(clazz)) { return transformer; } } throw new IllegalArgumentException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0001_NO_TRANSFORMER")); //$NON-NLS-1$ } /** * {@inheritDoc} */ @Override public RepositoryFile createFile(final Serializable parentFolderId, final RepositoryFile file, final IRepositoryFileData content, final RepositoryFileAcl acl, final String versionMessage) { return internalCreateFile(parentFolderId, file, content, acl, versionMessage); } /** * {@inheritDoc} */ @Override public RepositoryFile createFolder(final Serializable parentFolderId, final RepositoryFile folder, final RepositoryFileAcl acl, final String versionMessage) { Assert.notNull(folder); Assert.isTrue(folder.isFolder()); return (RepositoryFile) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { return internalCreateFolder(session, parentFolderId, folder, acl, versionMessage); } }); } /** * {@inheritDoc} */ @Override public RepositoryFile getFileById(final Serializable fileId) { return internalGetFileById(fileId, false, null); } /** * {@inheritDoc} */ @Override public RepositoryFile getFileById(final Serializable fileId, final boolean loadMaps) { return internalGetFileById(fileId, loadMaps, null); } @Override public RepositoryFile getFile(final String relPath, final IPentahoLocale locale) { return getFile(relPath, false, locale); } @Override public RepositoryFile getFileById(Serializable fileId, IPentahoLocale locale) { return internalGetFileById(fileId, false, locale); } @Override public RepositoryFile getFile(final String relPath, final boolean loadLocaleMaps, final IPentahoLocale locale) { Assert.hasText(relPath); Assert.isTrue(relPath.startsWith(RepositoryFile.SEPARATOR)); return (RepositoryFile) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { String absPath = pathConversionHelper.relToAbs(relPath); return internalGetFile(session, absPath, loadLocaleMaps, locale); } }); } @Override public RepositoryFile getFileById(Serializable fileId, boolean loadLocaleMaps, IPentahoLocale locale) { return internalGetFileById(fileId, loadLocaleMaps, locale); } private RepositoryFile internalGetFileById(final Serializable fileId, final boolean loadMaps, final IPentahoLocale locale) { Assert.notNull(fileId); return (RepositoryFile) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); Node fileNode = session.getNodeByIdentifier(fileId.toString()); RepositoryFile file = fileNode != null ? JcrRepositoryFileUtils.nodeToFile(session, pentahoJcrConstants, pathConversionHelper, lockHelper, fileNode, loadMaps, locale) : null; if (file != null) { RepositoryFileAcl acl = aclDao.getAcl(file.getId()); // Invoke accessVoterManager to see if we have access to perform this operation if (!accessVoterManager.hasAccess(file, RepositoryFilePermission.READ, acl, PentahoSessionHolder.getSession())) { return null; } } return file; } }); } /** * {@inheritDoc} */ @Override public RepositoryFile getFile(final String relPath) { return getFile(relPath, false, null); } /** * {@inheritDoc} */ @Override public RepositoryFile getFileByAbsolutePath(final String absPath) { Assert.hasText(absPath); Assert.isTrue(absPath.startsWith(RepositoryFile.SEPARATOR)); return (RepositoryFile) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { return internalGetFile(session, absPath, false, null); } }); } /** * {@inheritDoc} */ @Override public RepositoryFile getFile(final String relPath, final boolean loadMaps) { Assert.hasText(relPath); Assert.isTrue(relPath.startsWith(RepositoryFile.SEPARATOR)); return (RepositoryFile) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { String absPath = pathConversionHelper.relToAbs(relPath); return internalGetFile(session, absPath, loadMaps, null); } }); } private RepositoryFile internalGetFile(final Session session, final String absPath, final boolean loadMaps, final IPentahoLocale locale) throws RepositoryException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); Item fileNode; try { fileNode = session.getItem(JcrStringHelper.pathEncode(absPath)); // items are nodes or properties; this must be a node Assert.isTrue(fileNode.isNode()); } catch (PathNotFoundException e) { fileNode = null; } RepositoryFile file = fileNode != null ? JcrRepositoryFileUtils.nodeToFile(session, pentahoJcrConstants, pathConversionHelper, lockHelper, (Node) fileNode, loadMaps, locale) : null; if (file != null) { RepositoryFileAcl acl = aclDao.getAcl(file.getId()); // Invoke accessVoterManager to see if we have access to perform this operation if (!accessVoterManager.hasAccess(file, RepositoryFilePermission.READ, acl, PentahoSessionHolder.getSession())) { return null; } } return file; } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public <T extends IRepositoryFileData> T getData(final Serializable fileId, final Serializable versionId, final Class<T> contentClass) { Assert.notNull(fileId); return (T) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); IRepositoryFileData data = JcrRepositoryFileUtils.getContent(session, pentahoJcrConstants, fileId, versionId, findTransformerForRead(JcrRepositoryFileUtils.getFileContentType(session, pentahoJcrConstants, fileId, versionId), contentClass)); if (fileId != null) { RepositoryFile file = internalGetFileById(fileId, false, null); if (file != null) { RepositoryFileAcl acl = aclDao.getAcl(fileId); // Invoke accessVoterManager to see if we have access to perform this operation if (!accessVoterManager.hasAccess(file, RepositoryFilePermission.READ, acl, PentahoSessionHolder.getSession())) { return null; } } } return data; } }); } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public List<RepositoryFile> getChildren(final RepositoryRequest repositoryRequest) { Assert.notNull(repositoryRequest.getPath()); return (List<RepositoryFile>) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); return JcrRepositoryFileUtils.getChildren(session, pentahoJcrConstants, pathConversionHelper, lockHelper, repositoryRequest); } }); } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public List<RepositoryFile> getChildren(final Serializable folderId, final String filter, final Boolean showHiddenFiles) { Assert.notNull(folderId); return (List<RepositoryFile>) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); return JcrRepositoryFileUtils.getChildren(session, pentahoJcrConstants, pathConversionHelper, lockHelper, folderId, filter, showHiddenFiles); } }); } /** * {@inheritDoc} */ @Override public RepositoryFile updateFile(final RepositoryFile file, final IRepositoryFileData content, final String versionMessage) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(file); Assert.isTrue(!file.isFolder()); return (RepositoryFile) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); return internalUpdateFile(session, pentahoJcrConstants, file, content, versionMessage); } }); } /** * {@inheritDoc} */ @Override public void lockFile(final Serializable fileId, final String message) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(fileId); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); lockHelper.lockFile(session, pentahoJcrConstants, fileId, message); return null; } }); } /** * {@inheritDoc} */ @Override public void unlockFile(final Serializable fileId) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(fileId); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); lockHelper.unlockFile(session, pentahoJcrConstants, fileId); return null; } }); } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public List<VersionSummary> getVersionSummaries(final Serializable fileId) { Assert.notNull(fileId); return (List<VersionSummary>) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); return JcrRepositoryFileUtils.getVersionSummaries(session, pentahoJcrConstants, fileId, true); } }); } /** * {@inheritDoc} */ @Override public RepositoryFile getFile(final Serializable fileId, final Serializable versionId) { Assert.notNull(fileId); Assert.notNull(versionId); return (RepositoryFile) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); return JcrRepositoryFileUtils.getFileAtVersion(session, pentahoJcrConstants, pathConversionHelper, lockHelper, fileId, versionId); } }); } /** * {@inheritDoc} */ @Override public void deleteFile(final Serializable fileId, final String versionMessage) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(fileId); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { RepositoryFile fileToBeDeleted = getFileById(fileId); // Get repository file info and acl info of parent if (fileToBeDeleted != null) { RepositoryFileAcl toBeDeletedFileAcl = aclDao.getAcl(fileToBeDeleted.getId()); // Invoke accessVoterManager to see if we have access to perform this operation if (!accessVoterManager.hasAccess(fileToBeDeleted, RepositoryFilePermission.DELETE, toBeDeletedFileAcl, PentahoSessionHolder.getSession())) { return null; } } List<RepositoryFilePermission> perms = new ArrayList<RepositoryFilePermission>(); perms.add(RepositoryFilePermission.DELETE); if (!aclDao.hasAccess(fileToBeDeleted.getPath(), EnumSet.copyOf(perms))) { throw new AccessDeniedException(Messages.getInstance() .getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED_DELETE", fileId)); } PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); Serializable parentFolderId = JcrRepositoryFileUtils.getParentId(session, fileId); JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, parentFolderId); deleteHelper.deleteFile(session, pentahoJcrConstants, fileId); session.save(); JcrRepositoryFileUtils.checkinNearestVersionableFileIfNecessary(session, pentahoJcrConstants, parentFolderId, versionMessage); return null; } }); } /** * {@inheritDoc} */ @Override public void deleteFileAtVersion(final Serializable fileId, final Serializable versionId) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(fileId); Assert.notNull(versionId); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { RepositoryFile fileToBeDeleted = getFileById(fileId); // Get repository file info and acl info of parent if (fileToBeDeleted != null) { RepositoryFileAcl toBeDeletedFileAcl = aclDao.getAcl(fileToBeDeleted.getId()); // Invoke accessVoterManager to see if we have access to perform this operation if (!accessVoterManager.hasAccess(fileToBeDeleted, RepositoryFilePermission.DELETE, toBeDeletedFileAcl, PentahoSessionHolder.getSession())) { return null; } } Node fileToDeleteNode = session.getNodeByIdentifier(fileId.toString()); session.getWorkspace().getVersionManager().getVersionHistory(fileToDeleteNode.getPath()) .removeVersion(versionId.toString()); session.save(); return null; } }); } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public List<RepositoryFile> getDeletedFiles(final String origParentFolderPath, final String filter) { Assert.hasLength(origParentFolderPath); return (List<RepositoryFile>) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); return deleteHelper.getDeletedFiles(session, pentahoJcrConstants, origParentFolderPath, filter); } }); } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public List<RepositoryFile> getDeletedFiles() { return (List<RepositoryFile>) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); return deleteHelper.getDeletedFiles(session, pentahoJcrConstants); } }); } /** * {@inheritDoc} * <p/> * <p> * No checkout needed as .trash is not versioned. * </p> */ @Override public void permanentlyDeleteFile(final Serializable fileId, final String versionMessage) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(fileId); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { RepositoryFile fileToBeDeleted = getFileById(fileId); // Get repository file info and acl info of parent if (fileToBeDeleted != null) { RepositoryFileAcl toBeDeletedFileAcl = aclDao.getAcl(fileToBeDeleted.getId()); // Invoke accessVoterManager to see if we have access to perform this operation if (!accessVoterManager.hasAccess(fileToBeDeleted, RepositoryFilePermission.DELETE, toBeDeletedFileAcl, PentahoSessionHolder.getSession())) { return null; } } PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); deleteHelper.permanentlyDeleteFile(session, pentahoJcrConstants, fileId); session.save(); return null; } }); } /** * {@inheritDoc} */ @Override public void undeleteFile(final Serializable fileId, final String versionMessage) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(fileId); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); String absOrigParentFolderPath = deleteHelper.getOriginalParentFolderPath(session, pentahoJcrConstants, fileId); Serializable origParentFolderId = null; RepositoryFile file = getFileById(fileId); RepositoryFileAcl acl = aclDao.getAcl(fileId); if (!accessVoterManager.hasAccess(file, RepositoryFilePermission.WRITE, acl, PentahoSessionHolder.getSession())) { return null; } // original parent folder path may no longer exist! if (session.itemExists(JcrStringHelper.pathEncode(absOrigParentFolderPath))) { origParentFolderId = ((Node) session .getItem(JcrStringHelper.pathEncode(absOrigParentFolderPath))).getIdentifier(); } else { // go through each of the segments of the original parent folder path, creating as necessary String[] segments = pathConversionHelper.absToRel(absOrigParentFolderPath) .split(RepositoryFile.SEPARATOR); RepositoryFile lastParentFolder = internalGetFile(session, ServerRepositoryPaths.getTenantRootFolderPath(), false, null); for (String segment : segments) { if (StringUtils.hasLength(segment)) { RepositoryFile tmp = internalGetFile(session, pathConversionHelper .relToAbs((lastParentFolder.getPath().equals(RepositoryFile.SEPARATOR) ? "" //$NON-NLS-1$ : lastParentFolder.getPath()) + RepositoryFile.SEPARATOR + segment), false, null); if (tmp == null) { lastParentFolder = internalCreateFolder(session, lastParentFolder.getId(), new RepositoryFile.Builder(segment).folder(true).build(), defaultAclHandler.createDefaultAcl(lastParentFolder), null); } else { lastParentFolder = tmp; } } } origParentFolderId = lastParentFolder.getId(); } JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, origParentFolderId); deleteHelper.undeleteFile(session, pentahoJcrConstants, fileId); session.save(); JcrRepositoryFileUtils.checkinNearestVersionableFileIfNecessary(session, pentahoJcrConstants, origParentFolderId, versionMessage); return null; } }); } private void internalCopyOrMove(final Serializable fileId, final String destRelPath, final String versionMessage, final boolean copy) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(fileId); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { RepositoryFile file = getFileById(fileId); RepositoryFileAcl acl = aclDao.getAcl(fileId); if (!accessVoterManager.hasAccess(file, RepositoryFilePermission.WRITE, acl, PentahoSessionHolder.getSession())) { return null; } PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); String destAbsPath = pathConversionHelper.relToAbs(destRelPath); String cleanDestAbsPath = destAbsPath; if (cleanDestAbsPath.endsWith(RepositoryFile.SEPARATOR)) { cleanDestAbsPath.substring(0, cleanDestAbsPath.length() - 1); } Node srcFileNode = session.getNodeByIdentifier(fileId.toString()); Serializable srcParentFolderId = JcrRepositoryFileUtils.getParentId(session, fileId); boolean appendFileName = false; boolean destExists = true; Node destFileNode = null; Node destParentFolderNode = null; try { destFileNode = (Node) session.getItem(JcrStringHelper.pathEncode(cleanDestAbsPath)); } catch (PathNotFoundException e) { destExists = false; } if (destExists) { // make sure it's a file or folder Assert.isTrue(JcrRepositoryFileUtils.isSupportedNodeType(pentahoJcrConstants, destFileNode)); // existing item; make sure src is not a folder if dest is a file Assert.isTrue( !(JcrRepositoryFileUtils.isPentahoFolder(pentahoJcrConstants, srcFileNode) && JcrRepositoryFileUtils.isPentahoFile(pentahoJcrConstants, destFileNode)), Messages.getInstance().getString( "JcrRepositoryFileDao.ERROR_0002_CANNOT_OVERWRITE_FILE_WITH_FOLDER")); //$NON-NLS-1$ if (JcrRepositoryFileUtils.isPentahoFolder(pentahoJcrConstants, destFileNode)) { // existing item; caller is not renaming file, only moving it appendFileName = true; destParentFolderNode = destFileNode; } else { // get parent of existing dest item int lastSlashIndex = cleanDestAbsPath.lastIndexOf(RepositoryFile.SEPARATOR); Assert.isTrue(lastSlashIndex > 1, Messages.getInstance() .getString("JcrRepositoryFileDao.ERROR_0003_ILLEGAL_DEST_PATH")); //$NON-NLS-1$ String absPathToDestParentFolder = cleanDestAbsPath.substring(0, lastSlashIndex); destParentFolderNode = (Node) session .getItem(JcrStringHelper.pathEncode(absPathToDestParentFolder)); } } else { // destination doesn't exist; go up one level to a folder that does exist int lastSlashIndex = cleanDestAbsPath.lastIndexOf(RepositoryFile.SEPARATOR); Assert.isTrue(lastSlashIndex > 1, Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0003_ILLEGAL_DEST_PATH")); //$NON-NLS-1$ String absPathToDestParentFolder = cleanDestAbsPath.substring(0, lastSlashIndex); // Not need to check the name if we encoded it // JcrRepositoryFileUtils.checkName( cleanDestAbsPath.substring( lastSlashIndex + 1 ) ); try { destParentFolderNode = (Node) session .getItem(JcrStringHelper.pathEncode(absPathToDestParentFolder)); } catch (PathNotFoundException e1) { Assert.isTrue(false, Messages.getInstance() .getString("JcrRepositoryFileDao.ERROR_0004_PARENT_MUST_EXIST")); //$NON-NLS-1$ } Assert.isTrue(JcrRepositoryFileUtils.isPentahoFolder(pentahoJcrConstants, destParentFolderNode), Messages.getInstance() .getString("JcrRepositoryFileDao.ERROR_0005_PARENT_MUST_BE_FOLDER")); //$NON-NLS-1$ } if (!copy) { JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, srcParentFolderId); } JcrRepositoryFileUtils.checkoutNearestVersionableNodeIfNecessary(session, pentahoJcrConstants, destParentFolderNode); String finalEncodedSrcAbsPath = srcFileNode.getPath(); String finalDestAbsPath = appendFileName && !file.isFolder() ? cleanDestAbsPath + RepositoryFile.SEPARATOR + srcFileNode.getName() : cleanDestAbsPath; try { if (copy) { session.getWorkspace().copy(finalEncodedSrcAbsPath, JcrStringHelper.pathEncode(finalDestAbsPath)); } else { session.getWorkspace().move(finalEncodedSrcAbsPath, JcrStringHelper.pathEncode(finalDestAbsPath)); } } catch (ItemExistsException iae) { throw new UnifiedRepositoryException((file.isFolder() ? "Folder " : "File ") + "with path [" + cleanDestAbsPath + "] already exists in the repository"); } JcrRepositoryFileUtils.checkinNearestVersionableNodeIfNecessary(session, pentahoJcrConstants, destParentFolderNode, versionMessage); // if it's a move within the same folder, then the next checkin is unnecessary if (!copy && !destParentFolderNode.getIdentifier().equals(srcParentFolderId.toString())) { JcrRepositoryFileUtils.checkinNearestVersionableFileIfNecessary(session, pentahoJcrConstants, srcParentFolderId, versionMessage); } session.save(); return null; } }); } /** * {@inheritDoc} */ @Override public void moveFile(final Serializable fileId, final String destRelPath, final String versionMessage) { internalCopyOrMove(fileId, destRelPath, versionMessage, false); } /** * {@inheritDoc} */ @Override public void copyFile(final Serializable fileId, final String destRelPath, final String versionMessage) { internalCopyOrMove(fileId, destRelPath, versionMessage, true); } /** * {@inheritDoc} */ @Override public VersionSummary getVersionSummary(final Serializable fileId, final Serializable versionId) { Assert.notNull(fileId); return (VersionSummary) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); return JcrRepositoryFileUtils.getVersionSummary(session, pentahoJcrConstants, fileId, versionId); } }); } /** * {@inheritDoc} */ @Override public void restoreFileAtVersion(final Serializable fileId, final Serializable versionId, final String versionMessage) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(fileId); Assert.notNull(versionId); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { Node fileNode = session.getNodeByIdentifier(fileId.toString()); session.getWorkspace().getVersionManager().restore(fileNode.getPath(), versionId.toString(), true); return null; } }); } /** * {@inheritDoc} */ @Override public boolean canUnlockFile(final Serializable fileId) { return (Boolean) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); Node fileNode = session.getNodeByIdentifier(fileId.toString()); Lock lock = session.getWorkspace().getLockManager().getLock(fileNode.getPath()); return lockHelper.canUnlock(session, pentahoJcrConstants, lock); } }); } /** * {@inheritDoc} */ @Override public RepositoryFileTree getTree(final RepositoryRequest repositoryRequest) { Assert.hasText(repositoryRequest.getPath()); return (RepositoryFileTree) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); String absPath = pathConversionHelper.relToAbs(repositoryRequest.getPath()); return JcrRepositoryFileUtils.getTree(session, pentahoJcrConstants, pathConversionHelper, lockHelper, absPath, repositoryRequest, accessVoterManager); } }); } /** * {@inheritDoc} */ @Override @Deprecated public RepositoryFileTree getTree(final String relPath, final int depth, final String filter, final boolean showHidden) { Assert.hasText(relPath); final RepositoryRequest repositoryRequest = new RepositoryRequest(relPath, showHidden, depth, filter); return (RepositoryFileTree) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); String absPath = pathConversionHelper.relToAbs(relPath); return JcrRepositoryFileUtils.getTree(session, pentahoJcrConstants, pathConversionHelper, lockHelper, absPath, repositoryRequest, accessVoterManager); } }); } @Override @SuppressWarnings("unchecked") public List<RepositoryFile> getReferrers(final Serializable fileId) { if (fileId == null) { return new ArrayList<RepositoryFile>(); } return (List<RepositoryFile>) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); Node fileNode = session.getNodeByIdentifier(fileId.toString()); // guard against using a file retrieved from a more lenient session inside a more strict session Assert.notNull(fileNode); Set<RepositoryFile> referrers = new HashSet<RepositoryFile>(); PropertyIterator refIter = fileNode.getReferences(); if (refIter.hasNext()) { while (refIter.hasNext()) { // for each referrer property, march up the tree until we find the file node to which the property // belongs RepositoryFile referrer = getReferrerFile(session, pentahoJcrConstants, refIter.nextProperty()); if (referrer != null) { referrers.add(referrer); } } } session.save(); return Arrays.asList(referrers.toArray()); } }); } protected RepositoryFile getReferrerFile(final Session session, final PentahoJcrConstants pentahoJcrConstants, final Property referrerProperty) throws RepositoryException { Node currentNode = referrerProperty.getParent(); while (!currentNode.isNodeType(pentahoJcrConstants.getPHO_NT_PENTAHOHIERARCHYNODE())) { currentNode = currentNode.getParent(); } // if folder, then referrer is a lock token record (under the user's home folder) which will be cleaned up by // lockHelper; ignore it if (currentNode.isNodeType(pentahoJcrConstants.getPHO_NT_PENTAHOFOLDER())) { return null; } return JcrRepositoryFileUtils.nodeToFile(session, pentahoJcrConstants, pathConversionHelper, lockHelper, currentNode); } @Override public void setFileMetadata(final Serializable fileId, final Map<String, Serializable> metadataMap) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(fileId); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { JcrRepositoryFileUtils.setFileMetadata(session, fileId, metadataMap); return null; } }); } @Override @SuppressWarnings("unchecked") public Map<String, Serializable> getFileMetadata(final Serializable fileId) { Assert.notNull(fileId); return (Map<String, Serializable>) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(Session session) throws IOException, RepositoryException { return JcrRepositoryFileUtils.getFileMetadata(session, fileId); } }); } @Override public List<Character> getReservedChars() { return JcrRepositoryFileUtils.getReservedChars(); } public IRepositoryDefaultAclHandler getDefaultAclHandler() { return defaultAclHandler; } public void setDefaultAclHandler(IRepositoryDefaultAclHandler defaultAclHandler) { this.defaultAclHandler = defaultAclHandler; } @Override public List<Locale> getAvailableLocalesForFileById(Serializable fileId) { RepositoryFile repositoryFile = getFileById(fileId, true); return getAvailableLocalesForFile(repositoryFile); } @Override public List<Locale> getAvailableLocalesForFileByPath(String relPath) { RepositoryFile repositoryFile = getFileById(relPath, true); return getAvailableLocalesForFile(repositoryFile); } @Override public List<Locale> getAvailableLocalesForFile(RepositoryFile repositoryFile) { List<Locale> localeList = new ArrayList<Locale>(); if (repositoryFile != null && repositoryFile.getLocalePropertiesMap() != null) { for (String localeName : repositoryFile.getLocalePropertiesMap().keySet()) { String[] localePieces = localeName.split("_"); String language = localePieces[0]; String country = (localePieces.length > 1) ? localePieces[1] : ""; String variant = (localePieces.length > 2) ? localePieces[2] : ""; Locale locale = new Locale(language, country, variant); localeList.add(locale); } } return localeList; } @Override public Properties getLocalePropertiesForFileById(Serializable fileId, String locale) { RepositoryFile repositoryFile = getFileById(fileId, true); return getLocalePropertiesForFile(repositoryFile, locale); } @Override public Properties getLocalePropertiesForFileByPath(String relPath, String locale) { RepositoryFile repositoryFile = getFileById(relPath, true); return getLocalePropertiesForFile(repositoryFile, locale); } @Override public Properties getLocalePropertiesForFile(RepositoryFile repositoryFile, String locale) { if (org.apache.commons.lang.StringUtils.isBlank(locale)) { locale = RepositoryFile.DEFAULT_LOCALE; } if (repositoryFile != null && repositoryFile.getLocalePropertiesMap() != null) { Properties properties = repositoryFile.getLocalePropertiesMap().get(locale); return properties; } return null; } @Override public void setLocalePropertiesForFileById(Serializable fileId, String locale, Properties properties) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } RepositoryFile repositoryFile = getFileById(fileId, true); setLocalePropertiesForFile(repositoryFile, locale, properties); } @Override public void setLocalePropertiesForFileByPath(String relPath, String locale, Properties properties) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } RepositoryFile repositoryFile = getFileById(relPath, true); setLocalePropertiesForFile(repositoryFile, locale, properties); } @Override public void setLocalePropertiesForFile(final RepositoryFile repositoryFile, final String locale, final Properties properties) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(repositoryFile); Assert.notNull(locale); Assert.notNull(properties); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); String versionMessage = Messages.getInstance() .getString("JcrRepositoryFileDao.LOCALE_0001_UPDATE_PROPERTIES", repositoryFile.getId()); lockHelper.addLockTokenToSessionIfNecessary(session, pentahoJcrConstants, repositoryFile.getId()); JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, repositoryFile.getId()); JcrRepositoryFileUtils.updateFileLocaleProperties(session, repositoryFile.getId(), locale, properties); session.save(); JcrRepositoryFileUtils.checkinNearestVersionableFileIfNecessary(session, pentahoJcrConstants, repositoryFile.getId(), versionMessage); lockHelper.removeLockTokenFromSessionIfNecessary(session, pentahoJcrConstants, repositoryFile.getId()); return null; } }); } @Override public void deleteLocalePropertiesForFile(final RepositoryFile repositoryFile, final String locale) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(repositoryFile); Assert.notNull(locale); jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); String versionMessage = Messages.getInstance() .getString("JcrRepositoryFileDao.LOCALE_0002_DELETE_PROPERTIES", repositoryFile.getId()); lockHelper.addLockTokenToSessionIfNecessary(session, pentahoJcrConstants, repositoryFile.getId()); JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, repositoryFile.getId()); JcrRepositoryFileUtils.deleteFileLocaleProperties(session, repositoryFile.getId(), locale); session.save(); JcrRepositoryFileUtils.checkinNearestVersionableFileIfNecessary(session, pentahoJcrConstants, repositoryFile.getId(), versionMessage); lockHelper.removeLockTokenFromSessionIfNecessary(session, pentahoJcrConstants, repositoryFile.getId()); return null; } }); } @Override public RepositoryFile updateFolder(final RepositoryFile file, final String versionMessage) { if (isKioskEnabled()) { throw new RuntimeException( Messages.getInstance().getString("JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED")); //$NON-NLS-1$ } Assert.notNull(file); Assert.isTrue(file.isFolder()); return (RepositoryFile) jcrTemplate.execute(new JcrCallback() { @Override public Object doInJcr(final Session session) throws RepositoryException, IOException { PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session); return internalUpdateFolder(session, pentahoJcrConstants, file, versionMessage); } }); } private String extractNameFromPath(String path) { int startIndex = path.lastIndexOf(RepositoryFile.SEPARATOR); if (startIndex >= 0) { int endIndex = path.indexOf('.', startIndex); if (endIndex > startIndex) { return path.substring(startIndex + 1, endIndex); } } return null; } private boolean isKioskEnabled() { if (PentahoSystem.getInitializedOK()) { return "true".equals(PentahoSystem.getSystemSetting("kiosk-mode", "false")); } else { return false; } } }