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/MediaCache.java,v 1.4 2004/05/10 14:58:54 tj_willis Exp $
019     */ 
020    package net.sourceforge.pavlov.randommedia;
021    
022    import java.net.URL;
023    import org.apache.log4j.*;
024    
025    /**
026     * Loads and holds a bunch of audio files whose locations are specified
027     * relative to a fixed base URL.
028     * @author <a href="mailto:tj_willis@users.sourceforge.net">T.J. Willis</a>
029     * @version 1.0
030     */
031    public abstract class MediaCache extends java.util.Stack<Object> {
032        private int maxPriorityBound = 3;
033        private int normPriorityBound = 5;
034        private volatile int numLoading;
035        private int maxLoading = 10;
036        RandomURLProvider provider;
037        private Category cat
038            = Category.getInstance(MediaCache.class.getName());
039    
040        /**
041         * Creates a new <code>MediaCache</code> instance.
042         *
043         * @param p a <code>RandomURLProvider</code> value
044         * @param mySize an <code>int</code> value
045         */
046        public MediaCache(RandomURLProvider p,int mySize) {
047            super();
048            provider = p;
049            assert provider!=null: "RandomURLProvider is null";
050            ensureCapacity(mySize);
051            numLoading = 0;
052        }
053    
054        /**
055         * Describe <code>startLoading</code> method here.
056         *
057         * @param url an <code>URL</code> value
058         */
059        public void startLoading(URL url) {
060            if(numLoading>maxLoading) return;
061            if(url==null){
062                cat.warn("null url in startLoading");
063                return;
064            }
065            int pri = Thread.MIN_PRIORITY;
066            if(size()<=maxPriorityBound) pri = Thread.MAX_PRIORITY;
067            else if(size()<normPriorityBound) pri = Thread.NORM_PRIORITY;
068            //cat.debug(numLoading + "/" + maxLoading + ": Cache Loading: " + url + " at priority: " + pri + ": size is: " + size());
069            numLoading++;
070            //createMediaLoader(this,url,pri);
071            new MediaLoader(this, url,pri);
072        }
073    
074    
075        /**
076         * Describe <code>getObject</code> method here.
077         *
078         * @return an <code>Object</code> value
079         */
080        public Object getObject() {
081            if (size()<1) return null; 
082            //FIXME: change this to synchronously load an object
083            //cat.debug("size is " + size());
084            manageCache();
085            return pop();
086        }
087    
088        void decrementNumberLoading()
089        {
090            if(numLoading<=0) return;
091            numLoading-=1;
092        }
093    
094        /**
095         * Describe <code>add</code> method here.
096         *
097         * @param obj an <code>Object</code> value
098         * @return a <code>boolean</code> value
099         */
100        public boolean add(Object obj) {
101            numLoading--;
102            return super.add(obj);
103        }
104    
105        /**
106         * Describe <code>clearCache</code> method here.
107         *
108         */
109        public void clearCache()
110        {
111            super.clear();
112            // FIXME: this is unimplemented
113            //clear();
114        }
115    
116        /**
117         * Describe <code>manageCache</code> method here.
118         *
119         */
120        public void manageCache()
121        {
122            int ss = size();
123            if(ss<7)
124                loadObjects(1);
125            if(ss<5)
126                loadObjects(2);
127            if(ss<3)
128                loadObjects(4);
129        }
130    
131        void loadObjects(int num)
132        {
133            assert provider!=null : "loadMedia: RandomURLProvider is null";
134            for(int i=0;i<num;i++)
135                {
136                    URL it = provider.getRandomURL();
137                    if(it!=null)
138                        startLoading(it);
139                }
140        }
141    
142        abstract ContentLoader getContentLoader();
143    
144    }