aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl
diff options
context:
space:
mode:
authorYana Stamcheva <yana@jitsi.org>2010-09-07 15:30:40 +0000
committerYana Stamcheva <yana@jitsi.org>2010-09-07 15:30:40 +0000
commit7746c91783b490f5ca07d3b06a6d336ae1152253 (patch)
treeffd125368411c2ba3d2ebd80d0722a51bfef3d55 /src/net/java/sip/communicator/impl
parent42fbfc39645660bf0ee18c718a9d6e9423e6f5e4 (diff)
downloadjitsi-7746c91783b490f5ca07d3b06a6d336ae1152253.zip
jitsi-7746c91783b490f5ca07d3b06a6d336ae1152253.tar.gz
jitsi-7746c91783b490f5ca07d3b06a6d336ae1152253.tar.bz2
Support for video and photo previews in chat window provided by Purvesh Sahoo as part of its GSoC project.
Diffstat (limited to 'src/net/java/sip/communicator/impl')
-rw-r--r--src/net/java/sip/communicator/impl/gui/GuiActivator.java44
-rwxr-xr-xsrc/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java264
-rw-r--r--src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf1
-rw-r--r--src/net/java/sip/communicator/impl/gui/utils/Smiley.java19
-rw-r--r--src/net/java/sip/communicator/impl/replacement/bliptv/BliptvActivator.java70
-rw-r--r--src/net/java/sip/communicator/impl/replacement/bliptv/ReplacementServiceBliptvImpl.java130
-rw-r--r--src/net/java/sip/communicator/impl/replacement/bliptv/bliptv.source.manifest.mf13
-rw-r--r--src/net/java/sip/communicator/impl/replacement/dailymotion/DailymotionActivator.java70
-rw-r--r--src/net/java/sip/communicator/impl/replacement/dailymotion/ReplacementServiceDailymotionImpl.java98
-rw-r--r--src/net/java/sip/communicator/impl/replacement/dailymotion/dailymotion.source.manifest.mf14
-rw-r--r--src/net/java/sip/communicator/impl/replacement/directimage/DirectImageActivator.java70
-rw-r--r--src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java90
-rw-r--r--src/net/java/sip/communicator/impl/replacement/directimage/directimage.source.manifest.mf14
-rw-r--r--src/net/java/sip/communicator/impl/replacement/flickr/FlickrActivator.java70
-rw-r--r--src/net/java/sip/communicator/impl/replacement/flickr/ReplacementServiceFlickrImpl.java158
-rw-r--r--src/net/java/sip/communicator/impl/replacement/flickr/flickr.source.manifest.mf13
-rw-r--r--src/net/java/sip/communicator/impl/replacement/hulu/HuluActivator.java69
-rw-r--r--src/net/java/sip/communicator/impl/replacement/hulu/ReplacementServiceHuluImpl.java138
-rw-r--r--src/net/java/sip/communicator/impl/replacement/hulu/hulu.source.manifest.mf13
-rw-r--r--src/net/java/sip/communicator/impl/replacement/metacafe/MetacafeActivator.java70
-rw-r--r--src/net/java/sip/communicator/impl/replacement/metacafe/ReplacementServiceMetacafeImpl.java95
-rw-r--r--src/net/java/sip/communicator/impl/replacement/metacafe/metacafe.source.manifest.mf12
-rw-r--r--src/net/java/sip/communicator/impl/replacement/smiley/ReplacementServiceSmileyImpl.java166
-rw-r--r--src/net/java/sip/communicator/impl/replacement/smiley/SmileyActivator.java110
-rw-r--r--src/net/java/sip/communicator/impl/replacement/smiley/smiley.source.manifest.mf15
-rw-r--r--src/net/java/sip/communicator/impl/replacement/twitpic/ReplacementServiceTwitpicImpl.java89
-rw-r--r--src/net/java/sip/communicator/impl/replacement/twitpic/TwitpicActivator.java70
-rw-r--r--src/net/java/sip/communicator/impl/replacement/twitpic/twitpic.source.manifest.mf12
-rw-r--r--src/net/java/sip/communicator/impl/replacement/vbox7/ReplacementServiceVbox7Impl.java96
-rw-r--r--src/net/java/sip/communicator/impl/replacement/vbox7/Vbox7Activator.java70
-rw-r--r--src/net/java/sip/communicator/impl/replacement/vbox7/vbox7.source.manifest.mf12
-rw-r--r--src/net/java/sip/communicator/impl/replacement/viddler/ReplacementServiceViddlerImpl.java145
-rw-r--r--src/net/java/sip/communicator/impl/replacement/viddler/ViddlerActivator.java71
-rw-r--r--src/net/java/sip/communicator/impl/replacement/viddler/viddler.source.manifest.mf13
-rw-r--r--src/net/java/sip/communicator/impl/replacement/vimeo/ReplacementServiceVimeoImpl.java137
-rw-r--r--src/net/java/sip/communicator/impl/replacement/vimeo/VimeoActivator.java69
-rw-r--r--src/net/java/sip/communicator/impl/replacement/vimeo/vimeo.source.manifest.mf13
-rw-r--r--src/net/java/sip/communicator/impl/replacement/youtube/ReplacementServiceYoutubeImpl.java139
-rw-r--r--src/net/java/sip/communicator/impl/replacement/youtube/YoutubeActivator.java69
-rw-r--r--src/net/java/sip/communicator/impl/replacement/youtube/youtube.source.manifest.mf14
40 files changed, 2714 insertions, 131 deletions
diff --git a/src/net/java/sip/communicator/impl/gui/GuiActivator.java b/src/net/java/sip/communicator/impl/gui/GuiActivator.java
index 8e31dc0..488ae11 100644
--- a/src/net/java/sip/communicator/impl/gui/GuiActivator.java
+++ b/src/net/java/sip/communicator/impl/gui/GuiActivator.java
@@ -25,6 +25,7 @@ import net.java.sip.communicator.service.metahistory.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.notification.*;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.replacement.*;
import net.java.sip.communicator.service.resources.*;
import net.java.sip.communicator.service.shutdown.*;
import net.java.sip.communicator.service.systray.*;
@@ -83,10 +84,13 @@ public class GuiActivator implements BundleActivator
private static final Map<Object, ProtocolProviderFactory>
providerFactoriesMap = new Hashtable<Object, ProtocolProviderFactory>();
+ private static final Map<Object, ReplacementService>
+ replacementSourcesMap = new Hashtable<Object, ReplacementService>();
+
/**
* Indicates if this bundle has been started.
*/
- public static boolean isStarted = false;
+ public static boolean isStarted = false;
/**
* The contact list object.
@@ -614,6 +618,44 @@ public class GuiActivator implements BundleActivator
}
/**
+ * Returns all <tt>ReplacementService</tt>s obtained from the bundle
+ * context.
+ *
+ * @return all <tt>ReplacementService</tt> implementation obtained from the
+ * bundle context
+ */
+ public static Map<Object, ReplacementService> getReplacementSources()
+ {
+ ServiceReference[] serRefs = null;
+ try
+ {
+ // get all registered sources
+ serRefs
+ = bundleContext.getServiceReferences(ReplacementService.class
+ .getName(), null);
+
+ }
+ catch (InvalidSyntaxException e)
+ {
+ logger.error("Error : " + e);
+ }
+
+ if (serRefs != null)
+ {
+ for (int i = 0; i < serRefs.length; i++)
+ {
+ ReplacementService replacementSources =
+ (ReplacementService) bundleContext.getService(serRefs[i]);
+
+ replacementSourcesMap.put(serRefs[i]
+ .getProperty(ReplacementService.SOURCE_NAME),
+ replacementSources);
+ }
+ }
+ return replacementSourcesMap;
+ }
+
+ /**
* Sets the <tt>contactList</tt> component currently used to show the
* contact list.
* @param list the contact list object to set
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
index 30d0a16..afb57e0 100755
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
@@ -11,6 +11,7 @@ import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
+import java.util.Map.*;
import java.util.regex.*;
import javax.swing.*;
@@ -24,8 +25,10 @@ import net.java.sip.communicator.impl.gui.main.chat.history.*;
import net.java.sip.communicator.impl.gui.main.chat.menus.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.replacement.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
+import net.java.sip.communicator.util.swing.SwingWorker;
/**
* The <tt>ChatConversationPanel</tt> is the panel, where all sent and received
@@ -69,41 +72,68 @@ public class ChatConversationPanel
+ ")");
/**
- * The compiled <tt>Pattern</tt> which matches {@link #smileyStrings}.
+ * The component rendering chat conversation panel text.
*/
- private static Pattern smileyPattern;
+ private final JTextPane chatTextPane = new MyTextPane();
/**
- * The <tt>List</tt> of smiley strings which are matched by
- * {@link #smileyPattern}.
+ * The editor kit used by the text component.
*/
- private static final java.util.List<String> smileyStrings
- = new ArrayList<String>();
-
- private final JTextPane chatTextPane = new MyTextPane();
-
private final HTMLEditorKit editorKit;
+ /**
+ * The document used by the text component.
+ */
private HTMLDocument document;
+ /**
+ * The parent container.
+ */
private final ChatConversationContainer chatContainer;
+ /**
+ * The menu shown on right button mouse click.
+ */
private final ChatRightButtonMenu rightButtonMenu;
+ /**
+ * The currently shown href.
+ */
private String currentHref;
+ /**
+ * The copy link item, contained in the right mouse click menu.
+ */
private final JMenuItem copyLinkItem;
+ /**
+ * The open link item, contained in the right mouse click menu.
+ */
private final JMenuItem openLinkItem;
+ /**
+ * The right mouse click menu separator.
+ */
private final JSeparator copyLinkSeparator = new JSeparator();
+ /**
+ * The timestamp of the last incoming message.
+ */
private long lastIncomingMsgTimestamp;
+ /**
+ * Indicates if this component is rendering a history conversation.
+ */
private final boolean isHistory;
+ /**
+ * The html text content type.
+ */
public static final String HTML_CONTENT_TYPE = "text/html";
+ /**
+ * The plain text content type.
+ */
public static final String TEXT_CONTENT_TYPE = "text/plain";
/**
@@ -245,7 +275,7 @@ public class ChatConversationPanel
getViewport().addComponentListener(componentListener);
}
- /*
+ /**
* Overrides Component#setBounds(int, int, int, int) in order to determine
* whether an automatic scroll of #chatTextPane to its bottom will be
* necessary at a later time in order to keep its vertical scroll bar to its
@@ -519,10 +549,104 @@ public class ChatConversationPanel
}
if (!isHistory)
ensureDocumentSize();
+
+ // Process replacements.
+ final Element elem;
+ /*
+ * Check to make sure element isn't the first element in the HTML
+ * document.
+ */
+ if (!(root.getElementCount() < 2))
+ {
+ elem = root.getElement(root.getElementCount() - 2);
+ }
+ else
+ elem = root.getElement(1);
+
+ /*
+ * Replacements will be processed only if it is enabled in the
+ * property
+ */
+ if (GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.REPLACEMENT_ENABLE, true)
+ || GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.getPropertyName("SMILEY"), true))
+ {
+ processReplacement(elem, chatString);
+ }
}
}
/**
+ * Formats the given message. Processes the messages and replaces links to
+ * video/image sources with their previews or any other substitution. Spawns
+ * a separate thread for replacement.
+ *
+ * @param elem the element in the HTML Document.
+ * @param chatString the message.
+ */
+ private void processReplacement(final Element elem, final String chatString)
+ {
+ final String chatFinal = chatString;
+
+ SwingWorker worker = new SwingWorker()
+ {
+ public Object construct() throws Exception
+ {
+ String temp = "", msgStore = chatFinal;
+
+ boolean isEnabled
+ = GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.REPLACEMENT_ENABLE, true);
+
+ Map<Object, ReplacementService> listSources
+ = GuiActivator.getReplacementSources();
+
+ Iterator<Entry<Object, ReplacementService>> entrySetIter
+ = listSources.entrySet().iterator();
+
+ for (int i = 0; i < listSources.size(); i++)
+ {
+ Map.Entry<Object, ReplacementService> entry
+ = entrySetIter.next();
+
+ ReplacementService source = entry.getValue();
+
+ if (!(GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.getPropertyName((String) entry
+ .getKey()), true) && (isEnabled || entry.getKey()
+ .equals("SMILEY"))))
+ continue;
+
+ temp = source.getReplacedMessage(msgStore);
+
+ /*
+ * replace the msgStore variable with the current replaced
+ * message before next iteration
+ */
+
+ if (!temp.equals(msgStore))
+ {
+ msgStore = temp;
+ }
+ }
+
+ if (!temp.equals(chatFinal))
+ {
+ synchronized (scrollToBottomRunnable)
+ {
+ scrollToBottomIsPending = true;
+ document.setOuterHTML(elem, temp.toString().substring(
+ temp.indexOf("<DIV")));
+ }
+ }
+ return "";
+ }
+ };
+ worker.start();
+ }
+
+ /**
* Ensures that the document won't become too big. When the document reaches
* a certain size the first message in the page is removed.
*/
@@ -703,9 +827,6 @@ public class ChatConversationPanel
message = processImgTags(processBrTags(message));
}
- if (ConfigurationManager.isShowSmileys())
- message = processSmileys(message, contentType);
-
return message;
}
@@ -806,123 +927,6 @@ public class ChatConversationPanel
}
/**
- * Formats message smileys.
- *
- * @param message the source message string
- * @param contentType the content type
- * @return the message string with properly formated smileys
- */
- private String processSmileys(String message, String contentType)
- {
- String startPlainTextTag;
- String endPlainTextTag;
- if (!HTML_CONTENT_TYPE.equals(contentType))
- {
- startPlainTextTag = START_PLAINTEXT_TAG;
- endPlainTextTag = END_PLAINTEXT_TAG;
- }
- else
- {
- startPlainTextTag = "";
- endPlainTextTag = "";
- }
-
- Collection<Smiley> smileys = ImageLoader.getDefaultSmileyPack();
- Matcher m = getSmileyPattern(smileys).matcher(message);
- StringBuffer msgBuffer = new StringBuffer();
- int prevEnd = 0;
-
- while (m.find())
- {
- msgBuffer.append(message.substring(prevEnd, m.start()));
- prevEnd = m.end();
-
- String smileyString = m.group().trim();
-
- msgBuffer.append(endPlainTextTag);
- msgBuffer.append("<IMG SRC=\"");
- msgBuffer
- .append(ImageLoader.getSmiley(smileyString).getImagePath());
- msgBuffer.append("\" ALT=\"");
- msgBuffer.append(smileyString);
- msgBuffer.append("\"></IMG>");
- msgBuffer.append(startPlainTextTag);
- }
- msgBuffer.append(message.substring(prevEnd));
-
- return msgBuffer.toString();
- }
-
- /**
- * Gets a compiled <tt>Pattern</tt> which matches the smiley strings of the
- * specified <tt>Collection</tt> of <tt>Smiley</tt>s.
- *
- * @param smileys the <tt>Collection</tt> of <tt>Smiley</tt>s for which to
- * get a compiled <tt>Pattern</tt> which matches its smiley strings
- * @return a compiled <tt>Pattern</tt> which matches the smiley strings of
- * the specified <tt>Collection</tt> of <tt>Smiley</tt>s
- */
- private static Pattern getSmileyPattern(Collection<Smiley> smileys)
- {
- synchronized (smileyStrings)
- {
- boolean smileyStringsIsEqual;
-
- if (smileyPattern == null)
- smileyStringsIsEqual = false;
- else
- {
- smileyStringsIsEqual = true;
-
- int smileyStringIndex = 0;
- int smileyStringCount = smileyStrings.size();
-
- smileyLoop: for (Smiley smiley : smileys)
- for (String smileyString : smiley.getSmileyStrings())
- if ((smileyStringIndex < smileyStringCount)
- && smileyString
- .equals(
- smileyStrings.get(smileyStringIndex)))
- smileyStringIndex++;
- else
- {
- smileyStringsIsEqual = false;
- break smileyLoop;
- }
- if (smileyStringsIsEqual
- && (smileyStringIndex != smileyStringCount))
- smileyStringsIsEqual = false;
- }
-
- if (!smileyStringsIsEqual)
- {
- smileyStrings.clear();
-
- StringBuffer regex = new StringBuffer();
-
- regex.append("(?<!(alt='|alt=\"))(");
- for (Smiley smiley : smileys)
- for (String smileyString : smiley.getSmileyStrings())
- {
- smileyStrings.add(smileyString);
-
- regex
- .append(
- GuiUtils
- .replaceSpecialRegExpChars(
- smileyString))
- .append("|");
- }
- regex = regex.deleteCharAt(regex.length() - 1);
- regex.append(')');
-
- smileyPattern = Pattern.compile(regex.toString());
- }
- return smileyPattern;
- }
- }
-
- /**
* Opens a link in the default browser when clicked and shows link url in a
* popup on mouseover.
*
diff --git a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf
index 8139b8e..b516bdf 100644
--- a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf
+++ b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf
@@ -33,6 +33,7 @@ Import-Package: org.osgi.framework,
net.java.sip.communicator.service.neomedia,
net.java.sip.communicator.service.neomedia.device,
net.java.sip.communicator.service.contactsource,
+ net.java.sip.communicator.service.replacement,
net.java.sip.communicator.util,
net.java.sip.communicator.util.swing,
net.java.sip.communicator.util.swing.border,
diff --git a/src/net/java/sip/communicator/impl/gui/utils/Smiley.java b/src/net/java/sip/communicator/impl/gui/utils/Smiley.java
index a59ed17..8a6601f 100644
--- a/src/net/java/sip/communicator/impl/gui/utils/Smiley.java
+++ b/src/net/java/sip/communicator/impl/gui/utils/Smiley.java
@@ -32,6 +32,7 @@ public class Smiley
* @param imageID The image identifier of the smiley icon.
* @param smileyStrings A set of strings corresponding to the smiley
* icon.
+ * @param description the description of the smiley
*/
public Smiley(ImageID imageID, String[] smileyStrings, String description)
{
@@ -95,4 +96,22 @@ public class Smiley
return url.toString();
}
+
+ /**
+ * Returns the path of the image corresponding to this smiley.
+ * @param resourcesService The ResourceManagementService required to get the
+ * image URL.
+ * @return the path of the image corresponding to this smiley.
+ */
+ public String getImagePath(ResourceManagementService resourcesService)
+ {
+ URL url
+ = resourcesService
+ .getImageURL(this.getImageID().getId());
+
+ if(url == null)
+ return null;
+
+ return url.toString();
+ }
}
diff --git a/src/net/java/sip/communicator/impl/replacement/bliptv/BliptvActivator.java b/src/net/java/sip/communicator/impl/replacement/bliptv/BliptvActivator.java
new file mode 100644
index 0000000..40ff265
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/bliptv/BliptvActivator.java
@@ -0,0 +1,70 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.bliptv;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Blip.tv source bundle.
+ *
+ * @author Purvesh Sahoo
+ */
+public class BliptvActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>BliptvActivator</tt> class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(BliptvActivator.class);
+
+ /**
+ * The blip tv service registration.
+ */
+ private ServiceRegistration bliptvServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService bliptvSource = null;
+
+ /**
+ * Starts the Blip.tv replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "BLIPTV");
+ bliptvSource = new ReplacementServiceBliptvImpl();
+
+ bliptvServReg =
+ context.registerService(ReplacementService.class.getName(),
+ bliptvSource, hashtable);
+
+ logger.info("Blip.TV source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Blip.tv replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ bliptvServReg.unregister();
+ logger.info("Blip.TV source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/bliptv/ReplacementServiceBliptvImpl.java b/src/net/java/sip/communicator/impl/replacement/bliptv/ReplacementServiceBliptvImpl.java
new file mode 100644
index 0000000..70fb553
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/bliptv/ReplacementServiceBliptvImpl.java
@@ -0,0 +1,130 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.bliptv;
+
+import java.io.*;
+import java.net.*;
+import java.util.regex.*;
+
+import org.json.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Blip.tv
+ * links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceBliptvImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceBliptvImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String BLIPTV_PATTERN =
+ "(?:[\\>])(http:\\/\\/(?:www\\.)?blip\\.tv\\/file\\/(\\d+).*(?=<))";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String BLIPTV_CONFIG_LABEL = "BLIPTV";
+
+ /**
+ * Constructor for <tt>ReplacementServiceBliptvImpl</tt>. The source needs
+ * to add itself to {@link ReplacementService} sourceList to be displayed in
+ * the configuration panel.
+ */
+ public ReplacementServiceBliptvImpl()
+ {
+ sourceList.add(BLIPTV_CONFIG_LABEL);
+ logger.trace("Creating a Blip.TV Source.");
+ }
+
+ /**
+ * Replaces the Blip.tv video links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(BLIPTV_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ try
+ {
+ String url = "http://oohembed.com/oohembed/?url=" + m.group(1);
+
+ URL sourceURL = new URL(url);
+ URLConnection conn = sourceURL.openConnection();
+
+ BufferedReader in =
+ new BufferedReader(new InputStreamReader(conn
+ .getInputStream()));
+
+ String inputLine, holder = "";
+
+ while ((inputLine = in.readLine()) != null)
+ holder += inputLine;
+ in.close();
+
+ JSONObject wrapper = new JSONObject(holder);
+
+ String thumbUrl = wrapper.getString("thumbnail_url");
+
+ if (thumbUrl != null)
+ {
+ msgBuff.append("<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\"");
+ msgBuff.append(thumbUrl);
+ msgBuff.append("\"></IMG>");
+
+ }
+ else
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ }
+
+ }
+ catch (Exception e)
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ e.printStackTrace();
+ }
+
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/bliptv/bliptv.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/bliptv/bliptv.source.manifest.mf
new file mode 100644
index 0000000..dddb7da
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/bliptv/bliptv.source.manifest.mf
@@ -0,0 +1,13 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.bliptv.BliptvActivator
+Bundle-Name: Blip.tv Preview Replacement Source
+Bundle-Description: A bundle providing processing for Blip.tv previews.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement,
+ org.apache.http \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/dailymotion/DailymotionActivator.java b/src/net/java/sip/communicator/impl/replacement/dailymotion/DailymotionActivator.java
new file mode 100644
index 0000000..c21da84
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/dailymotion/DailymotionActivator.java
@@ -0,0 +1,70 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.dailymotion;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.service.resources.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Dailymotion source bundle.
+ * @author Purvesh Sahoo
+ */
+public class DailymotionActivator
+ implements BundleActivator
+{
+ /**
+ * The currently valid bundle context.
+ */
+ private static final Logger logger =
+ Logger.getLogger(DailymotionActivator.class);
+
+ /**
+ * The daily motion source service registration.
+ */
+ private ServiceRegistration dailymotionSourceServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService dailymotionSource = null;
+
+ /**
+ * Starts the Dailymotion replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "DAILYMOTION");
+ dailymotionSource = new ReplacementServiceDailymotionImpl();
+
+ dailymotionSourceServReg =
+ context.registerService(ReplacementService.class.getName(),
+ dailymotionSource, hashtable);
+ logger.info("Dailymotion source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Dailymotion replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ dailymotionSourceServReg.unregister();
+ logger.info("Dailymotion source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/dailymotion/ReplacementServiceDailymotionImpl.java b/src/net/java/sip/communicator/impl/replacement/dailymotion/ReplacementServiceDailymotionImpl.java
new file mode 100644
index 0000000..99204e9
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/dailymotion/ReplacementServiceDailymotionImpl.java
@@ -0,0 +1,98 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.dailymotion;
+
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Dailymotion
+ * links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceDailymotionImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceDailymotionImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String DAILYMOTION_PATTERN =
+ "(http.*?(www\\.)*?dailymotion\\.com\\/video\\/([a-zA-Z0-9_\\-]+))([?#]([a-zA-Z0-9_\\-]+))*";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String DAILYMOTION_CONFIG_LABEL = "DAILYMOTION";
+
+ /**
+ * Constructor for <tt>ReplacementServiceDailymotionImpl</tt>. The source
+ * needs to add itself to {@link ReplacementService} sourceList to be
+ * displayed in the configuration panel.
+ */
+ public ReplacementServiceDailymotionImpl()
+ {
+ sourceList.add(DAILYMOTION_CONFIG_LABEL);
+ logger.trace("Creating a DailyMotion Source.");
+ }
+
+ /**
+ * Replaces the dailymotion video links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(final String chatString)
+ {
+
+ final Pattern p =
+ Pattern.compile(DAILYMOTION_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ if (count % 2 == 0)
+ {
+ msgBuff.append("<IMG HEIGHT=\"120\" WIDTH=\"160\" SRC=\"");
+ msgBuff
+ .append("http://www.dailymotion.com/thumbnail/160x120/video/");
+ msgBuff.append(m.group(3));
+ msgBuff.append("\"></IMG>");
+ }
+ else
+ {
+ msgBuff.append(chatString.substring(m.start(), m.end()));
+ }
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/dailymotion/dailymotion.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/dailymotion/dailymotion.source.manifest.mf
new file mode 100644
index 0000000..e27a162
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/dailymotion/dailymotion.source.manifest.mf
@@ -0,0 +1,14 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.dailymotion.DailymotionActivator
+Bundle-Name: Dailymotion Replacement Source
+Bundle-Description: A bundle providing replacement for dailymotion links.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.service.configuration.event,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.version,
+ net.java.sip.communicator.service.replacement \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/directimage/DirectImageActivator.java b/src/net/java/sip/communicator/impl/replacement/directimage/DirectImageActivator.java
new file mode 100644
index 0000000..2e596fe
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/directimage/DirectImageActivator.java
@@ -0,0 +1,70 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.directimage;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the direct image links source bundle.
+ * @author Purvesh Sahoo
+ */
+public class DirectImageActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>DirectImageActivator</tt>
+ * class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(DirectImageActivator.class);
+
+ /**
+ * The direct image source service registration.
+ */
+ private ServiceRegistration directImageSourceServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService directImageSource = null;
+
+ /**
+ * Starts the Direct image links replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "DIRECTIMAGE");
+ directImageSource = new ReplacementServiceDirectImageImpl();
+
+ directImageSourceServReg =
+ context.registerService(ReplacementService.class.getName(),
+ directImageSource, hashtable);
+ logger.info("Direct Image Link source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Direct image links replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ directImageSourceServReg.unregister();
+ logger.info("Direct Image Link source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java b/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java
new file mode 100644
index 0000000..55987f1
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/directimage/ReplacementServiceDirectImageImpl.java
@@ -0,0 +1,90 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.directimage;
+
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for direct
+ * image links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceDirectImageImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceDirectImageImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String URL_PATTERN =
+ "[^<>]+\\.(?:jpg|png|gif)[^<>]*(?=</a>)";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String DIRECT_IMAGE_CONFIG_LABEL = "DIRECTIMAGE";
+
+ /**
+ * Constructor for <tt>ReplacementServiceDirectImageImpl</tt>. The source
+ * needs to add itself to {@link ReplacementService} sourceList to be
+ * displayed in the configuration panel.
+ */
+ public ReplacementServiceDirectImageImpl()
+ {
+ sourceList.add(DIRECT_IMAGE_CONFIG_LABEL);
+ logger.trace("Creating a Direct Image Link Source.");
+ }
+
+ /**
+ * Replaces the direct image links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of exception.
+ */
+ public String getReplacedMessage(String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(URL_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ String url =
+ "<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\"" + m.group(0)
+ + "\"></IMG>";
+ msgBuff.append(url);
+
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/directimage/directimage.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/directimage/directimage.source.manifest.mf
new file mode 100644
index 0000000..100de7b
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/directimage/directimage.source.manifest.mf
@@ -0,0 +1,14 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.directimage.DirectImageActivator
+Bundle-Name: Direct Image Link Replacement Source
+Bundle-Description: A bundle providing replacement for direct image links.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.service.configuration.event,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.version,
+ net.java.sip.communicator.service.replacement \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/flickr/FlickrActivator.java b/src/net/java/sip/communicator/impl/replacement/flickr/FlickrActivator.java
new file mode 100644
index 0000000..1a50210
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/flickr/FlickrActivator.java
@@ -0,0 +1,70 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.flickr;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Flickr source bundle.
+ *
+ * @author Purvesh Sahoo
+ */
+public class FlickrActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>FlickrActivator</tt> class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(FlickrActivator.class);
+
+ /**
+ * Flickr service registration.
+ */
+ private ServiceRegistration flickrServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService flickrSource = null;
+
+ /**
+ * Starts the Flickr replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "FLICKR");
+ flickrSource = new ReplacementServiceFlickrImpl();
+
+ flickrServReg =
+ context.registerService(ReplacementService.class.getName(),
+ flickrSource, hashtable);
+
+ logger.info("Flickr source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Flickr replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ flickrServReg.unregister();
+ logger.info("Flickr source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/flickr/ReplacementServiceFlickrImpl.java b/src/net/java/sip/communicator/impl/replacement/flickr/ReplacementServiceFlickrImpl.java
new file mode 100644
index 0000000..bd469f7
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/flickr/ReplacementServiceFlickrImpl.java
@@ -0,0 +1,158 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.flickr;
+
+import java.io.*;
+import java.net.*;
+import java.util.regex.*;
+
+import org.json.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Flickr
+ * links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceFlickrImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceFlickrImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String FLICKR_PATTERN =
+ "(http.*?(www\\.)*?flickr\\.com\\/photos\\/[0-9a-zA-Z_\\-\\@]+\\/([0-9]+)(\\/[^\"\\<]*)*)";
+
+ /**
+ * API Key required to access the Flickr api.
+ */
+ public static final String API_KEY = "8b5d9cee22f0f5154bf4e9846c025484";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String FLICKR_CONFIG_LABEL = "FLICKR";
+
+ /**
+ * Constructor for <tt>ReplacementServiceFlickrImpl</tt>. The source needs
+ * to add itself to {@link ReplacementService} sourceList to be displayed in
+ * the configuration panel.
+ */
+ public ReplacementServiceFlickrImpl()
+ {
+ sourceList.add(FLICKR_CONFIG_LABEL);
+ logger.trace("Creating a Flickr Source.");
+ }
+
+ /**
+ * Replaces the Flickr image links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(FLICKR_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ if (count % 2 == 0)
+ {
+ try
+ {
+ // API URL
+ String url =
+ "http://api.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key="
+ + API_KEY + "&photo_id=" + m.group(3)
+ + "&format=json&nojsoncallback=1";
+
+ URL flickrURL = new URL(url);
+ URLConnection conn = flickrURL.openConnection();
+
+ BufferedReader in =
+ new BufferedReader(new InputStreamReader(conn
+ .getInputStream()));
+
+ String inputLine, holder = "";
+
+ while ((inputLine = in.readLine()) != null)
+ holder = inputLine;
+ in.close();
+
+ JSONObject wrapper = new JSONObject(holder);
+
+ if (wrapper.getString("stat").equals("ok"))
+ {
+
+ JSONObject result = wrapper.getJSONObject("photo");
+
+ String farmID = result.getString("farm");
+ String serverID = result.getString("server");
+ String secret = result.getString("secret");
+
+ String thumbURL =
+ "http://farm" + farmID + ".static.flickr.com/"
+ + serverID + "/" + m.group(3) + "_" + secret
+ + "_t.jpg";
+
+ if (!(result.length() == 0))
+ {
+ msgBuff
+ .append("<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\"");
+ msgBuff.append(thumbURL);
+ msgBuff.append("\"></IMG>");
+ }
+ }
+ else
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ }
+ }
+ catch (Exception e)
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ msgBuff.append(chatString.substring(m.start(), m.end()));
+ }
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/flickr/flickr.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/flickr/flickr.source.manifest.mf
new file mode 100644
index 0000000..b3b3d3a
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/flickr/flickr.source.manifest.mf
@@ -0,0 +1,13 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.flickr.FlickrActivator
+Bundle-Name: Flickr Preview Replacement Source
+Bundle-Description: A bundle providing processing for flickr previews.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement,
+ org.apache.http \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/hulu/HuluActivator.java b/src/net/java/sip/communicator/impl/replacement/hulu/HuluActivator.java
new file mode 100644
index 0000000..85ab9f1
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/hulu/HuluActivator.java
@@ -0,0 +1,69 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.hulu;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Hulu source bundle.
+ *
+ * @author Purvesh Sahoo
+ */
+public class HuluActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>HuluActivator</tt> class.
+ */
+ private static final Logger logger = Logger.getLogger(HuluActivator.class);
+
+ /**
+ * The hulu service registration.
+ */
+ private ServiceRegistration huluServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService huluSource = null;
+
+ /**
+ * Starts the Hulu replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "HULU");
+ huluSource = new ReplacementServiceHuluImpl();
+
+ huluServReg =
+ context.registerService(ReplacementService.class.getName(),
+ huluSource, hashtable);
+
+ logger.info("HULU source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Hulu replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ huluServReg.unregister();
+ logger.info("Hulu source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/hulu/ReplacementServiceHuluImpl.java b/src/net/java/sip/communicator/impl/replacement/hulu/ReplacementServiceHuluImpl.java
new file mode 100644
index 0000000..21223e5
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/hulu/ReplacementServiceHuluImpl.java
@@ -0,0 +1,138 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.hulu;
+
+import java.io.*;
+import java.net.*;
+import java.util.regex.*;
+
+import org.json.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Hulu links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceHuluImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceHuluImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String HULU_PATTERN =
+ "(http.*?(www\\.)*?hulu\\.com\\/watch\\/([a-zA-Z0-9_\\-]+))(\\/([^\\\"\\<]*)*)";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String HULU_CONFIG_LABEL = "HULU";
+
+ /**
+ * Constructor for <tt>ReplacementServiceHuluImpl</tt>. The source needs to
+ * register itself with {@link ReplacementService} sourceList to be
+ * displayed in the configuration panel.
+ */
+ public ReplacementServiceHuluImpl()
+ {
+ sourceList.add(HULU_CONFIG_LABEL);
+ logger.trace("Creating a Hulu Source.");
+ }
+
+ /**
+ * Replaces the Hulu video links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(HULU_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ if (count % 2 == 0)
+ {
+ try
+ {
+ String url =
+ "http://oohembed.com/oohembed/?url=" + m.group(0);
+
+ URL sourceURL = new URL(url);
+ URLConnection conn = sourceURL.openConnection();
+
+ BufferedReader in =
+ new BufferedReader(new InputStreamReader(conn
+ .getInputStream()));
+
+ String inputLine, holder = "";
+
+ while ((inputLine = in.readLine()) != null)
+ holder = inputLine;
+ in.close();
+
+ JSONObject wrapper = new JSONObject(holder);
+
+ String thumbUrl = wrapper.getString("thumbnail_url");
+
+ if (thumbUrl != null)
+ {
+ msgBuff
+ .append("<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\"");
+ msgBuff.append(thumbUrl);
+ msgBuff.append("\"></IMG>");
+
+ }
+ else
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ }
+
+ }
+ catch (Exception e)
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ msgBuff.append(chatString.substring(m.start(), m.end()));
+ }
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/hulu/hulu.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/hulu/hulu.source.manifest.mf
new file mode 100644
index 0000000..d3c92fb
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/hulu/hulu.source.manifest.mf
@@ -0,0 +1,13 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.hulu.HuluActivator
+Bundle-Name: Hulu Preview Replacement Source
+Bundle-Description: A bundle providing processing for Hulu previews.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement,
+ org.apache.http \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/metacafe/MetacafeActivator.java b/src/net/java/sip/communicator/impl/replacement/metacafe/MetacafeActivator.java
new file mode 100644
index 0000000..b00f1c0
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/metacafe/MetacafeActivator.java
@@ -0,0 +1,70 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.metacafe;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Metacafe source bundle.
+ *
+ * @author Purvesh Sahoo
+ */
+public class MetacafeActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>MetacafeActivator</tt> class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(MetacafeActivator.class);
+
+ /**
+ * The metacafe service registration.
+ */
+ private ServiceRegistration metacafeServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService metacafeSource = null;
+
+ /**
+ * Starts the Metacafe replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "METACAFE");
+ metacafeSource = new ReplacementServiceMetacafeImpl();
+
+ metacafeServReg =
+ context.registerService(ReplacementService.class.getName(),
+ metacafeSource, hashtable);
+
+ logger.info("Metacafe source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Metacafe replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ metacafeServReg.unregister();
+ logger.info("Metacafe source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/metacafe/ReplacementServiceMetacafeImpl.java b/src/net/java/sip/communicator/impl/replacement/metacafe/ReplacementServiceMetacafeImpl.java
new file mode 100644
index 0000000..77dc40a
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/metacafe/ReplacementServiceMetacafeImpl.java
@@ -0,0 +1,95 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.metacafe;
+
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Metacafe
+ * links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceMetacafeImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceMetacafeImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String METACAFE_PATTERN =
+ "(http.*?(www\\.)*?metacafe\\.com\\/watch\\/([a-zA-Z0-9_\\-]+))(\\/[a-zA-Z0-9_\\-\\/]+)*";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String METACAFE_CONFIG_LABEL = "METACAFE";
+
+ /**
+ * Constructor for <tt>ReplacementServiceMetacafeImpl</tt>. The source needs
+ * to register itself with {@link ReplacementService} sourceList to be
+ * displayed in the configuration panel.
+ */
+ public ReplacementServiceMetacafeImpl()
+ {
+ logger.trace("Creating a Metacafe Source.");
+ sourceList.add(METACAFE_CONFIG_LABEL);
+ }
+
+ /**
+ * Replaces the metacafe video links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(METACAFE_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ if (count % 2 == 0)
+ {
+ msgBuff.append("<IMG HEIGHT=\"81\" WIDTH=\"136\" SRC=\"");
+ msgBuff.append("http://www.metacafe.com/thumb/");
+ msgBuff.append(m.group(3));
+ msgBuff.append(".jpg\"></IMG>");
+ }
+ else
+ {
+ msgBuff.append(chatString.substring(m.start(), m.end()));
+ }
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/metacafe/metacafe.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/metacafe/metacafe.source.manifest.mf
new file mode 100644
index 0000000..fd5d591
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/metacafe/metacafe.source.manifest.mf
@@ -0,0 +1,12 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.metacafe.MetacafeActivator
+Bundle-Name: Metacafe Preview Replacement Source
+Bundle-Description: A bundle providing processing for metacafe previews.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/smiley/ReplacementServiceSmileyImpl.java b/src/net/java/sip/communicator/impl/replacement/smiley/ReplacementServiceSmileyImpl.java
new file mode 100644
index 0000000..06faaa5
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/smiley/ReplacementServiceSmileyImpl.java
@@ -0,0 +1,166 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.smiley;
+
+import java.util.*;
+import java.util.regex.*;
+
+import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide smiley as replacement
+ * source.
+ *
+ * @author Yana Stamcheva
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceSmileyImpl
+ implements ReplacementService
+{
+ /**
+ * The compiled <tt>Pattern</tt> which matches {@link #smileyStrings}.
+ */
+ private static Pattern smileyPattern;
+
+ /**
+ * The <tt>List</tt> of smiley strings which are matched by
+ * {@link #smileyPattern}.
+ */
+ private static final java.util.List<String> smileyStrings =
+ new ArrayList<String>();
+
+ /**
+ * The closing tag of the <code>PLAINTEXT</code> HTML element.
+ */
+ private static final String END_PLAINTEXT_TAG = "</PLAINTEXT>";
+
+ /**
+ * The opening tag of the <code>PLAINTEXT</code> HTML element.
+ */
+ private static final String START_PLAINTEXT_TAG = "<PLAINTEXT>";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String SMILEY_SOURCE = "SMILEY";
+
+ /**
+ * Replaces the smiley strings in the chat message with their
+ * corresponding smiley image.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the smiley images; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(final String chatString)
+ {
+ String startPlainTextTag = START_PLAINTEXT_TAG;
+ String endPlainTextTag = END_PLAINTEXT_TAG;
+ Collection<Smiley> smileys = ImageLoader.getDefaultSmileyPack();
+
+ Matcher m = getSmileyPattern(smileys).matcher(chatString);
+ StringBuffer msgBuffer = new StringBuffer();
+
+ int prevEnd = 0;
+
+ while (m.find())
+ {
+ msgBuffer.append(chatString.substring(prevEnd, m.start()));
+ prevEnd = m.end();
+
+ String smileyString = m.group().trim();
+
+ msgBuffer.append(endPlainTextTag);
+ msgBuffer.append("<IMG SRC=\"");
+ try
+ {
+ msgBuffer.append(ImageLoader.getSmiley(smileyString)
+ .getImagePath(SmileyActivator.getResources()));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ msgBuffer.append("\" ALT=\"");
+ msgBuffer.append(smileyString);
+ msgBuffer.append("\"></IMG>");
+ msgBuffer.append(startPlainTextTag);
+
+ }
+ msgBuffer.append(chatString.substring(prevEnd));
+
+ return msgBuffer.toString();
+ }
+
+ /**
+ * Gets a compiled <tt>Pattern</tt> which matches the smiley strings of the
+ * specified <tt>Collection</tt> of <tt>Smiley</tt>s.
+ *
+ * @param smileys the <tt>Collection</tt> of <tt>Smiley</tt>s for which to
+ * get a compiled <tt>Pattern</tt> which matches its smiley
+ * strings
+ * @return a compiled <tt>Pattern</tt> which matches the smiley strings of
+ * the specified <tt>Collection</tt> of <tt>Smiley</tt>s
+ */
+ private static Pattern getSmileyPattern(Collection<Smiley> smileys)
+ {
+ synchronized (smileyStrings)
+ {
+ boolean smileyStringsIsEqual;
+
+ if (smileyPattern == null)
+ smileyStringsIsEqual = false;
+ else
+ {
+ smileyStringsIsEqual = true;
+
+ int smileyStringIndex = 0;
+ int smileyStringCount = smileyStrings.size();
+
+ smileyLoop: for (Smiley smiley : smileys)
+ for (String smileyString : smiley.getSmileyStrings())
+ if ((smileyStringIndex < smileyStringCount)
+ && smileyString.equals(smileyStrings
+ .get(smileyStringIndex)))
+ smileyStringIndex++;
+ else
+ {
+ smileyStringsIsEqual = false;
+ break smileyLoop;
+ }
+ if (smileyStringsIsEqual
+ && (smileyStringIndex != smileyStringCount))
+ smileyStringsIsEqual = false;
+ }
+
+ if (!smileyStringsIsEqual)
+ {
+ smileyStrings.clear();
+
+ StringBuffer regex = new StringBuffer();
+
+ regex.append("(?<!(alt='|alt=\"))(");
+ for (Smiley smiley : smileys)
+ for (String smileyString : smiley.getSmileyStrings())
+ {
+ smileyStrings.add(smileyString);
+
+ regex.append(
+ GuiUtils.replaceSpecialRegExpChars(smileyString))
+ .append("|");
+ }
+ regex = regex.deleteCharAt(regex.length() - 1);
+ regex.append(')');
+
+ smileyPattern = Pattern.compile(regex.toString());
+ }
+ return smileyPattern;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/smiley/SmileyActivator.java b/src/net/java/sip/communicator/impl/replacement/smiley/SmileyActivator.java
new file mode 100644
index 0000000..71c29bf
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/smiley/SmileyActivator.java
@@ -0,0 +1,110 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.smiley;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.service.resources.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Smiley source bundle.
+ * @author Purvesh Sahoo
+ */
+public class SmileyActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>SmileyActivator</tt>
+ * class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(SmileyActivator.class);
+
+ /**
+ * The currently valid bundle context.
+ */
+ private static BundleContext bundleContext = null;
+
+ /**
+ * The resources service
+ */
+ private static ResourceManagementService resourcesService;
+
+ /**
+ * The smileyy service registration.
+ */
+ private ServiceRegistration smileyServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService smileySource = null;
+
+ /**
+ * Starts the Smiley replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ bundleContext = context;
+
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "SMILEY");
+ smileySource = new ReplacementServiceSmileyImpl();
+
+ smileyServReg =
+ context.registerService(ReplacementService.class.getName(),
+ smileySource, hashtable);
+
+ logger.info("Smiley source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Smiley replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ smileyServReg.unregister();
+ logger.info("Smiley source implementation [STOPPED].");
+ }
+
+ /**
+ * Returns the <tt>ResourceManagementService</tt>, through which we will
+ * access all resources.
+ *
+ * @return the <tt>ResourceManagementService</tt>, through which we will
+ * access all resources.
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resourcesService == null)
+ {
+ ServiceReference serviceReference =
+ bundleContext
+ .getServiceReference(ResourceManagementService.class
+ .getName());
+
+ if (serviceReference == null)
+ return null;
+
+ resourcesService =
+ (ResourceManagementService) bundleContext
+ .getService(serviceReference);
+ }
+ return resourcesService;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/smiley/smiley.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/smiley/smiley.source.manifest.mf
new file mode 100644
index 0000000..25b491b
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/smiley/smiley.source.manifest.mf
@@ -0,0 +1,15 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.smiley.SmileyActivator
+Bundle-Name: Smiley Replacement Source
+Bundle-Description: A bundle providing processing for smileys.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.service.neomedia,
+ net.java.sip.communicator.service.configuration.event,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement,
+ net.java.sip.communicator.service.gui \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/twitpic/ReplacementServiceTwitpicImpl.java b/src/net/java/sip/communicator/impl/replacement/twitpic/ReplacementServiceTwitpicImpl.java
new file mode 100644
index 0000000..d62c69f
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/twitpic/ReplacementServiceTwitpicImpl.java
@@ -0,0 +1,89 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.twitpic;
+
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Twitpic
+ * links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceTwitpicImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger
+ = Logger.getLogger(ReplacementServiceTwitpicImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String TWITPIC_PATTERN =
+ "http:\\/\\/(?:www\\.)?twitpic\\.com\\/([^\\/<]*)(?=<)";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String TWITPIC_CONFIG_LABEL = "TWITPIC";
+
+ /**
+ * Constructor for <tt>ReplacementServiceTwitpicImpl</tt>. The source needs
+ * to register itself with {@link ReplacementService} sourceList to be
+ * displayed in the configuration panel.
+ */
+ public ReplacementServiceTwitpicImpl()
+ {
+ sourceList.add(TWITPIC_CONFIG_LABEL);
+ logger.trace("Creating a Twitpic Source.");
+ }
+
+ /**
+ * Replaces the twitpic image links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(TWITPIC_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ msgBuff.append("<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\"");
+ msgBuff.append("http://twitpic.com/show/thumb/");
+ msgBuff.append(m.group(1));
+ msgBuff.append("\"></IMG>");
+
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/twitpic/TwitpicActivator.java b/src/net/java/sip/communicator/impl/replacement/twitpic/TwitpicActivator.java
new file mode 100644
index 0000000..3737cfd
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/twitpic/TwitpicActivator.java
@@ -0,0 +1,70 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.twitpic;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Twitpic source bundle.
+ *
+ * @author Purvesh Sahoo
+ */
+public class TwitpicActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>TwitpicActivator</tt> class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(TwitpicActivator.class);
+
+ /**
+ * The twitpic service registration.
+ */
+ private ServiceRegistration twitpicServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService twitpicSource = null;
+
+ /**
+ * Starts the Twitpic replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "TWITPIC");
+ twitpicSource = new ReplacementServiceTwitpicImpl();
+
+ twitpicServReg =
+ context.registerService(ReplacementService.class.getName(),
+ twitpicSource, hashtable);
+
+ logger.info("Twitpic source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Twitpic replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ twitpicServReg.unregister();
+ logger.info("Twitpic source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/twitpic/twitpic.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/twitpic/twitpic.source.manifest.mf
new file mode 100644
index 0000000..d8a4cd9
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/twitpic/twitpic.source.manifest.mf
@@ -0,0 +1,12 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.twitpic.TwitpicActivator
+Bundle-Name: Twitpic Preview Replacement Source
+Bundle-Description: A bundle providing processing for Twitpic previews.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/vbox7/ReplacementServiceVbox7Impl.java b/src/net/java/sip/communicator/impl/replacement/vbox7/ReplacementServiceVbox7Impl.java
new file mode 100644
index 0000000..b20ead8
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/vbox7/ReplacementServiceVbox7Impl.java
@@ -0,0 +1,96 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.vbox7;
+
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Vbox7
+ * links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceVbox7Impl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceVbox7Impl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String VBOX7_PATTERN =
+ "(http.*?(www\\.)*?vbox7\\.com\\/play\\:([a-zA-Z0-9_\\-]+))([?&]\\w+=[\\w-]*)*";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String VBOX7_CONFIG_LABEL = "VBOX7";
+
+ /**
+ * Constructor for <tt>ReplacementServiceVbox7Impl</tt>. The source needs
+ * to register itself with {@link ReplacementService} sourceList to be
+ * displayed in the configuration panel.
+ */
+ public ReplacementServiceVbox7Impl()
+ {
+ sourceList.add(VBOX7_CONFIG_LABEL);
+ logger.trace("Creating a Vbox7 Source.");
+ }
+
+ /**
+ * Replaces the vbox7 video links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(VBOX7_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ if (count % 2 == 0)
+ {
+ msgBuff.append("<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\"");
+ msgBuff
+ .append("http://i.vbox7.com/p/");
+ msgBuff.append(m.group(3));
+ msgBuff.append("3.jpg\"></IMG>");
+ }
+ else
+ {
+ msgBuff.append(chatString.substring(m.start(), m.end()));
+ }
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/vbox7/Vbox7Activator.java b/src/net/java/sip/communicator/impl/replacement/vbox7/Vbox7Activator.java
new file mode 100644
index 0000000..16473df
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/vbox7/Vbox7Activator.java
@@ -0,0 +1,70 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.vbox7;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the VBOX7 source bundle.
+ * @author Purvesh Sahoo
+ */
+public class Vbox7Activator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>Vbox7Activator</tt>
+ * class.
+ */
+ private static final Logger logger = Logger.getLogger(Vbox7Activator.class);
+
+ /**
+ * The vbox7 service registration.
+ */
+ private ServiceRegistration vbox7ServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService vbox7Source = null;
+
+ /**
+ * Starts the Vbox7 replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "VBOX7");
+ vbox7Source = new ReplacementServiceVbox7Impl();
+
+ vbox7ServReg =
+ context.registerService(ReplacementService.class.getName(),
+ vbox7Source, hashtable);
+
+ logger.info("Vbox7 source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Vbox7 replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ vbox7ServReg.unregister();
+ logger.info("Vbox7 source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/vbox7/vbox7.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/vbox7/vbox7.source.manifest.mf
new file mode 100644
index 0000000..2bf7737
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/vbox7/vbox7.source.manifest.mf
@@ -0,0 +1,12 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.vbox7.Vbox7Activator
+Bundle-Name: Vbox7 Preview Replacement Source
+Bundle-Description: A bundle providing processing for vbox7 previews.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/viddler/ReplacementServiceViddlerImpl.java b/src/net/java/sip/communicator/impl/replacement/viddler/ReplacementServiceViddlerImpl.java
new file mode 100644
index 0000000..676ac55
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/viddler/ReplacementServiceViddlerImpl.java
@@ -0,0 +1,145 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.viddler;
+
+import java.io.*;
+import java.net.*;
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Viddler
+ * links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceViddlerImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceViddlerImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String VIDDLER_PATTERN =
+ "(?:[\\>])(http:\\/\\/(?:www\\.)?viddler\\.com\\/explore\\/(\\w+)\\/videos\\/\\d+.*(?=<\\/A>))";
+
+ /**
+ * API Key required to access the viddler api.
+ */
+ private static final String API_KEY = "1bi6ckuzmklyaqseiqtl";
+
+ /**
+ * Viddler API url.
+ */
+ private static final String sourceURL =
+ "http://api.viddler.com/rest/v1/?method=viddler.videos.getDetailsByUrl&api_key="
+ + API_KEY;
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String VIDDLER_CONFIG_LABEL = "VIDDLER";
+
+ /**
+ * Constructor for <tt>ReplacementServiceViddlerImpl</tt>. The source needs
+ * to add itself to {@link ReplacementService} sourceList to be
+ * displayed in the configuration panel.
+ */
+ public ReplacementServiceViddlerImpl()
+ {
+ sourceList.add(VIDDLER_CONFIG_LABEL);
+ logger.trace("Creating a Viddler Source.");
+ }
+
+ /**
+ * Replaces the viddler video links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(VIDDLER_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ try
+ {
+ String url = sourceURL + "&url=" + m.group(1) + "/";
+
+ URL sourceURL = new URL(url);
+ URLConnection conn = sourceURL.openConnection();
+
+ BufferedReader in =
+ new BufferedReader(new InputStreamReader(conn
+ .getInputStream()));
+
+ String inputLine;
+ StringBuffer holder = new StringBuffer();
+
+ while ((inputLine = in.readLine()) != null)
+ holder.append(inputLine);
+ in.close();
+
+ String startTag = "<thumbnail_url>";
+ String endTag = "</thumbnail_url>";
+
+ String response = holder.toString();
+
+ int start = response.indexOf(startTag) + startTag.length();
+ int end = response.toString().indexOf(endTag);
+ String thumbUrl = response.substring(start, end);
+
+ if (thumbUrl != null)
+ {
+ msgBuff.append("<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\"");
+ msgBuff.append(thumbUrl);
+ msgBuff.append("\"></IMG>");
+
+ }
+ else
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ }
+
+ }
+ catch (Exception e)
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ e.printStackTrace();
+ }
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/viddler/ViddlerActivator.java b/src/net/java/sip/communicator/impl/replacement/viddler/ViddlerActivator.java
new file mode 100644
index 0000000..8ea3dfa
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/viddler/ViddlerActivator.java
@@ -0,0 +1,71 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.viddler;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Viddler source bundle.
+ * @author Purvesh Sahoo
+ */
+public class ViddlerActivator
+ implements BundleActivator
+{
+
+ /**
+ * The <tt>Logger</tt> used by the <tt>ViddlerActivator</tt>
+ * class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ViddlerActivator.class);
+
+ /**
+ * The Viddler source service registration.
+ */
+ private ServiceRegistration viddlerServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService viddlerSource = null;
+
+ /**
+ * Starts this bundle.
+ *
+ * @param context bundle context.
+ * @throws Exception
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "VIDDLER");
+ viddlerSource = new ReplacementServiceViddlerImpl();
+
+ viddlerServReg =
+ context.registerService(ReplacementService.class.getName(),
+ viddlerSource, hashtable);
+
+ logger.info("Viddler source implementation [STARTED].");
+ }
+
+ /**
+ * Stops bundle.
+ *
+ * @param bc context.
+ * @throws Exception
+ */
+ public void stop(BundleContext bc) throws Exception
+ {
+ viddlerServReg.unregister();
+ logger.info("Viddler source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/viddler/viddler.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/viddler/viddler.source.manifest.mf
new file mode 100644
index 0000000..ed053c2
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/viddler/viddler.source.manifest.mf
@@ -0,0 +1,13 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.viddler.ViddlerActivator
+Bundle-Name: Viddler Preview Replacement Source
+Bundle-Description: A bundle providing processing for Viddler previews.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement,
+ org.apache.http \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/vimeo/ReplacementServiceVimeoImpl.java b/src/net/java/sip/communicator/impl/replacement/vimeo/ReplacementServiceVimeoImpl.java
new file mode 100644
index 0000000..b83485e
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/vimeo/ReplacementServiceVimeoImpl.java
@@ -0,0 +1,137 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.vimeo;
+
+import java.net.*;
+import java.util.regex.*;
+
+import org.json.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import java.io.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Vimeo
+ * links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceVimeoImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceVimeoImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static final String VIMEO_PATTERN =
+ "(http.*?(www\\.)*?vimeo\\.com\\/([a-zA-Z0-9_\\-]+))";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String VIMEO_CONFIG_LABEL = "VIMEO";
+
+ /**
+ * Constructor for <tt>ReplacementServiceVimeoImpl</tt>. The source needs
+ * to register itself with {@link ReplacementService} sourceList to be
+ * displayed in the configuration panel.
+ */
+ public ReplacementServiceVimeoImpl()
+ {
+ sourceList.add(VIMEO_CONFIG_LABEL);
+ logger.trace("Creating a Vimeo Source.");
+ }
+
+ /**
+ * Replaces the vimeo video links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(VIMEO_PATTERN, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ if (count % 2 == 0)
+ {
+
+ try
+ {
+ String url =
+ "http://vimeo.com/api/v2/video/" + m.group(3) + ".json";
+ URL vimeoURL = new URL(url);
+ URLConnection conn = vimeoURL.openConnection();
+
+ BufferedReader in =
+ new BufferedReader(new InputStreamReader(conn
+ .getInputStream()));
+
+ String inputLine, holder = "";
+
+ while ((inputLine = in.readLine()) != null)
+ holder = inputLine;
+ in.close();
+
+ JSONArray result = new JSONArray(holder);
+
+ if (!(result.length() == 0))
+ {
+ msgBuff
+ .append("<IMG HEIGHT=\"150\" WIDTH=\"200\" SRC=\"");
+ msgBuff.append(result.getJSONObject(0).getString(
+ "thumbnail_medium"));
+ msgBuff.append("\"></IMG>");
+ }
+ else
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ }
+ }
+ catch (Exception e)
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ msgBuff.append(chatString.substring(m.start(), m.end()));
+ }
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/vimeo/VimeoActivator.java b/src/net/java/sip/communicator/impl/replacement/vimeo/VimeoActivator.java
new file mode 100644
index 0000000..e5d99f6
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/vimeo/VimeoActivator.java
@@ -0,0 +1,69 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.vimeo;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Vimeo source bundle.
+ *
+ * @author Purvesh Sahoo
+ */
+public class VimeoActivator
+ implements BundleActivator
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger = Logger.getLogger(VimeoActivator.class);
+
+ /**
+ * The vimeo service registration.
+ */
+ private ServiceRegistration vimeoServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService vimeoSource = null;
+
+ /**
+ * Starts the Vimeo replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "VIMEO");
+ vimeoSource = new ReplacementServiceVimeoImpl();
+
+ vimeoServReg =
+ context.registerService(ReplacementService.class.getName(),
+ vimeoSource, hashtable);
+
+ logger.info("Vimeo source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Vimeo replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ vimeoServReg.unregister();
+ logger.info("Vimeo source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/vimeo/vimeo.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/vimeo/vimeo.source.manifest.mf
new file mode 100644
index 0000000..52dfcdf
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/vimeo/vimeo.source.manifest.mf
@@ -0,0 +1,13 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.vimeo.VimeoActivator
+Bundle-Name: Vimeo Preview Replacement Source
+Bundle-Description: A bundle providing processing for vimeo previews.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement,
+ org.apache.http \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/youtube/ReplacementServiceYoutubeImpl.java b/src/net/java/sip/communicator/impl/replacement/youtube/ReplacementServiceYoutubeImpl.java
new file mode 100644
index 0000000..45c8c2e
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/youtube/ReplacementServiceYoutubeImpl.java
@@ -0,0 +1,139 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.youtube;
+
+import java.io.*;
+import java.net.*;
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.json.*;
+
+/**
+ * Implements the {@link ReplacementService} to provide previews for Youtube
+ * links.
+ *
+ * @author Purvesh Sahoo
+ */
+public class ReplacementServiceYoutubeImpl
+ implements ReplacementService
+{
+ /**
+ * The logger for this class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(ReplacementServiceYoutubeImpl.class);
+
+ /**
+ * The regex used to match the link in the message.
+ */
+ public static String re1 =
+ "(http.*?(www\\.)*?youtube\\.com\\/watch\\?v=([a-zA-Z0-9_\\-]+))([?&]\\w+=[\\w-]+)*";
+
+ /**
+ * Configuration label property name. The label is saved in the languages
+ * file under this property.
+ */
+ public static final String YOUTUBE_CONFIG_LABEL = "YOUTUBE";
+
+ /**
+ * Constructor for <tt>ReplacementServiceYoutubeImpl</tt>. The source needs
+ * to register itself with {@link ReplacementService} sourceList to be
+ * displayed in the configuration panel.
+ */
+ public ReplacementServiceYoutubeImpl()
+ {
+ sourceList.add(YOUTUBE_CONFIG_LABEL);
+ logger.trace("Creating a Youtube Source.");
+ }
+
+ /**
+ * Replaces the youtube video links in the chat message with their
+ * corresponding thumbnails.
+ *
+ * @param chatString the original chat message.
+ * @return replaced chat message with the thumbnail image; the original
+ * message in case of no match.
+ */
+ public String getReplacedMessage(final String chatString)
+ {
+ final Pattern p =
+ Pattern.compile(re1, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+ Matcher m = p.matcher(chatString);
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+ count++;
+ msgBuff.append(chatString.substring(startPos, m.start()));
+ startPos = m.end();
+
+ // We only want to replace the inner link text and not the link src.
+ // All even matches are the text we want to replace.
+ if (count % 2 == 0)
+ {
+ try
+ {
+ String url =
+ "http://youtube.com/oembed/?url=" + m.group(0);
+
+ URL sourceURL = new URL(url);
+ URLConnection conn = sourceURL.openConnection();
+
+ BufferedReader in =
+ new BufferedReader(new InputStreamReader(conn
+ .getInputStream()));
+
+ String inputLine, holder = "";
+
+ while ((inputLine = in.readLine()) != null)
+ holder = inputLine;
+ in.close();
+
+ JSONObject wrapper = new JSONObject(holder);
+
+ String thumbUrl = wrapper.getString("thumbnail_url");
+
+ if (thumbUrl != null)
+ {
+ msgBuff
+ .append("<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\"");
+ msgBuff.append(thumbUrl);
+ msgBuff.append("\"></IMG>");
+
+ }
+ else
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ }
+
+ }
+ catch (Exception e)
+ {
+ startPos = 0;
+ msgBuff = new StringBuffer();
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ msgBuff.append(chatString.substring(m.start(), m.end()));
+ }
+ }
+
+ msgBuff.append(chatString.substring(startPos));
+
+ if (!msgBuff.toString().equals(chatString))
+ return msgBuff.toString();
+
+ return chatString;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/youtube/YoutubeActivator.java b/src/net/java/sip/communicator/impl/replacement/youtube/YoutubeActivator.java
new file mode 100644
index 0000000..0b76c49
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/youtube/YoutubeActivator.java
@@ -0,0 +1,69 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.replacement.youtube;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * Activator for the Youtube source bundle.
+ *
+ * @author Purvesh Sahoo
+ */
+public class YoutubeActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>YoutubeActivator</tt> class.
+ */
+ private static final Logger logger =
+ Logger.getLogger(YoutubeActivator.class);
+
+ /**
+ * The youtube source service registration.
+ */
+ private ServiceRegistration youtubeSourceServReg = null;
+
+ /**
+ * The source implementation reference.
+ */
+ private static ReplacementService youtubeSource = null;
+
+ /**
+ * Starts the Youtube replacement source bundle
+ *
+ * @param context the <tt>BundleContext</tt> as provided from the OSGi
+ * framework
+ * @throws Exception if anything goes wrong
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ Hashtable<String, String> hashtable = new Hashtable<String, String>();
+ hashtable.put(ReplacementService.SOURCE_NAME, "YOUTUBE");
+ youtubeSource = new ReplacementServiceYoutubeImpl();
+
+ youtubeSourceServReg =
+ context.registerService(ReplacementService.class.getName(),
+ youtubeSource, hashtable);
+ logger.info("Youtube source implementation [STARTED].");
+ }
+
+ /**
+ * Unregisters the Youtube replacement service.
+ *
+ * @param context BundleContext
+ * @throws Exception if anything goes wrong
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ youtubeSourceServReg.unregister();
+ logger.info("Youtube source implementation [STOPPED].");
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/replacement/youtube/youtube.source.manifest.mf b/src/net/java/sip/communicator/impl/replacement/youtube/youtube.source.manifest.mf
new file mode 100644
index 0000000..18b1d90
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/replacement/youtube/youtube.source.manifest.mf
@@ -0,0 +1,14 @@
+Bundle-Activator: net.java.sip.communicator.impl.replacement.youtube.YoutubeActivator
+Bundle-Name: Youtube Replacement Source
+Bundle-Description: A bundle providing replacement for youtube links.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 1.0.0
+System-Bundle: yes
+Export-Package: net.java.sip.communicator.service.replacement
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.service.configuration.event,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.replacement,
+ org.apache.http \ No newline at end of file