// $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; } }