/* * Jitsi, 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.protocol.dict; import java.util.*; import net.java.dict4j.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; /** * Instant messaging functionalities for the Dict protocol. * * @author ROTH Damien * @author LITZELMANN Cedric */ public class OperationSetBasicInstantMessagingDictImpl extends AbstractOperationSetBasicInstantMessaging implements RegistrationStateChangeListener { /** * The currently valid persistent presence operation set. */ private OperationSetPersistentPresenceDictImpl opSetPersPresence = null; /** * The protocol provider that created us. */ private ProtocolProviderServiceDictImpl parentProvider = null; private DictAccountID accountID; /** * Creates an instance of this operation set keeping a reference to the * parent protocol provider and presence operation set. * * @param provider The provider instance that creates us. * @param opSetPersPresence the currently valid * OperationSetPersistentPresenceDictImpl instance. */ public OperationSetBasicInstantMessagingDictImpl( ProtocolProviderServiceDictImpl provider, OperationSetPersistentPresenceDictImpl opSetPersPresence) { this.opSetPersPresence = opSetPersPresence; this.parentProvider = provider; this.accountID = (DictAccountID) provider.getAccountID(); parentProvider.addRegistrationStateChangeListener(this); } @Override public Message createMessage(String content) { return new MessageDictImpl(content, HTML_MIME_TYPE, DEFAULT_MIME_ENCODING, null); } @Override public Message createMessage(String content, String contentType, String encoding, String subject) { return new MessageDictImpl(content, contentType, encoding, subject); } /** * Sends the message to the destination indicated by the * to contact. * * @param to the Contact to send message to * @param message the Message to send. * @throws IllegalStateException if the underlying ICQ stack is not * registered and initialized. * @throws IllegalArgumentException if to is not an instance * belonging to the underlying implementation. */ public void sendInstantMessage(Contact to, Message message) throws IllegalStateException, IllegalArgumentException { if( !(to instanceof ContactDictImpl) ) { throw new IllegalArgumentException( "The specified contact is not a Dict contact." + to); } // Remove all html tags from the message message = createMessage(Html2Text.extractText(message.getContent())); // Display the queried word fireMessageDelivered(message, to); this.submitDictQuery((ContactDictImpl) to, message); } /** * Determines whether the protocol provider (or the protocol itself) supports * sending and receiving offline messages. Most often this method would * return true for protocols that support offline messages and false for * those that don't. It is however possible for a protocol to support these * messages and yet have a particular account that does not (i.e. feature * not enabled on the protocol server). In cases like this it is possible * for this method to return true even when offline messaging is not * supported, and then have the sendMessage method throw an * OperationFailedException with code - OFFLINE_MESSAGES_NOT_SUPPORTED. * * @return true if the protocol supports offline messages and * false otherwise. */ public boolean isOfflineMessagingSupported() { return false; } /** * Determines whether the protocol supports the supplied content type. * * @param contentType the type we want to check * @return true if the protocol supports it and * false otherwise. */ public boolean isContentTypeSupported(String contentType) { if(contentType.equals(DEFAULT_MIME_TYPE)) return true; else if(contentType.equals(HTML_MIME_TYPE)) return true; else return false; } /** * Returns the protocol provider that this operation set belongs to. * * @return a reference to the ProtocolProviderServiceDictImpl * instance that this operation set belongs to. */ public ProtocolProviderServiceDictImpl getParentProvider() { return this.parentProvider; } /** * Returns a reference to the presence operation set instance used by our * source provider. * * @return a reference to the OperationSetPersistentPresenceDictImpl * instance used by this provider. */ public OperationSetPersistentPresenceDictImpl getOpSetPersPresence() { return this.opSetPersPresence; } /** * The method is called by the ProtocolProvider whenever a change in the * registration state of the corresponding provider has occurred. * * @param evt ProviderStatusChangeEvent the event describing the status * change. */ public void registrationStateChanged(RegistrationStateChangeEvent evt) { } /** * Create, execute and display a query to a dictionary (ContactDictImpl) * * @param dictContact the contact containing the database name * @param message the message containing the word */ private void submitDictQuery(ContactDictImpl dictContact, Message message) { Message msg = this.createMessage(""); String database = dictContact.getContactID(); DictConnection conn = this.parentProvider.getConnection(); boolean doMatch = false; String word; // Formatting the query message, if the word as one or more spaces we // put it between quotes to prevent errors word = message.getContent().replace("\"", "").trim(); if (word.indexOf(' ') > 0) { word = "\"" + word + "\""; } // Try to get the definition of the work try { List definitions = conn.define(database, word); msg = this.createMessage(retrieveDefine(definitions, word)); } catch(DictException dx) { if (dx.getErrorCode() == DictReturnCode.NO_MATCH) { // No word found, we are going to try the match command doMatch = true; } else { // Otherwise we display the error returned by the server msg = this.createMessage(manageException(dx, database)); } } if (doMatch) { // Trying the match command try { List matchWords = conn.match(database, word, this.accountID.getStrategy()); msg = this.createMessage(retrieveMatch(matchWords, word)); } catch(DictException dx) { msg = this.createMessage(manageException(dx, database)); } } // Send message fireMessageReceived(msg, dictContact); } /** * Generate the display of the results of the Define command * * @param data the result of the Define command * @param word the queried word * @return the formatted result */ private String retrieveDefine(List data, String word) { StringBuffer res = new StringBuffer(); Definition def; for (int i=0; i 0) { res.append("
"); } res.append(def.getDefinition().replaceAll("\n", "
")) .append("
-- From ") .append(def.getDictionary()) .append("
"); } String result = res.toString(); result = formatResult(result, "\\\\", "", ""); result = formatResult(result, "[\\[\\]]", "", ""); result = formatResult(result, "[\\{\\}]", "", ""); result = formatWordDefined(result, word); return result; } /** * Makes a stronger emphasis for the word defined. * @param result The text containing the definition of the word. * @param word The word defined to display with bold font. For this we * had the strong HTML tag. * @return Returns the result text with an strong emphasis of all * the occurences of the word defined. */ private String formatWordDefined(String result, String word) { String tmpWord; tmpWord = word.toUpperCase(); result = result.replaceAll("\\b" + tmpWord + "\\b", "" + tmpWord + ""); tmpWord = word.toLowerCase(); result = result.replaceAll("\\b" + tmpWord + "\\b", "" + tmpWord + ""); if(tmpWord.length() > 1) { tmpWord = tmpWord.substring(0, 1).toUpperCase() + tmpWord.substring(1); result = result.replaceAll("\\b" + tmpWord + "\\b", "" + tmpWord + ""); } return result; } /** * Remplaces special characters into HTML tags to make some emphasis. * @param result The text containing the definition of the word. * @param regex The special character to replace with HTML tags. * @param startTag The start HTML tag to use. * @param endTag The end HTML tag to use. * @return The result with all special characters replaced by HTML * tags. */ private String formatResult(String result, String regex, String startTag, String endTag) { String[] tmp = result.split(regex); String res = ""; for(int i = 0; i < (tmp.length - 1); i += 2) { res += tmp[i] + startTag + tmp[i+1] + endTag; } if((tmp.length % 2) != 0) { res += tmp[tmp.length - 1]; } return res; } /** * Generate the display of the results of the Match command * * @param data the result of the Match command * @param word the queried word * @return the formatted result */ private String retrieveMatch(List data, String word) { StringBuffer result = new StringBuffer(); boolean isStart = true; result.append(DictActivator.getResources() .getI18NString("plugin.dictaccregwizz.MATCH_RESULT", new String[] {word})); for (int i=0; imessage to the destination indicated by the * to. Resources are not supported by this operation set * implementation. * * @param to the Contact to send message to * @param toResource the resource to which the message should be send * @param message the Message to send. * @throws java.lang.IllegalStateException if the underlying ICQ stack is * not registered and initialized. * @throws java.lang.IllegalArgumentException if to is not an * instance belonging to the underlying implementation. */ @Override public void sendInstantMessage( Contact to, ContactResource toResource, Message message) throws IllegalStateException, IllegalArgumentException { sendInstantMessage(to, message); } }