Package org.pentaho.platform.plugin.services.importer

Source Code of org.pentaho.platform.plugin.services.importer.SolutionImportHandler$SolutionRepositoryImportSource

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.platform.plugin.services.importer;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.database.model.IDatabaseConnection;
import org.pentaho.metadata.repository.DomainAlreadyExistsException;
import org.pentaho.metadata.repository.DomainIdNullException;
import org.pentaho.metadata.repository.DomainStorageException;
import org.pentaho.platform.api.repository.datasource.IDatasourceMgmtService;
import org.pentaho.platform.api.repository2.unified.RepositoryFile;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.plugin.services.importer.mimeType.MimeType;
import org.pentaho.platform.plugin.services.importexport.ExportFileNameEncoder;
import org.pentaho.platform.plugin.services.importexport.ImportSession;
import org.pentaho.platform.plugin.services.importexport.ImportSource.IRepositoryFileBundle;
import org.pentaho.platform.plugin.services.importexport.RepositoryFileBundle;
import org.pentaho.platform.plugin.services.importexport.exportManifest.ExportManifest;
import org.pentaho.platform.plugin.services.importexport.exportManifest.Parameters;
import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMetadata;
import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMondrian;
import org.pentaho.platform.repository.RepositoryFilenameUtils;
import org.pentaho.platform.repository.messages.Messages;
import org.pentaho.platform.web.http.api.resources.JobScheduleRequest;
import org.pentaho.platform.web.http.api.resources.SchedulerResource;

import javax.ws.rs.core.Response;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class SolutionImportHandler implements IPlatformImportHandler {

  private static final Log log = LogFactory.getLog( SolutionImportHandler.class );

  private static final String sep = ";";
  private Map<String, RepositoryFileImportBundle.Builder> cachedImports;
  private SolutionFileImportHelper solutionHelper;
  private List<MimeType> mimeTypes;

  public SolutionImportHandler( List<MimeType> mimeTypes ) {
    this.mimeTypes = mimeTypes;
    this.solutionHelper = new SolutionFileImportHelper();
  }

  public ImportSession getImportSession() {
    return ImportSession.getSession();
  }

  public void importFile( IPlatformImportBundle bundle ) throws PlatformImportException, DomainIdNullException,
      DomainAlreadyExistsException, DomainStorageException, IOException {

    RepositoryFileImportBundle importBundle = (RepositoryFileImportBundle) bundle;
    ZipInputStream zipImportStream = new ZipInputStream( bundle.getInputStream() );
    SolutionRepositoryImportSource importSource = new SolutionRepositoryImportSource( zipImportStream );
    LocaleFilesProcessor localeFilesProcessor = new LocaleFilesProcessor();

    // importSession.set(ImportSession.getSession());

    IPlatformImporter importer = PentahoSystem.get( IPlatformImporter.class );

    cachedImports = new HashMap<String, RepositoryFileImportBundle.Builder>();

    //Process Manifest Settings
    ExportManifest manifest = getImportSession().getManifest();
    String manifestVersion = null;
    if ( manifest != null ) {
      manifestVersion = manifest.getManifestInformation().getManifestVersion();
    }
    // Process Metadata
    if ( manifest != null ) {
      List<ExportManifestMetadata> metadataList = manifest.getMetadataList();
      for ( ExportManifestMetadata exportManifestMetadata : metadataList ) {

        String domainId = exportManifestMetadata.getDomainId();
        boolean overWriteInRepository = true;
        RepositoryFileImportBundle.Builder bundleBuilder =
            new RepositoryFileImportBundle.Builder().charSet( "UTF-8" ).hidden( false ).overwriteFile(
                overWriteInRepository ).mime( "text/xmi+xml" ).withParam( "domain-id", domainId );

        cachedImports.put( exportManifestMetadata.getFile(), bundleBuilder );

      }

      // Process Mondrian
      List<ExportManifestMondrian> mondrianList = manifest.getMondrianList();
      for ( ExportManifestMondrian exportManifestMondrian : mondrianList ) {

        String catName = exportManifestMondrian.getCatalogName();
        Parameters parametersMap = exportManifestMondrian.getParameters();
        StringBuilder parametersStr = new StringBuilder();
        for ( String s : parametersMap.keySet() ) {
          parametersStr.append( s ).append( "=" ).append( parametersMap.get( s ) ).append( sep );
        }

        RepositoryFileImportBundle.Builder bundleBuilder =
            new RepositoryFileImportBundle.Builder().charSet( "UTF_8" ).hidden( false ).name( catName ).overwriteFile(
                true ).mime( "application/vnd.pentaho.mondrian+xml" )
                .withParam( "parameters", parametersStr.toString() ).withParam( "domain-id", catName ); // TODO: this is
        // definitely
        // named wrong
        // at the very
        // least.
        // pass as param if not in parameters string
        String xmlaEnabled = "" + exportManifestMondrian.isXmlaEnabled();
        bundleBuilder.withParam( "EnableXmla", xmlaEnabled );

        cachedImports.put( exportManifestMondrian.getFile(), bundleBuilder );
      }
    }

    for ( IRepositoryFileBundle file : importSource.getFiles() ) {
      String fileName = file.getFile().getName();
      String actualFilePath = file.getPath();
      if ( manifestVersion != null ) {
        fileName = ExportFileNameEncoder.decodeZipFileName( fileName );
        actualFilePath = ExportFileNameEncoder.decodeZipFileName( actualFilePath );
      }
      String repositoryFilePath =
          RepositoryFilenameUtils.concat( PentahoPlatformImporter.computeBundlePath( actualFilePath ), fileName );

      if ( this.cachedImports.containsKey( repositoryFilePath ) ) {

        byte[] bytes = IOUtils.toByteArray( file.getInputStream() );
        RepositoryFileImportBundle.Builder builder = cachedImports.get( repositoryFilePath );
        builder.input( new ByteArrayInputStream( bytes ) );

        importer.importFile( build( builder ) );
        continue;
      }
      RepositoryFileImportBundle.Builder bundleBuilder = new RepositoryFileImportBundle.Builder();

      InputStream bundleInputStream = null;

      String decodedFilePath = file.getPath();
      RepositoryFile decodedFile = file.getFile();
      if ( manifestVersion != null ) {
        decodedFile = new RepositoryFile.Builder( decodedFile ).path( decodedFilePath ).name( fileName ).title( fileName ).build();
        decodedFilePath = ExportFileNameEncoder.decodeZipFileName( file.getPath() );
      }

      if ( file.getFile().isFolder() ) {
        bundleBuilder.mime( "text/directory" );
        bundleBuilder.file( decodedFile );
        fileName = repositoryFilePath;
        repositoryFilePath = importBundle.getPath();
      } else {
        byte[] bytes = IOUtils.toByteArray( file.getInputStream() );
        bundleInputStream = new ByteArrayInputStream( bytes );
        // If is locale file store it for later processing.
        if ( localeFilesProcessor.isLocaleFile( file, importBundle.getPath(), bytes ) ) {
          log.trace( "Skipping [" + repositoryFilePath + "], it is a locale property file" );
          continue;
        }
        bundleBuilder.input( bundleInputStream );
        bundleBuilder.mime( solutionHelper.getMime( fileName ) );

        String filePath =
            ( decodedFilePath.equals( "/" ) || decodedFilePath.equals( "\\" ) ) ? "" : decodedFilePath;
        repositoryFilePath = RepositoryFilenameUtils.concat( importBundle.getPath(), filePath );
      }

      bundleBuilder.name( fileName );
      bundleBuilder.path( repositoryFilePath );

      String sourcePath;
      if ( decodedFilePath.startsWith( "/" ) ) {
        sourcePath = RepositoryFilenameUtils.concat( decodedFilePath.substring( 1 ), fileName );
      } else {
        if ( file.getFile().isFolder() ) {
          sourcePath = fileName;
        } else {
          sourcePath = RepositoryFilenameUtils.concat( decodedFilePath, fileName );
        }
      }

      //This clause was added for processing ivb files so that it would not try process acls on folders that the user
      //may not have rights to such as /home or /public
      if ( manifest != null && manifest.getExportManifestEntity( sourcePath ) == null && file.getFile().isFolder() ) {
        continue;
      }

      getImportSession().setCurrentManifestKey( sourcePath );

      bundleBuilder.charSet( bundle.getCharset() );
      bundleBuilder.overwriteFile( bundle.overwriteInRepository() );
      bundleBuilder.hidden( isFileHidden( bundle, sourcePath ) );
      bundleBuilder.applyAclSettings( bundle.isApplyAclSettings() );
      bundleBuilder.retainOwnership( bundle.isRetainOwnership() );
      bundleBuilder.overwriteAclSettings( bundle.isOverwriteAclSettings() );
      bundleBuilder.acl( getImportSession().processAclForFile( sourcePath ) );
      IPlatformImportBundle platformImportBundle = build( bundleBuilder );
      importer.importFile( platformImportBundle );

      if ( bundleInputStream != null ) {
        bundleInputStream.close();
        bundleInputStream = null;
      }
    }
    if ( manifest != null ) {
      List<JobScheduleRequest> scheduleList = manifest.getScheduleList();
      if ( scheduleList != null ) {
        SchedulerResource schedulerResource = new SchedulerResource();
        for ( JobScheduleRequest jobScheduleRequest : scheduleList ) {
          try {
            Response response = createSchedulerJob( schedulerResource, jobScheduleRequest );
            if ( response.getStatus() == Response.Status.OK.getStatusCode() ) {
              if ( response.getEntity() != null ) {
                // get the schedule job id from the response and add it to the import session
                ImportSession.getSession().addImportedScheduleJobId( response.getEntity().toString() );
              }
            }
          } catch ( Exception e ) {
            throw new PlatformImportException( Messages.getInstance()
                .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ) );
          }
        }
      }

      // Add Pentaho Connections
      List<org.pentaho.database.model.DatabaseConnection> datasourceList = manifest.getDatasourceList();
      if ( datasourceList != null ) {
        IDatasourceMgmtService datasourceMgmtSvc = PentahoSystem.get( IDatasourceMgmtService.class );
        for ( org.pentaho.database.model.DatabaseConnection databaseConnection : datasourceList ) {
          try {
            IDatabaseConnection existingDBConnection =
                datasourceMgmtSvc.getDatasourceByName( databaseConnection.getName() );
            if ( existingDBConnection != null && existingDBConnection.getName() != null ) {
              databaseConnection.setId( existingDBConnection.getId() );
              datasourceMgmtSvc.updateDatasourceByName( databaseConnection.getName(), databaseConnection );
            } else {
              datasourceMgmtSvc.createDatasource( databaseConnection );
            }
          } catch ( Exception e ) {
            e.printStackTrace();
          }
        }
      }

    }
    // Process locale files.
    localeFilesProcessor.processLocaleFiles( importer );
  }

  /**
   * Determines if the file or folder should be hidden. If there is a manifest entry for the file, and we are not
   * ignoring the manifest, then set the hidden flag based on the manifest. Otherwise use the blacklist to determine if
   * it is hidden.
   *
   * @param bundle
   * @param filePath
   * @return true if file/folder should be hidden, false otherwise
   */
  private boolean isFileHidden( IPlatformImportBundle bundle, String filePath ) {
    Boolean result = getImportSession().isFileHidden( filePath );
    return ( result != null ) ? result : solutionHelper.isInHiddenList( filePath );
  }

  private boolean isSystemPath( final String bundlePath ) {
    final String[] split = StringUtils.split( bundlePath, RepositoryFile.SEPARATOR );
    return isSystemDir( split, 0 ) || isSystemDir( split, 1 );
  }

  private boolean isSystemDir( final String[] split, final int index ) {
    return ( split != null && index < split.length && ( StringUtils.equals( split[index], "system" ) || StringUtils
        .equals( split[index], "admin" ) ) );
  }

  class SolutionRepositoryImportSource {
    private ZipInputStream zipInputStream;
    private List<IRepositoryFileBundle> files;

    public SolutionRepositoryImportSource( final ZipInputStream zipInputStream ) {
      this.zipInputStream = zipInputStream;
      this.files = new ArrayList<IRepositoryFileBundle>();
      initialize();
    }

    protected void initialize() {
      try {
        ZipEntry entry = zipInputStream.getNextEntry();
        while ( entry != null ) {
          final String entryName = RepositoryFilenameUtils.separatorsToRepository( entry.getName() );
          File tempFile = null;
          boolean isDir = entry.isDirectory();
          if ( !isDir ) {
            if ( !solutionHelper.isInApprovedExtensionList( entryName ) ) {
              zipInputStream.closeEntry();
              entry = zipInputStream.getNextEntry();
              continue;
            }
            tempFile = File.createTempFile( "zip", null );
            tempFile.deleteOnExit();
            FileOutputStream fos = new FileOutputStream( tempFile );
            IOUtils.copy( zipInputStream, fos );
            fos.close();
          }
          File file = new File( entryName );
          RepositoryFile repoFile =
              new RepositoryFile.Builder( file.getName() ).folder( isDir ).hidden( false ).build();
          String parentDir =
              new File( entryName ).getParent() == null ? RepositoryFile.SEPARATOR : new File( entryName ).getParent()
                  + RepositoryFile.SEPARATOR;
          IRepositoryFileBundle repoFileBundle =
              new RepositoryFileBundle( repoFile, null, parentDir, tempFile, "UTF-8", null );

          if ( file.getName().equals( "exportManifest.xml" ) ) {
            initializeAclManifest( repoFileBundle );
          } else {
            files.add( repoFileBundle );
          }
          zipInputStream.closeEntry();
          entry = zipInputStream.getNextEntry();
        }
        zipInputStream.close();
      } catch ( IOException exception ) {
        final String errorMessage = Messages.getInstance().getErrorString( "", exception.getLocalizedMessage() );
        log.trace( errorMessage );
      }
    }

    private void initializeAclManifest( IRepositoryFileBundle file ) {
      try {
        byte[] bytes = IOUtils.toByteArray( file.getInputStream() );
        ByteArrayInputStream in = new ByteArrayInputStream( bytes );
        getImportSession().setManifest( ExportManifest.fromXml( in ) );
      } catch ( Exception e ) {
        log.trace( e );
      }
    }

    public List<IRepositoryFileBundle> getFiles() {
      return this.files;
    }
  }

  @Override
  public List<MimeType> getMimeTypes() {
    return mimeTypes;
  }

  // handlers that extend this class may override this method and perform operations
  // over the bundle prior to entering its designated importer.importFile()
  public IPlatformImportBundle build( RepositoryFileImportBundle.Builder builder ) {
    return builder != null ? builder.build() : null;
  }

  // handlers that extend this class may override this method and perform operations
  // over the job prior to its creation at scheduler.createJob()
  public Response createSchedulerJob( SchedulerResource scheduler, JobScheduleRequest jobRequest ) throws IOException {
    return scheduler != null ? scheduler.createJob( jobRequest ) : null;
  }
}
TOP

Related Classes of org.pentaho.platform.plugin.services.importer.SolutionImportHandler$SolutionRepositoryImportSource

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.