DefaultVCardProvider.java 6.96 KB
Newer Older
1 2 3 4 5
/**
 * $RCSfile: DefaultVCardProvider.java,v $
 * $Revision: 3062 $
 * $Date: 2005-11-11 13:26:30 -0300 (Fri, 11 Nov 2005) $
 *
6
 * Copyright (C) 2004-2008 Jive Software. All rights reserved.
7
 *
8 9 10 11 12 13 14 15 16 17 18
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
19 20
 */

21
package org.jivesoftware.openfire.vcard;
22 23 24 25 26 27 28 29 30

import java.io.StringReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

31 32 33 34 35 36 37 38
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.AlreadyExistsException;
import org.jivesoftware.util.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

39
/**
40
 * Default implementation of the VCardProvider interface, which reads and writes data
41
 * from the <tt>ofVCard</tt> database table.
42 43 44 45 46
 *
 * @author Gaston Dombiak
 */
public class DefaultVCardProvider implements VCardProvider {

47 48
	private static final Logger Log = LoggerFactory.getLogger(DefaultVCardProvider.class);

49
    private static final String LOAD_PROPERTIES =
50
        "SELECT vcard FROM ofVCard WHERE username=?";
51
    private static final String DELETE_PROPERTIES =
52
        "DELETE FROM ofVCard WHERE username=?";
53
    private static final String UPDATE_PROPERTIES =
54
        "UPDATE ofVCard SET vcard=? WHERE username=?";
55
    private static final String INSERT_PROPERTY =
56
        "INSERT INTO ofVCard (username, vcard) VALUES (?, ?)";
57

guus's avatar
guus committed
58
    private static final int POOL_SIZE = 10;
59 60 61
    /**
     * Pool of SAX Readers. SAXReader is not thread safe so we need to have a pool of readers.
     */
guus's avatar
guus committed
62
    private BlockingQueue<SAXReader> xmlReaders = new LinkedBlockingQueue<SAXReader>(POOL_SIZE);
63 64 65 66 67


    public DefaultVCardProvider() {
        super();
        // Initialize the pool of sax readers
guus's avatar
guus committed
68
        for (int i=0; i<POOL_SIZE; i++) {
69 70 71
            SAXReader xmlReader = new SAXReader();
            xmlReader.setEncoding("UTF-8");
            xmlReaders.add(xmlReader);
72 73 74 75
        }
    }

    public Element loadVCard(String username) {
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
        synchronized (username.intern()) {
            Element vCardElement = null;
            java.sql.Connection con = null;
            PreparedStatement pstmt = null;
            SAXReader xmlReader = null;
            try {
                // Get a sax reader from the pool
                xmlReader = xmlReaders.take();
                con = DbConnectionManager.getConnection();
                pstmt = con.prepareStatement(LOAD_PROPERTIES);
                pstmt.setString(1, username);
                ResultSet rs = pstmt.executeQuery();
                while (rs.next()) {
                    vCardElement =
                            xmlReader.read(new StringReader(rs.getString(1))).getRootElement();
                }
92
            }
93 94 95 96 97 98 99 100 101
            catch (Exception e) {
                Log.error("Error loading vCard of username: " + username, e);
            }
            finally {
                // Return the sax reader to the pool
                if (xmlReader != null) {
                    xmlReaders.add(xmlReader);
                }
                try { if (pstmt != null) { pstmt.close(); } }
102
                catch (Exception e) { Log.error(e.getMessage(), e); }
103
                try { if (con != null) { con.close(); } }
104
                catch (Exception e) { Log.error(e.getMessage(), e); }
105
            }
106
            return vCardElement;
107 108 109
        }
    }

110
    public Element createVCard(String username, Element vCardElement) throws AlreadyExistsException {
111 112 113
        if (loadVCard(username) != null) {
            // The user already has a vCard
            throw new AlreadyExistsException("Username " + username + " already has a vCard");
114 115 116 117 118 119 120 121 122 123 124 125
        }

        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = DbConnectionManager.getConnection();
            pstmt = con.prepareStatement(INSERT_PROPERTY);
            pstmt.setString(1, username);
            pstmt.setString(2, vCardElement.asXML());
            pstmt.executeUpdate();
        }
        catch (SQLException e) {
126
            Log.error("Error creating vCard for username: " + username, e);
127 128
        }
        finally {
129
            try { if (pstmt != null) { pstmt.close(); } }
130
            catch (Exception e) { Log.error(e.getMessage(), e); }
131
            try { if (con != null) { con.close(); } }
132
            catch (Exception e) { Log.error(e.getMessage(), e); }
133
        }
134
        return vCardElement;
135 136
    }

137
    public Element updateVCard(String username, Element vCardElement) throws NotFoundException {
138 139 140
        if (loadVCard(username) == null) {
            // The user already has a vCard
            throw new NotFoundException("Username " + username + " does not have a vCard");
141 142 143 144 145 146 147 148 149 150 151
        }
        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = DbConnectionManager.getConnection();
            pstmt = con.prepareStatement(UPDATE_PROPERTIES);
            pstmt.setString(1, vCardElement.asXML());
            pstmt.setString(2, username);
            pstmt.executeUpdate();
        }
        catch (SQLException e) {
152
            Log.error("Error updating vCard of username: " + username, e);
153 154
        }
        finally {
155
            try { if (pstmt != null) { pstmt.close(); } }
156
            catch (Exception e) { Log.error(e.getMessage(), e); }
157
            try { if (con != null) { con.close(); } }
158
            catch (Exception e) { Log.error(e.getMessage(), e); }
159
        }
160
        return vCardElement;
161 162 163 164 165 166 167 168 169 170 171 172
    }

    public void deleteVCard(String username) {
        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = DbConnectionManager.getConnection();
            pstmt = con.prepareStatement(DELETE_PROPERTIES);
            pstmt.setString(1, username);
            pstmt.executeUpdate();
        }
        catch (SQLException e) {
173
            Log.error("Error deleting vCard of username: " + username, e);
174 175
        }
        finally {
176
            try { if (pstmt != null) { pstmt.close(); } }
177
            catch (Exception e) { Log.error(e.getMessage(), e); }
178
            try { if (con != null) { con.close(); } }
179
            catch (Exception e) { Log.error(e.getMessage(), e); }
180 181 182 183 184 185 186
        }
    }

    public boolean isReadOnly() {
        return false;
    }
}