Package org.pentaho.platform.repository2.unified.fs

Source Code of org.pentaho.platform.repository2.unified.fs.FileSystemRepositoryFileDao

/*
* 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.fs;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.commons.lang.StringUtils;
import org.pentaho.platform.api.locale.IPentahoLocale;
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.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.NodeRepositoryFileData;
import org.pentaho.platform.api.repository2.unified.data.simple.SimpleRepositoryFileData;
import org.pentaho.platform.repository.RepositoryFilenameUtils;
import org.pentaho.platform.repository2.unified.IRepositoryFileDao;
import org.pentaho.platform.util.RepositoryPathEncoder;

@SuppressWarnings( "nls" )
public class FileSystemRepositoryFileDao implements IRepositoryFileDao {
  private File rootDir = new File( System.getProperty( "solution.root.dir", System.getProperty( "user.dir" ) ) );
  private static List<Character> reservedChars = Collections.unmodifiableList( Arrays.asList( new Character[] {
    '/', '\\', '\t', '\r', '\n' } ) );
  private static List<Character> reservedCharsWindows = Collections.unmodifiableList( Arrays.asList( new Character[]{
      '?', '*', ':', '<', '>', '|'} ) );

  public FileSystemRepositoryFileDao() {
    this( new File( System.getProperty( "solution.root.dir", System.getProperty( "user.dir" ) ) ) );
  }

  public FileSystemRepositoryFileDao( final String baseDir ) {
    this( new File( baseDir ) );
  }

  public FileSystemRepositoryFileDao( File baseDir ) {
    // Detect OS
    final String os = System.getProperty( "os.name" ).toLowerCase();
    if ( os.contains( "win" ) && baseDir.getPath().equals( "\\" ) ) {
      baseDir = new File( "C:\\" );
    }
    assert ( baseDir.exists() && baseDir.isDirectory() );
    this.rootDir = baseDir;
  }

  public boolean canUnlockFile( Serializable fileId ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public File getRootDir() {
    return new File( rootDir.getAbsolutePath() );
  }

  private byte[] inputStreamToBytes( InputStream in ) throws IOException {

    ByteArrayOutputStream out = new ByteArrayOutputStream( 4096 );
    byte[] buffer = new byte[4096];
    int len;

    while ( ( len = in.read( buffer ) ) >= 0 ) {
      out.write( buffer, 0, len );
    }

    in.close();
    out.close();
    return out.toByteArray();
  }

  public RepositoryFile createFile( Serializable parentFolderId, RepositoryFile file, IRepositoryFileData data,
      RepositoryFileAcl acl, String versionMessage ) {
    String fileNameWithPath = RepositoryFilenameUtils.concat( parentFolderId.toString(), file.getName() );
    FileOutputStream fos = null;
    File f = new File( fileNameWithPath );

    try {
      f.createNewFile();
      fos = new FileOutputStream( f );
      if ( data instanceof SimpleRepositoryFileData ) {
        fos.write( inputStreamToBytes( ( (SimpleRepositoryFileData) data ).getInputStream() ) );
      } else if ( data instanceof NodeRepositoryFileData ) {
        fos.write( inputStreamToBytes( new ByteArrayInputStream( ( (NodeRepositoryFileData) data ).getNode().toString()
            .getBytes() ) ) );
      }
    } catch ( FileNotFoundException e ) {
      throw new UnifiedRepositoryException( "Error writing file [" + fileNameWithPath + "]", e );
    } catch ( IOException e ) {
      throw new UnifiedRepositoryException( "Error writing file [" + fileNameWithPath + "]", e );
    } finally {
      IOUtils.closeQuietly( fos );
    }

    return internalGetFile( f );
  }

  public RepositoryFile createFolder( Serializable parentFolderId, RepositoryFile file, RepositoryFileAcl acl,
      String versionMessage ) {
    try {
      String folderNameWithPath = parentFolderId + "/" + file.getName();
      File newFolder = new File( folderNameWithPath );
      newFolder.mkdir();
      final RepositoryFile repositoryFolder = internalGetFile( newFolder );
      return repositoryFolder;
    } catch ( Throwable th ) {
      throw new UnifiedRepositoryException();
    }
  }

  public void deleteFile( Serializable fileId, String versionMessage ) {
    try {
      File f = new File( fileId.toString() );
      f.delete();
    } catch ( Exception e ) {
      // CHECKSTYLES IGNORE
    }

  }

  public void deleteFileAtVersion( Serializable fileId, Serializable versionId ) {
    deleteFile( fileId, null );
  }

  @Override
  public List<RepositoryFile> getChildren( RepositoryRequest repositoryRequest ) {
    List<RepositoryFile> children = new ArrayList<RepositoryFile>();
    File folder = new File( getPhysicalFileLocation( repositoryRequest.getPath() ) );
    for ( Iterator<File> iterator = FileUtils.listFiles( folder, new WildcardFileFilter( repositoryRequest.getChildNodeFilter() ), null ).iterator(); iterator
        .hasNext(); ) {
      children.add( internalGetFile( (File) iterator.next() ) );
    }
    return children;
  }
 
  @Deprecated
  public List<RepositoryFile> getChildren( Serializable folderId ) {
    return getChildren(folderId, "", false);
  }

  @Deprecated
  public List<RepositoryFile> getChildren( Serializable folderId, String filter ) {
    return getChildren(folderId, filter, false);
  }
 
  @Deprecated
  public List<RepositoryFile> getChildren( Serializable folderId, String filter, Boolean showHiddenFiles ) {
    return getChildren(new RepositoryRequest(folderId.toString(), showHiddenFiles, -1, filter));
  }

  @SuppressWarnings( "unchecked" )
  public <T extends IRepositoryFileData> T getData( Serializable fileId, Serializable versionId, Class<T> dataClass ) {
    File f = new File( fileId.toString() );
    T data = null;
    try {
      if( SimpleRepositoryFileData.class.getName().equals( dataClass.getName() ) ){
        data = (T) new SimpleRepositoryFileData ( new FileInputStream( f ), "UTF-8", "text/plain" );
     
      } else if( NodeRepositoryFileData.class.getName().equals( dataClass.getName() ) ) {
        throw new UnsupportedOperationException( "This operation is not support by this repository" );
      }
     
    } catch ( FileNotFoundException e ) {
      throw new UnifiedRepositoryException( e );
    }
    return data;
  }

  public List<RepositoryFile> getDeletedFiles( Serializable folderId, String filter ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public List<RepositoryFile> getDeletedFiles() {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public RepositoryFile internalGetFile( File f ) {

    RepositoryFile file = null;
    if ( f.exists() ) {
      String jcrPath = f.getAbsolutePath().substring( rootDir.getAbsolutePath().length() );
      if ( jcrPath.length() == 0 ) {
        jcrPath = "/";
      }
      file =
          new RepositoryFile.Builder( f.getAbsolutePath(), f.getName() ).createdDate( new Date( f.lastModified() ) )
              .lastModificationDate( new Date( f.lastModified() ) ).folder( f.isDirectory() ).versioned( false ).path(
                  jcrPath ).versionId( f.getName() ).locked( false ).lockDate( null ).lockMessage( null ).lockOwner(
                  null ).title( f.getName() ).description( f.getName() ).locale( null ).fileSize( f.length() ).build();
    }
    return file;

  }

  public RepositoryFile getFile( String relPath ) {
    return internalGetFile( new File( getPhysicalFileLocation( relPath ) ) );
  }

  static String idToPath( String relPath ) {
    relPath = RepositoryPathEncoder.decodeRepositoryPath( relPath );
    return relPath.replaceFirst( "^/?([A-z])/[/\\\\](.*)", "$1:/$2" );
  }

  public RepositoryFile getFile( Serializable fileId, Serializable versionId ) {
    return getFile( fileId.toString() );
  }

  public RepositoryFile getFileByAbsolutePath( String absPath ) {
    return getFile( absPath );
  }

  public RepositoryFile getFileById( Serializable fileId ) {
    return getFile( fileId.toString() );
  }

  public RepositoryFile getFile( String relPath, boolean loadLocaleMaps ) {
    return getFile( relPath );
  }

  public RepositoryFile getFileById( Serializable fileId, boolean loadLocaleMaps ) {
    return getFile( fileId.toString() );
  }

  @Override
  public RepositoryFile getFile( String relPath, IPentahoLocale locale ) {
    return getFile( relPath );
  }

  @Override
  public RepositoryFile getFileById( Serializable fileId, IPentahoLocale locale ) {
    return getFile( fileId.toString() );
  }

  @Override
  public RepositoryFile getFile( String relPath, boolean loadLocaleMaps, IPentahoLocale locale ) {
    return getFile( relPath );
  }

  @Override
  public RepositoryFile getFileById( Serializable fileId, boolean loadLocaleMaps, IPentahoLocale locale ) {
    return getFile( fileId.toString() );
  }
 

  @Override
  public RepositoryFileTree getTree( RepositoryRequest repositoryRequest ) {

    File root = new File( getPhysicalFileLocation( repositoryRequest.getPath() ) );
   
    //TODO ACL    
    return getTree( root , repositoryRequest.getDepth().intValue() ,
        repositoryRequest.getChildNodeFilter(), repositoryRequest.getTypes() );
  }
 
  @Deprecated
  public RepositoryFileTree getTree( String relPath, int depth, String filter, boolean showHidden ) {
   
    File root = new File( getPhysicalFileLocation( relPath ) );
 
    //TODO ACL    
    return getTree( root , depth , filter , RepositoryRequest.FILES_TYPE_FILTER.FILES_FOLDERS );
  }
 
  private RepositoryFileTree getTree( final File file, final int depth, final String childNodeFilter,
      RepositoryRequest.FILES_TYPE_FILTER types ) {

    RepositoryFile rootFile = internalGetFile( file );
  
    List<RepositoryFileTree> children;

    if ( depth != 0 ) {
      children = new ArrayList<RepositoryFileTree>();
     
      if ( file.isDirectory() ) {
       
        File[] childrenArray = file.listFiles();
       
        for( File child : childrenArray ){
         
          if( child.isFile() ){
           
            if( types == RepositoryRequest.FILES_TYPE_FILTER.FILES_FOLDERS || types == RepositoryRequest.FILES_TYPE_FILTER.FILES ){
              children.add( new RepositoryFileTree( internalGetFile( child ), new ArrayList<RepositoryFileTree>() ) );
            }
           
            continue;
          }
         
          RepositoryFileTree repositoryChildFileTree = getTree( child, depth - 1, childNodeFilter, types );
          if ( repositoryChildFileTree != null ) {
            children.add( repositoryChildFileTree );
          }
        }
      }
      Collections.sort( children );
    } else {
      children = null;
    }
    return new RepositoryFileTree( rootFile, children );
 

  public List<VersionSummary> getVersionSummaries( Serializable fileId ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public VersionSummary getVersionSummary( Serializable fileId, Serializable versionId ) {
    RepositoryFile file = getFile( fileId, versionId );
    List<String> labels = new ArrayList<String>();
    return new VersionSummary(fileId, ( versionId != null ? versionId : fileId ) ,
        false, file.getCreatedDate(), file.getCreatorId(), StringUtils.EMPTY,  labels );
  }

  public void lockFile( Serializable fileId, String message ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public void moveFile( Serializable fileId, String destRelPath, String versionMessage ) {
    RepositoryFile file = getFileById( fileId );
    SimpleRepositoryFileData data = getData( fileId, null, SimpleRepositoryFileData.class );
    deleteFile( fileId, versionMessage );
    createFile( null, file, data, null, versionMessage );
  }

  public void permanentlyDeleteFile( Serializable fileId, String versionMessage ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public void restoreFileAtVersion( Serializable fileId, Serializable versionId, String versionMessage ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public void undeleteFile( Serializable fileId, String versionMessage ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public void unlockFile( Serializable fileId ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public RepositoryFile updateFile( RepositoryFile file, IRepositoryFileData data, String versionMessage ) {
    File f = new File( file.getId().toString() );
    FileOutputStream fos = null;
    try {
      fos = new FileOutputStream( f, false );
      if ( data instanceof SimpleRepositoryFileData ) {
        fos.write( inputStreamToBytes( ( (SimpleRepositoryFileData) data ).getInputStream() ) );
      } else if ( data instanceof NodeRepositoryFileData ) {
        fos.write( inputStreamToBytes( new ByteArrayInputStream( ( (NodeRepositoryFileData) data ).getNode().toString()
            .getBytes() ) ) );
      }
    } catch ( FileNotFoundException e ) {
      throw new UnifiedRepositoryException( e );
    } catch ( IOException e ) {
      throw new UnifiedRepositoryException( e );
    } finally {
      IOUtils.closeQuietly( fos );
    }

    return getFile( file.getPath() );
  }

  public List<RepositoryFile> getReferrers( Serializable fileId ) {
    throw new UnsupportedOperationException();
  }

  public void setRootDir( File rootDir ) {
    this.rootDir = rootDir;
  }

  public void setFileMetadata( final Serializable fileId, Map<String, Serializable> metadataMap ) {
    final File targetFile = new File( fileId.toString() );
    if ( targetFile.exists() ) {
      FileOutputStream fos = null;
      try {
        final File metadataDir = new File( targetFile.getParent() + File.separatorChar + ".metadata" );
        if ( !metadataDir.exists() ) {
          metadataDir.mkdir();
        }
        final File metadataFile = new File( metadataDir, targetFile.getName() );
        if ( !metadataFile.exists() ) {
          metadataFile.createNewFile();
        }

        final StringBuilder data = new StringBuilder();
        for ( String key : metadataMap.keySet() ) {
          data.append( key ).append( '=' );
          if ( metadataMap.get( key ) != null ) {
            data.append( metadataMap.get( key ).toString() );
          }
          data.append( '\n' );
        }
        fos = new FileOutputStream( metadataFile );
        fos.write( data.toString().getBytes() );
      } catch ( FileNotFoundException e ) {
        throw new UnifiedRepositoryException( "Error writing file metadata [" + fileId + "]", e );
      } catch ( IOException e ) {
        throw new UnifiedRepositoryException( "Error writing file metadata [" + fileId + "]", e );
      } finally {
        IOUtils.closeQuietly( fos );
      }
    }
  }

  public Map<String, Serializable> getFileMetadata( final Serializable fileId ) {
    final String metadataFilename =
        FilenameUtils.concat( FilenameUtils.concat( FilenameUtils.getFullPathNoEndSeparator( fileId.toString() ),
            ".metadata" ), FilenameUtils.getName( fileId.toString() ) );
    final Map<String, Serializable> metadata = new HashMap<String, Serializable>();
    BufferedReader reader = null;
    try {
      reader = new BufferedReader( new FileReader( metadataFilename ) );
      String data = reader.readLine();
      while ( data != null ) {
        final int pos = data.indexOf( '=' );
        if ( pos > 0 ) {
          final String key = data.substring( 0, pos );
          final String value = ( data.length() > pos ? data.substring( pos + 1 ) : null );
          metadata.put( key, value );
        }
        data = reader.readLine();
      }
    } catch ( FileNotFoundException e ) {
      // Do nothing ... metadata empty
    } catch ( IOException e ) {
      throw new UnifiedRepositoryException( "Error reading metadata [" + fileId + "]", e );
    } finally {
      IOUtils.closeQuietly( reader );
    }
    return metadata;
  }

  public void copyFile( Serializable fileId, String destAbsPath, String versionMessage ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  public List<RepositoryFile> getDeletedFiles( String origParentFolderPath, String filter ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public List<Character> getReservedChars() {
    List<Character> charList = new ArrayList<Character>();
    String osName = System.getProperty( "os.name" );
    charList.addAll( reservedChars );
    if ( osName.contains( "Windows" ) ) {
      charList.addAll( reservedCharsWindows );
    }
    return charList;
  }

  @Override
  public List<Locale> getAvailableLocalesForFileById( Serializable fileId ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public List<Locale> getAvailableLocalesForFileByPath( String relPath ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public List<Locale> getAvailableLocalesForFile( RepositoryFile repositoryFile ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public Properties getLocalePropertiesForFileById( Serializable fileId, String locale ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public Properties getLocalePropertiesForFileByPath( String relPath, String locale ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public Properties getLocalePropertiesForFile( RepositoryFile repositoryFile, String locale ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public void setLocalePropertiesForFileById( Serializable fileId, String locale, Properties properties ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public void setLocalePropertiesForFileByPath( String relPath, String locale, Properties properties ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public void setLocalePropertiesForFile( RepositoryFile repositoryFile, String locale, Properties properties ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public void deleteLocalePropertiesForFile( RepositoryFile repositoryFile, String locale ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }

  @Override
  public RepositoryFile updateFolder( RepositoryFile file, String versionMessage ) {
    throw new UnsupportedOperationException( "This operation is not support by this repository" );
  }
 
  private String getPhysicalFileLocation( String relPath ){
   
    if( StringUtils.isEmpty( relPath ) ){
      return relPath;
    }
   
    String physicalFileLocation = relPath;
    if ( relPath.equals( "/" ) ) {
      physicalFileLocation = rootDir.getAbsolutePath();
    } else if ( relPath.startsWith( rootDir.getAbsolutePath() ) ) {
      physicalFileLocation = relPath;
    } else {
      physicalFileLocation = RepositoryFilenameUtils.concat( rootDir.getAbsolutePath(), relPath.substring( RepositoryFilenameUtils.getPrefixLength( relPath ) ) );
    }
   
    return physicalFileLocation;
  }
}
TOP

Related Classes of org.pentaho.platform.repository2.unified.fs.FileSystemRepositoryFileDao

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.