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/pluglets/feedback/velocity/VelocityPlugletLoader.java,v 1.2 2004/05/13 17:25:00 tj_willis Exp $
019     */
020    package net.sourceforge.pavlov.pluglets.feedback.velocity;
021    
022    import java.awt.Container;
023    import java.io.File;
024    import java.net.*;
025    import java.util.*;
026    import javax.swing.*;
027    import net.sourceforge.pavlov.event.*;
028    import net.sourceforge.pavlov.pluglets.*;
029    import net.sourceforge.pavlov.pluglets.feedback.*;
030    import net.sourceforge.sillyview.*;
031    import org.apache.velocity.*;
032    import org.apache.velocity.app.*;
033    import org.apache.log4j.*;
034    
035    /**
036     * <code>PluginLoader</code> 
037     * 
038     * Generates a vector of objects that are a subclass of a given class.
039     * These objects must have a no-arg constructor and be in a given directory.
040     *
041     * If a serious error occurs (no such directory, can't read directory, no
042     * files) the vector will be null.  Otherwise, individual classes are skipped.
043     * Current implementation prints status and error/exception information
044     * to stdout.
045     *
046     * There is, at this time, little support for JarFiles or subdirectories.
047     *
048     * @author <a href="mailto:tj_willis@users.sourceforge.net">T.J. Willis</a>
049     * @version $Revision: 1.2 $
050     */
051    public class VelocityPlugletLoader 
052        extends PlugletLoader
053        implements AnswerListener
054    {
055        protected VelocityContext context;
056        private static Category cat 
057            = Category.getInstance(VelocityPlugletLoader.class.getName());    
058    
059        /**
060         * Creates a new <code>VelocityPlugletLoader</code> instance.
061         *
062         * @param baseClassName a <code>String</code> value
063         * @param directory a <code>String</code> value
064         */
065        public VelocityPlugletLoader(String directory) 
066        {
067            cat.setLevel(Level.WARN);
068            try { 
069                Velocity.init();
070            } catch (Exception e) {
071                cat.error("Error init'ing velocity: " + e);
072            }
073            context = new VelocityContext();
074            pluglets = new Vector<Pluglet>();
075    
076            // DON'T call super constructor
077            // DO populate pluglets vector
078            File dir = new File(directory);
079            if( dir==null || !dir.exists()) return;
080            File files[] = dir.listFiles();
081            ArrayList<File> dirs = new ArrayList<File>();
082            
083    
084            for(File g : files) {
085                if(g.isDirectory()){
086                    String s = g.getName() + "/index.vm";
087                    File f = new File(dir,s);
088                    if(f!=null && f.exists()){
089                        dirs.add(g);
090                        cat.info("accepting pluglet: " + s);
091                    } else {
092                        cat.info("rejecting pluglet: " + s);
093                    }
094                }
095            }
096    
097            for(File g: dirs) {
098                try {
099                    cat.info("Creating pluglet " + g);
100    
101                    String s = g.getName() + "/index.vm";
102                    File f = new File(dir,s);
103                    URL templateURL = f.toURL();
104                    VelocityModel model = new VelocityModel(context,templateURL); 
105                    VelocityPluglet vp = new VelocityPluglet(model,g);
106                    //vp.setName(g.toString());
107                    pluglets.add(vp);
108                } catch (Exception e) {
109                    cat.warn("Exception loading pluglet : " + g + ":" + e);
110                    e.printStackTrace();
111                }
112            }
113        }
114    
115    
116        // FIXED: Velocity.init() in this class   CHECK
117        // FIXED: create a context in this class  CHECK
118        // FIXED: use the context to create the VelocityPluglets  CHECK
119        // FIXED: set this as only answerEventListener   CHECK
120        // FIXED: when event rec'd update the context   CHECK
121        // FIXED: when event rec'd tell pluglets to update themselves how? CHECK
122        //          pluglet.setToken("xxx","xxx");
123    
124        /**
125         * Describe <code>addToAnswerEventProducer</code> method here.
126         *
127         * @param cont an <code>AnswerEventProducer</code> value
128         * @deprecated This should be in FeedbackPluglet
129         */
130        @Deprecated public void addToAnswerEventProducer(AnswerEventProducer cont) {
131            cont.addAnswerListener(this);
132        }
133        /**
134         * Called when the user answers a question.
135         *
136         * @param e an <code>AnswerEvent</code> value
137         */
138        public void answerEvent(AnswerEvent e){
139            context.put(VelocityPluglet.ANSWER_EVENT,e);
140            for( Pluglet p : pluglets ) {
141                VelocityPluglet q = (VelocityPluglet)p;
142                q.answerEvent(e);
143                q.setToken("BASE_URL",q.getBaseURL());
144            }
145            //setToken(QUIZ_DATA,e.getQuizData());
146            //setToken("right",e.isCorrect());
147            
148        }
149    
150    }
151