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/user/LocalUserFile.java,v 1.3 2004/07/01 05:50:21 tj_willis Exp $
019     */ 
020    package net.sourceforge.pavlov.user;
021    import java.io.*;
022    import org.xml.sax.*;
023    import org.xml.sax.helpers.*;
024    import net.sourceforge.pavlov.zipUtilities.XMLFileFilter;
025    import org.apache.log4j.*;
026    
027    
028    /**
029     * A user file that resides on the same computer the application is
030     * running on.
031     *
032     * @author <a href="mailto:tj_willis@users.sourceforge.net"> T.J. Willis </a>
033     * @version 1.0
034     */
035    public final class LocalUserFile
036        implements UserFile
037    {
038        private String userDir = "users/";
039        private File userFile;
040        private String fname;
041        // FIXME: URLEncode the user file name!
042    
043    
044        /**
045         * Creates a new <code>LocalUserFile</code> named for the
046         * user in the given directory.
047         *
048         * @param userName a <code>String</code> value
049         * @param newUserDir a <code>String</code> value
050         * @exception IOException if an error occurs
051         */
052        public LocalUserFile(final String userName, final String userDir)
053            throws IOException
054        {
055            this.userDir = userDir;
056            String s = getFileName(userName);
057            fname = s;
058            userFile = new File(fname);
059        }
060    
061        /**
062         * Creates a new <code>LocalUserFile</code> instance named
063         * for this user in the subdirectory "users/".
064         *
065         * @param userName a <code>String</code> value
066         * @exception IOException if an error occurs
067         */
068        public LocalUserFile(final String userName)
069            throws IOException
070        {
071            this(userName,"users/");
072        }
073    
074        /**
075         * Returns true if the file exists and is readable.
076         *
077         * @return a <code>boolean</code> value
078         */
079        public boolean exists()
080        {
081            return canRead();
082        }
083    
084    
085        /**
086         * Saves the given user information to this file.
087         *
088         * @param user an <code>User</code> value
089         * @exception FileNotFoundException if an error occurs
090         * @exception IOException if an error occurs
091         */
092        public void save(User user)
093            throws FileNotFoundException, IOException
094        {
095            //FIXME: assert username = user.getName()
096            if(!canWrite()) 
097                throw new FileNotFoundException("Cannot write to file: " + userFile);
098            FileWriter out = new FileWriter(userFile);
099            user.toXML(out);
100            out.flush();
101            out.close();
102        }
103    
104    
105        /**
106         * Attempts to read the given user file.  Will not return the User
107         * if the password is incorrect.
108         *
109         * @param password a <code>String</code> value
110         * @return an <code>User</code> value
111         * @exception SAXException if an error occurs
112         * @exception FileNotFoundException if an error occurs
113         * @exception IOException if an error occurs
114         */
115        public User read(String password)
116            throws SAXException, FileNotFoundException, IOException
117        {
118            if(!canRead()) return null;
119            XMLReader xr = null;
120            xr = XMLReaderFactory.createXMLReader();
121            UserXMLHandler br = new UserXMLHandler();
122            xr.setContentHandler(br);
123            xr.parse(new InputSource(new FileReader(userFile)));
124            User x = br.getUser();
125            if(x.checkPassword(password)){
126                x.setUserFile(this);
127                return x;
128            } 
129            return null;
130        }
131    
132        /**
133         * Returns true if the file exists and is readable.
134         *
135         * @return a <code>boolean</code> value
136         */
137        public boolean canRead()
138        {
139            if(userFile==null) return false;
140            if(!userFile.exists()) return false;
141            if(!userFile.canRead()) return false;
142            return true;
143        }
144    
145        /**
146         * If the file exists, return if it is writable.  If not, create it,
147         * and try to write to it.
148         *
149         * @return a <code>boolean</code> value
150         */
151        public boolean canWrite()
152        {
153            if(!userFile.exists()){
154                try { 
155                    userFile.createNewFile();
156                } catch (Exception e) {
157                    return false;
158                }
159            } 
160            if(!userFile.canWrite()) return false;
161            return true;
162        }
163    
164    
165        /**
166         * Converts the userDir and the userName into a file path.
167         *
168         * @param userName a <code>String</code> value
169         * @return a <code>String</code> value
170         */
171        protected String getFileName(String userName)
172        {
173            return userDir+userName+".xml";
174    
175        }
176    
177    
178    
179    }