use of com.github.mangstadt.vinnie.VObjectProperty in project vinnie by mangstadt.
the class VObjectReaderTest method vcard_rules.
@Test
public void vcard_rules() throws Exception {
// @formatter:off
String string = "BEGIN:VCARD\r\n" + "PROP;PARAM=\"value\":\r\n" + "END:VCARD\r\n" + "BEGIN:VCARD\r\n" + "VERSION:10\r\n" + "PROP;PARAM=\"value\":\r\n" + "END:VCARD\r\n" + "BEGIN:VCARD\r\n" + "VERSION:2.1\r\n" + "PROP;PARAM=\"value\":\r\n" + "END:VCARD\r\n" + "BEGIN:VCARD\r\n" + "VERSION:3.0\r\n" + "PROP;PARAM=\"value\":\r\n" + "END:VCARD\r\n" + "BEGIN:VCARD\r\n" + "VERSION:4.0\r\n" + "PROP;PARAM=\"value\":\r\n" + "END:VCARD";
// @formatter:on
VObjectReader reader = new VObjectReader(new StringReader(string), SyntaxRules.vcard());
VObjectDataListenerMock listener = spy(new VObjectDataListenerMock());
reader.parse(listener);
VObjectProperty oldStyleProp = property().name("PROP").param("PARAM", "\"value\"").value("").build();
VObjectProperty newStyleProp = property().name("PROP").param("PARAM", "value").value("").build();
InOrder inorder = inOrder(listener);
// @formatter:off
inorder.verify(listener).onComponentBegin(eq("VCARD"), any(Context.class));
inorder.verify(listener).onProperty(eq(oldStyleProp), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("VCARD"), any(Context.class));
inorder.verify(listener).onComponentBegin(eq("VCARD"), any(Context.class));
inorder.verify(listener).onWarning(eq(Warning.UNKNOWN_VERSION), eq(property().name("VERSION").value("10").build()), isNull(Exception.class), any(Context.class));
inorder.verify(listener).onProperty(eq(property().name("VERSION").value("10").build()), any(Context.class));
inorder.verify(listener).onProperty(eq(oldStyleProp), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("VCARD"), any(Context.class));
inorder.verify(listener).onComponentBegin(eq("VCARD"), any(Context.class));
inorder.verify(listener).onVersion(eq("2.1"), any(Context.class));
inorder.verify(listener).onProperty(eq(oldStyleProp), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("VCARD"), any(Context.class));
inorder.verify(listener).onComponentBegin(eq("VCARD"), any(Context.class));
inorder.verify(listener).onVersion(eq("3.0"), any(Context.class));
inorder.verify(listener).onProperty(eq(newStyleProp), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("VCARD"), any(Context.class));
inorder.verify(listener).onComponentBegin(eq("VCARD"), any(Context.class));
inorder.verify(listener).onVersion(eq("4.0"), any(Context.class));
inorder.verify(listener).onProperty(eq(newStyleProp), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("VCARD"), any(Context.class));
// @formatter:on
// @formatter:off
String[] lines = string.split("\r\n");
int line = 0;
assertContexts(listener, context(lines[line], ++line), context(asList("VCARD"), lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(asList("VCARD"), lines[line], line + 1), context(asList("VCARD"), lines[line], ++line), context(asList("VCARD"), lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(asList("VCARD"), lines[line], ++line), context(asList("VCARD"), lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(asList("VCARD"), lines[line], ++line), context(asList("VCARD"), lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(asList("VCARD"), lines[line], ++line), context(asList("VCARD"), lines[line], ++line), context(lines[line], ++line));
// @formatter:on
}
use of com.github.mangstadt.vinnie.VObjectProperty in project vinnie by mangstadt.
the class VObjectReaderTest method icalendar_rules.
@Test
public void icalendar_rules() throws Exception {
// @formatter:off
String string = "BEGIN:VCALENDAR\r\n" + "PROP;PARAM=\"value\":\r\n" + "END:VCALENDAR\r\n" + "BEGIN:VCALENDAR\r\n" + "VERSION:10\r\n" + "PROP;PARAM=\"value\":\r\n" + "END:VCALENDAR\r\n" + "BEGIN:VCALENDAR\r\n" + "VERSION:1.0\r\n" + "PROP;PARAM=\"value\":\r\n" + "END:VCALENDAR\r\n" + "BEGIN:VCALENDAR\r\n" + "VERSION:2.0\r\n" + "PROP;PARAM=\"value\":\r\n" + "END:VCALENDAR\r\n";
// @formatter:on
VObjectReader reader = new VObjectReader(new StringReader(string), SyntaxRules.iCalendar());
VObjectDataListenerMock listener = spy(new VObjectDataListenerMock());
reader.parse(listener);
VObjectProperty oldStyleProp = property().name("PROP").param("PARAM", "\"value\"").value("").build();
VObjectProperty newStyleProp = property().name("PROP").param("PARAM", "value").value("").build();
InOrder inorder = inOrder(listener);
// @formatter:off
inorder.verify(listener).onComponentBegin(eq("VCALENDAR"), any(Context.class));
inorder.verify(listener).onProperty(eq(oldStyleProp), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("VCALENDAR"), any(Context.class));
inorder.verify(listener).onComponentBegin(eq("VCALENDAR"), any(Context.class));
inorder.verify(listener).onWarning(eq(Warning.UNKNOWN_VERSION), eq(property().name("VERSION").value("10").build()), isNull(Exception.class), any(Context.class));
inorder.verify(listener).onProperty(eq(property().name("VERSION").value("10").build()), any(Context.class));
inorder.verify(listener).onProperty(eq(oldStyleProp), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("VCALENDAR"), any(Context.class));
inorder.verify(listener).onComponentBegin(eq("VCALENDAR"), any(Context.class));
inorder.verify(listener).onVersion(eq("1.0"), any(Context.class));
inorder.verify(listener).onProperty(eq(oldStyleProp), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("VCALENDAR"), any(Context.class));
inorder.verify(listener).onComponentBegin(eq("VCALENDAR"), any(Context.class));
inorder.verify(listener).onVersion(eq("2.0"), any(Context.class));
inorder.verify(listener).onProperty(eq(newStyleProp), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("VCALENDAR"), any(Context.class));
// @formatter:on
// @formatter:off
String[] lines = string.split("\r\n");
int line = 0;
assertContexts(listener, context(lines[line], ++line), context(asList("VCALENDAR"), lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(asList("VCALENDAR"), lines[line], line + 1), context(asList("VCALENDAR"), lines[line], ++line), context(asList("VCALENDAR"), lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(asList("VCALENDAR"), lines[line], ++line), context(asList("VCALENDAR"), lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(asList("VCALENDAR"), lines[line], ++line), context(asList("VCALENDAR"), lines[line], ++line), context(lines[line], ++line));
// @formatter:on
}
use of com.github.mangstadt.vinnie.VObjectProperty in project vinnie by mangstadt.
the class VObjectReaderTest method quoted_printable.
/**
* Tests quoted-printable encoding.
*/
@Test
public void quoted_printable() throws Exception {
// @formatter:off
String string = "PROP;QUOTED-PRINTABLE:one=0D=0Atwo\r\n" + "PROP;quoted-printable:one=0D=0Atwo\r\n" + "PROP;ENCODING=QUOTED-PRINTABLE:one=0D=0Atwo\r\n" + "PROP;ENCODING=quoted-printable:one=0D=0Atwo\r\n" + "PROP;ENCODING=QUOTED-PRINTABLE:=XX\r\n" + "PROP;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:one=0D=0Atwo\r\n" + "PROP;ENCODING=QUOTED-PRINTABLE;CHARSET=invalid:one=0D=0Atwo\r\n" + "PROP;ENCODING=QUOTED-PRINTABLE;CHARSET=illegal name:one=0D=0Atwo";
for (SyntaxStyle style : SyntaxStyle.values()) {
VObjectReader reader = reader(string, style);
VObjectDataListenerMock listener = spy(new VObjectDataListenerMock());
reader.parse(listener);
InOrder inorder = inOrder(listener);
inorder.verify(listener).onProperty(eq(property().name("PROP").param(null, "QUOTED-PRINTABLE").value("one\r\ntwo").build()), any(Context.class));
inorder.verify(listener).onProperty(eq(property().name("PROP").param(null, "quoted-printable").value("one\r\ntwo").build()), any(Context.class));
inorder.verify(listener).onProperty(eq(property().name("PROP").param("ENCODING", "QUOTED-PRINTABLE").value("one\r\ntwo").build()), any(Context.class));
inorder.verify(listener).onProperty(eq(property().name("PROP").param("ENCODING", "quoted-printable").value("one\r\ntwo").build()), any(Context.class));
VObjectProperty errorDecoding = property().name("PROP").param("ENCODING", "QUOTED-PRINTABLE").value("=XX").build();
inorder.verify(listener).onWarning(eq(Warning.QUOTED_PRINTABLE_ERROR), eq(errorDecoding), any(DecoderException.class), any(Context.class));
inorder.verify(listener).onProperty(eq(errorDecoding), any(Context.class));
inorder.verify(listener).onProperty(eq(property().name("PROP").param("ENCODING", "QUOTED-PRINTABLE").param("CHARSET", "UTF-8").value("one\r\ntwo").build()), any(Context.class));
VObjectProperty invalidCharset = property().name("PROP").param("ENCODING", "QUOTED-PRINTABLE").param("CHARSET", "invalid").value("one\r\ntwo").build();
inorder.verify(listener).onWarning(eq(Warning.UNKNOWN_CHARSET), eq(invalidCharset), any(UnsupportedCharsetException.class), any(Context.class));
inorder.verify(listener).onProperty(eq(invalidCharset), any(Context.class));
VObjectProperty illegalName = property().name("PROP").param("ENCODING", "QUOTED-PRINTABLE").param("CHARSET", "illegal name").value("one\r\ntwo").build();
inorder.verify(listener).onWarning(eq(Warning.UNKNOWN_CHARSET), eq(illegalName), any(IllegalCharsetNameException.class), any(Context.class));
inorder.verify(listener).onProperty(eq(illegalName), any(Context.class));
// @formatter:off
String[] lines = string.split("\r\n");
int line = 0;
assertContexts(listener, context(lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(lines[line], line + 1), context(lines[line], ++line), context(lines[line], ++line), context(lines[line], line + 1), context(lines[line], ++line), context(lines[line], line + 1), context(lines[line], ++line));
// @formatter:on
}
}
use of com.github.mangstadt.vinnie.VObjectProperty in project vinnie by mangstadt.
the class VObjectReaderTest method pause_parsing.
@Test
public void pause_parsing() throws Exception {
// @formatter:off
String string = "BEGIN:COMP1\r\n" + "PROP:value\r\n" + "END:COMP1\r\n" + "BEGIN:COMP2\r\n" + "PROP:value\r\n" + "END:COMP2\r\n" + "PROP2:value\r\n" + "PROP:value";
for (SyntaxStyle style : SyntaxStyle.values()) {
VObjectReader reader = reader(string, style);
VObjectDataListenerMock listener = spy(new VObjectDataListenerMock() {
@Override
public void onComponentBegin(String name, Context context) {
super.onComponentBegin(name, context);
if (name.equals("COMP1")) {
context.stop();
}
}
@Override
public void onComponentEnd(String name, Context context) {
super.onComponentEnd(name, context);
if (name.equals("COMP2")) {
context.stop();
}
}
@Override
public void onProperty(VObjectProperty property, Context context) {
super.onProperty(property, context);
if (property.getName().equals("PROP2")) {
context.stop();
}
}
});
InOrder inorder = inOrder(listener);
reader.parse(listener);
inorder.verify(listener).onComponentBegin(eq("COMP1"), any(Context.class));
inorder.verifyNoMoreInteractions();
reader.parse(listener);
inorder.verify(listener).onProperty(eq(property().name("PROP").value("value").build()), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("COMP1"), any(Context.class));
inorder.verify(listener).onComponentBegin(eq("COMP2"), any(Context.class));
inorder.verify(listener).onProperty(eq(property().name("PROP").value("value").build()), any(Context.class));
inorder.verify(listener).onComponentEnd(eq("COMP2"), any(Context.class));
inorder.verifyNoMoreInteractions();
reader.parse(listener);
inorder.verify(listener).onProperty(eq(property().name("PROP2").value("value").build()), any(Context.class));
inorder.verifyNoMoreInteractions();
reader.parse(listener);
inorder.verify(listener).onProperty(eq(property().name("PROP").value("value").build()), any(Context.class));
inorder.verifyNoMoreInteractions();
// @formatter:off
String[] lines = string.split("\r\n");
int line = 0;
assertContexts(listener, context(lines[line], ++line), context(asList("COMP1"), lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(asList("COMP2"), lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line), context(lines[line], ++line));
// @formatter:on
}
}
use of com.github.mangstadt.vinnie.VObjectProperty in project vinnie by mangstadt.
the class VObjectReader method parse.
/**
* <p>
* Starts or continues to parse the data off the input stream.
* </p>
* <p>
* This method blocks until one of the following events happen:
* </p>
* <ol>
* <li>The end of the input stream has been reached or</li>
* <li>One of the methods in the given {@link VObjectDataListener}
* implementation has invoked {@link Context#stop()}.</li>
* </ol>
* @param listener callback interface for handling data as it is read off
* the input stream
* @throws IOException if there's a problem reading from the input stream
*/
public void parse(VObjectDataListener listener) throws IOException {
context.stop = false;
while (!eos && !context.stop) {
context.lineNumber = lineNumber;
buffer.clear();
context.unfoldedLine.clear();
VObjectProperty property = parseProperty(listener);
if (context.unfoldedLine.size() == 0) {
// input stream was empty
return;
}
if (property == null) {
listener.onWarning(Warning.MALFORMED_LINE, null, null, context);
continue;
}
if ("BEGIN".equalsIgnoreCase(property.getName().trim())) {
String componentName = property.getValue().trim().toUpperCase();
if (componentName.length() == 0) {
listener.onWarning(Warning.EMPTY_BEGIN, null, null, context);
continue;
}
listener.onComponentBegin(componentName, context);
stack.push(componentName);
continue;
}
if ("END".equalsIgnoreCase(property.getName().trim())) {
String componentName = property.getValue().trim().toUpperCase();
if (componentName.length() == 0) {
listener.onWarning(Warning.EMPTY_END, null, null, context);
continue;
}
// find the component that this END property matches up with
int popCount = stack.popCount(componentName);
if (popCount == 0) {
// END property does not match up with any BEGIN properties, so ignore
listener.onWarning(Warning.UNMATCHED_END, null, null, context);
continue;
}
while (popCount > 0) {
String poppedName = stack.pop();
listener.onComponentEnd(poppedName, context);
popCount--;
}
continue;
}
if ("VERSION".equalsIgnoreCase(property.getName())) {
String parentComponent = stack.peekName();
if (syntaxRules.hasSyntaxRules(parentComponent)) {
SyntaxStyle style = syntaxRules.getSyntaxStyle(parentComponent, property.getValue());
if (style == null) {
listener.onWarning(Warning.UNKNOWN_VERSION, property, null, context);
} else {
listener.onVersion(property.getValue(), context);
stack.updateSyntax(style);
continue;
}
}
}
listener.onProperty(property, context);
}
}
Aggregations