Coverage Report - org.openpermis.editor.policy.presenter.Problem
 
Classes in this File Line Coverage Branch Coverage Complexity
Problem
0%
0/71
0%
0/44
3.294
Problem$ProblemRecorder
0%
0/10
0%
0/2
3.294
 
 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.presenter;
 11  
 
 12  
 import java.util.ArrayList;
 13  
 import java.util.Arrays;
 14  
 import java.util.List;
 15  
 
 16  
 import org.slf4j.Logger;
 17  
 import org.slf4j.LoggerFactory;
 18  
 
 19  
 import org.openpermis.policy.Part;
 20  
 import org.openpermis.policy.PartProblemReporter;
 21  
 import org.openpermis.policy.Policy;
 22  
 import org.openpermis.policy.PartProblemReporter.ProblemMessage;
 23  
 import org.openpermis.policy.bean.PartBean;
 24  
 import org.openpermis.policy.bean.SerialNumber;
 25  
 
 26  
 /**
 27  
  * Describes a problem in a part.
 28  
  * @since 0.3.0
 29  
  */
 30  
 public class Problem {
 31  
 
 32  
         //---- Static
 33  
         
 34  
         /**
 35  
          * Creates a list of problem for the specified policy.
 36  
          * @param policy the policy for which to create the problem list.
 37  
          * @return the problem list requested, never {@code null}.
 38  
          * @since 0.3.0
 39  
          */
 40  
         public static final List<Problem> createProblemList (Policy policy) {
 41  0
                 final ProblemRecorder recorder = new ProblemRecorder();
 42  0
                 policy.isValid(recorder);
 43  0
                 return recorder.getProblemList();
 44  
         }
 45  
         
 46  
         /**
 47  
          * Seed value used when combining hash codes.
 48  
          * @since 0.3.0
 49  
          */
 50  
         private static final int HASH_CODE_SEED = 17;
 51  
 
 52  
         /**
 53  
          * Multiplier used when combining hash codes.
 54  
          * @since 0.3.0
 55  
          */
 56  
         private static final int HASH_CODE_MULTIPLIER = 37;
 57  
         
 58  
         //---- State
 59  
         
 60  
         /**
 61  
          * The part that has a problem.
 62  
          * @since 0.3.0
 63  
          */
 64  
         private final PartBean part;
 65  
         
 66  
         /**
 67  
          * The type of problem.
 68  
          * @since 0.3.0
 69  
          */
 70  
         private final ProblemMessage message;
 71  
         
 72  
         /**
 73  
          * Additional parameters for the problem.
 74  
          * @since 0.3.0
 75  
          */
 76  
         private final Object[] parameters;
 77  
 
 78  
         //---- Constructors
 79  
 
 80  
         /**
 81  
          * Creates a new problem for the specified part, type and parameters.
 82  
          * @param part the part that has a problem.
 83  
          * @param message the type of problem.
 84  
          * @param parameters additional parameters for the problem.
 85  
          * @since 0.3.0
 86  
          */
 87  0
         public Problem (PartBean part, ProblemMessage message, Object...parameters) {
 88  0
                 this.part = part;
 89  0
                 this.message = message;
 90  0
                 this.parameters = parameters;
 91  0
         }
 92  
 
 93  
         //---- Methods
 94  
         
 95  
         /**
 96  
          * Returns the serial number of the part that has a problem.
 97  
          * @return the serial number of the part that has a problem.
 98  
          * @since 0.3.0
 99  
          */
 100  
         public SerialNumber getPartSerialNumber () {
 101  0
                 return this.part.getSerialNumber();
 102  
         }
 103  
         
 104  
         /**
 105  
          * Returns the part that has a problem.
 106  
          * @return the part that has a problem.
 107  
          * @since 0.3.0
 108  
          */
 109  
         public PartBean getPart () {
 110  0
                 return this.part;
 111  
         }
 112  
 
 113  
         /**
 114  
          * Returns the type of the problem.
 115  
          * @return the type of the problem.
 116  
          * @since 0.3.0
 117  
          */
 118  
         public ProblemMessage getMessage () {
 119  0
                 return this.message;
 120  
         }
 121  
 
 122  
         /**
 123  
          * Returns the problem parameters.
 124  
          * @return the problem parameters.
 125  
          * @since 0.3.0
 126  
          */
 127  
         public Object[] getParameters () {
 128  0
                 return this.parameters;
 129  
         }
 130  
         
 131  
         /**
 132  
          * Check if the other problem has the same part.
 133  
          * @param other the other problem to compare to.
 134  
          * @return {@code true} if it has the same part, {@code false} otherwise.
 135  
          * @since 0.3.0
 136  
          */
 137  
         private boolean equalPart (Problem other) {
 138  0
                 if (!getPartSerialNumber().equals(other.getPartSerialNumber())) {
 139  0
                         return false;
 140  
                 }
 141  0
                 if (
 142  
                         SerialNumber.UNDEFINED.equals(getPartSerialNumber()) &&
 143  
                         !getPart().equals(other.getPart())
 144  
                 ) {
 145  0
                         return false;
 146  
                 }
 147  0
                 return true;
 148  
         }
 149  
         
 150  
         /**
 151  
          * Compare two parameters if they are equivalent.
 152  
          * <p>{@link PartBean} objects are compared by serial.</p> 
 153  
          * @param o1 the first parameter, not {@code null}.
 154  
          * @param o2 the second parameter, may be {@code null}.
 155  
          * @return {@code true} if they are equivalent or have the same serial, 
 156  
          * {@code false} otherwise.
 157  
          * @since 0.3.0
 158  
          */
 159  
         private boolean equalParameter (Object o1, Object o2) {
 160  0
                 if (o1 instanceof PartBean && o2 instanceof PartBean) {
 161  0
                         return ((PartBean) o1).getSerialNumber().equals(
 162  
                                 ((PartBean) o2).getSerialNumber()
 163  
                         );
 164  
                 }
 165  0
                 return o1.equals(o2);
 166  
         }
 167  
         
 168  
         /**
 169  
          * Check if the paramters of this problem are the same as the ones of the other problem.
 170  
          * @param other the other problem to compare the paramters to.
 171  
          * @return {@code true} if they have the same parameters, {@code false} otherwise.
 172  
          * @since 0.3.0
 173  
          */
 174  
         private boolean equalParameters (Problem other) {
 175  0
                 final Object[] p1 = getParameters();
 176  0
                 final Object[] p2 = getParameters();
 177  0
                 if (p1 == p2) {
 178  0
                         return true;
 179  
                 }
 180  0
                 if (p1 == null || p2 == null) {
 181  0
                         return false;
 182  
                 }
 183  0
                 final int length = p1.length;
 184  0
                 if (length != p2.length) {
 185  0
                         return false;
 186  
                 }
 187  0
                 for (int i = 0; i < length; i++) {
 188  0
                         final Object o1 = p1[i];
 189  0
                         final Object o2 = p2[i];
 190  0
                         if (!(o1 == null ? o2 == null : equalParameter(o1, o2))) {
 191  0
                                 return false;
 192  
                         }
 193  
                 }
 194  0
                 return true;
 195  
         }
 196  
         
 197  
         /**
 198  
          * Returns the hash code of a parameter.
 199  
          * @param parameter the parameter for which to retrieve the hash code.
 200  
          * @return the hash code requested.
 201  
          * @since 0.3.0
 202  
          */
 203  
         private int parameterHash (Object parameter) {
 204  0
                 if (parameter == null) {
 205  0
                         return 0;
 206  
                 }
 207  0
                 if (parameter instanceof PartBean) {
 208  0
                         return ((PartBean) parameter).getSerialNumber().hashCode();
 209  
                 }
 210  0
                 return parameter.hashCode();
 211  
         }
 212  
         
 213  
         /**
 214  
          * Creates a single hash code for all parameters.
 215  
          * @return the hash code requested.
 216  
          * @since 0.3.0
 217  
          */
 218  
         private int parametersHashCodes () {
 219  0
                 int result = HASH_CODE_SEED;
 220  0
                 for (Object parameter : getParameters()) {
 221  0
                         result = HASH_CODE_MULTIPLIER * result + parameterHash(parameter);
 222  
                 }
 223  0
                 return result;
 224  
         }
 225  
         
 226  
         //---- Object
 227  
         
 228  
         /**
 229  
          * @since 0.3.0
 230  
          */
 231  
         @Override
 232  
         public int hashCode () {
 233  0
                 int result = HASH_CODE_SEED;
 234  0
                 result = HASH_CODE_MULTIPLIER * result + getPartSerialNumber().hashCode();
 235  0
                 result = HASH_CODE_MULTIPLIER * result + getMessage().ordinal();
 236  0
                 result = HASH_CODE_MULTIPLIER * result + parametersHashCodes();
 237  0
                 return result;
 238  
         }
 239  
         
 240  
         /**
 241  
          * @since 0.3.0
 242  
          */
 243  
         @Override
 244  
         public boolean equals (Object obj) {
 245  0
                 if (obj == null) {
 246  0
                         return false;
 247  
                 }
 248  0
                 if (obj == this) {
 249  0
                         return true;
 250  
                 }
 251  0
                 if (!(obj instanceof Problem)) {
 252  0
                         return false;
 253  
                 }
 254  0
                 final Problem other = (Problem) obj;
 255  0
                 if (!equalPart(other)) {
 256  0
                         return false;
 257  
                 }
 258  0
                 if (!getMessage().equals(other.getMessage())) {
 259  0
                         return false;
 260  
                 }
 261  0
                 if (equalParameters(other)) {
 262  0
                         return false;
 263  
                 }
 264  0
                 return true;
 265  
         }
 266  
         
 267  
         /**
 268  
          * @since 0.3.0
 269  
          */
 270  
         @Override
 271  
         public String toString () {
 272  0
                 final StringBuilder sb = new StringBuilder(getMessage().toString());
 273  0
                 sb.append(" [part=");
 274  
                 try {
 275  0
                         sb.append(getPart());
 276  0
                 } catch (Exception e) {
 277  0
                         sb.append(getPartSerialNumber());
 278  0
                 }
 279  0
                 sb.append(",parameters=").append(Arrays.toString(getParameters())).append("]");
 280  0
                 return sb.toString();
 281  
         }
 282  
         
 283  
         //---- ProblemRecorder
 284  
         
 285  
         /**
 286  
          * Problem reporter that creates a list of problems.
 287  
          * <p>The recorder can only be used once and should be discarded afterwards.</p>
 288  
          * @since 0.3.0
 289  
          */
 290  
         private static class ProblemRecorder
 291  
                 implements PartProblemReporter
 292  
         {
 293  
                 
 294  
                 //---- Static
 295  
                 
 296  
                 /**
 297  
                  * The logger object of this class.
 298  
                  * @since 0.3.0
 299  
                  */
 300  0
                 private static final Logger LOGGER =
 301  
                         LoggerFactory.getLogger(ProblemRecorder.class);
 302  
 
 303  
                 //---- State
 304  
                 
 305  
                 private final List<Problem> problemList;
 306  
                 
 307  
                 //---- Constructors
 308  
                 
 309  0
                 public ProblemRecorder () {
 310  0
                         this.problemList = new ArrayList<Problem>();
 311  0
                 }
 312  
                 
 313  
                 //---- Methods
 314  
                 
 315  
                 public List<Problem> getProblemList () {
 316  0
                         return this.problemList;
 317  
                 }
 318  
                 
 319  
                 //---- PartProblemReporter
 320  
                 
 321  
                 /**
 322  
                  * @since 0.3.0
 323  
                  */
 324  
                 public void reportProblem (Part part, ProblemMessage message, Object... parameters) {
 325  0
                         if (!(part instanceof PartBean)) {
 326  0
                                 LOGGER.warn("Problem for a part that is not a bean encountered [{}].", part);
 327  0
                                 return;
 328  
                         }
 329  0
                         this.problemList.add(new Problem((PartBean) part, message, parameters));
 330  0
                 }
 331  
                 
 332  
         }
 333  
         
 334  
 }