/*!
* 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 java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.metadata.repository.DomainAlreadyExistsException;
import org.pentaho.metadata.repository.DomainIdNullException;
import org.pentaho.metadata.repository.DomainStorageException;
import org.pentaho.platform.api.mimetype.IMimeType;
import org.pentaho.platform.api.repository2.unified.IPlatformImportBundle;
import org.pentaho.platform.api.mimetype.IPlatformMimeResolver;
import org.pentaho.platform.api.repository2.unified.IRepositoryContentConverterHandler;
import org.pentaho.platform.api.repository2.unified.RepositoryFile;
import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryAccessDeniedException;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.plugin.services.importexport.IRepositoryImportLogger;
import org.pentaho.platform.plugin.services.messages.Messages;
import org.pentaho.platform.repository.RepositoryFilenameUtils;
/**
* Default implementation of IPlatformImporter. This class serves to route import requests to the appropriate
* IPlatformImportHandler based on the mime-type of the given content. If not supplied the mime-type will be computed by
* the IPlatformMimeResolver.
* <p/>
* User: nbaker Date: 5/29/12
*/
public class PentahoPlatformImporter implements IPlatformImporter {
private static final Log log = LogFactory.getLog( PentahoPlatformImporter.class );
private static final Messages messages = Messages.getInstance();
private Map<String, IPlatformImportHandler> importHandlers;
private IPlatformImportHandler defaultHandler;
private IPlatformMimeResolver mimeResolver;
private IRepositoryImportLogger repositoryImportLogger;
private IRepositoryContentConverterHandler repositoryContentConverterHandler;
public PentahoPlatformImporter( List<IPlatformImportHandler> handlerList,
IRepositoryContentConverterHandler repositoryContentConverterHandler ) {
this.repositoryContentConverterHandler = repositoryContentConverterHandler;
importHandlers = new HashMap<String, IPlatformImportHandler>();
mimeResolver = PentahoSystem.get( IPlatformMimeResolver.class );
for ( IPlatformImportHandler platformImportHandler : handlerList ) {
addHandler( platformImportHandler );
}
}
public IPlatformImportHandler getDefaultHandler() {
return this.defaultHandler;
}
public void setDefaultHandler( IPlatformImportHandler defaultHandler ) {
this.defaultHandler = defaultHandler;
}
/**
* To be consumed mainly by platform plugins who want to treat importing artifacts different.
*/
public void addHandler( String mimeType, IPlatformImportHandler handler ) {
this.importHandlers.put( mimeType, handler );
}
@Override
public void addHandler( IPlatformImportHandler platformImportHandler ) {
for ( IMimeType mimeType : platformImportHandler.getMimeTypes() ) {
this.importHandlers.put( mimeType.getName(), platformImportHandler );
this.mimeResolver.addMimeType( mimeType );
for ( String extension : mimeType.getExtensions() ) {
repositoryContentConverterHandler.addConverter( extension, mimeType.getConverter() );
}
}
}
/**
* this is the main method that uses the mime time (from Spring) to determine which handler to invoke.
*/
public void importFile( IPlatformImportBundle file ) throws PlatformImportException {
String mime = file.getMimeType() != null ? file.getMimeType() : mimeResolver.resolveMimeForBundle( file );
try {
if ( mime == null ) {
log.trace( messages.getString( "PentahoPlatformImporter.ERROR_0001_INVALID_MIME_TYPE" ) + file.getName() );
repositoryImportLogger.error( messages.getString( "PentahoPlatformImporter.ERROR_0001_INVALID_MIME_TYPE" )
+ file.getName() );
return;
}
IPlatformImportHandler handler =
( importHandlers.containsKey( mime ) == false ) ? defaultHandler : importHandlers.get( mime );
if ( handler == null ) {
throw new PlatformImportException( messages
.getString( "PentahoPlatformImporter.ERROR_0002_MISSING_IMPORT_HANDLER" ),
PlatformImportException.PUBLISH_GENERAL_ERROR
); // replace with default handler?
}
try {
logImportFile( file );
handler.importFile( file );
} catch ( DomainIdNullException e1 ) {
throw new PlatformImportException( messages
.getString( "PentahoPlatformImporter.ERROR_0004_PUBLISH_TO_SERVER_FAILED" ),
PlatformImportException.PUBLISH_TO_SERVER_FAILED, e1
);
} catch ( DomainAlreadyExistsException e1 ) {
throw new PlatformImportException( messages
.getString( "PentahoPlatformImporter.ERROR_0007_PUBLISH_SCHEMA_EXISTS_ERROR" ),
PlatformImportException.PUBLISH_SCHEMA_EXISTS_ERROR, e1
);
} catch ( DomainStorageException e1 ) {
throw new PlatformImportException( messages
.getString( "PentahoPlatformImporter.ERROR_0004_PUBLISH_TO_SERVER_FAILED" ),
PlatformImportException.PUBLISH_DATASOURCE_ERROR, e1
);
} catch ( IOException e1 ) {
throw new PlatformImportException( messages
.getString( "PentahoPlatformImporter.ERROR_0005_PUBLISH_GENERAL_ERRORR" ),
PlatformImportException.PUBLISH_GENERAL_ERROR, e1
);
} catch ( PlatformImportException pe ) {
throw pe; // if already converted - just rethrow
} catch ( Exception e1 ) {
throw new PlatformImportException( messages
.getString( "PentahoPlatformImporter.ERROR_0005_PUBLISH_GENERAL_ERRORR" ),
PlatformImportException.PUBLISH_GENERAL_ERROR, e1
);
}
} catch ( Exception e ) {
e.printStackTrace();
// If we are doing a logged import then we do not want to fail on a single file
// so log the error and keep going.
RepositoryFileImportBundle bundle = (RepositoryFileImportBundle) file;
String repositoryFilePath = RepositoryFilenameUtils.concat( bundle.getPath(), bundle.getName() );
if ( repositoryImportLogger.hasLogger() && repositoryFilePath != null && repositoryFilePath.length() > 0 ) {
repositoryImportLogger.error( e );
} else {
if ( e instanceof PlatformImportException ) {
throw (PlatformImportException) e;
} else {
// shouldn't happen but just in case
throw new PlatformImportException( e.getMessage() );
}
}
if ( e.getCause() instanceof UnifiedRepositoryAccessDeniedException ) {
throw new UnifiedRepositoryAccessDeniedException();
}
}
}
private void logImportFile( IPlatformImportBundle file ) {
RepositoryFileImportBundle bundle = (RepositoryFileImportBundle) file;
String repositoryFilePath = RepositoryFilenameUtils.concat( bundle.getPath(), bundle.getName() );
// If doing a mondrian publish then there will be no active logger
if ( repositoryImportLogger.hasLogger() && repositoryFilePath != null && repositoryFilePath.length() > 0 ) {
repositoryImportLogger.setCurrentFilePath( repositoryFilePath );
repositoryImportLogger.warn( file.getName() );
}
}
public static String computeBundlePath( String bundlePath ) {
bundlePath = RepositoryFilenameUtils.separatorsToRepository( bundlePath );
if ( bundlePath.startsWith( RepositoryFile.SEPARATOR ) ) {
bundlePath = bundlePath.substring( 1 );
}
return bundlePath;
}
public IRepositoryImportLogger getRepositoryImportLogger() {
return repositoryImportLogger;
}
public void setRepositoryImportLogger( IRepositoryImportLogger repositoryImportLogger ) {
this.repositoryImportLogger = repositoryImportLogger;
}
public Map<String, IPlatformImportHandler> getHandlers() {
return importHandlers;
}
}