/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Net; using System.Net.Sockets; using System.Threading; namespace Apache.NMS.ActiveMQ.Util { public class IdGenerator { private static readonly String UNIQUE_STUB; private static int instanceCount; private static readonly String hostName; private readonly String seed; private long sequence; static IdGenerator() { String stub = "-1-" + DateTime.Now.Ticks; hostName = "localhost"; try { hostName = Dns.GetHostName(); IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); Socket tempSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); tempSocket.Bind(endPoint); stub = "-" + ((IPEndPoint)tempSocket.LocalEndPoint).Port + "-" + DateTime.Now.Ticks + "-"; Thread.Sleep(100); tempSocket.Close(); } catch(Exception ioe) { Tracer.Warn("could not generate unique stub: " + ioe.Message); } UNIQUE_STUB = stub; } /** * Construct an IdGenerator */ public IdGenerator(String prefix) { lock(UNIQUE_STUB) { this.seed = prefix + UNIQUE_STUB + (instanceCount++) + ":"; } } public IdGenerator() : this("ID:" + hostName) { } /// /// As we have to find the hostname as a side-affect of generating a unique /// stub, we allow it's easy retrevial here /// public static String HostName { get { return hostName; } } /// /// Generate a Unique Id /// /// /// A /// public String GenerateId() { lock(UNIQUE_STUB) { return this.seed + (this.sequence++); } } /// /// Generate a unique ID - that is friendly for a URL or file system /// /// /// A /// public String GenerateSanitizedId() { String result = GenerateId(); result = result.Replace(':', '-'); result = result.Replace('_', '-'); result = result.Replace('.', '-'); return result; } /// /// From a generated id - return the seed (i.e. minus the count) /// /// /// A /// /// /// A /// public static String GetSeedFromId(String id) { String result = id; if(id != null) { int index = id.LastIndexOf(':'); if(index > 0 && (index + 1) < id.Length) { result = id.Substring(0, index + 1); } } return result; } /// /// From a generated id - return the generator count /// /// /// A /// /// /// A /// public static long GetSequenceFromId(String id) { long result = -1; if(id != null) { int index = id.LastIndexOf(':'); if(index > 0 && (index + 1) < id.Length) { String numStr = id.Substring(index + 1, id.Length); result = Int64.Parse(numStr); } } return result; } /// /// Does a proper compare on the ids /// /// /// A /// /// /// A /// /// /// A /// public static int Compare(String id1, String id2) { int result = -1; String seed1 = IdGenerator.GetSeedFromId(id1); String seed2 = IdGenerator.GetSeedFromId(id2); if(seed1 != null && seed2 != null) { result = seed1.CompareTo(seed2); if(result == 0) { long count1 = IdGenerator.GetSequenceFromId(id1); long count2 = IdGenerator.GetSequenceFromId(id2); result = (int)(count1 - count2); } } return result; } } }