1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.id.uuid; 18 19 import java.io.IOException; 20 import java.util.Iterator; 21 import java.util.Set; 22 23 import org.apache.commons.id.uuid.clock.Clock; 24 import org.apache.commons.id.uuid.state.Node; 25 import org.apache.commons.id.uuid.state.State; 26 import org.apache.commons.id.uuid.state.StateHelper; 27 28 /** 29 * <p>Class is responsible for managing the <code>Node</code>s identified for 30 * this system (JVM instance), as well as the state management for the 31 * <code>Node</code>s.</p> 32 * 33 * @author Commons-Id team 34 * @version $Revision: 480488 $ $Date: 2006-11-29 08:57:26 +0000 (Wed, 29 Nov 2006) $ 35 * 36 */ 37 public final class NodeManagerImpl implements NodeManager { 38 /** Reference to the State implementation to use for loading and storing */ 39 private State nodeState; 40 /** The current array index for the Node in use. */ 41 private int currentNodeIndex = 0; 42 /** Flag indicating the node state has been initialized. */ 43 private boolean isInit = false; 44 /** Set that references all instances. */ 45 private Set nodesSet; 46 /** Array of the Nodes */ 47 private Node[] allNodes; 48 /** UUID timestamp of last call to State.store */ 49 private long lastUUIDTimeStored = 0; 50 /** Single instance of this class */ 51 //private NodeManagerImpl instance; 52 53 /** Constructor for class. */ 54 public NodeManagerImpl() { 55 super(); 56 } 57 58 /** Initialization */ 59 public void init() { 60 nodeState = StateHelper.getStateImpl(); 61 try { 62 nodeState.load(); 63 } catch (Exception ex) { 64 throw new RuntimeException(ex); 65 } 66 nodesSet = nodeState.getNodes(); 67 Iterator it = nodesSet.iterator(); 68 allNodes = new Node[nodesSet.size()]; 69 int i = 0; 70 while (it.hasNext()) { 71 allNodes[i++] = (Node) it.next(); 72 } 73 isInit = true; 74 } 75 /* 76 * <p>Returns the singleton instance of this class.</p> 77 * 78 * @return the singleton instance of this class. 79 80 public NodeManager getInstance() { 81 if (instance == null) { 82 instance = new NodeManagerImpl(); 83 } 84 return instance; 85 } 86 */ 87 /** 88 * <p>Returns the current node in use for uuid generation. Calls to this 89 * method also signal the NodeManagerImpl when to store uuid state information. 90 * </p> 91 * 92 * @return the current node in use for uuid generation. 93 */ 94 public Node currentNode() { 95 if (!isInit) { 96 init(); 97 } 98 // See if we need to store state information. 99 if ((lastUUIDTimeStored + nodeState.getSynchInterval()) > (findMaxTimestamp() / Clock.INTERVALS_PER_MILLI)) { 100 try { 101 nodeState.store(nodesSet); 102 } catch (IOException ioe) { 103 //@TODO add listener and send notify 104 } 105 } 106 return allNodes[currentNodeIndex]; 107 } 108 109 /** 110 * <p>Returns the next available <code>Node</code> for uuid generation.</p> 111 * 112 * @return the next available <code>Node</code> for uuid generation. 113 */ 114 public Node nextAvailableNode() { 115 if (!isInit) { 116 init(); 117 } 118 currentNodeIndex++; 119 if (currentNodeIndex >= allNodes.length) { 120 currentNodeIndex = 0; 121 } 122 return currentNode(); 123 } 124 125 /** 126 * <p>Returns the maximum uuid timestamp generated from all <code>Node</code>s</p> 127 * 128 * @return maximum uuid timestamp generated from all <code>Node</code>s. 129 */ 130 private long findMaxTimestamp() { 131 if (!isInit) { 132 init(); 133 } 134 long max = 0; 135 for (int i = 0; i < allNodes.length; i++) { 136 if (allNodes[i] != null && allNodes[i].getLastTimestamp() > max) { 137 max = allNodes[i].getLastTimestamp(); 138 } 139 } 140 return max; 141 } 142 143 /** 144 * <p>Locks a node for use by a generator.</p> 145 * 146 * @param node the Node to lock. 147 */ 148 public void lockNode(Node node) { 149 //Not implemented in this version. 150 } 151 152 /** 153 * <p>Releases a node locked by a generator.</p> 154 * 155 * @param node the Node to release. 156 */ 157 public void releaseNode(Node node) { 158 //Not implemented in this version. 159 } 160 161 /** 162 * <p>Asks the State implementation to store.</p> 163 * 164 * @see Object#finalize 165 */ 166 protected void finalize() throws Throwable { 167 nodeState.store(nodesSet); 168 super.finalize(); 169 } 170 }