--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/visual-panels/core/src/java/vpanels/panel/com/oracle/solaris/vp/panel/common/action/DefaultStructuredAction.java Thu May 24 04:16:47 2012 -0400
@@ -0,0 +1,253 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.panel.common.action;
+
+import java.awt.EventQueue;
+import java.util.logging.Logger;
+import javax.swing.JOptionPane;
+import com.oracle.solaris.vp.panel.common.*;
+import com.oracle.solaris.vp.panel.common.api.auth.*;
+import com.oracle.solaris.vp.util.misc.*;
+import com.oracle.solaris.vp.util.misc.finder.Finder;
+
+/**
+ * The {@code DefaultStructuredAction} is a {@link StructuredAction} that uses a
+ * {@link ClientContext} to handle errors and show a busy indicator while work
+ * is being done.
+ * <p/>
+ * Subclasses should implement {@link #workBusy}, and optionally {@link
+ * #getRuntimeInput} if they need to interact with the user prior to running.
+ */
+public class DefaultStructuredAction<P, I, O>
+ extends StructuredAction<P, I, O> {
+
+ //
+ // Instance data
+ //
+
+ private ClientContext context;
+
+ //
+ // Constructors
+ //
+
+ public DefaultStructuredAction(String text, P pInput,
+ ClientContext context) {
+
+ super(text, pInput);
+ this.context = context;
+ }
+
+ public DefaultStructuredAction(String text, ClientContext context) {
+ this(text, null, context);
+ }
+
+ //
+ // StructuredAction methods
+ //
+
+ /**
+ * Calls {@link #setBusyAndWork}, then catches, displays, and re-throws any
+ * resulting {@link ActionFailedException}s, and catches any resulting
+ * {@link ActionUnauthorizedException}s and prompts the user to change his
+ * login before retrying.
+ * <p>
+ * Note: See {@link #setBusyAndWork} for the note about calling this method
+ * on the Swing event thread.
+ *
+ * @param pInput
+ * see {@link StructuredAction#work}
+ *
+ * @param rtInput
+ * see {@link StructuredAction#work}
+ *
+ * @return see {@link StructuredAction#work}
+ *
+ * @exception ActionAbortedException
+ * thrown by {@link #setBusyAndWork} or {@link
+ * ClientContext#login}
+ *
+ * @exception ActionFailedException
+ * see {@link StructuredAction#work}
+ */
+ @Override
+ public O work(P pInput, I rtInput) throws ActionAbortedException,
+ ActionFailedException {
+
+ LoginRequest request = null;
+
+ while (true) {
+ try {
+ if (request != null) {
+ try {
+ context.login(request, false);
+ } finally {
+ request = null;
+ }
+ }
+
+ return setBusyAndWork(pInput, rtInput);
+
+ } catch (ActionFailedException e) {
+ showError(e);
+ throw e;
+
+ } catch (ActionUnauthorizedException e) {
+ String eMessage = e.getMessage();
+ if (eMessage == null) {
+ eMessage = Finder.getString("error.server.permission");
+ }
+
+ String userVal = null;
+ String roleVal = null;
+
+ // Prioritize users over roles (more user-friendly)
+ PrincipalHintList hints = e.getHints();
+ UserHint uhint = hints.getFirstHint(UserHint.class);
+ if (uhint != null) {
+ userVal = uhint.getUsername();
+ } else {
+ RoleHint rhint = hints.getFirstHint(RoleHint.class);
+ if (rhint != null) {
+ roleVal = rhint.getRolename();
+ }
+ }
+
+ // Log in with a different user/role and try again
+ ConnectionInfo info = context.getConnectionInfo();
+ LoginProperty<String> host =
+ new LoginProperty<String>(info.getHost(), false);
+ LoginProperty<String> user =
+ new LoginProperty<String>(userVal != null ?
+ userVal : info.getUser(), true);
+ LoginProperty<String> role =
+ new LoginProperty<String>(roleVal != null ?
+ roleVal : info.getRole(), true);
+
+ DialogMessage message = new DialogMessage(
+ eMessage, JOptionPane.WARNING_MESSAGE);
+
+ request = new LoginRequest(host, user, role, message);
+ }
+ }
+ }
+
+ //
+ // DefaultStructuredAction methods
+ //
+
+ public ClientContext getClientContext() {
+ return context;
+ }
+
+ /**
+ * Sets the busy state of this {@code DefaultStructuredAction}'s {@link
+ * ClientContext}, then calls {@link #workBusy}, preventing the user from
+ * interacting with the application until {@link #workBusy} is complete.
+ * <p>
+ * Note: in a Swing context, this method should not be called on the event
+ * thread, since a) it calls {@link #workBusy} which may perform intensive
+ * non-UI work, and b) it displays the {@link ClientContext#getBusyIndicator
+ * ClientContext's busy indicator}, which may invoke UI effects that would
+ * not be displayed until after this method is done (when the event thread
+ * is free).
+ *
+ * @param pInput
+ * see {@link StructuredAction#work}
+ *
+ * @param rtInput
+ * see {@link StructuredAction#work}
+ *
+ * @return see {@link StructuredAction#work}
+ *
+ * @exception ActionAbortedException
+ * see {@link StructuredAction#work}
+ *
+ * @exception ActionFailedException
+ * see {@link StructuredAction#work}
+ *
+ * @exception ActionUnauthorizedException
+ * see {@link #workBusy}
+ */
+ public O setBusyAndWork(P pInput, I rtInput) throws ActionAbortedException,
+ ActionFailedException, ActionUnauthorizedException {
+
+ assert (!EventQueue.isDispatchThread());
+
+ context.getBusyIndicator().setBusyIndicatorDisplayed(true);
+
+ try {
+ return workBusy(pInput, rtInput);
+ } finally {
+ context.getBusyIndicator().setBusyIndicatorDisplayed(false);
+ }
+ }
+
+ protected void setClientContext(ClientContext context) {
+ this.context = context;
+ }
+
+ /**
+ * Handles {@link ActionFailedException}s thrown by {@link #work}.
+ * <p/>
+ * This default implementation logs ({@code Level.FINE}) the error to the
+ * {@link ClientContext} log.
+ */
+ protected void showError(ActionFailedException e) {
+ Logger.getLogger(getClass().getPackage().getName()).fine(
+ ThrowableUtil.getTrueMessage(e));
+ }
+
+ /**
+ * Does the core work of this action.
+ * <p>
+ * This default implementation does nothing and returns {@code null}.
+ *
+ * @param pInput
+ * see {@link StructuredAction#work}
+ *
+ * @param rtInput
+ * see {@link StructuredAction#work}
+ *
+ * @return see {@link StructuredAction#work}
+ *
+ * @exception ActionAbortedException
+ * see {@link StructuredAction#work}
+ *
+ * @exception ActionFailedException
+ * see {@link StructuredAction#work}
+ *
+ * @exception ActionUnauthorizedException
+ * if the current user has insufficient privileges for this
+ * operation
+ */
+ public O workBusy(P pInput, I rtInput)
+ throws ActionAbortedException, ActionFailedException,
+ ActionUnauthorizedException {
+
+ return null;
+ }
+}