http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/java/org/apache/marmotta/commons/sesame/rio/ical/ICalParser.java ---------------------------------------------------------------------- diff --git a/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/java/org/apache/marmotta/commons/sesame/rio/ical/ICalParser.java b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/java/org/apache/marmotta/commons/sesame/rio/ical/ICalParser.java new file mode 100644 index 0000000..167cf35 --- /dev/null +++ b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/java/org/apache/marmotta/commons/sesame/rio/ical/ICalParser.java @@ -0,0 +1,506 @@ +/** + * 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.marmotta.commons.sesame.rio.ical; + +import com.google.common.base.Preconditions; +import net.fortuna.ical4j.data.CalendarBuilder; +import net.fortuna.ical4j.data.ParserException; +import net.fortuna.ical4j.model.Calendar; +import net.fortuna.ical4j.model.Property; +import net.fortuna.ical4j.model.component.*; +import net.fortuna.ical4j.model.property.*; + +import org.apache.marmotta.commons.sesame.rio.ical.ICalFormat; +import org.openrdf.model.Literal; +import org.openrdf.model.Resource; +import org.openrdf.model.URI; +import org.openrdf.model.ValueFactory; +import org.openrdf.model.impl.ValueFactoryImpl; +import org.openrdf.rio.RDFFormat; +import org.openrdf.rio.RDFHandlerException; +import org.openrdf.rio.RDFParseException; +import org.openrdf.rio.helpers.RDFParserBase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * A parser for parsing iCalendar (http://de.wikipedia.org/wiki/ICalendar) files into RDF format. Represents + * data using the iCal vocabulary (http://www.w3.org/2002/12/cal/icaltzd, + * http://www.w3.org/wiki/RdfCalendarDocumentation) + * <p/> + * @author Sebastian Schaffert + * @see http://wiki.modularity.net.au/ical4j/index.php + * @see http://wiki.modularity.net.au/ical4j/index.php?title=Compatibility + */ +public class ICalParser extends RDFParserBase { + private static Logger log = LoggerFactory.getLogger(ICalParser.class); + + private final static SimpleDateFormat DF_DIGITS = new SimpleDateFormat("yyyyMMdd-hhmmss"); + + public final static String NS_ICAL = "http://www.w3.org/2002/12/cal/icaltzd#"; + public static final String NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; + public static final String NS_GEO = "http://www.w3.org/2003/01/geo/wgs84_pos#"; + + + private ValueFactory valueFactory; + + /** + * Creates a new RDFParserBase that will use a {@link org.openrdf.model.impl.ValueFactoryImpl} to + * create RDF model objects. + */ + public ICalParser() { + this(new ValueFactoryImpl()); + } + + /** + * Creates a new RDFParserBase that will use the supplied ValueFactory to + * create RDF model objects. + * + * @param valueFactory A ValueFactory. + */ + public ICalParser(ValueFactory valueFactory) { + super(valueFactory); + this.valueFactory = valueFactory; + } + + + @Override + public void setValueFactory(ValueFactory valueFactory) { + super.setValueFactory(valueFactory); + this.valueFactory = valueFactory; + } + + /** + * Gets the RDF format that this parser can parse. + */ + @Override + public RDFFormat getRDFFormat() { + return ICalFormat.FORMAT; + } + + /** + * Parses the data from the supplied InputStream, using the supplied baseURI + * to resolve any relative URI references. + * + * @param in The InputStream from which to read the data. + * @param baseURI The URI associated with the data in the InputStream. + * @throws java.io.IOException If an I/O error occurred while data was read from the InputStream. + * @throws org.openrdf.rio.RDFParseException + * If the parser has found an unrecoverable parse error. + * @throws org.openrdf.rio.RDFHandlerException + * If the configured statement handler has encountered an + * unrecoverable error. + */ + @Override + public void parse(InputStream in, String baseURI) throws IOException, RDFParseException, RDFHandlerException { + Preconditions.checkNotNull(baseURI); + + setBaseURI(baseURI); + try { + parseCalendar(new CalendarBuilder().build(in)); + } catch (ParserException e) { + throw new RDFParseException(e); + } + } + + /** + * Parses the data from the supplied Reader, using the supplied baseURI to + * resolve any relative URI references. + * + * @param reader The Reader from which to read the data. + * @param baseURI The URI associated with the data in the InputStream. + * @throws java.io.IOException If an I/O error occurred while data was read from the InputStream. + * @throws org.openrdf.rio.RDFParseException + * If the parser has found an unrecoverable parse error. + * @throws org.openrdf.rio.RDFHandlerException + * If the configured statement handler has encountered an + * unrecoverable error. + */ + @Override + public void parse(Reader reader, String baseURI) throws IOException, RDFParseException, RDFHandlerException { + Preconditions.checkNotNull(baseURI); + + setBaseURI(baseURI); + try { + parseCalendar(new CalendarBuilder().build(reader)); + } catch (ParserException e) { + throw new RDFParseException(e); + } + } + + + private void parseCalendar(Calendar calendar) throws RDFParseException, RDFHandlerException, UnsupportedEncodingException { + for(Object component : calendar.getComponents()) { + if(component instanceof VEvent) { + parseEvent((VEvent) component); + } else if(component instanceof VJournal) { + parseJournal((VJournal) component); + } else if(component instanceof VAlarm) { + parseAlarm((VAlarm) component); + } else if(component instanceof VFreeBusy) { + parseFreeBusy((VFreeBusy) component); + } else if(component instanceof VToDo) { + parseToDo((VToDo) component); + } + } + } + + private void parseEvent(VEvent event) throws RDFParseException, RDFHandlerException, UnsupportedEncodingException { + log.debug("parsing event: {}", event.getUid()); + Resource r_event; + + String uriBase = ""; + if(event.getUid() != null) { + uriBase = event.getUid().getValue(); + } else { + uriBase = UUID.randomUUID().toString(); + } + if(event.getRecurrenceId() != null) { + uriBase += "-" + DF_DIGITS.format(event.getRecurrenceId().getDate()); + } + if(event.getSequence() != null) { + uriBase += "-"+event.getSequence().getSequenceNo(); + } + r_event = resolveURI(uriBase); + + + Resource t_vevent = createURI(NS_ICAL + "Vevent"); + URI p_type = createURI(NS_RDF + "type"); + rdfHandler.handleStatement(createStatement(r_event,p_type,t_vevent)); + + parseCalendarComponent(event,r_event); + } + + private void parseJournal(VJournal journal) throws RDFParseException, RDFHandlerException, UnsupportedEncodingException { + log.debug("parsing journal: {}", journal.getUid()); + Resource r_event; + String uriBase = ""; + if(journal.getUid() != null) { + uriBase = journal.getUid().getValue(); + } else { + uriBase = UUID.randomUUID().toString(); + } + if(journal.getRecurrenceId() != null) { + uriBase += "-" + DF_DIGITS.format(journal.getRecurrenceId().getDate()); + } + if(journal.getSequence() != null) { + uriBase += "-"+journal.getSequence().getSequenceNo(); + } + r_event = resolveURI(uriBase); + + Resource t_vevent = createURI(NS_ICAL + "Vjournal"); + URI p_type = createURI(NS_RDF + "type"); + rdfHandler.handleStatement(createStatement(r_event,p_type,t_vevent)); + + parseCalendarComponent(journal,r_event); + } + + private void parseAlarm(VAlarm alarm) throws RDFParseException, RDFHandlerException, UnsupportedEncodingException { + log.debug("parsing alarm"); + Resource r_event = resolveURI(UUID.randomUUID().toString()); + + + Resource t_vevent = createURI(NS_ICAL + "Valarm"); + URI p_type = createURI(NS_RDF + "type"); + rdfHandler.handleStatement(createStatement(r_event,p_type,t_vevent)); + + parseCalendarComponent(alarm,r_event); + } + + private void parseFreeBusy(VFreeBusy freeBusy) throws RDFParseException, RDFHandlerException, UnsupportedEncodingException { + log.debug("parsing free/busy: {}", freeBusy.getUid()); + Resource r_event; + if(freeBusy.getUid() != null) { + r_event = resolveURI(freeBusy.getUid().getValue()); + } else { + r_event = resolveURI(UUID.randomUUID().toString()); + } + + Resource t_vevent = createURI(NS_ICAL + "Vfreebusy"); + URI p_type = createURI(NS_RDF + "type"); + rdfHandler.handleStatement(createStatement(r_event,p_type,t_vevent)); + + parseCalendarComponent(freeBusy,r_event); + } + + private void parseToDo(VToDo toDo) throws RDFParseException, RDFHandlerException, UnsupportedEncodingException { + log.debug("parsing todo: {}", toDo.getUid()); + Resource r_event; + if(toDo.getUid() != null) { + r_event = resolveURI(toDo.getUid().getValue()); + } else { + r_event = resolveURI(UUID.randomUUID().toString()); + } + + Resource t_vevent = createURI(NS_ICAL + "Vtodo"); + URI p_type = createURI(NS_RDF + "type"); + rdfHandler.handleStatement(createStatement(r_event,p_type,t_vevent)); + + parseCalendarComponent(toDo,r_event); + } + + @SuppressWarnings("unchecked") + private void parseCalendarComponent(CalendarComponent component, Resource resource) throws RDFHandlerException, RDFParseException, UnsupportedEncodingException { + if(component.getProperty(Property.ATTACH) != null) { + Attach attach = (Attach)component.getProperty(Property.ATTACH); + if(attach.getUri() != null) { + URI r_attach = createURI(URLDecoder.decode(attach.getUri().toString(),"UTF-8")); + URI p_attach = createURI(NS_ICAL + "attach"); + rdfHandler.handleStatement(createStatement(resource,p_attach,r_attach)); + } else { + log.warn("calendar entry: binary attachments not supported!"); + } + } + + + if(component.getProperty(Property.CATEGORIES) != null) { + Categories categories = (Categories)component.getProperty(Property.CATEGORIES); + URI p_categories = createURI(NS_ICAL + "categories"); + for(Iterator<String> it = categories.getCategories().iterator(); it.hasNext(); ) { + String value = it.next(); + Literal v_categories = createLiteral(value,null,null); + rdfHandler.handleStatement(createStatement(resource,p_categories,v_categories)); + } + } + + + createStringProperty(component,resource,Property.CLASS, NS_ICAL + "class"); + createStringProperty(component,resource,Property.COMMENT, NS_ICAL + "comment"); + createStringProperty(component,resource,Property.DESCRIPTION, NS_ICAL + "description"); + + if(component.getProperty(Property.GEO) != null) { + Geo geo = (Geo)component.getProperty(Property.GEO); + URI p_geo = createURI(NS_ICAL + "geo"); + createLocation(resource, p_geo, geo); + } + + createStringProperty(component,resource,Property.LOCATION, NS_ICAL + "location"); + createIntProperty(component,resource,Property.PERCENT_COMPLETE, NS_ICAL + "percentComplete"); + createIntProperty(component,resource,Property.PRIORITY, NS_ICAL + "priority"); + + if(component.getProperty(Property.RESOURCES) != null) { + Resources resources = (Resources)component.getProperty(Property.RESOURCES); + URI p_resources = createURI(NS_ICAL + "resources"); + for(Iterator<String> it = resources.getResources().iterator(); it.hasNext(); ) { + String value = it.next(); + Literal v_resources = createLiteral(value,null,null); + rdfHandler.handleStatement(createStatement(resource,p_resources,v_resources)); + } + } + + createStringProperty(component,resource,Property.STATUS, NS_ICAL + "status"); + createStringProperty(component,resource,Property.SUMMARY, NS_ICAL + "summary"); + + createDateProperty((DateProperty)component.getProperty(Property.COMPLETED), resource, NS_ICAL + "completed"); + createDateProperty((DateProperty)component.getProperty(Property.DUE), resource, NS_ICAL + "due"); + + createDateProperty((DateProperty)component.getProperty(Property.DTEND), resource, NS_ICAL + "dtend"); + createDateProperty((DateProperty)component.getProperty(Property.DTSTART), resource, NS_ICAL + "dtstart"); + + + if(component.getProperty(Property.DURATION) != null) { + Duration duration = (Duration)component.getProperty(Property.DURATION); + URI p_duration = createURI(NS_ICAL + "duration"); + try { + javax.xml.datatype.Duration dur = DatatypeFactory.newInstance().newDuration(duration.getDuration().getTime(new Date(0)).getTime()); + Literal v_duration = createLiteral(dur.toString(),null, createURI(dur.getXMLSchemaType().toString())); + rdfHandler.handleStatement(createStatement(resource,p_duration,v_duration)); + } catch (DatatypeConfigurationException e) { + log.warn("calendar entry: error while parsing duration"); + } + + } + + createStringProperty(component,resource,Property.TRANSP, NS_ICAL + "transp"); + + URI p_attendee = createURI(NS_ICAL + "attendee"); + for(Iterator<Property> it = component.getProperties(Property.ATTENDEE).iterator(); it.hasNext(); ) { + Attendee attendee = (Attendee) it.next(); + if(attendee.getCalAddress() != null) { + URI v_attendee = createURI(attendee.getCalAddress().toString()); + rdfHandler.handleStatement(createStatement(resource,p_attendee,v_attendee)); + } else { + log.warn("attendee without calendar address: {}",attendee); + } + } + + createStringProperty(component,resource,Property.CONTACT, NS_ICAL + "contact"); + + if(component.getProperty(Property.ORGANIZER) != null) { + Organizer organizer = (Organizer) component.getProperty(Property.ORGANIZER); + URI p_organizer = createURI(NS_ICAL + "organizer"); + if(organizer.getCalAddress() != null) { + URI v_organizer = createURI(organizer.getCalAddress().toString()); + rdfHandler.handleStatement(createStatement(resource,p_organizer,v_organizer)); + } + } + + createStringProperty(component,resource,Property.RELATED_TO, NS_ICAL + "relatedTo"); + createUrlProperty(component,resource,Property.URL, NS_ICAL + "url"); + createStringProperty(component,resource,Property.UID, NS_ICAL + "uid"); + + for(Iterator<Property> it = component.getProperties(Property.EXDATE).iterator(); it.hasNext(); ) { + createDateProperty(it.next(),resource, NS_ICAL + "exdate"); + } + for(Iterator<Property> it = component.getProperties(Property.EXRULE).iterator(); it.hasNext(); ) { + createStringProperty(it.next(),resource, NS_ICAL + "exrule"); + } + for(Iterator<Property> it = component.getProperties(Property.RDATE).iterator(); it.hasNext(); ) { + createDateProperty((DateProperty)it.next(),resource, NS_ICAL + "rdate"); + } + for(Iterator<Property> it = component.getProperties(Property.RRULE).iterator(); it.hasNext(); ) { + createStringProperty(it.next(),resource, NS_ICAL + "rrule"); + } + + if(component.getProperty(Property.TRIGGER) != null) { + Trigger duration = (Trigger)component.getProperty(Property.TRIGGER); + URI p_duration = createURI(NS_ICAL + "trigger"); + try { + javax.xml.datatype.Duration dur = DatatypeFactory.newInstance().newDuration(duration.getDuration().getTime(new Date(0)).getTime()); + Literal v_duration = createLiteral(dur.toString(),null, createURI(dur.getXMLSchemaType().toString())); + rdfHandler.handleStatement(createStatement(resource,p_duration,v_duration)); + } catch (DatatypeConfigurationException e) { + log.warn("calendar entry: error while parsing duration"); + } + + } + + createDateProperty((DateProperty) component.getProperty(Property.CREATED), resource, NS_ICAL + "created"); + createDateProperty((DateProperty) component.getProperty(Property.DTSTAMP), resource, NS_ICAL + "dtstamp"); + createDateProperty((DateProperty) component.getProperty(Property.LAST_MODIFIED), resource, NS_ICAL + "lastModified"); + + createDateProperty((DateProperty) component.getProperty(Property.RECURRENCE_ID), resource, NS_ICAL + "recurrenceId"); + createIntProperty(component,resource,Property.SEQUENCE, NS_ICAL + "sequence"); + + createStringProperty(component,resource,Property.REQUEST_STATUS,NS_ICAL+"requestStatus"); + + createStringProperty(component,resource,Property.ACTION,NS_ICAL+"action"); + createStringProperty(component,resource,Property.REPEAT,NS_ICAL+"repeat"); + + } + + + private void createLocation(Resource uri, URI prop, Geo geo) throws RDFHandlerException, RDFParseException { + Resource r_location = createBNode(); + Resource t_adr = createURI(NS_GEO + "Point"); + URI p_type = createURI(NS_RDF + "type"); + rdfHandler.handleStatement(createStatement(r_location,p_type,t_adr)); + + URI p_latitute = createURI(NS_GEO+"latitude"); + URI p_longitude = createURI(NS_GEO+"longitude"); + URI t_decimal = createURI("http://www.w3.org/2001/XMLSchema#double"); + + if(geo.getLatitude() != null) { + Literal v_latitude = createLiteral(geo.getLatitude().toPlainString(),null,t_decimal); + rdfHandler.handleStatement(createStatement(r_location,p_latitute,v_latitude)); + } + + if(geo.getLongitude() != null) { + Literal v_longitude = createLiteral(geo.getLongitude().toPlainString(), null, t_decimal); + rdfHandler.handleStatement(createStatement(r_location,p_longitude,v_longitude)); + } + + + rdfHandler.handleStatement(createStatement(uri,prop,r_location)); + } + + private void createStringProperty(CalendarComponent event, Resource r_event, String icalProperty, String rdfProperty) throws RDFParseException, RDFHandlerException { + if(event.getProperty(icalProperty) != null) { + Property description = event.getProperty(icalProperty); + URI p_description = createURI(rdfProperty); + Literal v_description = createLiteral(description.getValue(), null, null); + rdfHandler.handleStatement(createStatement(r_event,p_description,v_description)); + } + } + + private void createStringProperty(Property property, Resource r_event, String rdfProperty) throws RDFParseException, RDFHandlerException { + if(property != null) { + URI p_description = createURI(rdfProperty); + Literal v_description = createLiteral(property.getValue(), null, null); + rdfHandler.handleStatement(createStatement(r_event,p_description,v_description)); + } + } + + private void createIntProperty(CalendarComponent event, Resource r_event, String icalProperty, String rdfProperty) throws RDFParseException, RDFHandlerException { + if(event.getProperty(icalProperty) != null) { + Property description = event.getProperty(icalProperty); + URI p_description = createURI(rdfProperty); + Literal v_description = createLiteral(description.getValue(), null, createURI("http://www.w3.org/2001/XMLSchema#int")); + rdfHandler.handleStatement(createStatement(r_event,p_description,v_description)); + } + } + + private void createDateProperty(Property property, Resource r_event, String rdfProperty) throws RDFParseException, RDFHandlerException { + if(property != null) { + if(property instanceof DateProperty) { + DateProperty dateProperty = (DateProperty)property; + URI p_dateprop = createURI(rdfProperty); + Literal v_dateprop = valueFactory.createLiteral(getXMLCalendar(dateProperty.getDate(),dateProperty.getTimeZone())); + rdfHandler.handleStatement(createStatement(r_event,p_dateprop,v_dateprop)); + } else if(property instanceof DateListProperty) { + DateListProperty dateProperty = (DateListProperty)property; + URI p_dateprop = createURI(rdfProperty); + for(@SuppressWarnings("unchecked") Iterator<Date> it = dateProperty.getDates().iterator(); it.hasNext(); ) { + Literal v_dateprop = valueFactory.createLiteral(getXMLCalendar(it.next(),dateProperty.getTimeZone())); + rdfHandler.handleStatement(createStatement(r_event,p_dateprop,v_dateprop)); + } + } + } + } + + + private void createUrlProperty(CalendarComponent event, Resource r_event, String icalProperty, String rdfProperty) throws RDFParseException, RDFHandlerException { + if(event.getProperty(icalProperty) != null) { + Property description = event.getProperty(icalProperty); + URI p_description = createURI(rdfProperty); + URI v_description = createURI(description.getValue()); + rdfHandler.handleStatement(createStatement(r_event,p_description,v_description)); + } + } + + + public static Date getDate(XMLGregorianCalendar calendar) { + return calendar.toGregorianCalendar().getTime(); + } + + + public static XMLGregorianCalendar getXMLCalendar(Date date, TimeZone timezone) { + GregorianCalendar c = new GregorianCalendar(); + c.setTime(date); + if(timezone != null) + c.setTimeZone(timezone); + try { + return DatatypeFactory.newInstance().newXMLGregorianCalendar(c); + } catch (DatatypeConfigurationException e) { + return null; + } + } + + +}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/java/org/apache/marmotta/commons/sesame/rio/ical/ICalParserFactory.java ---------------------------------------------------------------------- diff --git a/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/java/org/apache/marmotta/commons/sesame/rio/ical/ICalParserFactory.java b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/java/org/apache/marmotta/commons/sesame/rio/ical/ICalParserFactory.java new file mode 100644 index 0000000..38e3831 --- /dev/null +++ b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/java/org/apache/marmotta/commons/sesame/rio/ical/ICalParserFactory.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.marmotta.commons.sesame.rio.ical; + +import org.apache.marmotta.commons.sesame.rio.ical.ICalFormat; +import org.openrdf.rio.RDFFormat; +import org.openrdf.rio.RDFParser; +import org.openrdf.rio.RDFParserFactory; + +/** + * Add file description here! + * <p/> + * Author: Sebastian Schaffert + */ +public class ICalParserFactory implements RDFParserFactory { + /** + * Returns the RDF format for this factory. + */ + @Override + public RDFFormat getRDFFormat() { + return ICalFormat.FORMAT; + } + + /** + * Returns a RDFParser instance. + */ + @Override + public RDFParser getParser() { + return new ICalParser(); + } + +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/resources/META-INF/services/org.openrdf.rio.RDFParserFactory ---------------------------------------------------------------------- diff --git a/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/resources/META-INF/services/org.openrdf.rio.RDFParserFactory b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/resources/META-INF/services/org.openrdf.rio.RDFParserFactory new file mode 100644 index 0000000..2149311 --- /dev/null +++ b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/main/resources/META-INF/services/org.openrdf.rio.RDFParserFactory @@ -0,0 +1 @@ +org.apache.marmotta.commons.sesame.rio.ical.ICalParserFactory \ No newline at end of file http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-rio-ical/src/test/java/org/apache/marmotta/commons/sesame/rio/ical/TestICalParser.java ---------------------------------------------------------------------- diff --git a/commons/marmotta-sesame-tools/marmotta-rio-ical/src/test/java/org/apache/marmotta/commons/sesame/rio/ical/TestICalParser.java b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/test/java/org/apache/marmotta/commons/sesame/rio/ical/TestICalParser.java new file mode 100644 index 0000000..30353b7 --- /dev/null +++ b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/test/java/org/apache/marmotta/commons/sesame/rio/ical/TestICalParser.java @@ -0,0 +1,108 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.commons.sesame.rio.ical; + +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.everyItem; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeThat; + +import info.aduna.iteration.Iterations; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; + +import net.fortuna.ical4j.util.CompatibilityHints; + +import org.apache.commons.io.IOUtils; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.openrdf.query.BooleanQuery; +import org.openrdf.query.QueryLanguage; +import org.openrdf.repository.Repository; +import org.openrdf.repository.RepositoryConnection; +import org.openrdf.repository.sail.SailRepository; +import org.openrdf.sail.memory.MemoryStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Add file description here! + * <p/> + * Author: Sebastian Schaffert + */ +@RunWith(Parameterized.class) +public class TestICalParser { + + private static Logger log = LoggerFactory.getLogger(TestICalParser.class); + + private String fileName; + + public TestICalParser(String fileName) { + this.fileName = fileName; + } + + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> data() { + ArrayList<Object[]> list = new ArrayList<Object[]>(); + list.add(new Object[] { "kmt" }); + list.add(new Object[] { "vacation" }); + return list; + } + + @BeforeClass + public static void beforeClass() { + // The test files contain old date format: + CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING, true); + } + + + + @Test + public void runTest() throws Exception { + log.info("running test {} ...", fileName); + + InputStream ical = this.getClass().getResourceAsStream(fileName+".ics"); + InputStream sparql = this.getClass().getResourceAsStream(fileName+".sparql"); + assumeThat("Could not load testfiles", asList(ical, sparql), everyItem(notNullValue(InputStream.class))); + + Repository repository = new SailRepository(new MemoryStore()); + repository.initialize(); + + RepositoryConnection connection = repository.getConnection(); + try { + connection.add(ical,"http://localhost/ical/", ICalFormat.FORMAT); + connection.commit(); + } catch(Exception ex) { + ex.printStackTrace(); + fail("parsing " + fileName + " failed!"); + } + assertTrue(connection.size() > 0); + + int count = Iterations.asList(connection.getStatements(null, null, null, false)).size(); + assertTrue(count > 0); + + BooleanQuery sparqlQuery = (BooleanQuery)connection.prepareQuery(QueryLanguage.SPARQL, IOUtils.toString(sparql)); + assertTrue("SPARQL query evaluation for "+fileName+" failed",sparqlQuery.evaluate()); + + connection.close(); + repository.shutDown(); + } + +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-rio-ical/src/test/resources/logback.xml ---------------------------------------------------------------------- diff --git a/commons/marmotta-sesame-tools/marmotta-rio-ical/src/test/resources/logback.xml b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/test/resources/logback.xml new file mode 100644 index 0000000..1bfecff --- /dev/null +++ b/commons/marmotta-sesame-tools/marmotta-rio-ical/src/test/resources/logback.xml @@ -0,0 +1,27 @@ +<!-- + ~ 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. + --> + +<configuration> + <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{HH:mm:ss.SSS} %highlight(%level) %cyan(%logger{15}) - %m%n</pattern> + </encoder> + </appender> + <root level="${root-level:-INFO}"> + <appender-ref ref="CONSOLE"/> + </root> +</configuration> \ No newline at end of file
