// $Id$
//
// 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.Collections.Generic;
namespace Org.Apache.Etch.Bindings.Csharp.Msg
{
/// Map by id and name of IdNames (or subclasses thereof).
/// the specific subclass of IdName that is in the map.
public abstract class IdNameMap where T : IdName
{
public IdNameMap()
{
// nothing to do
}
/// Constructs the IdNameMap.
/// maxAutoCount the maximum number of automatically declared IdNames
/// allowed. Set to 0 if you don't want any, but this may prevent working with a slightly different
/// version of a service.
public IdNameMap( int maxAutoCount )
{
this.maxAutoCount = maxAutoCount;
}
private int maxAutoCount;
/// Gets the IdName subclass which corresponds to the specified id, or creates it if it isn't found
/// and if autoCount less than maxAutoCount. If created, the IdName is given the name which is
/// id.toString().
/// id the id of an IdName.
/// the IdName subclass found or created.
public T Get( int id )
{
T t;
if (byId.TryGetValue(id, out t))
return t;
return null;
}
public T GetById( int id )
{
T t;
if (byId.TryGetValue(id, out t))
return t;
return null;
}
/// Gets the IdName subclass which corresponds to the specified name, or creates it if it isn't
/// found and if autoCount maxAutoCount. If created, the IdName is given the id which is
/// IdName.hash( name ).
/// name the name of an IdName.
/// the IdName subclass found or created.
public T Get( String name )
{
T t;
if (byName.TryGetValue(name, out t))
return t;
if (!locked)
return Add( MakeNew( name ) );
return null;
}
public T GetByName(String name)
{
T t;
if (byName.TryGetValue(name, out t))
return t;
if (!locked)
return Add(MakeNew(name));
return null;
}
///
/// Adds the IdName subclass to the map.
///
/// the IdName subclass to add.
/// the IdName from the map
/// Exception:
/// throws Exception (state) if there is a collision with id or name, or a collision with
/// id and name where they are not associated with the same object.
public T Add( T t )
{
if ( locked )
throw new Exception( "state exception -- locked" );
if ( byId.ContainsKey( t.Id ) )
{
if ( ( t.Name == "msg" ) || ( t.Name == "result" ) )
return t;
throw new ArgumentException( "id collision" );
}
if ( byName.ContainsKey( t.Name ) )
{
if ( ( t.Name == "msg" ) || ( t.Name == "result" ) )
return t;
throw new ArgumentException( "name collision" );
}
byId.Add ( t.Id, t);
byName.Add(t.Name, t);
return t;
}
///
/// Adds all the IdNames to this IdNameMap
///
///
public void AddAll( IdNameMap ts )
{
if ( locked )
throw new Exception( "locked" );
foreach ( T t in ts.byId.Values )
Add( t );
}
///
/// a snapshot collection of all the values.
public List Values()
{
return new List( byId.Values );
}
///
/// Locks the map, preventing further changes
///
public void Lock()
{
locked = true;
}
///
///
///
/// the number of values in the map
public int Size()
{
return byId.Count;
}
/// Makes a new subclass of IdName to put in this map.
/// name the name of the new subclass of IdName.
/// a newly constructed subclass of IdName to put in this map.
abstract public T MakeNew( String name );
private Dictionary byId = new Dictionary();
private Dictionary byName = new Dictionary();
private Boolean locked;
}
}