@Test public void parameters() throws Throwable { // @formatter:off String json = "[\"vcard\"," + "[" + "[\"prop\", { \"a\": \"one\", \"b\": [\"two\"], \"c\": [\"three\", \"four\"] }, \"text\", \"value\"]" + "]" + "]"; // @formatter:on JCardRawReader reader = createReader(json); JCardDataStreamListener listener = mock(JCardDataStreamListener.class); reader.readNext(listener); VCardParameters expected = new VCardParameters(); expected.put("a", "one"); expected.put("b", "two"); expected.put("c", "three"); expected.put("c", "four"); verify(listener).beginVCard(); verify(listener) .readProperty(null, "prop", expected, VCardDataType.TEXT, JCardValue.single("value")); verifyNoMoreInteractions(listener); }
@Test public void prepareParameters() { VCardPropertyScribeImpl m = new VCardPropertyScribeImpl() { @Override protected void _prepareParameters( TestProperty property, VCardParameters copy, VCardVersion version, VCard vcard) { copy.put("PARAM", "value"); } }; TestProperty property = new TestProperty("value"); VCardParameters copy = m.prepareParameters(property, V4_0, new VCard()); assertNotSame(property.getParameters(), copy); assertEquals("value", copy.first("PARAM")); }
private U parseContentType(String value, VCardParameters parameters, VCardVersion version) { switch (version) { case V2_1: case V3_0: // get the TYPE parameter String type = parameters.getType(); if (type != null) { return _mediaTypeFromTypeParameter(type); } break; case V4_0: // get the MEDIATYPE parameter String mediaType = parameters.getMediaType(); if (mediaType != null) { return _mediaTypeFromMediaTypeParameter(mediaType); } break; } // look for a file extension in the property value String extension = getFileExtension(value); return (extension == null) ? null : _mediaTypeFromFileExtension(extension); }
private T parse( String value, VCardDataType dataType, VCardParameters parameters, VCardVersion version, List<String> warnings) { U contentType = parseContentType(value, parameters, version); switch (version) { case V2_1: case V3_0: // parse as URL if (dataType == VCardDataType.URL || dataType == VCardDataType.URI) { return _newInstance(value, contentType); } // parse as binary Encoding encodingSubType = parameters.getEncoding(); if (encodingSubType == Encoding.BASE64 || encodingSubType == Encoding.B) { return _newInstance(Base64.decodeBase64(value), contentType); } break; case V4_0: try { // parse as data URI DataUri uri = new DataUri(value); contentType = _mediaTypeFromMediaTypeParameter(uri.getContentType()); return _newInstance(uri.getData(), contentType); } catch (IllegalArgumentException e) { // not a data URI } break; } return cannotUnmarshalValue(value, version, warnings, contentType); }
/** * Parses the next line of the vCard file. * * @return the next line or null if there are no more lines * @throws InvalidVersionException if a VERSION property with an invalid value is encountered * @throws VCardParseException if a line cannot be parsed * @throws IOException if there's a problem reading from the input stream */ public VCardRawLine readLine() throws IOException { String line = reader.readLine(); if (line == null) { return null; } String group = null; String propertyName = null; VCardParameters parameters = new VCardParameters(); String value = null; char escapeChar = 0; // is the next char escaped? boolean inQuotes = false; // are we inside of double quotes? StringBuilder buffer = new StringBuilder(); String curParamName = null; for (int i = 0; i < line.length(); i++) { char ch = line.charAt(i); if (escapeChar != 0) { // this character was escaped if (escapeChar == '\\') { if (ch == '\\') { buffer.append(ch); } else if (ch == 'n' || ch == 'N') { // newlines appear as "\n" or "\N" (see RFC 2426 p.7) buffer.append(NEWLINE); } else if (ch == '"' && version != VCardVersion.V2_1) { // double quotes don't need to be escaped in 2.1 parameter values because they have no // special meaning buffer.append(ch); } else if (ch == ';' && version == VCardVersion.V2_1) { // semi-colons can only be escaped in 2.1 parameter values (see section 2 of specs) // if a 3.0/4.0 param value has semi-colons, the value should be surrounded in double // quotes buffer.append(ch); } else { // treat the escape character as a normal character because it's not a valid escape // sequence buffer.append(escapeChar).append(ch); } } else if (escapeChar == '^') { if (ch == '^') { buffer.append(ch); } else if (ch == 'n') { buffer.append(NEWLINE); } else if (ch == '\'') { buffer.append('"'); } else { // treat the escape character as a normal character because it's not a valid escape // sequence buffer.append(escapeChar).append(ch); } } escapeChar = 0; continue; } if (ch == '\\' || (ch == '^' && version != VCardVersion.V2_1 && caretDecodingEnabled)) { // an escape character was read escapeChar = ch; continue; } if (ch == '.' && group == null && propertyName == null) { // set the group group = buffer.toString(); buffer.setLength(0); continue; } if ((ch == ';' || ch == ':') && !inQuotes) { if (propertyName == null) { // property name propertyName = buffer.toString(); } else { // parameter value String paramValue = buffer.toString(); if (version == VCardVersion.V2_1) { // 2.1 allows whitespace to surround the "=", so remove it paramValue = StringUtils.ltrim(paramValue); } parameters.put(curParamName, paramValue); curParamName = null; } buffer.setLength(0); if (ch == ':') { // the rest of the line is the property value if (i < line.length() - 1) { value = line.substring(i + 1); } else { value = ""; } break; } continue; } if (ch == ',' && !inQuotes && version != VCardVersion.V2_1) { // multi-valued parameter parameters.put(curParamName, buffer.toString()); buffer.setLength(0); continue; } if (ch == '=' && curParamName == null) { // parameter name String paramName = buffer.toString(); if (version == VCardVersion.V2_1) { // 2.1 allows whitespace to surround the "=", so remove it paramName = StringUtils.rtrim(paramName); } curParamName = paramName; buffer.setLength(0); continue; } if (ch == '"' && version != VCardVersion.V2_1) { // 2.1 doesn't use the quoting mechanism inQuotes = !inQuotes; continue; } buffer.append(ch); } if (propertyName == null || value == null) { throw new VCardParseException(line); } if ("VERSION".equalsIgnoreCase(propertyName)) { VCardVersion version = VCardVersion.valueOfByStr(value); if (version == null) { throw new InvalidVersionException(value, line); } this.version = version; } return new VCardRawLine(group, propertyName, parameters, value); }
@Override protected void _prepareParameters( T property, VCardParameters copy, VCardVersion version, VCard vcard) { MediaTypeParameter contentType = property.getContentType(); if (contentType == null) { contentType = new MediaTypeParameter(null, null, null); } if (property.getUrl() != null) { copy.setEncoding(null); switch (version) { case V2_1: copy.setType(contentType.getValue()); copy.setMediaType(null); break; case V3_0: copy.setType(contentType.getValue()); copy.setMediaType(null); break; case V4_0: copy.setMediaType(contentType.getMediaType()); break; } return; } if (property.getData() != null) { copy.setMediaType(null); switch (version) { case V2_1: copy.setEncoding(Encoding.BASE64); copy.setType(contentType.getValue()); break; case V3_0: copy.setEncoding(Encoding.B); copy.setType(contentType.getValue()); break; case V4_0: copy.setEncoding(null); // don't null out TYPE, it could be set to "home", "work", etc break; } return; } }