You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@any23.apache.org by ha...@apache.org on 2018/08/27 17:14:15 UTC
[1/3] any23 git commit: ANY23-390 implement ICal, JCal,
and XCal extractors
Repository: any23
Updated Branches:
refs/heads/master f3e66003a -> 19d85f2fc
ANY23-390 implement ICal, JCal, and XCal extractors
Project: http://git-wip-us.apache.org/repos/asf/any23/repo
Commit: http://git-wip-us.apache.org/repos/asf/any23/commit/54a92960
Tree: http://git-wip-us.apache.org/repos/asf/any23/tree/54a92960
Diff: http://git-wip-us.apache.org/repos/asf/any23/diff/54a92960
Branch: refs/heads/master
Commit: 54a92960ac2fda9510041b6886eb7259a9b1220b
Parents: f3e6600
Author: Hans <fi...@gmail.com>
Authored: Tue Aug 21 11:37:35 2018 -0500
Committer: Hans <fi...@gmail.com>
Committed: Tue Aug 21 11:37:35 2018 -0500
----------------------------------------------------------------------
core/pom.xml | 5 +
.../calendar/BaseCalendarExtractor.java | 222 +++++++++++++++++++
.../any23/extractor/calendar/ICalExtractor.java | 41 ++++
.../calendar/ICalExtractorFactory.java | 47 ++++
.../any23/extractor/calendar/JCalExtractor.java | 40 ++++
.../calendar/JCalExtractorFactory.java | 48 ++++
.../any23/extractor/calendar/XCalExtractor.java | 41 ++++
.../calendar/XCalExtractorFactory.java | 47 ++++
.../any23/extractor/calendar/package-info.java | 21 ++
pom.xml | 5 +
10 files changed, 517 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 49a1bfc..0fb5b28 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -93,6 +93,11 @@
</dependency>
<!-- END: httpcomponents -->
+ <dependency>
+ <groupId>net.sf.biweekly</groupId>
+ <artifactId>biweekly</artifactId>
+ </dependency>
+
<!-- BEGIN: Tika -->
<dependency>
<groupId>org.apache.tika</groupId>
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/core/src/main/java/org/apache/any23/extractor/calendar/BaseCalendarExtractor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/calendar/BaseCalendarExtractor.java b/core/src/main/java/org/apache/any23/extractor/calendar/BaseCalendarExtractor.java
new file mode 100644
index 0000000..74c3e10
--- /dev/null
+++ b/core/src/main/java/org/apache/any23/extractor/calendar/BaseCalendarExtractor.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import biweekly.ICalDataType;
+import biweekly.ICalVersion;
+import biweekly.ICalendar;
+import biweekly.component.ICalComponent;
+import biweekly.io.ParseWarning;
+import biweekly.io.SkipMeException;
+import biweekly.io.StreamReader;
+import biweekly.io.TimezoneInfo;
+import biweekly.io.WriteContext;
+import biweekly.io.scribe.ScribeIndex;
+import biweekly.io.scribe.component.ICalComponentScribe;
+import biweekly.io.scribe.property.ICalPropertyScribe;
+import biweekly.property.ICalProperty;
+import com.github.mangstadt.vinnie.io.VObjectPropertyValues;
+import org.apache.any23.extractor.ExtractionContext;
+import org.apache.any23.extractor.ExtractionException;
+import org.apache.any23.extractor.ExtractionParameters;
+import org.apache.any23.extractor.ExtractionResult;
+import org.apache.any23.extractor.Extractor;
+import org.apache.any23.extractor.IssueReport;
+import org.apache.any23.vocab.ICAL;
+import org.eclipse.rdf4j.model.BNode;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * @author Hans Brende (hansbrende@apache.org)
+ */
+abstract class BaseCalendarExtractor implements Extractor.ContentExtractor {
+
+ @Override
+ public void setStopAtFirstError(boolean b) {
+ //unsupported
+ }
+
+ private static final ValueFactory f = SimpleValueFactory.getInstance();
+ private static final ICAL vICAL = ICAL.getInstance();
+
+ abstract StreamReader reader(InputStream inputStream);
+
+ @Override
+ public final void run(ExtractionParameters extractionParameters, ExtractionContext extractionContext, InputStream inputStream,
+ ExtractionResult extractionResult) throws IOException, ExtractionException {
+ ScribeIndex index = new ScribeIndex();
+ try (StreamReader reader = reader(inputStream)) {
+ ICalendar cal;
+ while ((cal = reader.readNext()) != null) {
+ for (ParseWarning warning : reader.getWarnings()) {
+ String message = warning.getMessage();
+ Integer lineNumber = warning.getLineNumber();
+ if (lineNumber == null) {
+ extractionResult.notifyIssue(IssueReport.IssueLevel.WARNING, message, -1, -1);
+ } else {
+ extractionResult.notifyIssue(IssueReport.IssueLevel.WARNING, message, lineNumber, -1);
+ }
+ }
+
+ BNode calNode = f.createBNode();
+ extractionResult.writeTriple(calNode, RDF.TYPE, vICAL.Vcalendar);
+ extract(index, cal.getTimezoneInfo(), calNode, cal, extractionResult);
+ }
+ } catch (Exception e) {
+ extractionResult.notifyIssue(IssueReport.IssueLevel.FATAL, toString(e), -1, -1);
+ }
+ }
+
+ private static String toString(Throwable th) {
+ StringWriter writer = new StringWriter();
+ try (PrintWriter pw = new PrintWriter(writer)) {
+ th.printStackTrace(pw);
+ }
+ String string = writer.toString();
+ if (string.length() > 200) {
+ return string.substring(0, 197) + "...";
+ }
+ return string;
+ }
+
+
+ private static String localNameOfType(String typeName) {
+ if (typeName.isEmpty()) {
+ return "";
+ }
+ int ind = Character.charCount(typeName.codePointAt(0));
+ return typeName.substring(0, ind).toUpperCase(Locale.ENGLISH) + typeName.substring(ind);
+ }
+
+ private static String localNameOfProperty(String propertyName) {
+ String[] nameComponents = propertyName.split("-");
+ StringBuilder sb = new StringBuilder(propertyName.length());
+ sb.append(nameComponents[0]);
+ for (int i = 1, len = nameComponents.length; i < len; i++) {
+ sb.append(localNameOfType(nameComponents[i]));
+ }
+ return sb.toString();
+ }
+
+ private static IRI type(ICalComponentScribe<?> scribe, ExtractionResult result) {
+ if (scribe == null) {
+ return null;
+ }
+ String originalName = scribe.getComponentName();
+ String name = originalName.toLowerCase(Locale.ENGLISH);
+
+ if (name.startsWith("x-")) {
+ //non-standard class
+ return f.createIRI(ICAL.NS, "X-" + localNameOfType(name.substring(2)));
+ }
+
+ name = localNameOfType(name);
+
+ try {
+ return Objects.requireNonNull(vICAL.getClass(name));
+ } catch (RuntimeException e) {
+ IRI iri = f.createIRI(ICAL.NS, name);
+ result.notifyIssue(IssueReport.IssueLevel.ERROR,
+ "class " + iri + " (" + originalName + ") not defined in " + ICAL.class.getName(),
+ -1, -1);
+ return iri;
+ }
+ }
+
+ private static IRI predicate(ICalPropertyScribe<?> scribe, ExtractionResult result) {
+ if (scribe == null) {
+ return null;
+ }
+ String originalName = scribe.getPropertyName(ICalVersion.V2_0);
+ String name = originalName.toLowerCase(Locale.ENGLISH);
+ if (name.startsWith("x-")) {
+ //non-standard property
+ return f.createIRI(ICAL.NS, "x-" + localNameOfProperty(name.substring(2)));
+ }
+
+ name = localNameOfProperty(name);
+
+ try {
+ return Objects.requireNonNull(vICAL.getProperty(name));
+ } catch (RuntimeException e) {
+ IRI iri = f.createIRI(ICAL.NS, name);
+ result.notifyIssue(IssueReport.IssueLevel.ERROR,
+ "property " + iri + " (" + originalName + ") not defined in " + ICAL.class.getName(),
+ -1, -1);
+ return iri;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T extends ICalProperty> Value value(ICalPropertyScribe<T> scribe, ICalProperty property, TimezoneInfo info) {
+ try {
+ T prop = (T)property;
+ String text = scribe.writeText(prop, new WriteContext(ICalVersion.V2_0, info, null));
+ if (text == null) {
+ return null;
+ }
+ text = VObjectPropertyValues.unescape(text);
+ ICalDataType dataType = scribe.dataType(prop, ICalVersion.V2_0);
+ if (ICalDataType.URI.equals(dataType) || ICalDataType.URL.equals(dataType)) {
+ try {
+ return f.createIRI(text.trim());
+ } catch (IllegalArgumentException e) {
+ //ignore
+ }
+ }
+ return f.createLiteral(text);
+ } catch (SkipMeException e) {
+ return null;
+ }
+ }
+
+ private static void extract(ScribeIndex index, TimezoneInfo info, BNode node, ICalComponent component, ExtractionResult extractionResult) {
+ for (ICalProperty property : component.getProperties().values()) {
+ ICalPropertyScribe<?> scribe = index.getPropertyScribe(property);
+ IRI predicate = predicate(scribe, extractionResult);
+ if (predicate != null) {
+ Value value = value(scribe, property, info);
+ if (value != null) {
+ extractionResult.writeTriple(node, predicate, value);
+ }
+ }
+ }
+ for (ICalComponent child : component.getComponents().values()) {
+ BNode childNode = f.createBNode();
+ extractionResult.writeTriple(node, vICAL.component, childNode);
+ IRI childType = type(index.getComponentScribe(child), extractionResult);
+ if (childType != null) {
+ extractionResult.writeTriple(childNode, RDF.TYPE, childType);
+ }
+ extract(index, info, childNode, child, extractionResult);
+ }
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/core/src/main/java/org/apache/any23/extractor/calendar/ICalExtractor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/calendar/ICalExtractor.java b/core/src/main/java/org/apache/any23/extractor/calendar/ICalExtractor.java
new file mode 100644
index 0000000..adb2d7d
--- /dev/null
+++ b/core/src/main/java/org/apache/any23/extractor/calendar/ICalExtractor.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import biweekly.io.StreamReader;
+import biweekly.io.text.ICalReader;
+import org.apache.any23.extractor.ExtractorDescription;
+
+import java.io.InputStream;
+
+/**
+ * @author Hans Brende (hansbrende@apache.org)
+ */
+public class ICalExtractor extends BaseCalendarExtractor {
+
+ @Override
+ StreamReader reader(InputStream inputStream) {
+ return new ICalReader(inputStream);
+ }
+
+ @Override
+ public ExtractorDescription getDescription() {
+ return ICalExtractorFactory.getDescriptionInstance();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/core/src/main/java/org/apache/any23/extractor/calendar/ICalExtractorFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/calendar/ICalExtractorFactory.java b/core/src/main/java/org/apache/any23/extractor/calendar/ICalExtractorFactory.java
new file mode 100644
index 0000000..8a25dcb
--- /dev/null
+++ b/core/src/main/java/org/apache/any23/extractor/calendar/ICalExtractorFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import org.apache.any23.extractor.ExtractorDescription;
+import org.apache.any23.extractor.SimpleExtractorFactory;
+import org.apache.any23.rdf.Prefixes;
+
+import java.util.Collections;
+
+/**
+ * @author Hans Brende (hansbrende@apache.org)
+ */
+public class ICalExtractorFactory extends SimpleExtractorFactory<ICalExtractor> {
+
+ private static final String NAME = "ical";
+ private static final Prefixes PREFIXES = null;
+ private static final ExtractorDescription descriptionInstance = new ICalExtractorFactory();
+
+ public ICalExtractorFactory() {
+ super(NAME, PREFIXES, Collections.singletonList("text/calendar"), null);
+ }
+
+ public static ExtractorDescription getDescriptionInstance() {
+ return descriptionInstance;
+ }
+
+ @Override
+ public ICalExtractor createExtractor() {
+ return new ICalExtractor();
+ }
+}
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/core/src/main/java/org/apache/any23/extractor/calendar/JCalExtractor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/calendar/JCalExtractor.java b/core/src/main/java/org/apache/any23/extractor/calendar/JCalExtractor.java
new file mode 100644
index 0000000..32dc73b
--- /dev/null
+++ b/core/src/main/java/org/apache/any23/extractor/calendar/JCalExtractor.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import biweekly.io.StreamReader;
+import biweekly.io.json.JCalReader;
+import org.apache.any23.extractor.ExtractorDescription;
+
+import java.io.InputStream;
+
+/**
+ * @author Hans Brende (hansbrende@apache.org)
+ */
+public class JCalExtractor extends BaseCalendarExtractor {
+
+ @Override
+ StreamReader reader(InputStream inputStream) {
+ return new JCalReader(inputStream);
+ }
+
+ @Override
+ public ExtractorDescription getDescription() {
+ return JCalExtractorFactory.getDescriptionInstance();
+ }
+}
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/core/src/main/java/org/apache/any23/extractor/calendar/JCalExtractorFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/calendar/JCalExtractorFactory.java b/core/src/main/java/org/apache/any23/extractor/calendar/JCalExtractorFactory.java
new file mode 100644
index 0000000..2344bab
--- /dev/null
+++ b/core/src/main/java/org/apache/any23/extractor/calendar/JCalExtractorFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import org.apache.any23.extractor.ExtractorDescription;
+import org.apache.any23.extractor.SimpleExtractorFactory;
+import org.apache.any23.rdf.Prefixes;
+
+import java.util.Collections;
+
+/**
+ * @author Hans Brende (hansbrende@apache.org)
+ */
+public class JCalExtractorFactory extends SimpleExtractorFactory<JCalExtractor> {
+
+ private static final String NAME = "jcal";
+ private static final Prefixes PREFIXES = null;
+ private static final ExtractorDescription descriptionInstance = new JCalExtractorFactory();
+
+ public JCalExtractorFactory() {
+ super(NAME, PREFIXES, Collections.singletonList("application/calendar+json"), null);
+ }
+
+ public static ExtractorDescription getDescriptionInstance() {
+ return descriptionInstance;
+ }
+
+ @Override
+ public JCalExtractor createExtractor() {
+ return new JCalExtractor();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/core/src/main/java/org/apache/any23/extractor/calendar/XCalExtractor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/calendar/XCalExtractor.java b/core/src/main/java/org/apache/any23/extractor/calendar/XCalExtractor.java
new file mode 100644
index 0000000..555b4f7
--- /dev/null
+++ b/core/src/main/java/org/apache/any23/extractor/calendar/XCalExtractor.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import biweekly.io.StreamReader;
+import biweekly.io.xml.XCalReader;
+import org.apache.any23.extractor.ExtractorDescription;
+
+import java.io.InputStream;
+
+/**
+ * @author Hans Brende (hansbrende@apache.org)
+ */
+public class XCalExtractor extends BaseCalendarExtractor {
+
+ @Override
+ StreamReader reader(InputStream inputStream) {
+ return new XCalReader(inputStream);
+ }
+
+ @Override
+ public ExtractorDescription getDescription() {
+ return XCalExtractorFactory.getDescriptionInstance();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/core/src/main/java/org/apache/any23/extractor/calendar/XCalExtractorFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/calendar/XCalExtractorFactory.java b/core/src/main/java/org/apache/any23/extractor/calendar/XCalExtractorFactory.java
new file mode 100644
index 0000000..6519b1f
--- /dev/null
+++ b/core/src/main/java/org/apache/any23/extractor/calendar/XCalExtractorFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import org.apache.any23.extractor.ExtractorDescription;
+import org.apache.any23.extractor.SimpleExtractorFactory;
+import org.apache.any23.rdf.Prefixes;
+
+import java.util.Collections;
+
+/**
+ * @author Hans Brende (hansbrende@apache.org)
+ */
+public class XCalExtractorFactory extends SimpleExtractorFactory<XCalExtractor> {
+
+ private static final String NAME = "xcal";
+ private static final Prefixes PREFIXES = null;
+ private static final ExtractorDescription descriptionInstance = new XCalExtractorFactory();
+
+ public XCalExtractorFactory() {
+ super(NAME, PREFIXES, Collections.singletonList("application/calendar+xml"), null);
+ }
+
+ public static ExtractorDescription getDescriptionInstance() {
+ return descriptionInstance;
+ }
+
+ @Override
+ public XCalExtractor createExtractor() {
+ return new XCalExtractor();
+ }
+}
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/core/src/main/java/org/apache/any23/extractor/calendar/package-info.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/calendar/package-info.java b/core/src/main/java/org/apache/any23/extractor/calendar/package-info.java
new file mode 100644
index 0000000..50d731a
--- /dev/null
+++ b/core/src/main/java/org/apache/any23/extractor/calendar/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+ * This package contains extractors for various calendar serialization formats.
+ */
+package org.apache.any23.extractor.calendar;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/any23/blob/54a92960/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ce2ee5d..2aa6278 100644
--- a/pom.xml
+++ b/pom.xml
@@ -372,6 +372,11 @@
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
+ <dependency>
+ <groupId>net.sf.biweekly</groupId>
+ <artifactId>biweekly</artifactId>
+ <version>0.6.2</version>
+ </dependency>
<!-- BEGIN: Tika -->
<dependency>
[2/3] any23 git commit: ANY23-390 ical tests, support for params,
datatypes, & structured values
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.xml/rfc6321-example1-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.xml/rfc6321-example1-expected.nquads b/test-resources/src/test/resources/calendar.xml/rfc6321-example1-expected.nquads
new file mode 100644
index 0000000..779b6de
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.xml/rfc6321-example1-expected.nquads
@@ -0,0 +1,26 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu4bdubx2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu4bdubx2 <http://www.w3.org/2002/12/cal/icaltzd#calscale> "GREGORIAN" <http://bob.example.com/> .
+_:node1clu4bdubx2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//Example Inc.//Example Calendar//EN" <http://bob.example.com/> .
+_:node1clu4bdubx2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu4bdubx3 <http://bob.example.com/> .
+_:node1clu4bdubx3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vevent> <http://bob.example.com/> .
+_:node1clu4bdubx3 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "2008-02-05T19:12:24Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4bdubx3 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "2008-10-06"^^<http://www.w3.org/2001/XMLSchema#date> <http://bob.example.com/> .
+_:node1clu4bdubx3 <http://www.w3.org/2002/12/cal/icaltzd#summary> "Planning meeting" <http://bob.example.com/> .
+_:node1clu4bdubx3 <http://www.w3.org/2002/12/cal/icaltzd#uid> "4088E990AD89CB3DBB484909" <http://bob.example.com/> .
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.xml/rfc6321-example1.xml
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.xml/rfc6321-example1.xml b/test-resources/src/test/resources/calendar.xml/rfc6321-example1.xml
new file mode 100755
index 0000000..2c1f069
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.xml/rfc6321-example1.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+ <vcalendar>
+ <properties>
+ <calscale>
+ <text>GREGORIAN</text>
+ </calscale>
+ <prodid>
+ <text>-//Example Inc.//Example Calendar//EN</text>
+ </prodid>
+ <version>
+ <text>2.0</text>
+ </version>
+ </properties>
+ <components>
+ <vevent>
+ <properties>
+ <dtstamp>
+ <date-time>2008-02-05T19:12:24Z</date-time>
+ </dtstamp>
+ <dtstart>
+ <date>2008-10-06</date>
+ </dtstart>
+ <summary>
+ <text>Planning meeting</text>
+ </summary>
+ <uid>
+ <text>4088E990AD89CB3DBB484909</text>
+ </uid>
+ </properties>
+ </vevent>
+ </components>
+ </vcalendar>
+</icalendar>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.xml/rfc6321-example2-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.xml/rfc6321-example2-expected.nquads b/test-resources/src/test/resources/calendar.xml/rfc6321-example2-expected.nquads
new file mode 100644
index 0000000..70ebe15
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.xml/rfc6321-example2-expected.nquads
@@ -0,0 +1,75 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu4e12ox2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu4e12ox2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//Example Inc.//Example Client//EN" <http://bob.example.com/> .
+_:node1clu4e12ox2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu4e12ox3 <http://bob.example.com/> .
+_:node1clu4e12ox3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vtimezone> <http://bob.example.com/> .
+_:node1clu4e12ox3 <http://www.w3.org/2002/12/cal/icaltzd#lastModified> "2004-01-10T03:28:45Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4e12ox3 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu4e12ox3 <http://www.w3.org/2002/12/cal/icaltzd#daylight> _:node1clu4e12ox4 <http://bob.example.com/> .
+_:node1clu4e12ox4 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "2000-04-04T02:00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4e12ox4 <http://www.w3.org/2002/12/cal/icaltzd#rrule> _:node1clu4e12ox5 <http://bob.example.com/> .
+_:node1clu4e12ox5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_RECUR> <http://bob.example.com/> .
+_:node1clu4e12ox5 <http://www.w3.org/2002/12/cal/icaltzd#freq> "YEARLY" <http://bob.example.com/> .
+_:node1clu4e12ox5 <http://www.w3.org/2002/12/cal/icaltzd#byday> "1SU" <http://bob.example.com/> .
+_:node1clu4e12ox5 <http://www.w3.org/2002/12/cal/icaltzd#bymonth> "4"^^<http://www.w3.org/2001/XMLSchema#int> <http://bob.example.com/> .
+_:node1clu4e12ox4 <http://www.w3.org/2002/12/cal/icaltzd#tzname> "EDT" <http://bob.example.com/> .
+_:node1clu4e12ox4 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetfrom> "-05:00" <http://bob.example.com/> .
+_:node1clu4e12ox4 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetto> "-04:00" <http://bob.example.com/> .
+_:node1clu4e12ox3 <http://www.w3.org/2002/12/cal/icaltzd#standard> _:node1clu4e12ox6 <http://bob.example.com/> .
+_:node1clu4e12ox6 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "2000-10-26T02:00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4e12ox6 <http://www.w3.org/2002/12/cal/icaltzd#rrule> _:node1clu4e12ox7 <http://bob.example.com/> .
+_:node1clu4e12ox7 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_RECUR> <http://bob.example.com/> .
+_:node1clu4e12ox7 <http://www.w3.org/2002/12/cal/icaltzd#freq> "YEARLY" <http://bob.example.com/> .
+_:node1clu4e12ox7 <http://www.w3.org/2002/12/cal/icaltzd#byday> "-1SU" <http://bob.example.com/> .
+_:node1clu4e12ox7 <http://www.w3.org/2002/12/cal/icaltzd#bymonth> "10"^^<http://www.w3.org/2001/XMLSchema#int> <http://bob.example.com/> .
+_:node1clu4e12ox6 <http://www.w3.org/2002/12/cal/icaltzd#tzname> "EST" <http://bob.example.com/> .
+_:node1clu4e12ox6 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetfrom> "-04:00" <http://bob.example.com/> .
+_:node1clu4e12ox6 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetto> "-05:00" <http://bob.example.com/> .
+_:node1clu4e12ox2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu4e12ox8 <http://bob.example.com/> .
+_:node1clu4e12ox8 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vevent> <http://bob.example.com/> .
+_:node1clu4e12ox8 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "2006-02-06T00:11:21Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4e12ox8 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> _:node1clu4e12ox9 <http://bob.example.com/> .
+_:node1clu4e12ox9 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu4e12ox9 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> "2006-01-02T12:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4e12ox8 <http://www.w3.org/2002/12/cal/icaltzd#duration> "PT1H"^^<http://www.w3.org/2001/XMLSchema#duration> <http://bob.example.com/> .
+_:node1clu4e12ox8 <http://www.w3.org/2002/12/cal/icaltzd#rrule> _:node1clu4e12ox10 <http://bob.example.com/> .
+_:node1clu4e12ox10 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_RECUR> <http://bob.example.com/> .
+_:node1clu4e12ox10 <http://www.w3.org/2002/12/cal/icaltzd#freq> "DAILY" <http://bob.example.com/> .
+_:node1clu4e12ox10 <http://www.w3.org/2002/12/cal/icaltzd#count> "5"^^<http://www.w3.org/2001/XMLSchema#int> <http://bob.example.com/> .
+_:node1clu4e12ox8 <http://www.w3.org/2002/12/cal/icaltzd#rdate> _:node1clu4e12ox11 <http://bob.example.com/> .
+_:node1clu4e12ox11 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu4e12ox11 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> _:node1clu4e12ox12 <http://bob.example.com/> .
+_:node1clu4e12ox12 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_PERIOD> <http://bob.example.com/> .
+_:node1clu4e12ox12 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "2006-01-02T15:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4e12ox12 <http://www.w3.org/2002/12/cal/icaltzd#duration> "PT2H"^^<http://www.w3.org/2001/XMLSchema#duration> <http://bob.example.com/> .
+_:node1clu4e12ox8 <http://www.w3.org/2002/12/cal/icaltzd#summary> "Event #2" <http://bob.example.com/> .
+_:node1clu4e12ox8 <http://www.w3.org/2002/12/cal/icaltzd#description> "We are having a meeting all this week at 12pm for one hour, with an additional meeting on the first day 2 hours long.\nPlease bring your own lunch for the 12 pm meetings." <http://bob.example.com/> .
+_:node1clu4e12ox8 <http://www.w3.org/2002/12/cal/icaltzd#uid> "00959BC664CA650E933C892C@example.com" <http://bob.example.com/> .
+_:node1clu4e12ox2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu4e12ox13 <http://bob.example.com/> .
+_:node1clu4e12ox13 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vevent> <http://bob.example.com/> .
+_:node1clu4e12ox13 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "2006-02-06T00:11:21Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4e12ox13 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> _:node1clu4e12ox14 <http://bob.example.com/> .
+_:node1clu4e12ox14 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu4e12ox14 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> "2006-01-04T14:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4e12ox13 <http://www.w3.org/2002/12/cal/icaltzd#duration> "PT1H"^^<http://www.w3.org/2001/XMLSchema#duration> <http://bob.example.com/> .
+_:node1clu4e12ox13 <http://www.w3.org/2002/12/cal/icaltzd#recurrenceId> _:node1clu4e12ox15 <http://bob.example.com/> .
+_:node1clu4e12ox15 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu4e12ox15 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> "2006-01-04T12:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu4e12ox13 <http://www.w3.org/2002/12/cal/icaltzd#summary> "Event #2 bis" <http://bob.example.com/> .
+_:node1clu4e12ox13 <http://www.w3.org/2002/12/cal/icaltzd#uid> "00959BC664CA650E933C892C@example.com" <http://bob.example.com/> .
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.xml/rfc6321-example2.xml
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.xml/rfc6321-example2.xml b/test-resources/src/test/resources/calendar.xml/rfc6321-example2.xml
new file mode 100755
index 0000000..adcc49e
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.xml/rfc6321-example2.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+ <vcalendar>
+ <properties>
+ <prodid>
+ <text>-//Example Inc.//Example Client//EN</text>
+ </prodid>
+ <version>
+ <text>2.0</text>
+ </version>
+ </properties>
+ <components>
+ <vevent>
+ <properties>
+ <dtstamp>
+ <date-time>2006-02-06T00:11:21Z</date-time>
+ </dtstamp>
+ <dtstart>
+ <parameters>
+ <tzid>
+ <text>US/Eastern</text>
+ </tzid>
+ </parameters>
+ <date-time>2006-01-02T12:00:00</date-time>
+ </dtstart>
+ <duration>
+ <duration>PT1H</duration>
+ </duration>
+ <rrule>
+ <recur>
+ <freq>DAILY</freq>
+ <count>5</count>
+ </recur>
+ </rrule>
+ <rdate>
+ <parameters>
+ <tzid>
+ <text>US/Eastern</text>
+ </tzid>
+ </parameters>
+ <period>
+ <start>2006-01-02T15:00:00</start>
+ <duration>PT2H</duration>
+ </period>
+ </rdate>
+ <summary>
+ <text>Event #2</text>
+ </summary>
+ <description>
+ <text>We are having a meeting all this week at 12pm for one hour, with an additional meeting on the first day 2 hours long.
Please bring your own lunch for the 12 pm meetings.</text>
+ </description>
+ <uid>
+ <text>00959BC664CA650E933C892C@example.com</text>
+ </uid>
+ </properties>
+ </vevent>
+ <vevent>
+ <properties>
+ <dtstamp>
+ <date-time>2006-02-06T00:11:21Z</date-time>
+ </dtstamp>
+ <dtstart>
+ <parameters>
+ <tzid>
+ <text>US/Eastern</text>
+ </tzid>
+ </parameters>
+ <date-time>2006-01-04T14:00:00</date-time>
+ </dtstart>
+ <duration>
+ <duration>PT1H</duration>
+ </duration>
+ <recurrence-id>
+ <parameters>
+ <tzid>
+ <text>US/Eastern</text>
+ </tzid>
+ </parameters>
+ <date-time>2006-01-04T12:00:00</date-time>
+ </recurrence-id>
+ <summary>
+ <text>Event #2 bis</text>
+ </summary>
+ <uid>
+ <text>00959BC664CA650E933C892C@example.com</text>
+ </uid>
+ </properties>
+ </vevent>
+ <vtimezone>
+ <properties>
+ <last-modified>
+ <date-time>2004-01-10T03:28:45Z</date-time>
+ </last-modified>
+ <tzid>
+ <text>US/Eastern</text>
+ </tzid>
+ </properties>
+ <components>
+ <daylight>
+ <properties>
+ <dtstart>
+ <date-time>2000-04-04T02:00:00</date-time>
+ </dtstart>
+ <rrule>
+ <recur>
+ <freq>YEARLY</freq>
+ <byday>1SU</byday>
+ <bymonth>4</bymonth>
+ </recur>
+ </rrule>
+ <tzname>
+ <text>EDT</text>
+ </tzname>
+ <tzoffsetfrom>
+ <utc-offset>-05:00</utc-offset>
+ </tzoffsetfrom>
+ <tzoffsetto>
+ <utc-offset>-04:00</utc-offset>
+ </tzoffsetto>
+ </properties>
+ </daylight>
+ <standard>
+ <properties>
+ <dtstart>
+ <date-time>2000-10-26T02:00:00</date-time>
+ </dtstart>
+ <rrule>
+ <recur>
+ <freq>YEARLY</freq>
+ <byday>-1SU</byday>
+ <bymonth>10</bymonth>
+ </recur>
+ </rrule>
+ <tzname>
+ <text>EST</text>
+ </tzname>
+ <tzoffsetfrom>
+ <utc-offset>-04:00</utc-offset>
+ </tzoffsetfrom>
+ <tzoffsetto>
+ <utc-offset>-05:00</utc-offset>
+ </tzoffsetto>
+ </properties>
+ </standard>
+ </components>
+ </vtimezone>
+ </components>
+ </vcalendar>
+</icalendar>
\ No newline at end of file
[3/3] any23 git commit: ANY23-390 ical tests, support for params,
datatypes, & structured values
Posted by ha...@apache.org.
ANY23-390 ical tests, support for params, datatypes, & structured values
Project: http://git-wip-us.apache.org/repos/asf/any23/repo
Commit: http://git-wip-us.apache.org/repos/asf/any23/commit/19d85f2f
Tree: http://git-wip-us.apache.org/repos/asf/any23/tree/19d85f2f
Diff: http://git-wip-us.apache.org/repos/asf/any23/diff/19d85f2f
Branch: refs/heads/master
Commit: 19d85f2fc84b4431228b4978c0b1419b758aa203
Parents: 54a9296
Author: Hans <fi...@gmail.com>
Authored: Mon Aug 27 11:59:24 2018 -0500
Committer: Hans <fi...@gmail.com>
Committed: Mon Aug 27 12:06:50 2018 -0500
----------------------------------------------------------------------
.../main/java/org/apache/any23/vocab/ICAL.java | 9 +
.../calendar/BaseCalendarExtractor.java | 420 ++++++++++++++++---
.../calendar/BaseCalendarExtractorTest.java | 98 +++++
.../extractor/calendar/ICalExtractorTest.java | 67 +++
.../extractor/calendar/JCalExtractorTest.java | 46 ++
.../extractor/calendar/XCalExtractorTest.java | 46 ++
.../apache/any23/vocab/RDFSchemaUtilsTest.java | 4 +-
.../rfc7265-example1-expected.nquads | 26 ++
.../calendar.json/rfc7265-example1.json | 18 +
.../rfc7265-example2-expected.nquads | 75 ++++
.../calendar.json/rfc7265-example2.json | 96 +++++
.../rfc5545-example1-expected.nquads | 30 ++
.../calendar.text/rfc5545-example1.ics | 17 +
.../rfc5545-example2-expected.nquads | 55 +++
.../calendar.text/rfc5545-example2.ics | 34 ++
.../rfc5545-example3-expected.nquads | 40 ++
.../calendar.text/rfc5545-example3.ics | 22 +
.../rfc5545-example4-expected.nquads | 40 ++
.../calendar.text/rfc5545-example4.ics | 22 +
.../rfc5545-example5-expected.nquads | 30 ++
.../calendar.text/rfc5545-example5.ics | 23 +
.../rfc5545-example6-expected.nquads | 37 ++
.../calendar.text/rfc5545-example6.ics | 13 +
.../rfc6321-example1-expected.nquads | 26 ++
.../resources/calendar.xml/rfc6321-example1.xml | 34 ++
.../rfc6321-example2-expected.nquads | 75 ++++
.../resources/calendar.xml/rfc6321-example2.xml | 149 +++++++
27 files changed, 1488 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/api/src/main/java/org/apache/any23/vocab/ICAL.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/any23/vocab/ICAL.java b/api/src/main/java/org/apache/any23/vocab/ICAL.java
index 783d668..81bae3f 100644
--- a/api/src/main/java/org/apache/any23/vocab/ICAL.java
+++ b/api/src/main/java/org/apache/any23/vocab/ICAL.java
@@ -29,6 +29,11 @@ public class ICAL extends Vocabulary {
*/
public static final String NS = "http://www.w3.org/2002/12/cal/icaltzd#";
+ /**
+ * Recommended prefix for the ICAL namespace
+ */
+ public static final String PREFIX = "ical";
+
private static final class InstanceHolder {
private static final ICAL instance = new ICAL();
}
@@ -54,6 +59,8 @@ public class ICAL extends Vocabulary {
public final IRI Value_DATE = createClass("Value_DATE");
+ public final IRI Value_DATE_TIME = createClass("Value_DATE-TIME");
+
public final IRI Value_DURATION = createClass("Value_DURATION");
public final IRI Value_PERIOD = createClass("Value_PERIOD");
@@ -191,6 +198,8 @@ public class ICAL extends Vocabulary {
public final IRI byyearday = createProperty("byyearday");
+ public final IRI wkst = createProperty("wkst");
+
/**
* value type: TEXTThis IRI defines the calendar scale used for the calendar
* information specified in the iCalendar object..
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/core/src/main/java/org/apache/any23/extractor/calendar/BaseCalendarExtractor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/any23/extractor/calendar/BaseCalendarExtractor.java b/core/src/main/java/org/apache/any23/extractor/calendar/BaseCalendarExtractor.java
index 74c3e10..258006f 100644
--- a/core/src/main/java/org/apache/any23/extractor/calendar/BaseCalendarExtractor.java
+++ b/core/src/main/java/org/apache/any23/extractor/calendar/BaseCalendarExtractor.java
@@ -21,16 +21,23 @@ import biweekly.ICalDataType;
import biweekly.ICalVersion;
import biweekly.ICalendar;
import biweekly.component.ICalComponent;
+import biweekly.component.VTimezone;
import biweekly.io.ParseWarning;
import biweekly.io.SkipMeException;
import biweekly.io.StreamReader;
+import biweekly.io.TimezoneAssignment;
import biweekly.io.TimezoneInfo;
import biweekly.io.WriteContext;
+import biweekly.io.json.JCalValue;
+import biweekly.io.json.JsonValue;
import biweekly.io.scribe.ScribeIndex;
-import biweekly.io.scribe.component.ICalComponentScribe;
import biweekly.io.scribe.property.ICalPropertyScribe;
+import biweekly.parameter.Encoding;
+import biweekly.parameter.ICalParameters;
+import biweekly.property.Geo;
import biweekly.property.ICalProperty;
-import com.github.mangstadt.vinnie.io.VObjectPropertyValues;
+import biweekly.util.DateTimeComponents;
+import biweekly.util.ICalDateFormat;
import org.apache.any23.extractor.ExtractionContext;
import org.apache.any23.extractor.ExtractionException;
import org.apache.any23.extractor.ExtractionParameters;
@@ -38,19 +45,34 @@ import org.apache.any23.extractor.ExtractionResult;
import org.apache.any23.extractor.Extractor;
import org.apache.any23.extractor.IssueReport;
import org.apache.any23.vocab.ICAL;
+import org.apache.commons.lang.StringUtils;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.datatypes.XMLDatatypeUtil;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.ZoneOffset;
+import java.util.Collection;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Objects;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* @author Hans Brende (hansbrende@apache.org)
@@ -69,7 +91,11 @@ abstract class BaseCalendarExtractor implements Extractor.ContentExtractor {
@Override
public final void run(ExtractionParameters extractionParameters, ExtractionContext extractionContext, InputStream inputStream,
- ExtractionResult extractionResult) throws IOException, ExtractionException {
+ ExtractionResult result) throws IOException, ExtractionException {
+ result.writeNamespace(RDF.PREFIX, RDF.NAMESPACE);
+ result.writeNamespace(ICAL.PREFIX, ICAL.NS);
+ result.writeNamespace(XMLSchema.PREFIX, XMLSchema.NAMESPACE);
+
ScribeIndex index = new ScribeIndex();
try (StreamReader reader = reader(inputStream)) {
ICalendar cal;
@@ -78,18 +104,19 @@ abstract class BaseCalendarExtractor implements Extractor.ContentExtractor {
String message = warning.getMessage();
Integer lineNumber = warning.getLineNumber();
if (lineNumber == null) {
- extractionResult.notifyIssue(IssueReport.IssueLevel.WARNING, message, -1, -1);
+ result.notifyIssue(IssueReport.IssueLevel.WARNING, message, -1, -1);
} else {
- extractionResult.notifyIssue(IssueReport.IssueLevel.WARNING, message, lineNumber, -1);
+ result.notifyIssue(IssueReport.IssueLevel.WARNING, message, lineNumber, -1);
}
}
BNode calNode = f.createBNode();
- extractionResult.writeTriple(calNode, RDF.TYPE, vICAL.Vcalendar);
- extract(index, cal.getTimezoneInfo(), calNode, cal, extractionResult);
+ result.writeTriple(calNode, RDF.TYPE, vICAL.Vcalendar);
+ WriteContext ctx = new WriteContext(ICalVersion.V2_0, cal.getTimezoneInfo(), null);
+ extract(index, ctx, calNode, cal, result, true);
}
} catch (Exception e) {
- extractionResult.notifyIssue(IssueReport.IssueLevel.FATAL, toString(e), -1, -1);
+ result.notifyIssue(IssueReport.IssueLevel.FATAL, toString(e), -1, -1);
}
}
@@ -111,56 +138,42 @@ abstract class BaseCalendarExtractor implements Extractor.ContentExtractor {
return "";
}
int ind = Character.charCount(typeName.codePointAt(0));
- return typeName.substring(0, ind).toUpperCase(Locale.ENGLISH) + typeName.substring(ind);
+ return typeName.substring(0, ind).toUpperCase(Locale.ENGLISH)
+ + typeName.substring(ind).toLowerCase(Locale.ENGLISH);
}
private static String localNameOfProperty(String propertyName) {
String[] nameComponents = propertyName.split("-");
StringBuilder sb = new StringBuilder(propertyName.length());
- sb.append(nameComponents[0]);
+ sb.append(nameComponents[0].toLowerCase(Locale.ENGLISH));
for (int i = 1, len = nameComponents.length; i < len; i++) {
sb.append(localNameOfType(nameComponents[i]));
}
return sb.toString();
}
- private static IRI type(ICalComponentScribe<?> scribe, ExtractionResult result) {
- if (scribe == null) {
- return null;
- }
- String originalName = scribe.getComponentName();
- String name = originalName.toLowerCase(Locale.ENGLISH);
-
- if (name.startsWith("x-")) {
+ private static IRI type(String originalName) {
+ if (originalName.regionMatches(true, 0, "X-", 0, 2)) {
//non-standard class
- return f.createIRI(ICAL.NS, "X-" + localNameOfType(name.substring(2)));
+ return f.createIRI(ICAL.NS, "X-" + localNameOfType(originalName.substring(2)));
}
- name = localNameOfType(name);
+ String name = localNameOfType(originalName);
try {
return Objects.requireNonNull(vICAL.getClass(name));
} catch (RuntimeException e) {
- IRI iri = f.createIRI(ICAL.NS, name);
- result.notifyIssue(IssueReport.IssueLevel.ERROR,
- "class " + iri + " (" + originalName + ") not defined in " + ICAL.class.getName(),
- -1, -1);
- return iri;
+ return null;
}
}
- private static IRI predicate(ICalPropertyScribe<?> scribe, ExtractionResult result) {
- if (scribe == null) {
- return null;
- }
- String originalName = scribe.getPropertyName(ICalVersion.V2_0);
- String name = originalName.toLowerCase(Locale.ENGLISH);
- if (name.startsWith("x-")) {
+ private static IRI predicate(String originalName, ExtractionResult result) {
+ if (originalName.regionMatches(true, 0, "X-", 0, 2)) {
//non-standard property
- return f.createIRI(ICAL.NS, "x-" + localNameOfProperty(name.substring(2)));
+ return f.createIRI(ICAL.NS, "x-" + localNameOfProperty(originalName.substring(2)));
}
- name = localNameOfProperty(name);
+ String name = localNameOfProperty(originalName);
try {
return Objects.requireNonNull(vICAL.getProperty(name));
@@ -173,49 +186,332 @@ abstract class BaseCalendarExtractor implements Extractor.ContentExtractor {
}
}
- @SuppressWarnings("unchecked")
- private static <T extends ICalProperty> Value value(ICalPropertyScribe<T> scribe, ICalProperty property, TimezoneInfo info) {
- try {
- T prop = (T)property;
- String text = scribe.writeText(prop, new WriteContext(ICalVersion.V2_0, info, null));
- if (text == null) {
- return null;
+ private static final String NaN = Double.toString(Double.NaN);
+ private static String str(Double d) {
+ return d == null ? NaN : d.toString();
+ }
+
+ private static void writeParams(BNode subject, ICalParameters params, ExtractionResult result) {
+ for (Map.Entry<String, List<String>> entry : params.getMap().entrySet()) {
+ List<String> strings = entry.getValue();
+ if (strings != null && !strings.isEmpty()) {
+ IRI predicate = predicate(entry.getKey(), result);
+ for (String v : strings) {
+ result.writeTriple(subject, predicate, f.createLiteral(v));
+ }
}
- text = VObjectPropertyValues.unescape(text);
- ICalDataType dataType = scribe.dataType(prop, ICalVersion.V2_0);
- if (ICalDataType.URI.equals(dataType) || ICalDataType.URL.equals(dataType)) {
+ }
+ }
+
+
+ private static IRI dataType(ICalDataType dataType) {
+ if (dataType == null || ICalDataType.TEXT.equals(dataType)) {
+ return XMLSchema.STRING;
+ } else if (ICalDataType.BOOLEAN.equals(dataType)) {
+ return XMLSchema.BOOLEAN;
+ } else if (ICalDataType.INTEGER.equals(dataType)) {
+ return XMLSchema.INTEGER;
+ } else if (ICalDataType.FLOAT.equals(dataType)) {
+ return XMLSchema.FLOAT;
+ } else if (ICalDataType.BINARY.equals(dataType)) {
+ return XMLSchema.BASE64BINARY;
+ } else if (ICalDataType.URI.equals(dataType)
+ || ICalDataType.URL.equals(dataType)
+ || ICalDataType.CONTENT_ID.equals(dataType)
+ || ICalDataType.CAL_ADDRESS.equals(dataType)) {
+ return XMLSchema.ANYURI;
+ } else if (ICalDataType.DATE_TIME.equals(dataType)) {
+ return XMLSchema.DATETIME;
+ } else if (ICalDataType.DATE.equals(dataType)) {
+ return XMLSchema.DATE;
+ } else if (ICalDataType.TIME.equals(dataType)) {
+ return XMLSchema.TIME;
+ } else if (ICalDataType.DURATION.equals(dataType)) {
+ return XMLSchema.DURATION;
+ } else if (ICalDataType.PERIOD.equals(dataType)) {
+ return vICAL.Value_PERIOD;
+ } else if (ICalDataType.RECUR.equals(dataType)) {
+ return vICAL.Value_RECUR;
+ } else {
+ return XMLSchema.STRING;
+ }
+ }
+
+
+ private static final Pattern durationWeeksPattern = Pattern.compile("(-?P)(\\d+)W");
+
+ private static String normalizeAndReportIfInvalid(String s, IRI dataType, TimeZone zone, ExtractionResult result) {
+ if (dataType == null) {
+ return s;
+ }
+ try {
+ if (XMLSchema.DURATION.equals(dataType)) {
+ Matcher m = durationWeeksPattern.matcher(s);
+ if (m.matches()) {
+ long days = Long.parseLong(m.group(2)) * 7;
+ return m.group(1) + days + "D";
+ }
+ } else if (vICAL.Value_PERIOD.equals(dataType)) {
+ if (s.indexOf('/') == -1) {
+ throw new IllegalArgumentException();
+ }
+ } else if (zone != null && XMLSchema.DATETIME.equals(dataType)) {
try {
- return f.createIRI(text.trim());
+ DateTimeComponents dt = DateTimeComponents.parse(s);
+ if (!dt.isUtc()) {
+ s = ICalDateFormat.DATE_TIME_EXTENDED.format(dt.toDate(zone), zone);
+ }
} catch (IllegalArgumentException e) {
//ignore
}
+ } else {
+ s = XMLDatatypeUtil.normalize(s, dataType);
}
- return f.createLiteral(text);
- } catch (SkipMeException e) {
+
+ if (!XMLDatatypeUtil.isValidValue(s, dataType)) {
+ throw new IllegalArgumentException();
+ }
+ } catch (IllegalArgumentException e) {
+ String m = e.getMessage();
+ if (StringUtils.isBlank(m)) {
+ m = "Not a valid " + dataType + " value: " + s;
+ }
+ result.notifyIssue(IssueReport.IssueLevel.ERROR, m, -1, -1);
+ }
+ return s;
+ }
+
+ private static boolean writeValue(BNode subject, IRI predicate, JsonValue jsonValue, String lang, IRI dataType, TimeZone zone, ExtractionResult result) {
+ if (jsonValue == null || jsonValue.isNull()) {
+ return false;
+ }
+ Object val = jsonValue.getValue();
+ if (val != null) {
+ Value v;
+ if (val instanceof Byte) {
+ v = f.createLiteral((byte)val);
+ } else if (val instanceof Short) {
+ v = f.createLiteral((short)val);
+ } else if (val instanceof Integer) {
+ v = f.createLiteral((int)val);
+ } else if (val instanceof Long) {
+ v = f.createLiteral((long)val);
+ } else if (val instanceof Float) {
+ v = f.createLiteral((float)val);
+ } else if (val instanceof Double) {
+ v = f.createLiteral((double)val);
+ } else if (val instanceof Boolean) {
+ v = f.createLiteral((boolean)val);
+ } else if (val instanceof BigInteger) {
+ v = f.createLiteral((BigInteger)val);
+ } else if (val instanceof BigDecimal) {
+ v = f.createLiteral((BigDecimal)val);
+ } else {
+ String str = normalizeAndReportIfInvalid(val.toString(), dataType, zone, result);
+
+ if (XMLSchema.STRING.equals(dataType)) {
+ if (lang == null) {
+ v = f.createLiteral(str);
+ } else {
+ v = f.createLiteral(str, lang);
+ }
+ } else if (XMLSchema.ANYURI.equals(dataType)) {
+ try {
+ v = f.createIRI(str);
+ } catch (IllegalArgumentException e) {
+ v = f.createLiteral(str, dataType);
+ }
+ } else if (vICAL.Value_PERIOD.equals(dataType)) {
+ String[] strs = str.split("/");
+ if (strs.length != 2) {
+ v = f.createLiteral(str);
+ } else {
+ BNode bNode = f.createBNode();
+ result.writeTriple(subject, predicate, bNode);
+ result.writeTriple(bNode, RDF.TYPE, dataType);
+
+ String start = normalizeAndReportIfInvalid(strs[0], XMLSchema.DATETIME, zone, result);
+ result.writeTriple(bNode, vICAL.dtstart, f.createLiteral(start, XMLSchema.DATETIME));
+ String str1 = strs[1];
+ if (str1.indexOf('P') != -1) { //duration
+ String duration = normalizeAndReportIfInvalid(str1, XMLSchema.DURATION, zone, result);
+ result.writeTriple(bNode, vICAL.duration, f.createLiteral(duration, XMLSchema.DURATION));
+ } else {
+ String end = normalizeAndReportIfInvalid(str1, XMLSchema.DATETIME, zone, result);
+ result.writeTriple(bNode, vICAL.dtend, f.createLiteral(end, XMLSchema.DATETIME));
+ }
+ return true;
+ }
+ } else if (dataType != null) {
+ v = f.createLiteral(str, dataType);
+ } else {
+ v = f.createLiteral(str);
+ }
+
+ }
+ result.writeTriple(subject, predicate, v);
+ return true;
+ }
+
+ List<JsonValue> array = jsonValue.getArray();
+ if (array != null && !array.isEmpty()) {
+ if (array.size() == 1) {
+ return writeValue(subject, predicate, array.get(0), lang, dataType, zone, result);
+ } else {
+ BNode bNode = f.createBNode();
+ result.writeTriple(subject, predicate, bNode);
+ for (JsonValue value : array) {
+ writeValue(bNode, RDF.VALUE, value, lang, dataType, zone, result);
+ }
+ return true;
+ }
+ }
+
+ Map<String, JsonValue> object = jsonValue.getObject();
+ if (object != null) {
+ BNode bNode = f.createBNode();
+ result.writeTriple(subject, predicate, bNode);
+ if (dataType != null && ICAL.NS.equals(dataType.getNamespace())) {
+ result.writeTriple(bNode, RDF.TYPE, dataType);
+ }
+ for (Map.Entry<String, JsonValue> entry : object.entrySet()) {
+ writeValue(bNode, predicate(entry.getKey(), result), entry.getValue(), lang, XMLSchema.STRING, zone, result);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ private static TimeZone getTimeZone(ICalProperty prop, TimezoneInfo info) {
+ if (info.isFloating(prop)) {
return null;
}
+ TimezoneAssignment assignment = info.getTimezoneToWriteIn(prop);
+ if (assignment == null) {
+ return TimeZone.getTimeZone(ZoneOffset.UTC);
+ } else {
+ return assignment.getTimeZone();
+ }
}
- private static void extract(ScribeIndex index, TimezoneInfo info, BNode node, ICalComponent component, ExtractionResult extractionResult) {
- for (ICalProperty property : component.getProperties().values()) {
- ICalPropertyScribe<?> scribe = index.getPropertyScribe(property);
- IRI predicate = predicate(scribe, extractionResult);
- if (predicate != null) {
- Value value = value(scribe, property, info);
- if (value != null) {
- extractionResult.writeTriple(node, predicate, value);
+ @SuppressWarnings("unchecked")
+ private static <T extends ICalProperty> void writeProperty(BNode subject, ICalPropertyScribe<T> scribe, ICalProperty property, WriteContext ctx, ExtractionResult result) {
+ try {
+ T prop = (T)property;
+
+ ICalVersion version = ctx.getVersion();
+
+ ICalDataType dataType = scribe.dataType(prop, version);
+
+ ICalParameters params = scribe.prepareParameters(prop, ctx);
+
+ String lang = params.getLanguage();
+ params.removeAll(ICalParameters.LANGUAGE);
+
+ Encoding encoding = params.getEncoding();
+
+ if (dataType == null) {
+ dataType = params.getValue();
+ if (dataType == null && Encoding.BASE64.equals(encoding)) {
+ dataType = ICalDataType.BINARY;
+ }
+ }
+ params.removeAll(ICalParameters.VALUE);
+
+ if (ICalDataType.BINARY.equals(dataType)) {
+ // RFC 5545 s. 3.2.7.
+ // If the value type parameter is ";VALUE=BINARY", then the inline
+ // encoding parameter MUST be specified with the value
+ // ";ENCODING=BASE64"
+ if (encoding != null && !Encoding.BASE64.equals(encoding)) {
+ result.notifyIssue(IssueReport.IssueLevel.ERROR,
+ "Invalid encoding " + encoding + " specified for BINARY value", -1, -1);
+ dataType = null;
}
+ params.removeAll(ICalParameters.ENCODING);
}
+
+ if (Encoding._8BIT.equals(encoding)) {
+ // RFC 5545 s. 3.2.7.
+ // The default encoding is "8BIT",
+ // corresponding to a property value consisting of text.
+ params.removeAll(ICalParameters.ENCODING);
+ }
+
+ // RFC 5545 s. 3.1.4.
+ // There is not a property parameter to declare the charset used in a
+ // property value. The default charset for an iCalendar stream is UTF-8
+ // as defined in [RFC3629].
+ params.removeAll(ICalParameters.CHARSET);
+
+ IRI predicate = predicate(scribe.getPropertyName(version), result);
+
+ if (!params.isEmpty()) {
+ BNode bNode = f.createBNode();
+ result.writeTriple(subject, predicate, bNode);
+ writeParams(bNode, params, result);
+
+ subject = bNode;
+ predicate = RDF.VALUE;
+ }
+
+ if (prop instanceof Geo) {
+ // RFC 5870
+ Geo g = (Geo)prop;
+ IRI value = f.createIRI("geo:" + str(g.getLatitude()) + "," + str(g.getLongitude()));
+ result.writeTriple(subject, predicate, value);
+ } else {
+ TimeZone timeZone = getTimeZone(prop, ctx.getTimezoneInfo());
+ IRI dataTypeIRI = dataType(dataType);
+
+ JCalValue jsonVal = scribe.writeJson(prop, ctx);
+ List<JsonValue> jsonVals = jsonVal.getValues();
+
+ boolean mod = false;
+ for (JsonValue value : jsonVals) {
+ mod |= writeValue(subject, predicate, value, lang, dataTypeIRI, timeZone, result);
+ }
+ if (!mod) {
+ result.writeTriple(subject, predicate, f.createLiteral(jsonVal.asSingle()));
+ }
+ }
+ } catch (SkipMeException e) {
+ //ignore
+ }
+ }
+
+ private static void extract(ScribeIndex index, WriteContext ctx, BNode node, ICalComponent component, ExtractionResult result, boolean writeTimezones) {
+ for (ICalProperty property : component.getProperties().values()) {
+ ctx.setParent(component);
+ writeProperty(node, index.getPropertyScribe(property), property, ctx, result);
}
- for (ICalComponent child : component.getComponents().values()) {
+
+ Stream<ICalComponent> components = component.getComponents().values().stream();
+
+ if (writeTimezones) {
+ Collection<VTimezone> tzs = ctx.getTimezoneInfo().getComponents();
+ Set<String> tzIds = tzs.stream()
+ .map(tz -> tz.getTimezoneId().getValue())
+ .collect(Collectors.toSet());
+ components = Stream.concat(tzs.stream(), components.filter(c ->
+ !(c instanceof VTimezone && tzIds.contains(((VTimezone) c).getTimezoneId().getValue())))
+ );
+ }
+
+ components.forEachOrdered(child -> {
BNode childNode = f.createBNode();
- extractionResult.writeTriple(node, vICAL.component, childNode);
- IRI childType = type(index.getComponentScribe(child), extractionResult);
- if (childType != null) {
- extractionResult.writeTriple(childNode, RDF.TYPE, childType);
+ String componentName = index.getComponentScribe(child).getComponentName();
+ IRI childType = type(componentName);
+
+ if (childType == null) {
+ result.writeTriple(node, predicate(componentName, result), childNode);
+ } else {
+ result.writeTriple(node, vICAL.component, childNode);
+ result.writeTriple(childNode, RDF.TYPE, childType);
}
- extract(index, info, childNode, child, extractionResult);
- }
+ extract(index, ctx, childNode, child, result, false);
+ });
}
}
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/core/src/test/java/org/apache/any23/extractor/calendar/BaseCalendarExtractorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/any23/extractor/calendar/BaseCalendarExtractorTest.java b/core/src/test/java/org/apache/any23/extractor/calendar/BaseCalendarExtractorTest.java
new file mode 100644
index 0000000..701b9ad
--- /dev/null
+++ b/core/src/test/java/org/apache/any23/extractor/calendar/BaseCalendarExtractorTest.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import org.apache.any23.extractor.html.AbstractExtractorTestCase;
+import org.eclipse.rdf4j.model.BNode;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.repository.RepositoryException;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.RDFHandler;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParseException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.Rio;
+import org.junit.Assert;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+abstract class BaseCalendarExtractorTest extends AbstractExtractorTestCase {
+
+ abstract String filePrefix();
+
+ protected void extractAndVerifyAgainstNQuads(String actual, String expected)
+ throws RepositoryException, RDFHandlerException, IOException, RDFParseException {
+ String filePrefix = filePrefix();
+ assertExtract(filePrefix + actual);
+ assertModelNotEmpty();
+ List<Statement> expectedStatements = loadResultStatement(filePrefix + expected);
+ int actualStmtSize = getStatementsSize(null, null, null);
+ Assert.assertEquals(expectedStatements.size(), actualStmtSize);
+ for (Statement statement : expectedStatements) {
+ assertContains(
+ statement.getSubject() instanceof BNode ? null : statement.getSubject(),
+ statement.getPredicate(),
+ statement.getObject() instanceof BNode ? null : statement.getObject()
+ );
+ }
+ }
+
+ private List<Statement> loadResultStatement(String resultFilePath)
+ throws RDFHandlerException, IOException, RDFParseException {
+ RDFParser nQuadsParser = Rio.createParser(RDFFormat.NQUADS);
+ TestRDFHandler rdfHandler = new TestRDFHandler();
+ nQuadsParser.setRDFHandler(rdfHandler);
+ File file = copyResourceToTempFile(resultFilePath);
+ nQuadsParser.parse(
+ new FileReader(file),
+ baseIRI.toString()
+ );
+ return rdfHandler.getStatements();
+ }
+
+ private static class TestRDFHandler implements RDFHandler {
+
+ private final List<Statement> statements = new ArrayList<Statement>();
+
+ protected List<Statement> getStatements() {
+ return statements;
+ }
+
+ public void startRDF() throws RDFHandlerException {
+ }
+
+ public void endRDF() throws RDFHandlerException {
+ }
+
+ public void handleNamespace(String s, String s1) throws RDFHandlerException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void handleStatement(Statement statement) throws RDFHandlerException {
+ statements.add(statement);
+ }
+
+ public void handleComment(String s) throws RDFHandlerException {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/core/src/test/java/org/apache/any23/extractor/calendar/ICalExtractorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/any23/extractor/calendar/ICalExtractorTest.java b/core/src/test/java/org/apache/any23/extractor/calendar/ICalExtractorTest.java
new file mode 100644
index 0000000..9000d64
--- /dev/null
+++ b/core/src/test/java/org/apache/any23/extractor/calendar/ICalExtractorTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import org.apache.any23.extractor.ExtractorFactory;
+import org.junit.Test;
+
+import java.io.IOException;
+
+
+public class ICalExtractorTest extends BaseCalendarExtractorTest {
+ @Override
+ protected ExtractorFactory<?> getExtractorFactory() {
+ return new ICalExtractorFactory();
+ }
+
+ @Override
+ String filePrefix() {
+ return "/calendar.text/";
+ }
+
+ @Test
+ public void testRFC5545example1() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc5545-example1.ics", "rfc5545-example1-expected.nquads");
+ }
+
+ @Test
+ public void testRFC5545example2() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc5545-example2.ics", "rfc5545-example2-expected.nquads");
+ }
+
+ @Test
+ public void testRFC5545example3() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc5545-example3.ics", "rfc5545-example3-expected.nquads");
+ }
+
+ @Test
+ public void testRFC5545example4() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc5545-example4.ics", "rfc5545-example4-expected.nquads");
+ }
+
+ @Test
+ public void testRFC5545example5() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc5545-example5.ics", "rfc5545-example5-expected.nquads");
+ }
+
+ @Test
+ public void testRFC5545example6() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc5545-example6.ics", "rfc5545-example6-expected.nquads");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/core/src/test/java/org/apache/any23/extractor/calendar/JCalExtractorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/any23/extractor/calendar/JCalExtractorTest.java b/core/src/test/java/org/apache/any23/extractor/calendar/JCalExtractorTest.java
new file mode 100644
index 0000000..bbe633b
--- /dev/null
+++ b/core/src/test/java/org/apache/any23/extractor/calendar/JCalExtractorTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import org.apache.any23.extractor.ExtractorFactory;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class JCalExtractorTest extends BaseCalendarExtractorTest {
+
+ @Override
+ String filePrefix() {
+ return "/calendar.json/";
+ }
+
+ @Override
+ protected ExtractorFactory<?> getExtractorFactory() {
+ return new JCalExtractorFactory();
+ }
+
+ @Test
+ public void testRFC7265example1() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc7265-example1.json", "rfc7265-example1-expected.nquads");
+ }
+
+ @Test
+ public void testRFC7265example2() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc7265-example2.json", "rfc7265-example2-expected.nquads");
+ }
+}
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/core/src/test/java/org/apache/any23/extractor/calendar/XCalExtractorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/any23/extractor/calendar/XCalExtractorTest.java b/core/src/test/java/org/apache/any23/extractor/calendar/XCalExtractorTest.java
new file mode 100644
index 0000000..c063179
--- /dev/null
+++ b/core/src/test/java/org/apache/any23/extractor/calendar/XCalExtractorTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.any23.extractor.calendar;
+
+import org.apache.any23.extractor.ExtractorFactory;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class XCalExtractorTest extends BaseCalendarExtractorTest {
+
+ @Override
+ String filePrefix() {
+ return "/calendar.xml/";
+ }
+
+ @Override
+ protected ExtractorFactory<?> getExtractorFactory() {
+ return new XCalExtractorFactory();
+ }
+
+ @Test
+ public void testRFC6321example1() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc6321-example1.xml", "rfc6321-example1-expected.nquads");
+ }
+
+ @Test
+ public void testRFC6321example2() throws IOException {
+ extractAndVerifyAgainstNQuads("rfc6321-example2.xml", "rfc6321-example2-expected.nquads");
+ }
+}
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/core/src/test/java/org/apache/any23/vocab/RDFSchemaUtilsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/any23/vocab/RDFSchemaUtilsTest.java b/core/src/test/java/org/apache/any23/vocab/RDFSchemaUtilsTest.java
index d8fd8d5..83917bf 100644
--- a/core/src/test/java/org/apache/any23/vocab/RDFSchemaUtilsTest.java
+++ b/core/src/test/java/org/apache/any23/vocab/RDFSchemaUtilsTest.java
@@ -43,7 +43,7 @@ public class RDFSchemaUtilsTest {
*/
@Test
public void testSerializeVocabulariesNTriples() {
- serializeVocabularies(RDFFormat.NTRIPLES, 2174);
+ serializeVocabularies(RDFFormat.NTRIPLES, 2178);
}
/**
@@ -53,7 +53,7 @@ public class RDFSchemaUtilsTest {
*/
@Test
public void testSerializeVocabulariesRDFXML() {
- serializeVocabularies(RDFFormat.RDFXML, 5699); // Effective lines + separators.
+ serializeVocabularies(RDFFormat.RDFXML, 5709); // Effective lines + separators.
}
private void serializeVocabularies(RDFFormat format, int expectedLines) {
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.json/rfc7265-example1-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.json/rfc7265-example1-expected.nquads b/test-resources/src/test/resources/calendar.json/rfc7265-example1-expected.nquads
new file mode 100644
index 0000000..ae9c0bc
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.json/rfc7265-example1-expected.nquads
@@ -0,0 +1,26 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu3uv03x2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu3uv03x2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//Example Inc.//Example Calendar//EN" <http://bob.example.com/> .
+_:node1clu3uv03x2 <http://www.w3.org/2002/12/cal/icaltzd#calscale> "GREGORIAN" <http://bob.example.com/> .
+_:node1clu3uv03x2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu3uv03x3 <http://bob.example.com/> .
+_:node1clu3uv03x3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vevent> <http://bob.example.com/> .
+_:node1clu3uv03x3 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "2008-02-05T19:12:24Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu3uv03x3 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "2008-10-06"^^<http://www.w3.org/2001/XMLSchema#date> <http://bob.example.com/> .
+_:node1clu3uv03x3 <http://www.w3.org/2002/12/cal/icaltzd#summary> "Planning meeting" <http://bob.example.com/> .
+_:node1clu3uv03x3 <http://www.w3.org/2002/12/cal/icaltzd#uid> "4088E990AD89CB3DBB484909" <http://bob.example.com/> .
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.json/rfc7265-example1.json
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.json/rfc7265-example1.json b/test-resources/src/test/resources/calendar.json/rfc7265-example1.json
new file mode 100755
index 0000000..c94699e
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.json/rfc7265-example1.json
@@ -0,0 +1,18 @@
+["vcalendar",
+ [
+ ["version", {}, "text", "2.0"],
+ ["prodid", {}, "text", "-//Example Inc.//Example Calendar//EN"],
+ ["calscale", {}, "text", "GREGORIAN"]
+ ],
+ [
+ ["vevent",
+ [
+ ["dtstamp", {}, "date-time", "2008-02-05T19:12:24Z"],
+ ["dtstart", {}, "date", "2008-10-06"],
+ ["summary", {}, "text", "Planning meeting"],
+ ["uid", {}, "text", "4088E990AD89CB3DBB484909"]
+ ],
+ []
+ ]
+ ]
+]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.json/rfc7265-example2-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.json/rfc7265-example2-expected.nquads b/test-resources/src/test/resources/calendar.json/rfc7265-example2-expected.nquads
new file mode 100644
index 0000000..11ce490
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.json/rfc7265-example2-expected.nquads
@@ -0,0 +1,75 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu415j2x2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu415j2x2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//Example Corp.//Example Client//EN" <http://bob.example.com/> .
+_:node1clu415j2x2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu415j2x3 <http://bob.example.com/> .
+_:node1clu415j2x3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vtimezone> <http://bob.example.com/> .
+_:node1clu415j2x3 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu415j2x3 <http://www.w3.org/2002/12/cal/icaltzd#lastModified> "2004-01-10T03:28:45Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu415j2x3 <http://www.w3.org/2002/12/cal/icaltzd#daylight> _:node1clu415j2x4 <http://bob.example.com/> .
+_:node1clu415j2x4 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "2000-04-04T02:00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu415j2x4 <http://www.w3.org/2002/12/cal/icaltzd#rrule> _:node1clu415j2x5 <http://bob.example.com/> .
+_:node1clu415j2x5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_RECUR> <http://bob.example.com/> .
+_:node1clu415j2x5 <http://www.w3.org/2002/12/cal/icaltzd#freq> "YEARLY" <http://bob.example.com/> .
+_:node1clu415j2x5 <http://www.w3.org/2002/12/cal/icaltzd#byday> "1SU" <http://bob.example.com/> .
+_:node1clu415j2x5 <http://www.w3.org/2002/12/cal/icaltzd#bymonth> "4"^^<http://www.w3.org/2001/XMLSchema#int> <http://bob.example.com/> .
+_:node1clu415j2x4 <http://www.w3.org/2002/12/cal/icaltzd#tzname> "EDT" <http://bob.example.com/> .
+_:node1clu415j2x4 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetfrom> "-05:00" <http://bob.example.com/> .
+_:node1clu415j2x4 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetto> "-04:00" <http://bob.example.com/> .
+_:node1clu415j2x3 <http://www.w3.org/2002/12/cal/icaltzd#standard> _:node1clu415j2x6 <http://bob.example.com/> .
+_:node1clu415j2x6 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "2000-10-26T02:00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu415j2x6 <http://www.w3.org/2002/12/cal/icaltzd#rrule> _:node1clu415j2x7 <http://bob.example.com/> .
+_:node1clu415j2x7 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_RECUR> <http://bob.example.com/> .
+_:node1clu415j2x7 <http://www.w3.org/2002/12/cal/icaltzd#freq> "YEARLY" <http://bob.example.com/> .
+_:node1clu415j2x7 <http://www.w3.org/2002/12/cal/icaltzd#byday> "1SU" <http://bob.example.com/> .
+_:node1clu415j2x7 <http://www.w3.org/2002/12/cal/icaltzd#bymonth> "10"^^<http://www.w3.org/2001/XMLSchema#int> <http://bob.example.com/> .
+_:node1clu415j2x6 <http://www.w3.org/2002/12/cal/icaltzd#tzname> "EST" <http://bob.example.com/> .
+_:node1clu415j2x6 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetfrom> "-04:00" <http://bob.example.com/> .
+_:node1clu415j2x6 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetto> "-05:00" <http://bob.example.com/> .
+_:node1clu415j2x2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu415j2x8 <http://bob.example.com/> .
+_:node1clu415j2x8 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vevent> <http://bob.example.com/> .
+_:node1clu415j2x8 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "2006-02-06T00:11:21Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu415j2x8 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> _:node1clu415j2x9 <http://bob.example.com/> .
+_:node1clu415j2x9 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu415j2x9 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> "2006-01-02T12:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu415j2x8 <http://www.w3.org/2002/12/cal/icaltzd#duration> "PT1H"^^<http://www.w3.org/2001/XMLSchema#duration> <http://bob.example.com/> .
+_:node1clu415j2x8 <http://www.w3.org/2002/12/cal/icaltzd#rrule> _:node1clu415j2x10 <http://bob.example.com/> .
+_:node1clu415j2x10 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_RECUR> <http://bob.example.com/> .
+_:node1clu415j2x10 <http://www.w3.org/2002/12/cal/icaltzd#freq> "DAILY" <http://bob.example.com/> .
+_:node1clu415j2x10 <http://www.w3.org/2002/12/cal/icaltzd#count> "5"^^<http://www.w3.org/2001/XMLSchema#int> <http://bob.example.com/> .
+_:node1clu415j2x8 <http://www.w3.org/2002/12/cal/icaltzd#rdate> _:node1clu415j2x11 <http://bob.example.com/> .
+_:node1clu415j2x11 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu415j2x11 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> _:node1clu415j2x12 <http://bob.example.com/> .
+_:node1clu415j2x12 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_PERIOD> <http://bob.example.com/> .
+_:node1clu415j2x12 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "2006-01-02T15:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu415j2x12 <http://www.w3.org/2002/12/cal/icaltzd#duration> "PT2H"^^<http://www.w3.org/2001/XMLSchema#duration> <http://bob.example.com/> .
+_:node1clu415j2x8 <http://www.w3.org/2002/12/cal/icaltzd#summary> "Event #2" <http://bob.example.com/> .
+_:node1clu415j2x8 <http://www.w3.org/2002/12/cal/icaltzd#description> "We are having a meeting all this week at 12 pm for one hour, with an additional meeting on the first day 2 hours long.\nPlease bring your own lunch for the 12 pm meetings." <http://bob.example.com/> .
+_:node1clu415j2x8 <http://www.w3.org/2002/12/cal/icaltzd#uid> "00959BC664CA650E933C892C@example.com" <http://bob.example.com/> .
+_:node1clu415j2x2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu415j2x13 <http://bob.example.com/> .
+_:node1clu415j2x13 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vevent> <http://bob.example.com/> .
+_:node1clu415j2x13 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "2006-02-06T00:11:21Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu415j2x13 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> _:node1clu415j2x14 <http://bob.example.com/> .
+_:node1clu415j2x14 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu415j2x14 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> "2006-01-02T14:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu415j2x13 <http://www.w3.org/2002/12/cal/icaltzd#duration> "PT1H"^^<http://www.w3.org/2001/XMLSchema#duration> <http://bob.example.com/> .
+_:node1clu415j2x13 <http://www.w3.org/2002/12/cal/icaltzd#recurrenceId> _:node1clu415j2x15 <http://bob.example.com/> .
+_:node1clu415j2x15 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "US/Eastern" <http://bob.example.com/> .
+_:node1clu415j2x15 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> "2006-01-04T12:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu415j2x13 <http://www.w3.org/2002/12/cal/icaltzd#summary> "Event #2" <http://bob.example.com/> .
+_:node1clu415j2x13 <http://www.w3.org/2002/12/cal/icaltzd#uid> "00959BC664CA650E933C892C@example.com" <http://bob.example.com/> .
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.json/rfc7265-example2.json
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.json/rfc7265-example2.json b/test-resources/src/test/resources/calendar.json/rfc7265-example2.json
new file mode 100755
index 0000000..1deb906
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.json/rfc7265-example2.json
@@ -0,0 +1,96 @@
+["vcalendar",
+ [
+ ["version", {}, "text", "2.0"],
+ ["prodid", {}, "text", "-//Example Corp.//Example Client//EN"]
+ ],
+ [
+ ["vtimezone",
+ [
+ ["tzid", {}, "text", "US/Eastern"],
+ ["last-modified", {}, "date-time", "2004-01-10T03:28:45Z"]
+ ],
+ [
+ ["daylight",
+ [
+ ["dtstart", {}, "date-time", "2000-04-04T02:00:00"],
+ ["rrule",
+ {},
+ "recur",
+ {
+ "freq": "YEARLY",
+ "byday": "1SU",
+ "bymonth": 4
+ }
+ ],
+ ["tzname", {}, "text", "EDT"],
+ ["tzoffsetfrom", {}, "utc-offset", "-05:00"],
+ ["tzoffsetto", {}, "utc-offset", "-04:00"]
+ ],
+ []
+ ],
+ ["standard",
+ [
+ ["dtstart", {}, "date-time", "2000-10-26T02:00:00"],
+ ["rrule",
+ {},
+ "recur",
+ {
+ "freq": "YEARLY",
+ "byday": "1SU",
+ "bymonth": 10
+ }
+ ],
+ ["tzname", {}, "text", "EST"],
+ ["tzoffsetfrom", {}, "utc-offset", "-04:00"],
+ ["tzoffsetto", {}, "utc-offset", "-05:00"]
+ ],
+ []
+ ]
+ ]
+ ],
+ ["vevent",
+ [
+ ["dtstamp", {}, "date-time", "2006-02-06T00:11:21Z"],
+ ["dtstart",
+ { "tzid": "US/Eastern" },
+ "date-time",
+ "2006-01-02T12:00:00"
+ ],
+ ["duration", {}, "duration", "PT1H"],
+ ["rrule", {}, "recur", {"freq": "DAILY", "count": 5 }],
+ ["rdate",
+ { "tzid": "US/Eastern" },
+ "period",
+ "2006-01-02T15:00:00/PT2H"
+ ],
+ ["summary", {}, "text", "Event #2"],
+ ["description",
+ {},
+ "text",
+ "We are having a meeting all this week at 12 pm for one hour, with an additional meeting on the first day 2 hours long.\nPlease bring your own lunch for the 12 pm meetings."
+ ],
+ ["uid", {}, "text", "00959BC664CA650E933C892C@example.com"]
+ ],
+ []
+ ],
+ ["vevent",
+ [
+ ["dtstamp", {}, "date-time", "2006-02-06T00:11:21Z"],
+ ["dtstart",
+ { "tzid": "US/Eastern" },
+ "date-time",
+ "2006-01-02T14:00:00"
+ ],
+ ["duration", {}, "duration", "PT1H"],
+ ["recurrence-id",
+ { "tzid": "US/Eastern" },
+ "date-time",
+ "2006-01-04T12:00:00"
+ ],
+ ["summary", {}, "text", "Event #2"],
+ ["uid", {}, "text", "00959BC664CA650E933C892C@example.com"]
+ ],
+ []
+ ]
+ ]
+]
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example1-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example1-expected.nquads b/test-resources/src/test/resources/calendar.text/rfc5545-example1-expected.nquads
new file mode 100644
index 0000000..c043a1c
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example1-expected.nquads
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu1knnlx2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu1knnlx2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN" <http://bob.example.com/> .
+_:node1clu1knnlx2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu1knnlx3 <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vevent> <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "1996-07-04T12:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/2002/12/cal/icaltzd#uid> "uid1@example.com" <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/2002/12/cal/icaltzd#organizer> <ma...@example.com> <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "1996-09-18T14:30:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/2002/12/cal/icaltzd#dtend> "1996-09-20T22:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/2002/12/cal/icaltzd#status> "CONFIRMED" <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/2002/12/cal/icaltzd#categories> "CONFERENCE" <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/2002/12/cal/icaltzd#summary> "Networld+Interop Conference" <http://bob.example.com/> .
+_:node1clu1knnlx3 <http://www.w3.org/2002/12/cal/icaltzd#description> "Networld+Interop Conferenceand Exhibit\nAtlanta World Congress Center\nAtlanta, Georgia" <http://bob.example.com/> .
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example1.ics
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example1.ics b/test-resources/src/test/resources/calendar.text/rfc5545-example1.ics
new file mode 100755
index 0000000..34ba23e
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example1.ics
@@ -0,0 +1,17 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN
+BEGIN:VEVENT
+DTSTAMP:19960704T120000Z
+UID:uid1@example.com
+ORGANIZER:mailto:jsmith@example.com
+DTSTART:19960918T143000Z
+DTEND:19960920T220000Z
+STATUS:CONFIRMED
+CATEGORIES:CONFERENCE
+SUMMARY:Networld+Interop Conference
+DESCRIPTION:Networld+Interop Conference
+ and Exhibit\nAtlanta World Congress Center\n
+ Atlanta\, Georgia
+END:VEVENT
+END:VCALENDAR
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example2-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example2-expected.nquads b/test-resources/src/test/resources/calendar.text/rfc5545-example2-expected.nquads
new file mode 100644
index 0000000..89f06e8
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example2-expected.nquads
@@ -0,0 +1,55 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu1u3ipx2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu1u3ipx2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//RDU Software//NONSGML HandCal//EN" <http://bob.example.com/> .
+_:node1clu1u3ipx2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu1u3ipx3 <http://bob.example.com/> .
+_:node1clu1u3ipx3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vtimezone> <http://bob.example.com/> .
+_:node1clu1u3ipx3 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "America/New_York" <http://bob.example.com/> .
+_:node1clu1u3ipx3 <http://www.w3.org/2002/12/cal/icaltzd#standard> _:node1clu1u3ipx4 <http://bob.example.com/> .
+_:node1clu1u3ipx4 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "1998-10-25T02:00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu1u3ipx4 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetfrom> "-04:00" <http://bob.example.com/> .
+_:node1clu1u3ipx4 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetto> "-05:00" <http://bob.example.com/> .
+_:node1clu1u3ipx4 <http://www.w3.org/2002/12/cal/icaltzd#tzname> "EST" <http://bob.example.com/> .
+_:node1clu1u3ipx3 <http://www.w3.org/2002/12/cal/icaltzd#daylight> _:node1clu1u3ipx5 <http://bob.example.com/> .
+_:node1clu1u3ipx5 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "1999-04-04T02:00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu1u3ipx5 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetfrom> "-05:00" <http://bob.example.com/> .
+_:node1clu1u3ipx5 <http://www.w3.org/2002/12/cal/icaltzd#tzoffsetto> "-04:00" <http://bob.example.com/> .
+_:node1clu1u3ipx5 <http://www.w3.org/2002/12/cal/icaltzd#tzname> "EDT" <http://bob.example.com/> .
+_:node1clu1u3ipx2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu1u3ipx6 <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vevent> <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "1998-03-09T23:10:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#uid> "guid-1.example.com" <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#organizer> <ma...@example.com> <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#attendee> _:node1clu1u3ipx7 <http://bob.example.com/> .
+_:node1clu1u3ipx7 <http://www.w3.org/2002/12/cal/icaltzd#cutype> "GROUP" <http://bob.example.com/> .
+_:node1clu1u3ipx7 <http://www.w3.org/2002/12/cal/icaltzd#rsvp> "TRUE" <http://bob.example.com/> .
+_:node1clu1u3ipx7 <http://www.w3.org/2002/12/cal/icaltzd#role> "REQ-PARTICIPANT" <http://bob.example.com/> .
+_:node1clu1u3ipx7 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> <ma...@example.com> <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#description> "Project XYZ Review Meeting" <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#categories> "MEETING" <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#class> "PUBLIC" <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#created> "1998-03-09T13:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#summary> "XYZ Project Review" <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> _:node1clu1u3ipx8 <http://bob.example.com/> .
+_:node1clu1u3ipx8 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "America/New_York" <http://bob.example.com/> .
+_:node1clu1u3ipx8 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> "1998-03-12T08:30:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#dtend> _:node1clu1u3ipx9 <http://bob.example.com/> .
+_:node1clu1u3ipx9 <http://www.w3.org/2002/12/cal/icaltzd#tzid> "America/New_York" <http://bob.example.com/> .
+_:node1clu1u3ipx9 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> "1998-03-12T09:30:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu1u3ipx6 <http://www.w3.org/2002/12/cal/icaltzd#location> "1CP Conference Room 4350" <http://bob.example.com/> .
+
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example2.ics
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example2.ics b/test-resources/src/test/resources/calendar.text/rfc5545-example2.ics
new file mode 100755
index 0000000..0bb0c27
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example2.ics
@@ -0,0 +1,34 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//RDU Software//NONSGML HandCal//EN
+BEGIN:VTIMEZONE
+TZID:America/New_York
+BEGIN:STANDARD
+DTSTART:19981025T020000
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+TZNAME:EST
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:19990404T020000
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+TZNAME:EDT
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:19980309T231000Z
+UID:guid-1.example.com
+ORGANIZER:mailto:mrbig@example.com
+ATTENDEE;CUTYPE=GROUP;RSVP=TRUE;ROLE=REQ-PARTICIPANT:
+ mailto:employee-A@example.com
+DESCRIPTION:Project XYZ Review Meeting
+CATEGORIES:MEETING
+CLASS:PUBLIC
+CREATED:19980309T130000Z
+SUMMARY:XYZ Project Review
+DTSTART;TZID=America/New_York:19980312T083000
+DTEND;TZID=America/New_York:19980312T093000
+LOCATION:1CP Conference Room 4350
+END:VEVENT
+END:VCALENDAR
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example3-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example3-expected.nquads b/test-resources/src/test/resources/calendar.text/rfc5545-example3-expected.nquads
new file mode 100644
index 0000000..9d48895
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example3-expected.nquads
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu24refx2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu24refx2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//ABC Corporation//NONSGML My Product//EN" <http://bob.example.com/> .
+_:node1clu24refx2 <http://www.w3.org/2002/12/cal/icaltzd#method> "xyz" <http://bob.example.com/> .
+_:node1clu24refx2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu24refx3 <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vevent> <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "1997-03-24T12:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#sequence> "0"^^<http://www.w3.org/2001/XMLSchema#int> <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#uid> "uid3@example.com" <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#organizer> <ma...@example.com> <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#attendee> _:node1clu24refx4 <http://bob.example.com/> .
+_:node1clu24refx4 <http://www.w3.org/2002/12/cal/icaltzd#rsvp> "TRUE" <http://bob.example.com/> .
+_:node1clu24refx4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> <ma...@example.com> <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "1997-03-24T12:30:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#dtend> "1997-03-24T21:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#categories> "MEETING" <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#categories> "PROJECT" <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#class> "PUBLIC" <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#summary> "Calendaring Interoperability Planning Meeting" <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#description> "Discuss how we can test c&s interoperability\nusing iCalendar and other IETF standards." <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#location> "LDB Lobby" <http://bob.example.com/> .
+_:node1clu24refx3 <http://www.w3.org/2002/12/cal/icaltzd#attach> _:node1clu24refx5 <http://bob.example.com/> .
+_:node1clu24refx5 <http://www.w3.org/2002/12/cal/icaltzd#fmttype> "application/postscript" <http://bob.example.com/> .
+_:node1clu24refx5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> <ftp://example.com/pub/conf/bkgrnd.ps> <http://bob.example.com/> .
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example3.ics
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example3.ics b/test-resources/src/test/resources/calendar.text/rfc5545-example3.ics
new file mode 100755
index 0000000..da83a1b
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example3.ics
@@ -0,0 +1,22 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//ABC Corporation//NONSGML My Product//EN
+METHOD:xyz
+BEGIN:VEVENT
+DTSTAMP:19970324T120000Z
+SEQUENCE:0
+UID:uid3@example.com
+ORGANIZER:mailto:jdoe@example.com
+ATTENDEE;RSVP=TRUE:mailto:jsmith@example.com
+DTSTART:19970324T123000Z
+DTEND:19970324T210000Z
+CATEGORIES:MEETING,PROJECT
+CLASS:PUBLIC
+SUMMARY:Calendaring Interoperability Planning Meeting
+DESCRIPTION:Discuss how we can test c&s interoperability\n
+ using iCalendar and other IETF standards.
+LOCATION:LDB Lobby
+ATTACH;FMTTYPE=application/postscript:ftp://example.com/pub/
+ conf/bkgrnd.ps
+END:VEVENT
+END:VCALENDAR
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example4-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example4-expected.nquads b/test-resources/src/test/resources/calendar.text/rfc5545-example4-expected.nquads
new file mode 100644
index 0000000..7b34215
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example4-expected.nquads
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu27ji5x2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu27ji5x2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//ABC Corporation//NONSGML My Product//EN" <http://bob.example.com/> .
+_:node1clu27ji5x2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu27ji5x3 <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vtodo> <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "1998-01-30T13:45:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/2002/12/cal/icaltzd#sequence> "2"^^<http://www.w3.org/2001/XMLSchema#int> <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/2002/12/cal/icaltzd#uid> "uid4@example.com" <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/2002/12/cal/icaltzd#organizer> <ma...@example.com> <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/2002/12/cal/icaltzd#attendee> _:node1clu27ji5x4 <http://bob.example.com/> .
+_:node1clu27ji5x4 <http://www.w3.org/2002/12/cal/icaltzd#partstat> "ACCEPTED" <http://bob.example.com/> .
+_:node1clu27ji5x4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> <ma...@example.com> <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/2002/12/cal/icaltzd#due> "1998-04-15T00:00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/2002/12/cal/icaltzd#status> "NEEDS-ACTION" <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/2002/12/cal/icaltzd#summary> "Submit Income Taxes" <http://bob.example.com/> .
+_:node1clu27ji5x3 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu27ji5x5 <http://bob.example.com/> .
+_:node1clu27ji5x5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Valarm> <http://bob.example.com/> .
+_:node1clu27ji5x5 <http://www.w3.org/2002/12/cal/icaltzd#action> "AUDIO" <http://bob.example.com/> .
+_:node1clu27ji5x5 <http://www.w3.org/2002/12/cal/icaltzd#trigger> "1998-04-03T12:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu27ji5x5 <http://www.w3.org/2002/12/cal/icaltzd#attach> _:node1clu27ji5x6 <http://bob.example.com/> .
+_:node1clu27ji5x6 <http://www.w3.org/2002/12/cal/icaltzd#fmttype> "audio/basic" <http://bob.example.com/> .
+_:node1clu27ji5x6 <http://www.w3.org/1999/02/22-rdf-syntax-ns#value> <http://example.com/pub/audio-files/ssbanner.aud> <http://bob.example.com/> .
+_:node1clu27ji5x5 <http://www.w3.org/2002/12/cal/icaltzd#repeat> "4"^^<http://www.w3.org/2001/XMLSchema#int> <http://bob.example.com/> .
+_:node1clu27ji5x5 <http://www.w3.org/2002/12/cal/icaltzd#duration> "PT1H"^^<http://www.w3.org/2001/XMLSchema#duration> <http://bob.example.com/> .
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example4.ics
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example4.ics b/test-resources/src/test/resources/calendar.text/rfc5545-example4.ics
new file mode 100755
index 0000000..18d53df
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example4.ics
@@ -0,0 +1,22 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//ABC Corporation//NONSGML My Product//EN
+BEGIN:VTODO
+DTSTAMP:19980130T134500Z
+SEQUENCE:2
+UID:uid4@example.com
+ORGANIZER:mailto:unclesam@example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:jqpublic@example.com
+DUE:19980415T000000
+STATUS:NEEDS-ACTION
+SUMMARY:Submit Income Taxes
+BEGIN:VALARM
+ACTION:AUDIO
+TRIGGER;VALUE=DATE-TIME:19980403T120000Z
+ATTACH;FMTTYPE=audio/basic:http://example.com/pub/audio-
+ files/ssbanner.aud
+REPEAT:4
+DURATION:PT1H
+END:VALARM
+END:VTODO
+END:VCALENDAR
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example5-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example5-expected.nquads b/test-resources/src/test/resources/calendar.text/rfc5545-example5-expected.nquads
new file mode 100644
index 0000000..1fb93ed
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example5-expected.nquads
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu28m86x2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu28m86x2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//ABC Corporation//NONSGML My Product//EN" <http://bob.example.com/> .
+_:node1clu28m86x2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu28m86x3 <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vjournal> <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/2002/12/cal/icaltzd#dtstamp> "1997-03-24T12:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/2002/12/cal/icaltzd#uid> "uid5@example.com" <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/2002/12/cal/icaltzd#organizer> <ma...@example.com> <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/2002/12/cal/icaltzd#status> "DRAFT" <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/2002/12/cal/icaltzd#class> "PUBLIC" <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/2002/12/cal/icaltzd#categories> "Project Report" <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/2002/12/cal/icaltzd#categories> "XYZ" <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/2002/12/cal/icaltzd#categories> "Weekly Meeting" <http://bob.example.com/> .
+_:node1clu28m86x3 <http://www.w3.org/2002/12/cal/icaltzd#description> "Project xyz Review Meeting Minutes\nAgenda\n1. Review of project version 1.0 requirements.\n2.Definitionof project processes.\n3. Review of project schedule.\nParticipants: John Smith, Jane Doe, Jim Dandy\n-It wasdecided that the requirements need to be signed off byproduct marketing.\n-Project processes were accepted.\n-Project schedule needs to account for scheduled holidaysand employee vacation time. Check with HR for specificdates.\n-New schedule will be distributed by Friday.\n-Next weeks meeting is cancelled. No meeting until 3/23." <http://bob.example.com/> .
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example5.ics
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example5.ics b/test-resources/src/test/resources/calendar.text/rfc5545-example5.ics
new file mode 100755
index 0000000..2dfa4a6
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example5.ics
@@ -0,0 +1,23 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//ABC Corporation//NONSGML My Product//EN
+BEGIN:VJOURNAL
+DTSTAMP:19970324T120000Z
+UID:uid5@example.com
+ORGANIZER:mailto:jsmith@example.com
+STATUS:DRAFT
+CLASS:PUBLIC
+CATEGORIES:Project Report,XYZ,Weekly Meeting
+DESCRIPTION:Project xyz Review Meeting Minutes\n
+ Agenda\n1. Review of project version 1.0 requirements.\n2.
+ Definition
+ of project processes.\n3. Review of project schedule.\n
+ Participants: John Smith\, Jane Doe\, Jim Dandy\n-It was
+ decided that the requirements need to be signed off by
+ product marketing.\n-Project processes were accepted.\n
+ -Project schedule needs to account for scheduled holidays
+ and employee vacation time. Check with HR for specific
+ dates.\n-New schedule will be distributed by Friday.\n-
+ Next weeks meeting is cancelled. No meeting until 3/23.
+END:VJOURNAL
+END:VCALENDAR
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example6-expected.nquads
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example6-expected.nquads b/test-resources/src/test/resources/calendar.text/rfc5545-example6-expected.nquads
new file mode 100644
index 0000000..0425e4b
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example6-expected.nquads
@@ -0,0 +1,37 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+_:node1clu29scrx2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vcalendar> <http://bob.example.com/> .
+_:node1clu29scrx2 <http://www.w3.org/2002/12/cal/icaltzd#prodid> "-//RDU Software//NONSGML HandCal//EN" <http://bob.example.com/> .
+_:node1clu29scrx2 <http://www.w3.org/2002/12/cal/icaltzd#component> _:node1clu29scrx3 <http://bob.example.com/> .
+_:node1clu29scrx3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Vfreebusy> <http://bob.example.com/> .
+_:node1clu29scrx3 <http://www.w3.org/2002/12/cal/icaltzd#organizer> <ma...@example.com> <http://bob.example.com/> .
+_:node1clu29scrx3 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "1998-03-13T14:17:11Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu29scrx3 <http://www.w3.org/2002/12/cal/icaltzd#dtend> "1998-04-10T14:17:11Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu29scrx3 <http://www.w3.org/2002/12/cal/icaltzd#freebusy> _:node1clu29scrx4 <http://bob.example.com/> .
+_:node1clu29scrx4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_PERIOD> <http://bob.example.com/> .
+_:node1clu29scrx4 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "1998-03-14T23:30:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu29scrx4 <http://www.w3.org/2002/12/cal/icaltzd#dtend> "1998-03-15T00:30:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu29scrx3 <http://www.w3.org/2002/12/cal/icaltzd#freebusy> _:node1clu29scrx5 <http://bob.example.com/> .
+_:node1clu29scrx5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_PERIOD> <http://bob.example.com/> .
+_:node1clu29scrx5 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "1998-03-16T15:30:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu29scrx5 <http://www.w3.org/2002/12/cal/icaltzd#dtend> "1998-03-16T16:30:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu29scrx3 <http://www.w3.org/2002/12/cal/icaltzd#freebusy> _:node1clu29scrx6 <http://bob.example.com/> .
+_:node1clu29scrx6 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/12/cal/icaltzd#Value_PERIOD> <http://bob.example.com/> .
+_:node1clu29scrx6 <http://www.w3.org/2002/12/cal/icaltzd#dtstart> "1998-03-18T03:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu29scrx6 <http://www.w3.org/2002/12/cal/icaltzd#dtend> "1998-03-18T04:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://bob.example.com/> .
+_:node1clu29scrx3 <http://www.w3.org/2002/12/cal/icaltzd#url> <http://www.example.com/calendar/busytime/jsmith.ifb> <http://bob.example.com/> .
http://git-wip-us.apache.org/repos/asf/any23/blob/19d85f2f/test-resources/src/test/resources/calendar.text/rfc5545-example6.ics
----------------------------------------------------------------------
diff --git a/test-resources/src/test/resources/calendar.text/rfc5545-example6.ics b/test-resources/src/test/resources/calendar.text/rfc5545-example6.ics
new file mode 100755
index 0000000..2623678
--- /dev/null
+++ b/test-resources/src/test/resources/calendar.text/rfc5545-example6.ics
@@ -0,0 +1,13 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//RDU Software//NONSGML HandCal//EN
+BEGIN:VFREEBUSY
+ORGANIZER:mailto:jsmith@example.com
+DTSTART:19980313T141711Z
+DTEND:19980410T141711Z
+FREEBUSY:19980314T233000Z/19980315T003000Z
+FREEBUSY:19980316T153000Z/19980316T163000Z
+FREEBUSY:19980318T030000Z/19980318T040000Z
+URL:http://www.example.com/calendar/busytime/jsmith.ifb
+END:VFREEBUSY
+END:VCALENDAR