# HG changeset patch # User Da Risk # Date 1281397611 -7200 # Node ID b2572c048dd70859d345f0ac5bb8b8eabe77e88b # Parent 5dd9d68b6ad3e5fd792f37aa3ac759ecd50d9911 Implement a disk cache for Capabilities. #286 almost done. diff -r 5dd9d68b6ad3 -r b2572c048dd7 src/com/beem/project/beem/service/BeemCapsManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/beem/project/beem/service/BeemCapsManager.java Tue Aug 10 01:46:51 2010 +0200 @@ -0,0 +1,162 @@ +/* + BEEM is a videoconference application on the Android Platform. + + Copyright (C) 2009 by Frederic-Charles Barthelery, + Jean-Manuel Da Silva, + Nikita Kozlov, + Philippe Lago, + Jean Baptiste Vergely, + Vincent Veronis. + + This file is part of BEEM. + + BEEM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + BEEM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with BEEM. If not, see . + + Please send bug reports with examples or suggestions to + contact@beem-project.com or http://dev.beem-project.com/ + + Epitech, hereby disclaims all copyright interest in the program "Beem" + written by Frederic-Charles Barthelery, + Jean-Manuel Da Silva, + Nikita Kozlov, + Philippe Lago, + Jean Baptiste Vergely, + Vincent Veronis. + + Nicolas Sadirac, November 26, 2009 + President of Epitech. + + Flavien Astraud, November 26, 2009 + Head of the EIP Laboratory. + +*/ +package com.beem.project.beem.service; + +import org.jivesoftware.smack.Connection; +import org.jivesoftware.smackx.packet.DiscoverInfo; +import org.jivesoftware.smackx.ServiceDiscoveryManager; +import org.jivesoftware.smack.util.PacketParserUtils; +import org.xmlpull.v1.XmlPullParserFactory; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParser; + +import android.util.Log; +import java.io.FileReader; +import java.io.Reader; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.Writer; + +import java.io.File; +import java.io.IOException; + +import android.content.Context; + +import com.beem.project.beem.smack.caps.CapsManager; + +/** + * An implementation of CapsManager which keeps DiscoverInfo on the Cache directory of the android application. + */ +public class BeemCapsManager extends CapsManager { + + private static final String TAG = "BeemCapsManager"; + + private Context mContext; + private File mCacheDir; + private XmlPullParser mParser; + + /** + * Create a BeemCapsManager. + * + * @param sdm the ServiceDiscoveryManager to use + * @param conn the connection to use + * @param context the Android context to use to store data + */ + public BeemCapsManager(final ServiceDiscoveryManager sdm, final Connection conn, final Context context) { + super(sdm, conn); + mContext = context; + initCacheDirectory(); + } + + + @Override + protected DiscoverInfo load(String ver) { + File fver = new File(mCacheDir, ver); + try { + Reader fr = new BufferedReader(new FileReader(fver)); + try { + if (mParser == null) + mParser = makeParser(); + mParser.setInput(fr); + return (DiscoverInfo) PacketParserUtils.parsePacketExtension("query", + "http://jabber.org/protocol/disco#info", mParser); + + } finally { + fr.close(); + } + } catch (Exception e) { + // The parsePacketExtension throw Exception on error + Log.d(TAG, "Error while loading Capabilities " + ver, e); + } + return null; + } + + @Override + protected void store(String ver, DiscoverInfo info) { + File fver = new File(mCacheDir, ver); + try { + Writer fw = new BufferedWriter(new FileWriter(fver)); + try { + String data = info.toXML(); + fw.write(data, 0, data.length()); + } finally { + fw.close(); + } + } catch (IOException e) { + Log.d(TAG, "Error while saving Capabilities " + ver, e); + } + } + + @Override + protected boolean isInCache(String ver) { + boolean result = super.isInCache(ver); + if (!result) { + File fver = new File(mCacheDir, ver); + result = fver.exists(); + } + return result; + } + + /** + * Init the cache directory. + */ + private void initCacheDirectory() { + File dir = mContext.getCacheDir(); + mCacheDir = new File(dir, "capabilities"); + mCacheDir.mkdir(); + } + + /** + * Make an Xml parser. + * + * @return the created xml parser. + * @throws XmlPullParserException if an error occurs while creating the parser. + */ + private XmlPullParser makeParser() throws XmlPullParserException { + XmlPullParserFactory fact = XmlPullParserFactory.newInstance(); + fact.setNamespaceAware(true); + return fact.newPullParser(); + } +} diff -r 5dd9d68b6ad3 -r b2572c048dd7 src/com/beem/project/beem/service/XmppConnectionAdapter.java --- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java Mon Jul 26 01:21:28 2010 +0200 +++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java Tue Aug 10 01:46:51 2010 +0200 @@ -76,7 +76,6 @@ import com.beem.project.beem.ui.Subscription; import com.beem.project.beem.utils.BeemBroadcastReceiver; import com.beem.project.beem.utils.Status; -import com.beem.project.beem.smack.caps.CapsManager; /** * This class implements an adapter for XMPPConnection. @@ -397,7 +396,7 @@ sdm.addFeature("jabber:iq:privacy"); sdm.addFeature("http://jabber.org/protocol/caps"); mChatStateManager = ChatStateManager.getInstance(mAdaptee); - CapsManager caps = new CapsManager(sdm, mAdaptee); + BeemCapsManager caps = new BeemCapsManager(sdm, mAdaptee, mService); caps.setNode("http://www.beem-project.com"); } diff -r 5dd9d68b6ad3 -r b2572c048dd7 src/com/beem/project/beem/smack/caps/CapsExtension.java --- a/src/com/beem/project/beem/smack/caps/CapsExtension.java Mon Jul 26 01:21:28 2010 +0200 +++ b/src/com/beem/project/beem/smack/caps/CapsExtension.java Tue Aug 10 01:46:51 2010 +0200 @@ -49,8 +49,6 @@ /** * This extension represents a capability of XEP-0115. * - * @author Frédéric Barthéléry - * @version $Revision$ */ public class CapsExtension implements PacketExtension { diff -r 5dd9d68b6ad3 -r b2572c048dd7 src/com/beem/project/beem/smack/caps/CapsManager.java --- a/src/com/beem/project/beem/smack/caps/CapsManager.java Mon Jul 26 01:21:28 2010 +0200 +++ b/src/com/beem/project/beem/smack/caps/CapsManager.java Tue Aug 10 01:46:51 2010 +0200 @@ -70,9 +70,8 @@ /** * Capabilities manager to implements XEP-0115. + * The DiscoverInfo are cached in memory. * - * @author Frédéric Barthéléry - * @version $Revision$ */ public class CapsManager { // the verCache should be stored on disk @@ -97,6 +96,76 @@ } /** + * Get the discover info associated with a ver attribute. + * + * @param ver the ver attribute. + * @return the discover info or null if it was not cached. + */ + public DiscoverInfo getDiscoverInfo(String ver) { + return mVerCache.get(ver); + } + + /** + * Get the discover info of a contact. + * + * @param jid the jid of the contact. + * @param ver the ver attribute of the contact capability. + * @return The info of the client null if the info was not cached. + */ + public DiscoverInfo getDiscoverInfo(String jid, String ver) { + DiscoverInfo info = mVerCache.get(ver); + if (info == null) { + info = load(ver); + if (info == null) + info = mJidCache.get(jid); + } + return info; + } + + /** + * Set the node attribute to send in your capability. + * This is usually an uri to identify the client. + * + * @param node the node attribute to set. + */ + public void setNode(String node) { + mNode = node; + } + + /** + * Load a persistent DiscoverInfo. + * The default implementation does nothing and always return null. + * + * @param ver the ver hash of the discoverInfo. + * @return The discover info or null if not present. + */ + protected DiscoverInfo load(String ver) { + return null; + } + + /** + * Store a DiscoverInfo for persistence. + * The default implementation does nothing. + * + * @param ver the ver hash of the DiscoverInfo + * @param info the DiscoverInfo to store + */ + protected void store(String ver, DiscoverInfo info) { + } + + /** + * Check if the discover info correspondig to the ver hash is in cache. + * This implementation checks the memory cache. + * If the info is not in cache it is necessary to request it from the network. + * + * @param ver the ver hash + * @return true if it is in cache false otherwise + */ + protected boolean isInCache(String ver) { + return mVerCache.containsKey(ver); + } + + /** * Initialize this CapsManageer. */ private void init() { @@ -104,10 +173,13 @@ PacketFilter filter = new PacketExtensionFilter("c", "http://jabber.org/protocol/caps"); mConnection.addPacketListener(new PacketListener() { public void processPacket(Packet packet) { + if (packet.getFrom().equals(mConnection.getUser())) + return; PacketExtension p = packet.getExtension("c", "http://jabber.org/protocol/caps"); CapsExtension caps = (CapsExtension) p; - if (!mVerCache.containsKey(caps.getVer())) + if (!isInCache(caps.getVer())) { validate(packet.getFrom(), caps.getVer(), caps.getHash()); + } } }, filter); mConnection.addPacketInterceptor(new PacketInterceptor() { @@ -129,40 +201,6 @@ } /** - * Get the discover info associated with a ver attribute. - * - * @param ver the ver attribute. - * @return the discover info or null if it was not cached. - */ - public DiscoverInfo getDiscoverInfo(String ver) { - return mVerCache.get(ver); - } - - /** - * Get the discover info of a contact. - * - * @param jid the jid of the contact. - * @param ver the ver attribute of the contact capability. - * @return The info of the client null if the info was not cached. - */ - public DiscoverInfo getDiscoverInfo(String jid, String ver) { - DiscoverInfo info = mVerCache.get(ver); - if (info == null) - info = mJidCache.get(jid); - return info; - } - - /** - * Set the node attribute to send in your capability. - * This is usually an uri to identify the client. - * - * @param node the node attribute to set. - */ - public void setNode(String node) { - mNode = node; - } - - /** * Validate the ver attribute of a received capability. * * @param jid the jid of the sender of the capability. @@ -179,8 +217,10 @@ } String v = calculateVer(info, hashMethod); boolean res = v.equals(ver); - if (res) + if (res) { mVerCache.put(ver, info); + store(ver, info); + } return res; } catch (XMPPException e) { e.printStackTrace();