/*
* 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 - 2016 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.ItemNotFoundException;
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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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 {
private static final Log logger = LogFactory.getLog( JcrRepositoryFileDao.class );
// ~ 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", folder.getName(), ( parentFolderId == null ? "root" : parentFolderId.toString() ) ) ); //$NON-NLS-1$ //$NON-NLS-2$
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", file.getName(), ( parentFolderId == null ? "root" : parentFolderId.toString() ) ) ); //$NON-NLS-1$ //$NON-NLS-2$
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(
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;
try {
fileNode = session.getNodeByIdentifier( fileId.toString() );
} catch ( ItemNotFoundException e ) {
logger.info( "Couldn't find file by id: " + fileId );
fileNode = null;
}
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 )
? "" : lastParentFolder.getPath() ) + RepositoryFile.SEPARATOR + segment ), false, null ); //$NON-NLS-1$
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 {
// if we're moving the file,
// check that user has permissions to remove the file from it's current location
RepositoryFile file = getFileById( fileId );
if ( !copy ) {
RepositoryFileAcl acl = aclDao.getAcl( fileId );
if ( !accessVoterManager.hasAccess( file, RepositoryFilePermission.WRITE, acl,
PentahoSessionHolder.getSession() ) ) {
throw new AccessDeniedException( Messages.getInstance().getString(
"JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED_DELETE", fileId ) );
}
}
// check that user has permissions to write to the destination folder
RepositoryFile destFolder = getFile( destRelPath );
if ( destFolder != null ) {
RepositoryFileAcl destFolderAcl = aclDao.getAcl( destFolder.getId() );
if ( !accessVoterManager.hasAccess( destFolder, RepositoryFilePermission.WRITE, destFolderAcl,
PentahoSessionHolder.getSession() ) ) {
throw new AccessDeniedException( Messages.getInstance().getString(
"JcrRepositoryFileDao.ERROR_0006_ACCESS_DENIED_CREATE", destFolder.getId() ) );
}
}
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 finalEncodedDestAbsPath = null;
if ( appendFileName ) {
final String fileName = srcFileNode.getName();
if ( JcrStringHelper.isEncoded( fileName ) ) {
finalEncodedDestAbsPath = JcrStringHelper.pathEncode( cleanDestAbsPath ) + RepositoryFile.SEPARATOR + fileName;
} else {
finalEncodedDestAbsPath = JcrStringHelper.pathEncode( cleanDestAbsPath + RepositoryFile.SEPARATOR + fileName );
}
} else {
finalEncodedDestAbsPath = JcrStringHelper.pathEncode( cleanDestAbsPath );
}
try {
if ( copy ) {
session.getWorkspace().copy( finalEncodedSrcAbsPath, finalEncodedDestAbsPath );
} else {
session.getWorkspace().move( finalEncodedSrcAbsPath, finalEncodedDestAbsPath );
}
} 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;
}
}
}