001    /*
002      Copyright (C) 2001-2003 Renaud Pawlak <renaud@aopsys.com>
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public License
015      along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
017    
018    package org.objectweb.jac.util;
019    
020    import java.util.*;
021    import org.apache.log4j.Logger;
022    
023    /**
024     * @author <a href="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a>
025     */
026    
027    /**
028     * This class can be subclassed to create specific repositories.
029     * 
030     * <p>A repository class should be a singleton (a sole instance
031     * class). Thus, the repository subclasses should define a static
032     * field and a static method 'get' that returns the unique repository
033     * for the class and that creates it if it does not exist. */
034    
035    public class Repository {
036        static Logger logger = Logger.getLogger("repository");
037    
038        /**
039         * Get the sole repository instance for this class. Creates it if
040         * it does not exist yet.
041         *
042         * <p>NOTE: this method MUST be defined by all subclasses.
043         */
044       
045        public static Repository get () {
046            if ( repository == null ) repository = new Repository();
047            return repository;
048        }
049       
050        /**
051         * Store the sole instance of repository.
052         *
053         * <p>NOTE: this field MUST be defined by all subclasses.
054         * 
055         * @see #get()
056         */
057        protected static Repository repository = null;
058    
059        /**
060         * Link JAC objects to the names  (String -> Object) */
061        public Map objects;
062    
063        /**
064         * Reverse hashtable to find an objet from its name  (Object -> String)*/
065        public Map names;
066    
067        public Repository() {
068            objects = new Hashtable();
069            names = new Hashtable();
070        }
071    
072        /**
073         * Register a new object into the repository.
074         *
075         * @param logicalName the key that allows to find the object
076         * @param object the object to register
077         * @return true if the object registered, false if already
078         * registered
079         *
080         * @see #unregister(String) */
081    
082        public boolean register(String logicalName, Object object) {
083            logger.debug("register("+logicalName+","+object.getClass().getName()+")");
084            Object o = objects.get(logicalName);
085            if (o != null) {
086                logger.warn("overriding "+logicalName+" -> "+o+" with "+object);
087                objects.remove(logicalName);
088                names.remove(o);
089            }
090            objects.put(logicalName, object);      
091            names.put(object, logicalName);
092            return true;
093        }
094    
095        /**
096         * Unregister a JacObject from the repository.
097         *
098         * @param logicalName the key that allows to find the object
099         *
100         * @see #register(String,Object)
101         * @see #unregisterObject(Object) */
102    
103        public void unregister(String logicalName) {
104            logger.debug("unregister("+logicalName+")");
105            Object object = objects.get(logicalName);
106            if (object == null) {
107                return;
108            }
109            names.remove(object);
110            objects.remove(logicalName);
111        }
112    
113        /**
114         * Unregister a JacObject from the repository.
115         *
116         * @param object the object to unregister
117         *
118         * @see #register(String,Object)
119         * @see #unregister(String) */
120    
121        public void unregisterObject(Object object) {
122            logger.debug("unregisterObject("+object+")");
123            Object logicalName = names.get(object);
124            if (logicalName == null) {
125                return;
126            }
127            objects.remove(logicalName);
128            names.remove(object);
129        }
130    
131        /**
132         * Returns true if an object is registered with this name.
133         *
134         * @param logicalName the key that allows to find the object
135         *
136         * @see #register(String,Object) */
137    
138        public boolean isRegistered(String logicalName) {
139            if (objects.containsKey(logicalName)) {
140                return true;
141            }
142            return false;
143        }
144    
145        /**
146         * Return all the registered objects as an array.
147         *
148         * <p>Reverse operation is <code>getNames()</code>.
149         *
150         * @return the registered objects in this repository
151         *
152         * @see #register(String,Object)
153         * @see #getNames() 
154         */
155        public Object[] getObjects() {
156            return objects.values().toArray();
157        }
158    
159        /**
160         * Return the names of the registered objects as an array.    
161         *
162         * <p>Reverse operation is <code>getObjects()</code>.
163         *
164         * @return the registered object names in this repository
165         *
166         * @see #register(String,Object)
167         * @see #getObjects() 
168         */
169        public String[] getNames() {
170            return (String[])names.values().toArray(ExtArrays.emptyStringArray);
171        }
172    
173        /**
174         * Return a registered object for a given logical name.
175         * 
176         * <p>Return <code>null</code> if the name does not correspond to
177         * any registered object or if <code>logicalName</code> is null.
178         *
179         * <p>Reverse operation is <code>getName(Object)</code>.
180         *
181         * @param logicalName the key that allows to find the object
182         * @return the corresponding object, null if not registered
183         *
184         * @see #register(String,Object)
185         * @see #getName(Object) */
186    
187        public Object getObject(String logicalName) {
188            if (logicalName == null) 
189                return null;
190            Object ret = objects.get ( logicalName );
191            logger.debug("getObject("+logicalName+") -> "+
192                         (ret==null?"null":ret.getClass().getName()));
193            return ret;
194        }
195    
196        /**
197         * Returns the name of a registered object. Null if not
198         * registered.
199         *
200         * <p>Reverse operation is <code>getObject(String)</code>.
201         *
202         * @param object the object to get the name of
203         * @return the object name, null if not registered
204         *
205         * @see #register(String,Object) 
206         * @see #getObject(String)
207         */
208    
209        public String getName(Object object) {
210            if (object == null) {
211                return null;
212            }
213            return (String)names.get(object);
214        }
215    
216        /**
217         * Dump all the registered objects. */
218    
219        public void dump() {            
220            System.out.println(this + " dump:");
221            System.out.println(getPrintableString());
222        }
223    
224        public String getPrintableString() {
225            return ""+objects;
226        }
227    
228    }