001    /* PAVLOV -- Multiple Choice Study System
002     * Copyright (C) 2000 - 2004 T.J. Willis
003     * 
004     * This program is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU General Public License
006     * as published by the Free Software Foundation; either version 2
007     * of the 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 General Public License for more details.
013     *          
014     * You should have received a copy of the GNU 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, USA.
017     *  
018     * $Header: /cvsroot/pavlov/net/sourceforge/pavlov/randommedia/MediaDirectoryManager.java,v 1.3 2004/05/10 14:58:54 tj_willis Exp $
019     */ 
020    package net.sourceforge.pavlov.randommedia;
021    
022    import java.net.URI;
023    import java.net.URL;
024    import java.util.*;
025    import org.apache.log4j.*;
026    
027    
028    /**
029     * Describe class <code>MediaDirectoryManager</code> here.
030     *
031     * @author <a href="mailto:tj_willis@users.sourceforge.net">T.J. Willis</a>
032     * @version 1.0
033     */
034    public class MediaDirectoryManager
035    {
036        private volatile Hashtable<String, RandomMediaDirectory> enabledDirectories;
037        private volatile Hashtable<String, RandomMediaDirectory>  disabledDirectories;
038        private volatile Vector<URL> readyVector;
039        private int enabledSize;
040        private int disabledSize;
041        private Random rand;
042        private Category cat
043            = Category.getInstance(MediaDirectoryManager.class.getName());
044        /**
045         * Creates a new <code>MediaDirectoryManager</code> instance.
046         *
047         */
048        public MediaDirectoryManager()
049        {
050            enabledDirectories = new Hashtable<String, RandomMediaDirectory>();
051            disabledDirectories = new Hashtable<String, RandomMediaDirectory>();
052            readyVector = new Vector<URL>(500,500);
053            enabledSize = 0;
054            disabledSize = 0;
055            rand = new Random();
056        }
057    
058        synchronized void clear()
059        {
060            enabledDirectories.clear();
061            disabledDirectories.clear();
062            readyVector.clear();
063            enabledSize = 0;
064            disabledSize = 0;
065        }
066    
067        synchronized RandomMediaDirectory getDirectory(final String name)
068        {
069            RandomMediaDirectory e;
070            assert enabledDirectories!=null : "enabledDirectories is null";
071            assert disabledDirectories!=null: "disabledDirectories is null";
072            e = enabledDirectories.get(name);
073            if( e==null)
074                e = disabledDirectories.get(name);
075            return e;
076        }
077    
078        /**
079         * Describe <code>toggleDirectory</code> method here.
080         *
081         * @param d a <code>RandomMediaDirectory</code> value
082         */
083        public synchronized void toggleDirectory(RandomMediaDirectory d)
084        {
085            // slightly wasteful
086            RandomMediaDirectory e;
087            e = enabledDirectories.get(d.getName());
088            if(e==null) {
089                enableDirectory(d);
090            } else {
091                disableDirectory(d);
092            }
093        }
094    
095        // these were more efficient, but buggy
096        synchronized void enableDirectory(final RandomMediaDirectory d)
097        {
098            addEnabled(d);
099        }
100    
101        // these were more efficient, but buggy
102        synchronized void disableDirectory(final RandomMediaDirectory d)
103        {
104            addDisabled(d);
105        }
106    
107        /**
108         * Describe <code>addEnabled</code> method here.
109         *
110         * @param d a <code>RandomMediaDirectory</code> value
111         */
112        public synchronized void addEnabled(final RandomMediaDirectory d)
113        {
114            enabledDirectories.put(d.getName(),d);
115            disabledDirectories.remove(d.getName());
116            refresh();
117        }
118    
119        /**
120         * Describe <code>addDisabled</code> method here.
121         *
122         * @param d a <code>RandomMediaDirectory</code> value
123         */
124        public synchronized void addDisabled(final RandomMediaDirectory d)
125        {
126            disabledDirectories.put(d.getName(),d);
127            enabledDirectories.remove(d.getName());
128            refresh();
129        }
130    
131    
132        URL getRandomURL()
133        throws java.net.MalformedURLException
134        {
135            if(readyVector==null) return null;
136            if(readyVector.size()<1) return null;
137    
138            int i = rand.nextInt(readyVector.size());
139            //cat.debug(" i = " + i + " size = " + readyVector.size());
140            Object bar = readyVector.elementAt(i);
141            if( bar instanceof URL)
142                return (URL)bar;
143            else if ( bar instanceof URI){
144                //URI tmp = getRandomURI();
145                return  ((URI)bar).toURL();
146            }
147            return null;
148        }
149    
150        private synchronized void refresh()
151        {
152            Collection<RandomMediaDirectory> en = enabledDirectories.values();
153            enabledSize =0;
154            disabledSize =0;
155            readyVector.clear();
156    
157            for(RandomMediaDirectory d : en) {
158                enabledSize += d.getSize();
159                readyVector.addAll(d.getURLVector());
160            }
161    
162            //cat.debug("manager.refresh(), readyvec has " + readyVector.size());
163    
164            en = disabledDirectories.values();
165            for(RandomMediaDirectory d : en) {
166                disabledSize += d.getSize();
167            }
168        }
169    
170        boolean isEnabled(final String key)
171        {
172            assert enabledDirectories!=null : "EnabledDirectories is null";
173            if(key==null) return false;
174            RandomMediaDirectory d= (RandomMediaDirectory)enabledDirectories.get(key);
175            if(d==null) return false;
176            return true;
177        }
178    
179        int getTotalSize()
180        {
181            return getEnabledSize() + getDisabledSize();
182        }
183    
184        int getEnabledSize()
185        {
186            return enabledSize;
187        }
188    
189        int getDisabledSize()
190        {
191            return disabledSize;
192        }
193    
194        private synchronized String[] getEnabledDirectoryNames()
195        {
196            Set<String> keys = enabledDirectories.keySet();
197            String arr[] = new String[keys.size()];
198            return keys.toArray(arr);
199        }
200    
201        /**
202         * Describe <code>getDisabledDirectoryNames</code> method here.
203         *
204         * @return a <code>String[]</code> value
205         */
206        public synchronized String[] getDisabledDirectoryNames()
207        {
208            Set<String> keys = disabledDirectories.keySet();
209            String arr[] = new String[keys.size()];
210            return keys.toArray(arr);
211        }
212    
213        synchronized String[] getSubDirNames()
214        {
215            Set<String> ena = enabledDirectories.keySet();
216            Set<String> dis = disabledDirectories.keySet();
217            ena.addAll(dis);
218            String arr[] = new String[ena.size()];
219            return ena.toArray(arr);
220        }
221    
222    }