View Javadoc

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 }