/*!
* 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.reporting.designer.extensions.pentaho.repository.actions;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Window;
import javax.swing.SwingUtilities;
import org.pentaho.reporting.designer.core.ReportDesignerContext;
import org.pentaho.reporting.designer.core.auth.AuthenticationData;
import org.pentaho.reporting.designer.core.auth.AuthenticationStore;
import org.pentaho.reporting.designer.core.editor.ReportDocumentContext;
import org.pentaho.reporting.designer.extensions.pentaho.repository.Messages;
import org.pentaho.reporting.designer.extensions.pentaho.repository.dialogs.RepositoryLoginDialog;
import org.pentaho.reporting.designer.extensions.pentaho.repository.util.PublishSettings;
import org.pentaho.reporting.engine.classic.core.modules.gui.commonswing.ExceptionDialog;
import org.pentaho.reporting.libraries.designtime.swing.LibSwingUtil;
import org.pentaho.reporting.libraries.designtime.swing.background.BackgroundCancellableProcessHelper;
import org.pentaho.reporting.libraries.designtime.swing.background.GenericCancelHandler;
public class LoginTask implements Runnable {
private final ReportDesignerContext designerContext;
private final Component uiContext;
private final AuthenticatedServerTask followUpTask;
private final boolean loginForPublish;
private boolean skipFirstShowDialog;
private RepositoryLoginDialog loginDialog;
private AuthenticationData loginData;
public LoginTask( final ReportDesignerContext designerContext, final Component uiContext,
final AuthenticatedServerTask followUpTask ) {
this( designerContext, uiContext, followUpTask, null, false );
}
public LoginTask( final ReportDesignerContext designerContext, final Component uiContext,
final AuthenticatedServerTask followUpTask, final AuthenticationData loginData ) {
this( designerContext, uiContext, followUpTask, loginData, false );
}
public LoginTask( final ReportDesignerContext designerContext, final Component uiContext,
final AuthenticatedServerTask followUpTask, final AuthenticationData loginData, final boolean loginForPublish ) {
if ( designerContext == null ) {
throw new NullPointerException();
}
if ( uiContext == null ) {
throw new NullPointerException();
}
this.loginForPublish = loginForPublish;
this.designerContext = designerContext;
this.uiContext = uiContext;
this.followUpTask = followUpTask;
if ( loginData != null ) {
this.loginData = loginData;
this.skipFirstShowDialog = true;
} else {
final ReportDocumentContext reportRenderContext = designerContext.getActiveContext();
if ( reportRenderContext != null ) {
final Object o = reportRenderContext.getProperties().get( "pentaho-login-url" );
if ( o != null ) {
// prepopulate the dialog with the correct login data, but do not skip login completely.
this.loginData = RepositoryLoginDialog.getStoredLoginData( String.valueOf( o ), designerContext );
}
}
if ( this.loginData == null ) {
this.loginData = RepositoryLoginDialog.getDefaultData( designerContext );
}
this.skipFirstShowDialog = false;
}
}
/**
* When an object implementing interface <code>Runnable</code> is used to create a thread, starting the thread causes
* the object's <code>run</code> method to be called in that separately executing thread.
* <p/>
* The general contract of the method <code>run</code> is that it may take any action whatsoever.
*
* @see Thread#run()
*/
public void run() {
boolean loginComplete;
do {
if ( loginDialog == null ) {
final Window window = LibSwingUtil.getWindowAncestor( uiContext );
if ( window instanceof Frame ) {
loginDialog = new RepositoryLoginDialog( (Frame) window, loginForPublish );
} else if ( window instanceof Dialog ) {
loginDialog = new RepositoryLoginDialog( (Dialog) window, loginForPublish );
} else {
loginDialog = new RepositoryLoginDialog( loginForPublish );
}
}
if ( skipFirstShowDialog ) {
skipFirstShowDialog = false;
} else {
this.loginData = loginDialog.performLogin( designerContext, loginData );
if ( loginData == null ) {
return;
}
}
final ValidateLoginTask validateLoginTask = new ValidateLoginTask( this );
final Thread loginThread = new Thread( validateLoginTask );
loginThread.setDaemon( true );
loginThread.setPriority( Thread.MIN_PRIORITY );
final GenericCancelHandler cancelHandler = new GenericCancelHandler( loginThread );
BackgroundCancellableProcessHelper.executeProcessWithCancelDialog( loginThread, cancelHandler, uiContext,
Messages.getInstance().getString( "LoginTask.ValidateLoginMessage" ) );
if ( cancelHandler.isCancelled() ) {
return;
}
if ( validateLoginTask.getException() != null ) {
final Exception exception = validateLoginTask.getException();
ExceptionDialog.showExceptionDialog( uiContext, Messages.getInstance().getString(
"LoadReportFromRepositoryAction.LoginError.Title" ), Messages.getInstance().formatMessage(
"LoadReportFromRepositoryAction.LoginError.Message", exception.getMessage() ), exception );
loginComplete = false;
} else {
loginComplete = validateLoginTask.isLoginComplete();
}
} while ( loginComplete == false );
if ( loginDialog != null && loginDialog.isRememberSettings() ) {
final ReportDocumentContext reportRenderContext = designerContext.getActiveContext();
if ( reportRenderContext != null ) {
final AuthenticationStore store = reportRenderContext.getAuthenticationStore();
store.add( loginData, true );
} else {
designerContext.getGlobalAuthenticationStore().add( loginData, true );
}
}
final boolean storeUpdates;
if ( loginDialog == null ) {
storeUpdates = PublishSettings.getInstance().isRememberSettings();
} else {
storeUpdates = loginDialog.isRememberSettings();
}
if ( followUpTask != null ) {
followUpTask.setLoginData( loginData, storeUpdates );
SwingUtilities.invokeLater( followUpTask );
}
UpdateReservedCharsTask updateReservedCharsTask = new UpdateReservedCharsTask( loginData );
SwingUtilities.invokeLater( updateReservedCharsTask );
}
public AuthenticationData getLoginData() {
return loginData;
}
}