1 /* 2 * Copyright 2007-2011 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.exceptions.id; 17 18 import java.util.concurrent.atomic.AtomicLong; 19 20 import org.apache.commons.logging.Log; 21 import org.apache.commons.logging.LogFactory; 22 23 import de.smartics.exceptions.core.IdFactory; 24 25 /** 26 * The factory that created {@link de.smartics.exceptions.core.ExceptionId}s 27 * that provides a number that is larger than zero. If the last number has been 28 * provided, it continues with 1, issuing a message on info level. 29 * 30 * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a> 31 * @version $Revision$ 32 */ 33 public class IncrementFactory implements IdFactory 34 { 35 // ********************************* Fields ********************************* 36 37 // --- constants ------------------------------------------------------------ 38 39 // --- members -------------------------------------------------------------- 40 41 /** 42 * Reference to the logger for this class. 43 */ 44 private final Log log = LogFactory.getLog(IncrementFactory.class); 45 46 /** 47 * The thread-safe incrementor of long values. 48 */ 49 private final AtomicLong atomic; 50 51 // ****************************** Initializer ******************************* 52 53 // ****************************** Constructors ****************************** 54 55 /** 56 * Default constructor with counter initialized with <code>1</code>. 57 */ 58 public IncrementFactory() 59 { 60 this(1); 61 } 62 63 /** 64 * Convenience constructor. 65 * 66 * @param startValue the start value of the counter. 67 * @throws IllegalArgumentException if the start value is smaller than or 68 * equal to zero. 69 */ 70 public IncrementFactory(final long startValue) 71 throws IllegalArgumentException 72 { 73 if (startValue <= 0L) 74 { 75 throw new IllegalArgumentException( 76 "Start value must be greater than zero, but is '" + startValue + "'."); 77 } 78 this.atomic = new AtomicLong(startValue); 79 } 80 81 // ****************************** Inner Classes ***************************** 82 83 // ********************************* Methods ******************************** 84 85 // --- init ----------------------------------------------------------------- 86 87 // --- get&set -------------------------------------------------------------- 88 89 // --- business ------------------------------------------------------------- 90 91 /** 92 * {@inheritDoc} 93 * 94 * @see de.smartics.exceptions.core.IdFactory#createId() 95 */ 96 public LongExceptionId createId() 97 { 98 boolean notSet; 99 long current; 100 do 101 { 102 current = atomic.getAndIncrement(); 103 notSet = false; 104 105 if (current <= 0L) 106 { 107 final boolean success = atomic.compareAndSet(current + 1, 2); 108 if (success) 109 { 110 current = 1; 111 if (log.isInfoEnabled()) 112 { 113 log.info("Increment factory resetted exception identifier to '1'."); 114 } 115 } 116 else 117 { 118 notSet = true; 119 } 120 } 121 } 122 while (notSet); 123 124 return new LongExceptionId(current); 125 } 126 127 // --- object basics -------------------------------------------------------- 128 }