Coverage Report - org.openpermis.editor.policy.gui.binding.ErrorBindingListener
 
Classes in this File Line Coverage Branch Coverage Complexity
ErrorBindingListener
0%
0/32
0%
0/22
2.333
 
 1  
 /*
 2  
  * Copyright (c) 2009, Swiss Federal Department of Defence Civil Protection and Sport
 3  
  *                     (http://www.vbs.admin.ch)
 4  
  * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch)
 5  
  * All rights reserved.
 6  
  *
 7  
  * Licensed under the Open Permis License which accompanies this distribution,
 8  
  * and is available at http://www.openpermis.org/BSDlicenceKent.txt
 9  
  */
 10  
 package org.openpermis.editor.policy.gui.binding;
 11  
 
 12  
 import java.awt.Color;
 13  
 import java.awt.Component;
 14  
 import java.awt.Container;
 15  
 
 16  
 import javax.swing.JComponent;
 17  
 
 18  
 import org.jdesktop.application.ResourceMap;
 19  
 import org.jdesktop.beansbinding.AbstractBindingListener;
 20  
 import org.jdesktop.beansbinding.Binding;
 21  
 import org.jdesktop.beansbinding.Binding.SyncFailure;
 22  
 
 23  
 
 24  
 /**
 25  
  * Binding listener that updates the background of a component if a sync fails.
 26  
  * <p>Also sets a component property to indicate that there was an error.</p>
 27  
  * @see #hasError(JComponent)
 28  
  * @see #hasAnyError(JComponent)
 29  
  * @since 0.1.0
 30  
  */
 31  
 public class ErrorBindingListener
 32  
         extends AbstractBindingListener
 33  
 {
 34  
 
 35  
         //---- Static
 36  
         
 37  
         /**
 38  
          * Property of type {@link Boolean} set at components to indicate an error.
 39  
          * @since 0.1.0
 40  
          */
 41  
         private static final String ERROR_STATE_PROPERTY_KEY = "bindingSyncErrorState";
 42  
         
 43  
         /**
 44  
          * Property of type {@link String} set at components if they have an error.
 45  
          * @since 0.1.0
 46  
          */
 47  
         private static final String ERROR_MESSAGE_PROPERTY_KEY = "bindingSyncErrorMessage";
 48  
         
 49  
         /**
 50  
          * Returns the error message of a component that has an error.
 51  
          * @param component the component for wich to retrieve the error message.
 52  
          * @return the error message or {@code null} if the component has no error.
 53  
          * @since 0.1.0
 54  
          */
 55  
         public static String getErrorMessage (JComponent component) {
 56  0
                 return (String) component.getClientProperty(ERROR_MESSAGE_PROPERTY_KEY);
 57  
         }
 58  
         
 59  
         /**
 60  
          * Check if the specified or any child component has a synchronization error.
 61  
          * @param component the component to check.
 62  
          * @return {@code true} if at least one component has an error, {@code false} otherwise.
 63  
          * @since 0.1.0
 64  
          */
 65  
         public static boolean hasAnyError (JComponent component) {
 66  0
                 return hasError(component) || primHasAnyError(component);
 67  
         }
 68  
         
 69  
         /**
 70  
          * Primitive to traverse the child list of the specified container and check for errors.
 71  
          * @param container the container to traverse.
 72  
          * @return {@code true} if at least one component has an error, {@code false} otherwise.
 73  
          * @since 0.1.0
 74  
          */
 75  
         private static boolean primHasAnyError (Container container) {
 76  0
                 for (Component child : container.getComponents()) {
 77  0
                         if (child instanceof JComponent && hasAnyError((JComponent) child)) {
 78  0
                                 return true;
 79  0
                         } else if (child instanceof Container && primHasAnyError((Container) child)) {
 80  0
                                 return true;
 81  
                         }
 82  
                 }
 83  0
                 return false;
 84  
         }
 85  
         
 86  
         /**
 87  
          * Check if the specified component has a synchronization error.
 88  
          * @param component the component to check.
 89  
          * @return {@code true} if it has an error, {@code false} otherwise.
 90  
          * @since 0.1.0
 91  
          */
 92  
         public static boolean hasError (JComponent component) {
 93  0
                 return Boolean.TRUE.equals(component.getClientProperty(ERROR_STATE_PROPERTY_KEY));
 94  
         }
 95  
         
 96  
         /**
 97  
          * Marks the component with a synchronization error state.
 98  
          * @param component the component to set the state for.
 99  
          * @param message the message describing the error.
 100  
          * @since 0.1.0
 101  
          */
 102  
         private static void markError (JComponent component, String message) {
 103  0
                 component.putClientProperty(ERROR_STATE_PROPERTY_KEY, Boolean.TRUE);
 104  0
                 component.putClientProperty(ERROR_MESSAGE_PROPERTY_KEY, message);
 105  0
         }
 106  
         
 107  
         /**
 108  
          * Clears the synchronization error state of a component.
 109  
          * @param component the component to clear the state for.
 110  
          * @since 0.1.0
 111  
          */
 112  
         private static void clearError (JComponent component) {
 113  0
                 component.putClientProperty(ERROR_STATE_PROPERTY_KEY, null);
 114  0
                 component.putClientProperty(ERROR_MESSAGE_PROPERTY_KEY, null);
 115  0
         }
 116  
         
 117  
         //---- State
 118  
         
 119  
         /**
 120  
          * The component this error binding listener modifies.
 121  
          * @since 0.1.0
 122  
          */
 123  
         private final JComponent component;
 124  
         
 125  
         /**
 126  
          * The error color to use.
 127  
          * @since 0.1.0
 128  
          */
 129  
         private final Color errorColor;
 130  
         
 131  
         /**
 132  
          * The error message in case of a failure.
 133  
          * @since 0.1.0
 134  
          */
 135  
         private final String errorMessage;
 136  
         
 137  
         /**
 138  
          * The error reporter to use.
 139  
          * @since 0.1.0
 140  
          */
 141  
         private final ErrorReporter errorReporter;
 142  
         
 143  
         /**
 144  
          * The original background color of the component.
 145  
          * @since 0.1.0
 146  
          */
 147  
         private Color backgroundColor;
 148  
         
 149  
         //---- Constructors
 150  
         
 151  
         /**
 152  
          * Creates a new error binding listener for the specified component.
 153  
          * @param reporter the error reporter to use if not {@code null}.
 154  
          * @param resourceMap resource map used to configure display properties.
 155  
          * @param component the component this error binding listener modifies.
 156  
          * @param errorKey key in the resource map to a translation of the error type, 
 157  
          * may be {@code null} for a generic error message.
 158  
          * @since 0.1.0
 159  
          */
 160  
         public ErrorBindingListener (
 161  
                 ErrorReporter reporter, ResourceMap resourceMap, JComponent component, String errorKey
 162  0
         ) {
 163  0
                 this.component = component;
 164  0
                 this.errorColor = resourceMap.getColor("errorBackgroundColor");
 165  0
                 this.errorMessage = resourceMap.getString(errorKey == null ? "errorMessage" : errorKey);
 166  0
                 this.errorReporter = reporter;
 167  0
         }
 168  
         
 169  
         //---- AbstractBindingListener
 170  
 
 171  
         /**
 172  
          * @since 0.1.0
 173  
          */
 174  
         @Override
 175  
         @SuppressWarnings("unchecked")
 176  
         public void synced (Binding binding) {
 177  0
                 if (hasError(this.component)) {
 178  0
                         this.component.setBackground(this.backgroundColor);
 179  0
                         clearError(this.component);
 180  
                 }
 181  0
         }
 182  
         
 183  
         /**
 184  
          * @since 0.1.0
 185  
          */
 186  
         @Override
 187  
         @SuppressWarnings("unchecked")
 188  
         public void syncFailed (Binding binding, final SyncFailure failure) {
 189  0
                 if (!hasError(this.component)) {
 190  0
                         this.backgroundColor = this.component.getBackground();
 191  0
                         this.component.setBackground(this.errorColor);
 192  0
                         markError(this.component, this.errorMessage);
 193  0
                         if (this.errorReporter != null) {
 194  0
                                 this.errorReporter.showStatusError(this.errorMessage);
 195  
                         }
 196  
                 }
 197  0
         }
 198  
 
 199  
 }