mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-12-13 06:21:08 +01:00
Prefix subprojects with 'smack-'
instead of using the old baseName=smack appendix=project.name approach, we are now going convention over configuration and renaming the subprojects directories to the proper name. Having a prefix is actually very helpful, because the resulting libraries will be named like the subproject. And a core-4.0.0-rc1.jar is not as explicit about what it actually *is* as a smack-core-4.0.0-rc1.jar. SMACK-265
This commit is contained in:
parent
b6fb1f3743
commit
91fd15ad86
758 changed files with 42 additions and 42 deletions
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.xhtmlim;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.xhtmlim.packet.XHTMLExtension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages XHTML formatted texts within messages. A XHTMLManager provides a high level access to
|
||||
* get and set XHTML bodies to messages, enable and disable XHTML support and check if remote XMPP
|
||||
* clients support XHTML.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class XHTMLManager {
|
||||
private final static String namespace = "http://jabber.org/protocol/xhtml-im";
|
||||
|
||||
// Enable the XHTML support on every established connection
|
||||
// The ServiceDiscoveryManager class should have been already initialized
|
||||
static {
|
||||
XMPPConnection.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
XHTMLManager.setServiceEnabled(connection, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the XHTML bodies in the message. Returns null if
|
||||
* the message does not contain an XHTML extension.
|
||||
*
|
||||
* @param message an XHTML message
|
||||
* @return an Iterator for the bodies in the message or null if none.
|
||||
*/
|
||||
public static List<String> getBodies(Message message) {
|
||||
XHTMLExtension xhtmlExtension = (XHTMLExtension) message.getExtension("html", namespace);
|
||||
if (xhtmlExtension != null)
|
||||
return xhtmlExtension.getBodies();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an XHTML body to the message.
|
||||
*
|
||||
* @param message the message that will receive the XHTML body
|
||||
* @param body the string to add as an XHTML body to the message
|
||||
*/
|
||||
public static void addBody(Message message, String body) {
|
||||
XHTMLExtension xhtmlExtension = (XHTMLExtension) message.getExtension("html", namespace);
|
||||
if (xhtmlExtension == null) {
|
||||
// Create an XHTMLExtension and add it to the message
|
||||
xhtmlExtension = new XHTMLExtension();
|
||||
message.addExtension(xhtmlExtension);
|
||||
}
|
||||
// Add the required bodies to the message
|
||||
xhtmlExtension.addBody(body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the message contains an XHTML extension.
|
||||
*
|
||||
* @param message the message to check if contains an XHTML extentsion or not
|
||||
* @return a boolean indicating whether the message is an XHTML message
|
||||
*/
|
||||
public static boolean isXHTMLMessage(Message message) {
|
||||
return message.getExtension("html", namespace) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables the XHTML support on a given connection.<p>
|
||||
*
|
||||
* Before starting to send XHTML messages to a user, check that the user can handle XHTML
|
||||
* messages. Enable the XHTML support to indicate that this client handles XHTML messages.
|
||||
*
|
||||
* @param connection the connection where the service will be enabled or disabled
|
||||
* @param enabled indicates if the service will be enabled or disabled
|
||||
*/
|
||||
public synchronized static void setServiceEnabled(XMPPConnection connection, boolean enabled) {
|
||||
if (isServiceEnabled(connection) == enabled)
|
||||
return;
|
||||
|
||||
if (enabled) {
|
||||
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(namespace);
|
||||
}
|
||||
else {
|
||||
ServiceDiscoveryManager.getInstanceFor(connection).removeFeature(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the XHTML support is enabled for the given connection.
|
||||
*
|
||||
* @param connection the connection to look for XHTML support
|
||||
* @return a boolean indicating if the XHTML support is enabled for the given connection
|
||||
*/
|
||||
public static boolean isServiceEnabled(XMPPConnection connection) {
|
||||
return ServiceDiscoveryManager.getInstanceFor(connection).includesFeature(namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified user handles XHTML messages.
|
||||
*
|
||||
* @param connection the connection to use to perform the service discovery
|
||||
* @param userID the user to check. A fully qualified xmpp ID, e.g. jdoe@example.com
|
||||
* @return a boolean indicating whether the specified user handles XHTML messages
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
*/
|
||||
public static boolean isServiceEnabled(XMPPConnection connection, String userID)
|
||||
throws NoResponseException, XMPPErrorException, NotConnectedException {
|
||||
return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(userID, namespace);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,428 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.xhtmlim;
|
||||
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
/**
|
||||
* An XHTMLText represents formatted text. This class also helps to build valid
|
||||
* XHTML tags.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class XHTMLText {
|
||||
|
||||
private static final String NAMESPACE = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
private StringBuilder text = new StringBuilder(30);
|
||||
|
||||
/**
|
||||
* Creates a new XHTMLText with body tag params.
|
||||
*
|
||||
* @param style the XHTML style of the body
|
||||
* @param lang the language of the body
|
||||
*/
|
||||
public XHTMLText(String style, String lang) {
|
||||
appendOpenBodyTag(style, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an anchor section begins.
|
||||
*
|
||||
* @param href indicates the URL being linked to
|
||||
* @param style the XHTML style of the anchor
|
||||
*/
|
||||
public void appendOpenAnchorTag(String href, String style) {
|
||||
StringBuilder sb = new StringBuilder("<a");
|
||||
if (href != null) {
|
||||
sb.append(" href=\"");
|
||||
sb.append(href);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an anchor section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseAnchorTag() {
|
||||
text.append("</a>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a blockquote section begins.
|
||||
*
|
||||
* @param style the XHTML style of the blockquote
|
||||
*/
|
||||
public void appendOpenBlockQuoteTag(String style) {
|
||||
StringBuilder sb = new StringBuilder("<blockquote");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a blockquote section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseBlockQuoteTag() {
|
||||
text.append("</blockquote>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a body section begins.
|
||||
*
|
||||
* @param style the XHTML style of the body
|
||||
* @param lang the language of the body
|
||||
*/
|
||||
private void appendOpenBodyTag(String style, String lang) {
|
||||
StringBuilder sb = new StringBuilder("<body xmlns=\"" + NAMESPACE + "\"");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (lang != null) {
|
||||
sb.append(" xml:lang=\"");
|
||||
sb.append(lang);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a body section ends.
|
||||
*
|
||||
*/
|
||||
private String closeBodyTag() {
|
||||
return "</body>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that inserts a single carriage return.
|
||||
*
|
||||
*/
|
||||
public void appendBrTag() {
|
||||
text.append("<br/>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates a reference to work, such as a book, report or web site.
|
||||
*
|
||||
*/
|
||||
public void appendOpenCiteTag() {
|
||||
text.append("<cite>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates text that is the code for a program.
|
||||
*
|
||||
*/
|
||||
public void appendOpenCodeTag() {
|
||||
text.append("<code>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates end of text that is the code for a program.
|
||||
*
|
||||
*/
|
||||
public void appendCloseCodeTag() {
|
||||
text.append("</code>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates emphasis.
|
||||
*
|
||||
*/
|
||||
public void appendOpenEmTag() {
|
||||
text.append("<em>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates end of emphasis.
|
||||
*
|
||||
*/
|
||||
public void appendCloseEmTag() {
|
||||
text.append("</em>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates a header, a title of a section of the message.
|
||||
*
|
||||
* @param level the level of the Header. It should be a value between 1 and 3
|
||||
* @param style the XHTML style of the blockquote
|
||||
*/
|
||||
public void appendOpenHeaderTag(int level, String style) {
|
||||
if (level > 3 || level < 1) {
|
||||
return;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder("<h");
|
||||
sb.append(level);
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a header section ends.
|
||||
*
|
||||
* @param level the level of the Header. It should be a value between 1 and 3
|
||||
*/
|
||||
public void appendCloseHeaderTag(int level) {
|
||||
if (level > 3 || level < 1) {
|
||||
return;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder("</h");
|
||||
sb.append(level);
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates an image.
|
||||
*
|
||||
* @param align how text should flow around the picture
|
||||
* @param alt the text to show if you don't show the picture
|
||||
* @param height how tall is the picture
|
||||
* @param src where to get the picture
|
||||
* @param width how wide is the picture
|
||||
*/
|
||||
public void appendImageTag(String align, String alt, String height, String src, String width) {
|
||||
StringBuilder sb = new StringBuilder("<img");
|
||||
if (align != null) {
|
||||
sb.append(" align=\"");
|
||||
sb.append(align);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (alt != null) {
|
||||
sb.append(" alt=\"");
|
||||
sb.append(alt);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (height != null) {
|
||||
sb.append(" height=\"");
|
||||
sb.append(height);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (src != null) {
|
||||
sb.append(" src=\"");
|
||||
sb.append(src);
|
||||
sb.append("\"");
|
||||
}
|
||||
if (width != null) {
|
||||
sb.append(" width=\"");
|
||||
sb.append(width);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates the start of a new line item within a list.
|
||||
*
|
||||
* @param style the style of the line item
|
||||
*/
|
||||
public void appendLineItemTag(String style) {
|
||||
StringBuilder sb = new StringBuilder("<li");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that creates an ordered list. "Ordered" means that the order of the items
|
||||
* in the list is important. To show this, browsers automatically number the list.
|
||||
*
|
||||
* @param style the style of the ordered list
|
||||
*/
|
||||
public void appendOpenOrderedListTag(String style) {
|
||||
StringBuilder sb = new StringBuilder("<ol");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an ordered list section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseOrderedListTag() {
|
||||
text.append("</ol>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that creates an unordered list. The unordered part means that the items
|
||||
* in the list are not in any particular order.
|
||||
*
|
||||
* @param style the style of the unordered list
|
||||
*/
|
||||
public void appendOpenUnorderedListTag(String style) {
|
||||
StringBuilder sb = new StringBuilder("<ul");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an unordered list section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseUnorderedListTag() {
|
||||
text.append("</ul>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates the start of a new paragraph. This is usually rendered
|
||||
* with two carriage returns, producing a single blank line in between the two paragraphs.
|
||||
*
|
||||
* @param style the style of the paragraph
|
||||
*/
|
||||
public void appendOpenParagraphTag(String style) {
|
||||
StringBuilder sb = new StringBuilder("<p");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates the end of a new paragraph. This is usually rendered
|
||||
* with two carriage returns, producing a single blank line in between the two paragraphs.
|
||||
*
|
||||
*/
|
||||
public void appendCloseParagraphTag() {
|
||||
text.append("</p>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an inlined quote section begins.
|
||||
*
|
||||
* @param style the style of the inlined quote
|
||||
*/
|
||||
public void appendOpenInlinedQuoteTag(String style) {
|
||||
StringBuilder sb = new StringBuilder("<q");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that an inlined quote section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseInlinedQuoteTag() {
|
||||
text.append("</q>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that allows to set the fonts for a span of text.
|
||||
*
|
||||
* @param style the style for a span of text
|
||||
*/
|
||||
public void appendOpenSpanTag(String style) {
|
||||
StringBuilder sb = new StringBuilder("<span");
|
||||
if (style != null) {
|
||||
sb.append(" style=\"");
|
||||
sb.append(style);
|
||||
sb.append("\"");
|
||||
}
|
||||
sb.append(">");
|
||||
text.append(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a span section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseSpanTag() {
|
||||
text.append("</span>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates text which should be more forceful than surrounding text.
|
||||
*
|
||||
*/
|
||||
public void appendOpenStrongTag() {
|
||||
text.append("<strong>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a tag that indicates that a strong section ends.
|
||||
*
|
||||
*/
|
||||
public void appendCloseStrongTag() {
|
||||
text.append("</strong>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a given text to the XHTMLText.
|
||||
*
|
||||
* @param textToAppend the text to append
|
||||
*/
|
||||
public void append(String textToAppend) {
|
||||
text.append(StringUtils.escapeForXML(textToAppend));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text of the XHTMLText.
|
||||
*
|
||||
* Note: Automatically adds the closing body tag.
|
||||
*
|
||||
* @return the text of the XHTMLText
|
||||
*/
|
||||
public String toString() {
|
||||
return text.toString().concat(closeBodyTag());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smackx.xhtmlim.packet;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An XHTML sub-packet, which is used by XMPP clients to exchange formatted text. The XHTML
|
||||
* extension is only a subset of XHTML 1.0.<p>
|
||||
*
|
||||
* The following link summarizes the requirements of XHTML IM:
|
||||
* <a href="http://www.jabber.org/jeps/jep-0071.html#sect-id2598018">Valid tags</a>.<p>
|
||||
*
|
||||
* Warning: this is an non-standard protocol documented by
|
||||
* <a href="http://www.jabber.org/jeps/jep-0071.html">JEP-71</a>. Because this is a
|
||||
* non-standard protocol, it is subject to change.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class XHTMLExtension implements PacketExtension {
|
||||
|
||||
private List<String> bodies = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Returns the XML element name of the extension sub-packet root element.
|
||||
* Always returns "html"
|
||||
*
|
||||
* @return the XML element name of the packet extension.
|
||||
*/
|
||||
public String getElementName() {
|
||||
return "html";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML namespace of the extension sub-packet root element.
|
||||
* According the specification the namespace is always "http://jabber.org/protocol/xhtml-im"
|
||||
*
|
||||
* @return the XML namespace of the packet extension.
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return "http://jabber.org/protocol/xhtml-im";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML representation of a XHTML extension according the specification.
|
||||
*
|
||||
* Usually the XML representation will be inside of a Message XML representation like
|
||||
* in the following example:
|
||||
* <pre>
|
||||
* <message id="MlIpV-4" to="gato1@gato.home" from="gato3@gato.home/Smack">
|
||||
* <subject>Any subject you want</subject>
|
||||
* <body>This message contains something interesting.</body>
|
||||
* <html xmlns="http://jabber.org/protocol/xhtml-im">
|
||||
* <body><p style='font-size:large'>This message contains something <em>interesting</em>.</p></body>
|
||||
* </html>
|
||||
* </message>
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public String toXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
|
||||
"\">");
|
||||
// Loop through all the bodies and append them to the string buffer
|
||||
for (String body : getBodies()) {
|
||||
buf.append(body);
|
||||
}
|
||||
buf.append("</").append(getElementName()).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a List of the bodies in the packet.
|
||||
*
|
||||
* @return a List of the bodies in the packet.
|
||||
*/
|
||||
public List<String> getBodies() {
|
||||
synchronized (bodies) {
|
||||
return Collections.unmodifiableList(new ArrayList<String>(bodies));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a body to the packet.
|
||||
*
|
||||
* @param body the body to add.
|
||||
*/
|
||||
public void addBody(String body) {
|
||||
synchronized (bodies) {
|
||||
bodies.add(body);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a count of the bodies in the XHTML packet.
|
||||
*
|
||||
* @return the number of bodies in the XHTML packet.
|
||||
*/
|
||||
public int getBodiesCount() {
|
||||
return bodies.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software, 2014 Vyacheslav Blinov
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.xhtmlim.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smackx.xhtmlim.packet.XHTMLExtension;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The XHTMLExtensionProvider parses XHTML packets.
|
||||
*
|
||||
* @author Vyacheslav Blinov
|
||||
*/
|
||||
public class XHTMLExtensionProvider implements PacketExtensionProvider {
|
||||
public static final String BODY_ELEMENT = "body";
|
||||
|
||||
@Override
|
||||
public PacketExtension parseExtension(XmlPullParser parser) throws IOException, XmlPullParserException {
|
||||
XHTMLExtension xhtmlExtension = new XHTMLExtension();
|
||||
final String XHTML_EXTENSION_ELEMENT_NAME = xhtmlExtension.getElementName();
|
||||
|
||||
int startDepth = parser.getDepth();
|
||||
int tagDepth = parser.getDepth();
|
||||
boolean tagStarted = false;
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
while (true) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
boolean appendNamespace = false;
|
||||
if (BODY_ELEMENT.equals(parser.getName())) {
|
||||
buffer = new StringBuilder();
|
||||
tagDepth = parser.getDepth();
|
||||
appendNamespace = true;
|
||||
}
|
||||
maybeCloseTag(tagStarted, buffer);
|
||||
appendStartTagPartial(buffer, parser, appendNamespace);
|
||||
tagStarted = true;
|
||||
} else if (eventType == XmlPullParser.TEXT) {
|
||||
tagStarted = maybeCloseTag(tagStarted, buffer);
|
||||
appendText(buffer, parser);
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
String name = parser.getName();
|
||||
if (XHTML_EXTENSION_ELEMENT_NAME.equals(name) && parser.getDepth() <= startDepth) {
|
||||
return xhtmlExtension;
|
||||
} else {
|
||||
// xpp does not allows us to detect if tag is self-closing, so we have to
|
||||
// handle self-closing tags by our own means
|
||||
appendEndTag(buffer, parser, tagStarted);
|
||||
tagStarted = false;
|
||||
if (BODY_ELEMENT.equals(name) && parser.getDepth() <= tagDepth) {
|
||||
xhtmlExtension.addBody(buffer.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendStartTagPartial(StringBuilder builder, XmlPullParser parser, boolean withNamespace) {
|
||||
builder.append('<');
|
||||
|
||||
String prefix = parser.getPrefix();
|
||||
if (StringUtils.isNotEmpty(prefix)) {
|
||||
builder.append(prefix).append(':');
|
||||
}
|
||||
builder.append(parser.getName());
|
||||
|
||||
int attributesCount = parser.getAttributeCount();
|
||||
// handle namespace
|
||||
if (withNamespace) {
|
||||
String namespace = parser.getNamespace();
|
||||
if (StringUtils.isNotEmpty(namespace)) {
|
||||
builder.append(" xmlns='").append(namespace).append('\'');
|
||||
}
|
||||
}
|
||||
// handle attributes
|
||||
for (int i = 0; i < attributesCount; ++i) {
|
||||
builder.append(' ');
|
||||
String attributeNamespace = parser.getAttributeNamespace(i);
|
||||
if (StringUtils.isNotEmpty(attributeNamespace)) {
|
||||
builder.append(attributeNamespace).append(':');
|
||||
}
|
||||
builder.append(parser.getAttributeName(i));
|
||||
String value = parser.getAttributeValue(i);
|
||||
if (value != null) {
|
||||
// We need to return valid XML so any inner text needs to be re-escaped
|
||||
builder.append("='").append(StringUtils.escapeForXML(value)).append('\'');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void appendEndTag(StringBuilder builder, XmlPullParser parser, boolean tagStarted) {
|
||||
if (tagStarted) {
|
||||
builder.append("/>");
|
||||
} else {
|
||||
builder.append("</").append(parser.getName()).append('>');
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean appendText(StringBuilder builder, XmlPullParser parser) {
|
||||
String text = parser.getText();
|
||||
if (text == null) {
|
||||
return false;
|
||||
} else {
|
||||
// We need to return valid XML so any inner text needs to be re-escaped
|
||||
builder.append(StringUtils.escapeForXML(parser.getText()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean maybeCloseTag(boolean tagStarted, StringBuilder builder) {
|
||||
if (tagStarted) {
|
||||
builder.append('>');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue