/** * Parse a properties sub-packet. If any errors occur while de-serializing Java object properties, * an exception will be printed and not thrown since a thrown exception will shut down the entire * connection. ClassCastExceptions will occur when both the sender and receiver of the packet * don't have identical versions of the same class. * * @param parser the XML parser, positioned at the start of a properties sub-packet. * @return a map of the properties. * @throws Exception if an error occurs while parsing the properties. */ public static Map<String, Object> parseProperties(XmlPullParser parser) throws Exception { Map<String, Object> properties = new HashMap<String, Object>(); while (true) { int eventType = parser.next(); if (eventType == XmlPullParser.START_TAG && parser.getName().equals("property")) { // Parse a property boolean done = false; String name = null; String type = null; String valueText = null; Object value = null; while (!done) { eventType = parser.next(); if (eventType == XmlPullParser.START_TAG) { String elementName = parser.getName(); if (elementName.equals("name")) { name = parser.nextText(); } else if (elementName.equals("value")) { type = parser.getAttributeValue("", "type"); valueText = parser.nextText(); } } else if (eventType == XmlPullParser.END_TAG) { if (parser.getName().equals("property")) { if ("integer".equals(type)) { value = Integer.valueOf(valueText); } else if ("long".equals(type)) { value = Long.valueOf(valueText); } else if ("float".equals(type)) { value = Float.valueOf(valueText); } else if ("double".equals(type)) { value = Double.valueOf(valueText); } else if ("boolean".equals(type)) { value = Boolean.valueOf(valueText); } else if ("string".equals(type)) { value = valueText; } else if ("java-object".equals(type)) { try { byte[] bytes = StringUtils.decodeBase64(valueText); ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes)); value = in.readObject(); } catch (Exception e) { LOGGER.log(Level.SEVERE, "", e); } } if (name != null && value != null) { properties.put(name, value); } done = true; } } } } else if (eventType == XmlPullParser.END_TAG) { if (parser.getName().equals("properties")) { break; } } } return properties; }
@Override protected void printContent(StringBuilder xml) { List<PayloadTypePacketExtension> payloadTypes = getPayloadTypes(); List<SourcePacketExtension> sources = getSources(); int[] ssrcs = getSSRCs(); for (PayloadTypePacketExtension payloadType : payloadTypes) xml.append(payloadType.toXML()); for (SourcePacketExtension source : sources) xml.append(source.toXML()); for (int i = 0; i < ssrcs.length; i++) { xml.append('<') .append(SSRC_ELEMENT_NAME) .append('>') .append(Long.toString(ssrcs[i] & 0xFFFFFFFFL)) .append("</") .append(SSRC_ELEMENT_NAME) .append('>'); } }
/** * Decodes a String into an object of the specified type. If the object type is not supported, * null will be returned. * * @param type the type of the property. * @param value the encode String value to decode. * @return the String value decoded into the specified type. * @throws Exception If decoding failed due to an error. */ private static Object decode(Class type, String value) throws Exception { if (type.getName().equals("java.lang.String")) { return value; } if (type.getName().equals("boolean")) { return Boolean.valueOf(value); } if (type.getName().equals("int")) { return Integer.valueOf(value); } if (type.getName().equals("long")) { return Long.valueOf(value); } if (type.getName().equals("float")) { return Float.valueOf(value); } if (type.getName().equals("double")) { return Double.valueOf(value); } if (type.getName().equals("java.lang.Class")) { return Class.forName(value); } return null; }
/** * Parses the given <tt>parser</tt> in order to create a <tt>FileElement</tt> from it. * * @param parser the parser to parse * @see IQProvider#parseIQ(XmlPullParser) */ public IQ parseIQ(final XmlPullParser parser) throws Exception { boolean done = false; // si String id = parser.getAttributeValue("", "id"); String mimeType = parser.getAttributeValue("", "mime-type"); StreamInitiation initiation = new StreamInitiation(); // file String name = null; String size = null; String hash = null; String date = null; String desc = null; ThumbnailElement thumbnail = null; boolean isRanged = false; // feature DataForm form = null; DataFormProvider dataFormProvider = new DataFormProvider(); int eventType; String elementName; String namespace; while (!done) { eventType = parser.next(); elementName = parser.getName(); namespace = parser.getNamespace(); if (eventType == XmlPullParser.START_TAG) { if (elementName.equals("file")) { name = parser.getAttributeValue("", "name"); size = parser.getAttributeValue("", "size"); hash = parser.getAttributeValue("", "hash"); date = parser.getAttributeValue("", "date"); } else if (elementName.equals("desc")) { desc = parser.nextText(); } else if (elementName.equals("range")) { isRanged = true; } else if (elementName.equals("x") && namespace.equals("jabber:x:data")) { form = (DataForm) dataFormProvider.parseExtension(parser); } else if (elementName.equals("thumbnail")) { thumbnail = new ThumbnailElement(parser.getText()); } } else if (eventType == XmlPullParser.END_TAG) { if (elementName.equals("si")) { done = true; } // The name-attribute is required per XEP-0096, so ignore the // IQ if the name is not set to avoid exceptions. Particularly, // the SI response of Empathy contains an invalid, empty // file-tag. else if (elementName.equals("file") && name != null) { long fileSize = 0; if (size != null && size.trim().length() != 0) { try { fileSize = Long.parseLong(size); } catch (NumberFormatException e) { logger.warn( "Received an invalid file size," + " continuing with fileSize set to 0", e); } } FileElement file = new FileElement(name, fileSize); file.setHash(hash); if (date != null) { // try all known date formats boolean found = false; if (date.matches(".*?T\\d+:\\d+:\\d+(\\.\\d+)?(\\+|-)\\d+:\\d+")) { int timeZoneColon = date.lastIndexOf(":"); date = date.substring(0, timeZoneColon) + date.substring(timeZoneColon + 1, date.length()); } for (DateFormat fmt : DATE_FORMATS) { try { file.setDate(fmt.parse(date)); found = true; break; } catch (ParseException ex) { } } if (!found) { logger.warn("Unknown dateformat on incoming file transfer: " + date); } } if (thumbnail != null) file.setThumbnailElement(thumbnail); file.setDesc(desc); file.setRanged(isRanged); initiation.setFile(file); } } } initiation.setSesssionID(id); initiation.setMimeType(mimeType); initiation.setFeatureNegotiationForm(form); return initiation; }
/** * Returns the next unique thread id. Each thread id made up of a short alphanumeric prefix along * with a unique numeric value. * * @return the next thread id. */ public static synchronized String nextThreadID() { return prefix + Long.toString(id++); }