This modification fixes issues w.r.t. message caused by loss of styling
due to opening/closing <plaintext> tags. Additionally it simplifies
html / plain text message handling and text replacement.
Implemented a different approach to ChatMessage processing. This new
implementation strictly watches for the moment when a chat message
(possibly HTML already, but might also be plain text) is definitely
converted into HTML. This happens when certain processing steps are
taken.
As soon as these processing steps are taken, the approach changes into
HTML by default and every piece of text that still is plain text will be
HTML-escaped. Just before appending the new text message to the (HTML)
chat document, we always have HTML "text" and as soon as a processing
step is used of which we know that it definitely converts to HTML, we
start using the HTML content type. This also means that on a number of
occasions we have removed the contentType parameter, since we already
know or have this information.
Since we now know for sure that from a certain moment on, we are
strictly dealing with HTML "text" and we also know that everything plain
text will be HTML-escaped, we can adopt a different plain text search
pattern (TEXT_TO_REPLACE_PATTERN). This search approach searches for all
text in between lesser than (<) and greater than (>) signs, since we can
be sure that that is normal (escaped) text. We unescape these pieces of
text before running through the replacement services such that they can
behave as they always have. This shouldn't break (much of) the
Replacement Services implementations.
Also check and tag hyperlinks for HTML messages.
Added dependency to Apache Commons Lang to swing-ui.
Removed option skipSmiley. It is not needed anymore, now that hyperlink
hrefs aren't found anymore.
In the "Add chat room" dialog there's no default operation when you
press ENTER in one of the input fields. From now on pressing ENTER
will default to the "Join" button if it is enabled.
This comparator's general contract is broken for the case where both
node1 and node2 have negative source indexes. In that case the returned
results are:
- (node1, node2) => -1
- (node2, node1) => -1
which is not symmetric, as is expected by the Comparator interface.
This is noticed by the TimSort implementation when sorting:
12:59:34.108 SEVERE: [38] util.UtilActivator.uncaughtException().108 An uncaught exception occurred in thread=Thread[AWT-EventQueue-0,6,main] and message was: Comparison method violates its general contract! java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:868)
at java.util.TimSort.mergeAt(TimSort.java:485)
at java.util.TimSort.mergeCollapse(TimSort.java:410)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
at net.java.sip.communicator.impl.gui.main.contactlist.GroupNode$1.run(GroupNode.java:323)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
This proposition tries to distinguish between two nodes by comparing
their hashCode value. This is kind of a work around, however, since this
is already a special case it should not matter that much. Since the
hashCode is a comparable value we can ensure that we make a consistent,
symmetric choice every time. Thus enforcing the contract.
listing.
Previously chat rooms were inserted one by one into the result and
listeners were informed for each of the chat rooms immediately after it
was inserted, and on top of that we reorder after each insertion. All in
all this caused very unpredictable results.
The modification massively inserts the whole result set and then fires a
listener event for each of the added chat rooms.