/*! * 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; } }