/*!
* 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-2016 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.platform.plugin.services.importer;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.ws.rs.core.Response;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
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.engine.security.userroledao.AlreadyExistsException;
import org.pentaho.platform.api.engine.security.userroledao.IPentahoRole;
import org.pentaho.platform.api.engine.security.userroledao.IUserRoleDao;
import org.pentaho.platform.api.mimetype.IMimeType;
import org.pentaho.platform.api.mt.ITenant;
import org.pentaho.platform.api.repository.datasource.IDatasourceMgmtService;
import org.pentaho.platform.api.repository2.unified.IPlatformImportBundle;
import org.pentaho.platform.api.repository2.unified.IUnifiedRepository;
import org.pentaho.platform.api.repository2.unified.RepositoryFile;
import org.pentaho.platform.api.scheduler2.Job;
import org.pentaho.platform.api.scheduler2.Job.JobState;
import org.pentaho.platform.api.usersettings.IAnyUserSettingService;
import org.pentaho.platform.api.usersettings.IUserSettingService;
import org.pentaho.platform.api.usersettings.pojo.IUserSetting;
import org.pentaho.platform.core.mt.Tenant;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.engine.core.system.TenantUtils;
import org.pentaho.platform.plugin.services.importexport.ExportFileNameEncoder;
import org.pentaho.platform.plugin.services.importexport.ExportManifestUserSetting;
import org.pentaho.platform.plugin.services.importexport.ImportSession;
import org.pentaho.platform.plugin.services.importexport.ImportSession.ManifestFile;
import org.pentaho.platform.plugin.services.importexport.ImportSource.IRepositoryFileBundle;
import org.pentaho.platform.plugin.services.importexport.RepositoryFileBundle;
import org.pentaho.platform.plugin.services.importexport.RoleExport;
import org.pentaho.platform.plugin.services.importexport.UserExport;
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.ExportManifestMetaStore;
import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMetadata;
import org.pentaho.platform.plugin.services.importexport.exportManifest.bindings.ExportManifestMondrian;
import org.pentaho.platform.plugin.services.importexport.legacy.MondrianCatalogRepositoryHelper;
import org.pentaho.platform.repository.RepositoryFilenameUtils;
import org.pentaho.platform.repository.messages.Messages;
import org.pentaho.platform.security.policy.rolebased.IRoleAuthorizationPolicyRoleBindingDao;
import org.pentaho.platform.web.http.api.resources.JobRequest;
import org.pentaho.platform.web.http.api.resources.JobScheduleParam;
import org.pentaho.platform.web.http.api.resources.JobScheduleRequest;
import org.pentaho.platform.web.http.api.resources.SchedulerResource;
public class SolutionImportHandler implements IPlatformImportHandler {
private static final Log log = LogFactory.getLog( SolutionImportHandler.class );
public static final String RESERVEDMAPKEY_LINEAGE_ID = "lineage-id";
private static final String sep = ";";
private IUnifiedRepository repository; // TODO inject via Spring
protected Map<String, RepositoryFileImportBundle.Builder> cachedImports;
private SolutionFileImportHelper solutionHelper;
private List<IMimeType> mimeTypes;
private boolean overwriteFile;
public SolutionImportHandler( List<IMimeType> mimeTypes ) {
this.mimeTypes = mimeTypes;
this.solutionHelper = new SolutionFileImportHelper();
repository = PentahoSystem.get( IUnifiedRepository.class );
}
public ImportSession getImportSession() {
return ImportSession.getSession();
}
@Override
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();
setOverwriteFile( bundle.overwriteInRepository() );
// 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 ) {
// import the users
Map<String, List<String>> roleToUserMap = importUsers( manifest.getUserExports() );
// import the roles
importRoles( manifest.getRoleExports(), roleToUserMap );
List<ExportManifestMetadata> metadataList = manifest.getMetadataList();
for ( ExportManifestMetadata exportManifestMetadata : metadataList ) {
String domainId = exportManifestMetadata.getDomainId();
boolean overWriteInRepository = isOverwriteFile();
RepositoryFileImportBundle.Builder bundleBuilder =
new RepositoryFileImportBundle.Builder().charSet( "UTF-8" )
.hidden( RepositoryFile.HIDDEN_BY_DEFAULT ).schedulable( RepositoryFile.SCHEDULABLE_BY_DEFAULT )
// let the parent bundle control whether or not to preserve DSW settings
.preserveDsw( bundle.isPreserveDsw() )
.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( RepositoryFile.HIDDEN_BY_DEFAULT )
.schedulable( RepositoryFile.SCHEDULABLE_BY_DEFAULT ).name( catName ).overwriteFile(
isOverwriteFile() ).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 );
String annotationsFile = exportManifestMondrian.getAnnotationsFile();
if ( annotationsFile != null ) {
RepositoryFileImportBundle.Builder annotationsBundle =
new RepositoryFileImportBundle.Builder().path( MondrianCatalogRepositoryHelper.ETC_MONDRIAN_JCR_FOLDER
+ RepositoryFile.SEPARATOR + catName ).name( "annotations.xml" ).charSet( "UTF_8" ).overwriteFile(
isOverwriteFile() ).mime( "text/xml" ).hidden( RepositoryFile.HIDDEN_BY_DEFAULT ).schedulable(
RepositoryFile.SCHEDULABLE_BY_DEFAULT ).withParam( "domain-id", catName );
cachedImports.put( annotationsFile, annotationsBundle );
}
}
}
importMetaStore( manifest, bundle.overwriteInRepository() );
for ( IRepositoryFileBundle fileBundle : importSource.getFiles() ) {
String fileName = fileBundle.getFile().getName();
String actualFilePath = fileBundle.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( fileBundle.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 = fileBundle.getPath();
RepositoryFile decodedFile = fileBundle.getFile();
if ( manifestVersion != null ) {
decodedFile = new RepositoryFile.Builder( decodedFile ).path( decodedFilePath ).name( fileName ).title( fileName ).build();
decodedFilePath = ExportFileNameEncoder.decodeZipFileName( fileBundle.getPath() );
}
if ( fileBundle.getFile().isFolder() ) {
bundleBuilder.mime( "text/directory" );
bundleBuilder.file( decodedFile );
fileName = repositoryFilePath;
repositoryFilePath = importBundle.getPath();
} else {
byte[] bytes = IOUtils.toByteArray( fileBundle.getInputStream() );
bundleInputStream = new ByteArrayInputStream( bytes );
// If is locale file store it for later processing.
if ( localeFilesProcessor.isLocaleFile( fileBundle, 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 ( fileBundle.getFile().isFolder() ) {
sourcePath = fileName;
} else {
sourcePath =
RepositoryFilenameUtils.concat( PentahoPlatformImporter.computeBundlePath( actualFilePath ), 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 && fileBundle.getFile()
.isFolder() ) {
continue;
}
getImportSession().setCurrentManifestKey( sourcePath );
bundleBuilder.charSet( bundle.getCharset() );
bundleBuilder.overwriteFile( bundle.overwriteInRepository() );
bundleBuilder.applyAclSettings( bundle.isApplyAclSettings() );
bundleBuilder.retainOwnership( bundle.isRetainOwnership() );
bundleBuilder.overwriteAclSettings( bundle.isOverwriteAclSettings() );
bundleBuilder.acl( getImportSession().processAclForFile( sourcePath ) );
RepositoryFile file = getFile( importBundle, fileBundle );
ManifestFile manifestFile = getImportSession().getManifestFile( sourcePath, file != null );
bundleBuilder.hidden( isFileHidden( file, manifestFile, sourcePath ) );
bundleBuilder.schedulable( isSchedulable( file, manifestFile ) );
IPlatformImportBundle platformImportBundle = build( bundleBuilder );
importer.importFile( platformImportBundle );
if ( bundleInputStream != null ) {
bundleInputStream.close();
bundleInputStream = null;
}
}
if ( manifest != null ) {
importSchedules( manifest.getScheduleList() );
// 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 ) {
if ( databaseConnection.getDatabaseType() == null ) {
// don't try to import the connection if there is no type it will cause an error
// However, if this is the DI Server, and the connection is defined in a ktr, it will import automatically
log.warn(
"Can't import connection " + databaseConnection.getName() + " because it doesn't have a databaseType" );
continue;
}
try {
IDatabaseConnection existingDBConnection =
datasourceMgmtSvc.getDatasourceByName( databaseConnection.getName() );
if ( existingDBConnection != null && existingDBConnection.getName() != null ) {
if ( isOverwriteFile() ) {
databaseConnection.setId( existingDBConnection.getId() );
datasourceMgmtSvc.updateDatasourceByName( databaseConnection.getName(), databaseConnection );
}
} else {
datasourceMgmtSvc.createDatasource( databaseConnection );
}
} catch ( Exception e ) {
e.printStackTrace();
}
}
}
}
// Process locale files.
localeFilesProcessor.processLocaleFiles( importer );
}
List<Job> getAllJobs( SchedulerResource schedulerResource ) {
return schedulerResource.getAllJobs();
}
private RepositoryFile getFile( IPlatformImportBundle importBundle, IRepositoryFileBundle fileBundle ) {
String repositoryFilePath =
repositoryPathConcat( importBundle.getPath(), fileBundle.getPath(), fileBundle.getFile().getName() );
return repository.getFile( repositoryFilePath );
}
protected void importSchedules( List<JobScheduleRequest> scheduleList ) throws PlatformImportException {
if ( CollectionUtils.isNotEmpty( scheduleList ) ) {
SchedulerResource schedulerResource = new SchedulerResource();
schedulerResource.pause();
for ( JobScheduleRequest jobScheduleRequest : scheduleList ) {
boolean jobExists = false;
List<Job> jobs = getAllJobs( schedulerResource );
if ( jobs != null ) {
//paramRequest to map<String, Serializable>
Map<String, Serializable> mapParamsRequest = new HashMap<>();
for ( JobScheduleParam paramRequest : jobScheduleRequest.getJobParameters() ) {
mapParamsRequest.put( paramRequest.getName(), paramRequest.getValue() );
}
for ( Job job : jobs ) {
if ( ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID ) != null )
&& ( mapParamsRequest.get( RESERVEDMAPKEY_LINEAGE_ID )
.equals( job.getJobParams().get( RESERVEDMAPKEY_LINEAGE_ID ) ) ) ) {
jobExists = true;
}
if ( overwriteFile && jobExists ) {
JobRequest jobRequest = new JobRequest();
jobRequest.setJobId( job.getJobId() );
schedulerResource.removeJob( jobRequest );
jobExists = false;
break;
}
}
}
if ( !jobExists ) {
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 ) {
// there is a scenario where if the file scheduled has a space in the file name, that it won't work. the
// di server
// replaces spaces with underscores and the export mechanism can't determine if it needs this to happen
// or not
// so, if we failed to import and there is a space in the path, try again but this time with replacing
// the space(s)
if ( jobScheduleRequest.getInputFile().contains( " " ) || jobScheduleRequest.getOutputFile()
.contains( " " ) ) {
log.info( "Could not import schedule, attempting to replace spaces with underscores and retrying: "
+ jobScheduleRequest.getInputFile() );
File inFile = new File( jobScheduleRequest.getInputFile() );
File outFile = new File( jobScheduleRequest.getOutputFile() );
String inputFileName = inFile.getParent() + RepositoryFile.SEPARATOR
+ inFile.getName().replaceAll( " ", "_" );
String outputFileName = outFile.getParent() + RepositoryFile.SEPARATOR
+ outFile.getName().replaceAll( " ", "_" );
jobScheduleRequest.setInputFile( inputFileName );
jobScheduleRequest.setOutputFile( outputFileName );
try {
if ( File.separator != RepositoryFile.SEPARATOR ) {
// on windows systems, the backslashes will result in the file not being found in the repository
jobScheduleRequest.setInputFile( inputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) );
jobScheduleRequest
.setOutputFile( outputFileName.replace( File.separator, RepositoryFile.SEPARATOR ) );
}
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 ex ) {
// log it and keep going. we should stop processing all schedules just because one fails.
log.error( Messages.getInstance()
.getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ), ex );
}
} else {
// log it and keep going. we should stop processing all schedules just because one fails.
log.error( Messages.getInstance()
.getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage() ) );
}
}
} else {
log.info( Messages.getInstance()
.getString( "DefaultImportHandler.ERROR_0009_OVERWRITE_CONTENT", jobScheduleRequest.toString() ) );
}
}
schedulerResource.start();
}
}
protected void importMetaStore( ExportManifest manifest, boolean overwrite ) {
// get the metastore
if ( manifest != null ) {
ExportManifestMetaStore manifestMetaStore = manifest.getMetaStore();
if ( manifestMetaStore != null ) {
// get the zipped metastore from the export bundle
RepositoryFileImportBundle.Builder bundleBuilder =
new RepositoryFileImportBundle.Builder()
.path( manifestMetaStore.getFile() )
.name( manifestMetaStore.getName() )
.withParam( "description", manifestMetaStore.getDescription() )
.charSet( "UTF-8" )
.overwriteFile( overwrite )
.mime( "application/vnd.pentaho.metastore" );
cachedImports.put( manifestMetaStore.getFile(), bundleBuilder );
}
}
}
/**
* Imports UserExport objects into the platform as users.
*
* @param users
* @return A map of role names to list of users in that role
*/
protected Map<String, List<String>> importUsers( List<UserExport> users ) {
Map<String, List<String>> roleToUserMap = new HashMap<>();
IUserRoleDao roleDao = PentahoSystem.get( IUserRoleDao.class );
ITenant tenant = new Tenant( "/pentaho/" + TenantUtils.getDefaultTenant(), true );
if ( users != null && roleDao != null ) {
for ( UserExport user : users ) {
String password = user.getPassword();
log.debug( "Importing user: " + user.getUsername() );
// map the user to the roles he/she is in
for ( String role : user.getRoles() ) {
List<String> userList;
if ( !roleToUserMap.containsKey( role ) ) {
userList = new ArrayList<>();
roleToUserMap.put( role, userList );
} else {
userList = roleToUserMap.get( role );
}
userList.add( user.getUsername() );
}
String[] userRoles = user.getRoles().toArray( new String[] {} );
try {
roleDao.createUser( tenant, user.getUsername(), password, null, userRoles );
} catch ( AlreadyExistsException e ) {
// it's ok if the user already exists, it is probably a default user
log.info( Messages.getInstance().getString( "USER.Already.Exists", user.getUsername() ) );
try {
if ( isOverwriteFile() ) {
// set the roles, maybe they changed
roleDao.setUserRoles( tenant, user.getUsername(), userRoles );
// set the password just in case it changed
roleDao.setPassword( tenant, user.getUsername(), password );
}
} catch ( Exception ex ) {
// couldn't set the roles or password either
log.debug( "Failed to set roles or password for existing user on import", ex );
}
} catch ( Exception e ) {
log.error( Messages.getInstance().getString( "ERROR.CreatingUser", user.getUsername() ) );
}
importUserSettings( user );
}
}
return roleToUserMap;
}
protected void importGlobalUserSettings( List<ExportManifestUserSetting> globalSettings ) {
IUserSettingService settingService = PentahoSystem.get( IUserSettingService.class );
if ( settingService != null ) {
for ( ExportManifestUserSetting globalSetting : globalSettings ) {
if ( isOverwriteFile() ) {
settingService.setGlobalUserSetting( globalSetting.getName(), globalSetting.getValue() );
} else {
IUserSetting userSetting = settingService.getGlobalUserSetting( globalSetting.getName(), null );
if ( userSetting == null ) {
settingService.setGlobalUserSetting( globalSetting.getName(), globalSetting.getValue() );
}
}
}
}
}
protected void importUserSettings( UserExport user ) {
IUserSettingService settingService = PentahoSystem.get( IUserSettingService.class );
IAnyUserSettingService userSettingService = null;
if ( settingService != null && settingService instanceof IAnyUserSettingService ) {
userSettingService = (IAnyUserSettingService) settingService;
}
if ( userSettingService != null ) {
List<ExportManifestUserSetting> exportedSettings = user.getUserSettings();
try {
for ( ExportManifestUserSetting exportedSetting : exportedSettings ) {
if ( isOverwriteFile() ) {
userSettingService.setUserSetting( user.getUsername(),
exportedSetting.getName(), exportedSetting.getValue() );
} else {
// see if it's there first before we set this setting
IUserSetting userSetting =
userSettingService.getUserSetting( user.getUsername(), exportedSetting.getName(), null );
if ( userSetting == null ) {
// only set it if we didn't find that it exists already
userSettingService.setUserSetting( user.getUsername(),
exportedSetting.getName(), exportedSetting.getValue() );
}
}
}
} catch ( SecurityException e ) {
log.error( Messages.getInstance().getString( "ERROR.ImportingUserSetting", user.getUsername() ) );
log.debug( Messages.getInstance().getString( "ERROR.ImportingUserSetting", user.getUsername() ), e );
}
}
}
protected void importRoles( List<RoleExport> roles, Map<String, List<String>> roleToUserMap ) {
IUserRoleDao roleDao = PentahoSystem.get( IUserRoleDao.class );
ITenant tenant = new Tenant( "/pentaho/" + TenantUtils.getDefaultTenant(), true );
IRoleAuthorizationPolicyRoleBindingDao roleBindingDao = PentahoSystem.get(
IRoleAuthorizationPolicyRoleBindingDao.class );
Set<String> existingRoles = new HashSet<>();
if ( roles != null ) {
for ( RoleExport role : roles ) {
log.debug( "Importing role: " + role.getRolename() );
try {
List<String> users = roleToUserMap.get( role.getRolename() );
String[] userarray = users == null ? new String[] {} : users.toArray( new String[] {} );
IPentahoRole role1 = roleDao.createRole( tenant, role.getRolename(), null, userarray );
} catch ( AlreadyExistsException e ) {
existingRoles.add( role.getRolename() );
// it's ok if the role already exists, it is probably a default role
log.info( Messages.getInstance().getString( "ROLE.Already.Exists", role.getRolename() ) );
}
try {
if ( existingRoles.contains( role.getRolename() ) ) {
//Only update an existing role if the overwrite flag is set
if ( isOverwriteFile() ) {
roleBindingDao.setRoleBindings( tenant, role.getRolename(), role.getPermissions() );
}
} else {
//Always write a roles permissions that were not previously existing
roleBindingDao.setRoleBindings( tenant, role.getRolename(), role.getPermissions() );
}
} catch ( Exception e ) {
log.info( Messages.getInstance().getString( "ERROR.SettingRolePermissions", role.getRolename() ), e );
}
}
}
}
private boolean isFileHidden( RepositoryFile file, ManifestFile manifestFile, String sourcePath ) {
Boolean result = manifestFile.isFileHidden();
if ( result != null ) {
return result; // file absent or must receive a new setting and the setting is exist
}
if ( file != null ) {
return file.isHidden(); // old setting
}
result = solutionHelper.isInHiddenList( sourcePath );
if ( result ) {
return true;
}
return RepositoryFile.HIDDEN_BY_DEFAULT; // default setting of type
}
private boolean isSchedulable( RepositoryFile file, ManifestFile manifestFile ) {
Boolean result = manifestFile.isFileSchedulable();
if ( result != null ) {
return result; // file absent or must receive a new setting and the setting is exist
}
if ( file != null ) {
return file.isSchedulable(); // old setting
}
return RepositoryFile.SCHEDULABLE_BY_DEFAULT; // default setting of type
}
// 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" ) ) );
// }
private String repositoryPathConcat( String path, String... subPaths ) {
for ( String subPath : subPaths ) {
path = RepositoryFilenameUtils.concat( path, subPath );
}
return path;
}
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<IMimeType> 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 jobScheduleRequest )
throws IOException {
Response rs = scheduler != null ? scheduler.createJob( jobScheduleRequest ) : null;
if ( jobScheduleRequest.getJobState() != JobState.NORMAL ) {
JobRequest jobRequest = new JobRequest();
jobRequest.setJobId( rs.getEntity().toString() );
scheduler.pauseJob( jobRequest );
}
return rs;
}
public boolean isOverwriteFile() {
return overwriteFile;
}
public void setOverwriteFile( boolean overwriteFile ) {
this.overwriteFile = overwriteFile;
}
}