blob: e09c1410d3414d32fb2e0aca6bdd1ab255636a58 [file] [log] [blame]
/*
* 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.Stomp.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)
{
}
/// <summary>
/// As we have to find the hostname as a side-affect of generating a unique
/// stub, we allow it's easy retrevial here
/// </summary>
public static String HostName
{
get { return hostName; }
}
/// <summary>
/// Generate a Unique Id
/// </summary>
public String GenerateId()
{
lock(UNIQUE_STUB)
{
return this.seed + (this.sequence++);
}
}
/// <summary>
/// Generate a unique ID - that is friendly for a URL or file system
/// </summary>
public String GenerateSanitizedId()
{
String result = GenerateId();
result = result.Replace(':', '-');
result = result.Replace('_', '-');
result = result.Replace('.', '-');
return result;
}
/// <summary>
/// From a generated id - return the seed (i.e. minus the count)
/// </summary>
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;
}
/// <summary>
/// From a generated id - return the generator count
/// </summary>
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;
}
/// <summary>
/// Does a proper compare on the ids
/// </summary>
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;
}
}
}