Coverage Report - com.allanbank.mongodb.DurabilityEditor
 
Classes in this File Line Coverage Branch Coverage Complexity
DurabilityEditor
97%
80/82
90%
45/50
10
 
 1  
 /*
 2  
  * #%L
 3  
  * DurabilityEditor.java - mongodb-async-driver - Allanbank Consulting, Inc.
 4  
  * %%
 5  
  * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
 6  
  * %%
 7  
  * Licensed under the Apache License, Version 2.0 (the "License");
 8  
  * you may not use this file except in compliance with the License.
 9  
  * You may obtain a copy of the License at
 10  
  * 
 11  
  *      http://www.apache.org/licenses/LICENSE-2.0
 12  
  * 
 13  
  * Unless required by applicable law or agreed to in writing, software
 14  
  * distributed under the License is distributed on an "AS IS" BASIS,
 15  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 16  
  * See the License for the specific language governing permissions and
 17  
  * limitations under the License.
 18  
  * #L%
 19  
  */
 20  
 package com.allanbank.mongodb;
 21  
 
 22  
 import java.beans.PropertyEditorSupport;
 23  
 import java.util.Collections;
 24  
 import java.util.HashSet;
 25  
 import java.util.Map;
 26  
 import java.util.Set;
 27  
 
 28  
 /**
 29  
  * {@link java.beans.PropertyEditor} for the {@link Durability} class.
 30  
  * <p>
 31  
  * The string value must be one of the following tokens or parse-able by
 32  
  * {@link Durability#valueOf(String)} method.
 33  
  * </p>
 34  
  * <p>
 35  
  * Valid tokens are:
 36  
  * <ul>
 37  
  * <li>{@code NONE}</li>
 38  
  * <li>{@code ACK}</li>
 39  
  * <li>{@code FSYNC}</li>
 40  
  * <li>{@code JOURNAL}</li>
 41  
  * <li>{@code MAJORITY}</li>
 42  
  * </ul>
 43  
  * </p>
 44  
  * <p>
 45  
  * {@code FSYNC}, {@code JOURNAL}, and {@code MAJORITY} all use
 46  
  * {@value #DEFAULT_WAIT_TIME_MS} milliseconds for the wait time.
 47  
  * </p>
 48  
  * <p>
 49  
  * This editor will also parses a full MongoDB URI to extract the specified
 50  
  * {@link Durability}. See the <a href=
 51  
  * "http://docs.mongodb.org/manual/reference/connection-string/#write-concern-options"
 52  
  * >Connection String URI Format</a> documentation for information on
 53  
  * constructing a MongoDB URI.
 54  
  * </p>
 55  
  * 
 56  
  * @api.yes This class is part of the driver's API. Public and protected members
 57  
  *          will be deprecated for at least 1 non-bugfix release (version
 58  
  *          numbers are &lt;major&gt;.&lt;minor&gt;.&lt;bugfix&gt;) before being
 59  
  *          removed or modified.
 60  
  * @copyright 2013-2014, Allanbank Consulting, Inc., All Rights Reserved
 61  
  */
 62  
 public class DurabilityEditor extends PropertyEditorSupport {
 63  
 
 64  
     /** The default wait time for tokenized durabilities: {@value} ms. */
 65  
     public static final int DEFAULT_WAIT_TIME_MS = 30000;
 66  
 
 67  
     /** The set of fields used to determine a Durability from a MongoDB URI. */
 68  
     public static final Set<String> MONGODB_URI_FIELDS;
 69  
 
 70  
     static {
 71  1
         final Set<String> fields = new HashSet<String>();
 72  1
         fields.add("safe");
 73  1
         fields.add("w");
 74  1
         fields.add("wtimeout");
 75  1
         fields.add("wtimeoutms");
 76  1
         fields.add("fsync");
 77  1
         fields.add("journal");
 78  
 
 79  1
         MONGODB_URI_FIELDS = Collections.unmodifiableSet(fields);
 80  1
     }
 81  
 
 82  
     /**
 83  
      * Creates a new DurabilityEditor.
 84  
      */
 85  
     public DurabilityEditor() {
 86  20
         super();
 87  20
     }
 88  
 
 89  
     /**
 90  
      * {@inheritDoc}
 91  
      * <p>
 92  
      * Overridden to parse a string to a {@link Durability}.
 93  
      * </p>
 94  
      * 
 95  
      * @throws IllegalArgumentException
 96  
      *             If the string cannot be parsed into a {@link Durability}.
 97  
      */
 98  
     @Override
 99  
     public void setAsText(final String durabilityString)
 100  
             throws IllegalArgumentException {
 101  
 
 102  20
         if ("NONE".equalsIgnoreCase(durabilityString)) {
 103  1
             setValue(Durability.NONE);
 104  
         }
 105  19
         else if ("ACK".equalsIgnoreCase(durabilityString)) {
 106  1
             setValue(Durability.ACK);
 107  
         }
 108  18
         else if ("FSYNC".equalsIgnoreCase(durabilityString)) {
 109  1
             setValue(Durability.fsyncDurable(DEFAULT_WAIT_TIME_MS));
 110  
         }
 111  17
         else if ("JOURNAL".equalsIgnoreCase(durabilityString)) {
 112  1
             setValue(Durability.journalDurable(DEFAULT_WAIT_TIME_MS));
 113  
         }
 114  16
         else if ("MAJORITY".equalsIgnoreCase(durabilityString)) {
 115  1
             setValue(Durability.replicaDurable(Durability.MAJORITY_MODE,
 116  
                     DEFAULT_WAIT_TIME_MS));
 117  
         }
 118  15
         else if (MongoDbUri.isUri(durabilityString)) {
 119  13
             final MongoDbUri uri = new MongoDbUri(durabilityString);
 120  13
             final Durability parsed = fromUriParameters(uri.getParsedOptions());
 121  13
             if (parsed != null) {
 122  11
                 setValue(parsed);
 123  
             }
 124  13
         }
 125  
         else {
 126  2
             final Durability durability = Durability.valueOf(durabilityString);
 127  2
             if (durability != null) {
 128  1
                 setValue(durability);
 129  
             }
 130  
             else {
 131  1
                 throw new IllegalArgumentException(
 132  
                         "Could not determine the durability for '"
 133  
                                 + durabilityString + "'.");
 134  
             }
 135  
         }
 136  19
     }
 137  
 
 138  
     /**
 139  
      * Uses the URI parameters to determine a durability. May return null if the
 140  
      * URI did not contain any durability settings.
 141  
      * 
 142  
      * @param parameters
 143  
      *            The URI parameters.
 144  
      * @return The {@link Durability} from the URI parameters.
 145  
      */
 146  
     private Durability fromUriParameters(final Map<String, String> parameters) {
 147  13
         boolean safe = false;
 148  13
         int w = 1;
 149  13
         String wTxt = null;
 150  13
         boolean fsync = false;
 151  13
         boolean journal = false;
 152  13
         int wtimeout = 0;
 153  
 
 154  
         // Without order surprising things happen.
 155  13
         for (final Map.Entry<String, String> entry : parameters.entrySet()) {
 156  47
             final String parameter = entry.getKey();
 157  47
             final String value = entry.getValue();
 158  
 
 159  47
             if ("safe".equalsIgnoreCase(parameter)) {
 160  4
                 safe = Boolean.parseBoolean(value);
 161  
             }
 162  43
             else if ("w".equalsIgnoreCase(parameter)) {
 163  5
                 safe = true;
 164  
                 try {
 165  5
                     w = Integer.parseInt(value);
 166  4
                     wTxt = null;
 167  
                 }
 168  1
                 catch (final NumberFormatException nfe) {
 169  1
                     w = 2;
 170  1
                     wTxt = value;
 171  5
                 }
 172  
             }
 173  38
             else if ("wtimeout".equalsIgnoreCase(parameter)
 174  
                     || "wtimeoutms".equalsIgnoreCase(parameter)) {
 175  10
                 safe = true;
 176  10
                 wtimeout = Integer.parseInt(value);
 177  10
                 if (w <= 1) {
 178  8
                     w = 2;
 179  
                 }
 180  
             }
 181  28
             else if ("fsync".equalsIgnoreCase(parameter)) {
 182  4
                 fsync = Boolean.parseBoolean(value);
 183  4
                 if (fsync) {
 184  4
                     journal = false;
 185  4
                     safe = true;
 186  
                 }
 187  
             }
 188  24
             else if ("journal".equalsIgnoreCase(parameter)) {
 189  4
                 journal = Boolean.parseBoolean(value);
 190  4
                 if (journal) {
 191  2
                     fsync = false;
 192  2
                     safe = true;
 193  
                 }
 194  
             }
 195  47
         }
 196  
 
 197  
         // Figure out the intended durability.
 198  13
         Durability result = null;
 199  13
         if (safe) {
 200  11
             if (fsync) {
 201  2
                 result = Durability.fsyncDurable(wtimeout);
 202  
             }
 203  9
             else if (journal) {
 204  2
                 result = Durability.journalDurable(wtimeout);
 205  
             }
 206  7
             else if (w == 1) {
 207  2
                 result = Durability.ACK;
 208  
             }
 209  5
             else if (w > 1) {
 210  5
                 if (wTxt != null) {
 211  1
                     result = Durability.replicaDurable(wTxt, wtimeout);
 212  
                 }
 213  
                 else {
 214  4
                     result = Durability.replicaDurable(w, wtimeout);
 215  
                 }
 216  
             }
 217  0
             else if (w <= 0) {
 218  0
                 result = Durability.NONE;
 219  
             }
 220  
         }
 221  13
         return result;
 222  
 
 223  
     }
 224  
 }