components/visual-panels/core/src/java/vpanels/panel/com/oracle/solaris/vp/panel/common/action/DefaultStructuredAction.java
changeset 3553 f1d133b09a8c
parent 3552 077ebe3d0d24
child 3554 ef58713bafc4
equal deleted inserted replaced
3552:077ebe3d0d24 3553:f1d133b09a8c
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 
       
    22 /*
       
    23  * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
       
    24  */
       
    25 
       
    26 package com.oracle.solaris.vp.panel.common.action;
       
    27 
       
    28 import java.awt.EventQueue;
       
    29 import java.util.logging.Logger;
       
    30 import javax.swing.JOptionPane;
       
    31 import com.oracle.solaris.vp.panel.common.*;
       
    32 import com.oracle.solaris.vp.panel.common.api.auth.*;
       
    33 import com.oracle.solaris.vp.util.misc.*;
       
    34 import com.oracle.solaris.vp.util.misc.finder.Finder;
       
    35 
       
    36 /**
       
    37  * The {@code DefaultStructuredAction} is a {@link StructuredAction} that uses a
       
    38  * {@link ClientContext} to handle errors and show a busy indicator while work
       
    39  * is being done.
       
    40  * <p/>
       
    41  * Subclasses should implement {@link #workBusy}, and optionally {@link
       
    42  * #getRuntimeInput} if they need to interact with the user prior to running.
       
    43  */
       
    44 public class DefaultStructuredAction<P, I, O>
       
    45     extends StructuredAction<P, I, O> {
       
    46 
       
    47     //
       
    48     // Instance data
       
    49     //
       
    50 
       
    51     private ClientContext context;
       
    52 
       
    53     //
       
    54     // Constructors
       
    55     //
       
    56 
       
    57     public DefaultStructuredAction(String text, P pInput,
       
    58 	ClientContext context) {
       
    59 
       
    60 	super(text, pInput);
       
    61 	this.context = context;
       
    62     }
       
    63 
       
    64     public DefaultStructuredAction(String text, ClientContext context) {
       
    65 	this(text, null, context);
       
    66     }
       
    67 
       
    68     //
       
    69     // StructuredAction methods
       
    70     //
       
    71 
       
    72     /**
       
    73      * Calls {@link #setBusyAndWork}, then catches, displays, and re-throws any
       
    74      * resulting {@link ActionFailedException}s, and catches any resulting
       
    75      * {@link ActionUnauthorizedException}s and prompts the user to change his
       
    76      * login before retrying.
       
    77      * <p>
       
    78      * Note: See {@link #setBusyAndWork} for the note about calling this method
       
    79      * on the Swing event thread.
       
    80      *
       
    81      * @param	    pInput
       
    82      *		    see {@link StructuredAction#work}
       
    83      *
       
    84      * @param	    rtInput
       
    85      *		    see {@link StructuredAction#work}
       
    86      *
       
    87      * @return	    see {@link StructuredAction#work}
       
    88      *
       
    89      * @exception   ActionAbortedException
       
    90      *		    thrown by {@link #setBusyAndWork} or {@link
       
    91      *		    ClientContext#login}
       
    92      *
       
    93      * @exception   ActionFailedException
       
    94      *		    see {@link StructuredAction#work}
       
    95      */
       
    96     @Override
       
    97     public O work(P pInput, I rtInput) throws ActionAbortedException,
       
    98 	ActionFailedException {
       
    99 
       
   100 	LoginRequest request = null;
       
   101 
       
   102 	while (true) {
       
   103 	    try {
       
   104 		if (request != null) {
       
   105 		    try {
       
   106 			context.login(request, false);
       
   107 		    } finally {
       
   108 			request = null;
       
   109 		    }
       
   110 		}
       
   111 
       
   112 		return setBusyAndWork(pInput, rtInput);
       
   113 
       
   114 	    } catch (ActionFailedException e) {
       
   115 		showError(e);
       
   116 		throw e;
       
   117 
       
   118 	    } catch (ActionUnauthorizedException e) {
       
   119 		String eMessage = e.getMessage();
       
   120 		if (eMessage == null) {
       
   121 		    eMessage = Finder.getString("error.server.permission");
       
   122 		}
       
   123 
       
   124 		String userVal = null;
       
   125 		String roleVal = null;
       
   126 
       
   127 		// Prioritize users over roles (more user-friendly)
       
   128 		PrincipalHintList hints = e.getHints();
       
   129 		UserHint uhint = hints.getFirstHint(UserHint.class);
       
   130 		if (uhint != null) {
       
   131 		    userVal = uhint.getUsername();
       
   132 		} else {
       
   133 		    RoleHint rhint = hints.getFirstHint(RoleHint.class);
       
   134 		    if (rhint != null) {
       
   135 			roleVal = rhint.getRolename();
       
   136 		    }
       
   137 		}
       
   138 
       
   139 		// Log in with a different user/role and try again
       
   140 		ConnectionInfo info = context.getConnectionInfo();
       
   141 		LoginProperty<String> host =
       
   142 		    new LoginProperty<String>(info.getHost(), false);
       
   143 		LoginProperty<String> user =
       
   144 		    new LoginProperty<String>(userVal != null ?
       
   145 		    userVal : info.getUser(), true);
       
   146 		LoginProperty<String> role =
       
   147 		    new LoginProperty<String>(roleVal != null ?
       
   148 		    roleVal : info.getRole(), true);
       
   149 
       
   150 		DialogMessage message = new DialogMessage(
       
   151 		    eMessage, JOptionPane.WARNING_MESSAGE);
       
   152 
       
   153 		request = new LoginRequest(host, user, role, message);
       
   154 	    }
       
   155 	}
       
   156     }
       
   157 
       
   158     //
       
   159     // DefaultStructuredAction methods
       
   160     //
       
   161 
       
   162     public ClientContext getClientContext() {
       
   163 	return context;
       
   164     }
       
   165 
       
   166     /**
       
   167      * Sets the busy state of this {@code DefaultStructuredAction}'s {@link
       
   168      * ClientContext}, then calls {@link #workBusy}, preventing the user from
       
   169      * interacting with the application until {@link #workBusy} is complete.
       
   170      * <p>
       
   171      * Note: in a Swing context, this method should not be called on the event
       
   172      * thread, since a) it calls {@link #workBusy} which may perform intensive
       
   173      * non-UI work, and b) it displays the {@link ClientContext#getBusyIndicator
       
   174      * ClientContext's busy indicator}, which may invoke UI effects that would
       
   175      * not be displayed until after this method is done (when the event thread
       
   176      * is free).
       
   177      *
       
   178      * @param	    pInput
       
   179      *		    see {@link StructuredAction#work}
       
   180      *
       
   181      * @param	    rtInput
       
   182      *		    see {@link StructuredAction#work}
       
   183      *
       
   184      * @return	    see {@link StructuredAction#work}
       
   185      *
       
   186      * @exception   ActionAbortedException
       
   187      *		    see {@link StructuredAction#work}
       
   188      *
       
   189      * @exception   ActionFailedException
       
   190      *		    see {@link StructuredAction#work}
       
   191      *
       
   192      * @exception   ActionUnauthorizedException
       
   193      *		    see {@link #workBusy}
       
   194      */
       
   195     public O setBusyAndWork(P pInput, I rtInput) throws ActionAbortedException,
       
   196 	ActionFailedException, ActionUnauthorizedException {
       
   197 
       
   198 	assert (!EventQueue.isDispatchThread());
       
   199 
       
   200 	context.getBusyIndicator().setBusyIndicatorDisplayed(true);
       
   201 
       
   202 	try {
       
   203 	    return workBusy(pInput, rtInput);
       
   204 	} finally {
       
   205 	    context.getBusyIndicator().setBusyIndicatorDisplayed(false);
       
   206 	}
       
   207     }
       
   208 
       
   209     protected void setClientContext(ClientContext context) {
       
   210 	this.context = context;
       
   211     }
       
   212 
       
   213     /**
       
   214      * Handles {@link ActionFailedException}s thrown by {@link #work}.
       
   215      * <p/>
       
   216      * This default implementation logs ({@code Level.FINE}) the error to the
       
   217      * {@link ClientContext} log.
       
   218      */
       
   219     protected void showError(ActionFailedException e) {
       
   220 	Logger.getLogger(getClass().getPackage().getName()).fine(
       
   221 	    ThrowableUtil.getTrueMessage(e));
       
   222     }
       
   223 
       
   224     /**
       
   225      * Does the core work of this action.
       
   226      * <p>
       
   227      * This default implementation does nothing and returns {@code null}.
       
   228      *
       
   229      * @param	    pInput
       
   230      *		    see {@link StructuredAction#work}
       
   231      *
       
   232      * @param	    rtInput
       
   233      *		    see {@link StructuredAction#work}
       
   234      *
       
   235      * @return	    see {@link StructuredAction#work}
       
   236      *
       
   237      * @exception   ActionAbortedException
       
   238      *		    see {@link StructuredAction#work}
       
   239      *
       
   240      * @exception   ActionFailedException
       
   241      *		    see {@link StructuredAction#work}
       
   242      *
       
   243      * @exception   ActionUnauthorizedException
       
   244      *		    if the current user has insufficient privileges for this
       
   245      *		    operation
       
   246      */
       
   247     public O workBusy(P pInput, I rtInput)
       
   248 	throws ActionAbortedException, ActionFailedException,
       
   249 	ActionUnauthorizedException {
       
   250 
       
   251 	return null;
       
   252     }
       
   253 }