Commit 72252a09 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

. Storage strategy is now plugable. JM-339

. Modified to store the DOM presentation in the database. JM-338


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@1651 b35dd754-fafc-0310-a699-88a17e54d16e
parent b2bd83db
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.vcard;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.AlreadyExistsException;
import org.jivesoftware.util.NotFoundException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.SQLException;
import java.io.StringReader;
/**
* Default implementation of the VCardProvider interface, which reads and writes data
* from the <tt>jiveVCard</tt> database table.
*
* @author Gaston Dombiak
*/
public class DefaultVCardProvider implements VCardProvider {
private static final String LOAD_PROPERTIES =
"SELECT value FROM jiveVCard WHERE username=?";
private static final String DELETE_PROPERTIES =
"DELETE FROM jiveVCard WHERE username=?";
private static final String UPDATE_PROPERTIES =
"UPDATE jiveVCard SET value=? WHERE username=?";
private static final String INSERT_PROPERTY =
"INSERT INTO jiveVCard (username, value) VALUES (?, ?)";
private SAXReader saxReader = new SAXReader();
public Element loadVCard(String username) {
synchronized (username.intern()) {
Element vCardElement = null;
java.sql.Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_PROPERTIES);
pstmt.setString(1, username);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
vCardElement =
saxReader.read(new StringReader(rs.getString(1))).getRootElement();
}
}
catch (Exception e) {
Log.error(e);
}
finally {
try { if (pstmt != null) { pstmt.close(); } }
catch (Exception e) { Log.error(e); }
try { if (con != null) { con.close(); } }
catch (Exception e) { Log.error(e); }
}
return vCardElement;
}
}
public void createVCard(String username, Element vCardElement) throws AlreadyExistsException {
if (loadVCard(username) != null) {
// The user already has a vCard
throw new AlreadyExistsException("Username " + username + " already has a vCard");
}
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) {
Log.error(e);
}
finally {
try { if (pstmt != null) { pstmt.close(); } }
catch (Exception e) { Log.error(e); }
try { if (con != null) { con.close(); } }
catch (Exception e) { Log.error(e); }
}
}
public void updateVCard(String username, Element vCardElement) throws NotFoundException {
if (loadVCard(username) == null) {
// The user already has a vCard
throw new NotFoundException("Username " + username + " does not have a vCard");
}
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) {
Log.error(e);
}
finally {
try { if (pstmt != null) { pstmt.close(); } }
catch (Exception e) { Log.error(e); }
try { if (con != null) { con.close(); } }
catch (Exception e) { Log.error(e); }
}
}
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) {
Log.error(e);
}
finally {
try { if (pstmt != null) { pstmt.close(); } }
catch (Exception e) { Log.error(e); }
try { if (con != null) { con.close(); } }
catch (Exception e) { Log.error(e); }
}
}
public boolean isReadOnly() {
return false;
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.vcard;
import org.dom4j.Element;
import org.jivesoftware.util.*;
import java.util.StringTokenizer;
/**
* Manages VCard information for users.
*
* @author Matt Tucker
*/
public class VCardManager {
private static VCardProvider provider;
private static VCardManager instance = new VCardManager();
private Cache vcardCache;
static {
// Load a VCard provider.
String className = JiveGlobals.getXMLProperty("provider.vcard.className",
DefaultVCardProvider.class.getName());
try {
Class c = ClassUtils.forName(className);
provider = (VCardProvider)c.newInstance();
}
catch (Exception e) {
Log.error("Error loading vcard provider: " + className, e);
provider = new DefaultVCardProvider();
}
}
public static VCardManager getInstance() {
return instance;
}
/**
* Returns the currently-installed VCardProvider. <b>Warning:</b> in virtually all
* cases the vcard provider should not be used directly. Instead, the appropriate
* methods in VCardManager should be called. Direct access to the vcard provider is
* only provided for special-case logic.
*
* @return the current VCardProvider.
*/
public static VCardProvider getProvider() {
return provider;
}
private VCardManager() {
CacheManager.initializeCache("vcardCache", 512 * 1024);
vcardCache = CacheManager.getCache("vcardCache");
}
/**
* Returns the user's vCard information for a given vcard property name. If the property
* has no defined text then an empty string will be returned. However, if the property
* does not exist then a <tt>null</tt> value will be answered. Advanced user systems can
* use vCard information to link to user directory information or store other relevant
* user information.</p>
*
* Note that many elements in the vCard may have the same path so the returned value in that
* case will be the first found element. For instance, "ADR:STREET" may be present in
* many addresses of the user. Use {@link #getVCard(String)} to get the whole vCard of
* the user.
*
* @param username The username of the user to return his vCard property.
* @param name The name of the vcard property to retrieve encoded with ':' to denote
* the path.
* @return The vCard value found
*/
public String getVCardProperty(String username, String name) {
String answer = null;
Element vCardElement = getOrLoadVCard(username);
if (vCardElement != null) {
// A vCard was found for this user so now look for the correct element
Element subElement = null;
StringTokenizer tokenizer = new StringTokenizer(name, ":");
while (tokenizer.hasMoreTokens()) {
String tok = tokenizer.nextToken();
if (subElement == null) {
subElement = vCardElement.element(tok);
}
else {
subElement = subElement.element(tok);
}
if (subElement == null) {
break;
}
}
if (subElement != null) {
answer = subElement.getTextTrim();
}
}
return answer;
}
/**
* Sets the user's vCard information. The new vCard information will be persistent. Advanced
* user systems can use vCard information to link to user directory information or store
* other relevant user information.
*
* @param username The username of the user to set his new vCard.
* @param vCardElement The DOM element sent by the user as his new vcard.
* @throws Exception if an error occured while storing the new vCard.
*/
public void setVCard(String username, Element vCardElement) throws Exception {
if (provider.isReadOnly()) {
throw new UnsupportedOperationException("VCard provider is read-only.");
}
Element oldVCard = getOrLoadVCard(username);
// See if we need to update the vCard or insert a new one.
if (oldVCard != null) {
// Only update the vCard in the database if the vCard has changed.
if (!oldVCard.equals(vCardElement)) {
try {
provider.updateVCard(username, vCardElement);
}
catch (NotFoundException e) {
Log.warn("Tried to update a vCard that does not exist", e);
provider.createVCard(username, vCardElement);
}
}
}
else {
try {
provider.createVCard(username, vCardElement);
}
catch (AlreadyExistsException e) {
Log.warn("Tried to create a vCard when one already exist", e);
provider.updateVCard(username, vCardElement);
}
}
vcardCache.put(username, vCardElement);
}
/**
* Deletes the user's vCard from the user account.
*
* @param username The username of the user to delete his vCard.
*/
public void deleteVCard(String username) {
if (provider.isReadOnly()) {
throw new UnsupportedOperationException("VCard provider is read-only.");
}
Element oldVCard = getOrLoadVCard(username);
if (oldVCard != null) {
vcardCache.remove(username);
// Delete the property from the DB if it was present in memory
provider.deleteVCard(username);
}
}
/**
* Returns the vCard of a given user or null if none was defined before. Changes to the
* returned vCard will not be stored in the database. Use the returned vCard as a
* read-only vCard.
*
* @return the vCard of a given user.
*/
public Element getVCard(String username) {
Element vCardElement = getOrLoadVCard(username);
return vCardElement == null ? null : vCardElement.createCopy();
}
private Element getOrLoadVCard(String username) {
Element vCardElement = (Element) vcardCache.get(username);
if (vCardElement == null) {
vCardElement = provider.loadVCard(username);
if (vCardElement != null) {
vcardCache.put(username, vCardElement);
}
}
return vCardElement;
}
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.vcard;
import org.dom4j.Element;
import org.jivesoftware.util.AlreadyExistsException;
import org.jivesoftware.util.NotFoundException;
/**
* Provider interface for users vcards.
*
* @author Gaston Dombiak
*/
public interface VCardProvider {
/**
* Loads the specified user vcard by username. Returns <tt>null</tt> if no
* vCard was found for the specified username.
*
* @param username the username
* @return the vCard as an DOM element or <tt>null</tt> if none was found.
*/
Element loadVCard(String username);
/**
* Creates and saves the new user vcard. This method should throw an
* UnsupportedOperationException if this operation is not supported by
* the backend vcard store.
*
* @param username the username.
* @param vCardElement the vCard to save.
* @throws AlreadyExistsException if the user already has a vCard.
* @throws UnsupportedOperationException if the provider does not support the
* operation.
*/
void createVCard(String username, Element vCardElement) throws AlreadyExistsException;
/**
* Updates the user vcard in the backend store. This method should throw an
* UnsupportedOperationException if this operation is not supported by
* the backend vcard store.
*
* @param username the username.
* @param vCardElement the vCard to save.
* @throws NotFoundException if the vCard to update does not exist.
* @throws UnsupportedOperationException if the provider does not support the
* operation.
*/
void updateVCard(String username, Element vCardElement) throws NotFoundException;
/**
* Delets a user vcard. This method should throw an UnsupportedOperationException
* if this operation is not supported by the backend vcard store.
*
* @param username the username to delete.
* @throws UnsupportedOperationException if the provider does not support the
* operation.
*/
void deleteVCard(String username);
/**
* Returns true if this VCardProvider is read-only. When read-only,
* vcards can not be created, deleted, or modified.
*
* @return true if the vcard provider is read-only.
*/
boolean isReadOnly();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment