All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.marmotta.commons.sesame.rio.vcard.VCardParser Maven / Gradle / Ivy

/*
 * 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.vcard;

import com.google.common.base.Preconditions;
import net.fortuna.ical4j.data.ParserException;
import net.fortuna.ical4j.util.CompatibilityHints;
import net.fortuna.ical4j.vcard.Parameter;
import net.fortuna.ical4j.vcard.Property;
import net.fortuna.ical4j.vcard.VCard;
import net.fortuna.ical4j.vcard.VCardBuilder;
import net.fortuna.ical4j.vcard.parameter.Type;
import net.fortuna.ical4j.vcard.property.*;
import org.openrdf.model.Literal;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
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 java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * A parser for parsing VCard files into RDF. Uses the vcard vocabulary (http://www.w3.org/2006/vcard/ns) for
 * representing properties.
 * 

* Ontology documentation: http://www.w3.org/2006/vcard/ns-2006.html#Name *

* Author: Sebastian Schaffert */ public class VCardParser extends RDFParserBase { private static Logger log = LoggerFactory.getLogger(VCardParser.class); public static final String NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; public static final String NS_VCARD = "http://www.w3.org/2006/vcard/ns#"; private static Map propertyMappings = new HashMap<>(); static { propertyMappings.put(Property.Id.ADR, "http://www.w3.org/2006/vcard/ns#adr"); propertyMappings.put(Property.Id.AGENT, "http://www.w3.org/2006/vcard/ns#agent"); propertyMappings.put(Property.Id.BDAY, "http://www.w3.org/2006/vcard/ns#bday"); propertyMappings.put(Property.Id.CATEGORIES, "http://www.w3.org/2006/vcard/ns#category"); propertyMappings.put(Property.Id.CLASS, "http://www.w3.org/2006/vcard/ns#class"); propertyMappings.put(Property.Id.EMAIL, "http://www.w3.org/2006/vcard/ns#email"); propertyMappings.put(Property.Id.EXTENDED, "http://www.w3.org/2006/vcard/ns#extended-address"); propertyMappings.put(Property.Id.FN, "http://www.w3.org/2006/vcard/ns#fn"); propertyMappings.put(Property.Id.GEO, "http://www.w3.org/2006/vcard/ns#geo"); propertyMappings.put(Property.Id.KEY, "http://www.w3.org/2006/vcard/ns#key"); propertyMappings.put(Property.Id.LABEL, "http://www.w3.org/2006/vcard/ns#label"); propertyMappings.put(Property.Id.LOGO, "http://www.w3.org/2006/vcard/ns#logo"); propertyMappings.put(Property.Id.N, "http://www.w3.org/2006/vcard/ns#n"); propertyMappings.put(Property.Id.NICKNAME, "http://www.w3.org/2006/vcard/ns#nickname"); propertyMappings.put(Property.Id.NOTE, "http://www.w3.org/2006/vcard/ns#note"); propertyMappings.put(Property.Id.ORG, "http://www.w3.org/2006/vcard/ns#org"); propertyMappings.put(Property.Id.PHOTO, "http://www.w3.org/2006/vcard/ns#photo"); propertyMappings.put(Property.Id.PRODID, "http://www.w3.org/2006/vcard/ns#prodid"); propertyMappings.put(Property.Id.REV, "http://www.w3.org/2006/vcard/ns#rev"); propertyMappings.put(Property.Id.ROLE, "http://www.w3.org/2006/vcard/ns#role"); propertyMappings.put(Property.Id.SORT_STRING,"http://www.w3.org/2006/vcard/ns#sort-string"); propertyMappings.put(Property.Id.SOUND, "http://www.w3.org/2006/vcard/ns#sound"); propertyMappings.put(Property.Id.TEL, "http://www.w3.org/2006/vcard/ns#tel"); propertyMappings.put(Property.Id.TITLE, "http://www.w3.org/2006/vcard/ns#title"); propertyMappings.put(Property.Id.TZ, "http://www.w3.org/2006/vcard/ns#tz"); propertyMappings.put(Property.Id.UID, "http://www.w3.org/2006/vcard/ns#uid"); propertyMappings.put(Property.Id.URL, "http://www.w3.org/2006/vcard/ns#url"); } /** * Creates a new RDFParserBase that will use a {@link org.openrdf.model.impl.ValueFactoryImpl} to * create RDF model objects. */ public VCardParser() { CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING,true); } /** * Creates a new RDFParserBase that will use the supplied ValueFactory to * create RDF model objects. * * @param valueFactory A ValueFactory. */ public VCardParser(ValueFactory valueFactory) { super(valueFactory); CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING,true); } /** * Gets the RDF format that this parser can parse. */ @Override public RDFFormat getRDFFormat() { return VCardFormat.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 { for(VCard card : new VCardBuilder(in).buildAll()) { parseVCard(card); } } 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 { for(VCard card : new VCardBuilder(reader).buildAll()) { parseVCard(card); } } catch (ParserException e) { throw new RDFParseException(e); } } private void parseVCard(VCard vCard) throws RDFHandlerException, RDFParseException { URI uri; // create uri for resource representing the vcard based on the UID if present or on a random UUID if(vCard.getProperty(Property.Id.UID) != null) { uri = resolveURI(vCard.getProperty(Property.Id.UID).getValue()); } else { uri = resolveURI(UUID.randomUUID().toString()); } Resource t_vcard = createURI(NS_VCARD + "VCard"); URI p_type = createURI(NS_RDF + "type"); rdfHandler.handleStatement(createStatement(uri,p_type,t_vcard)); for(Property p : vCard.getProperties()) { if(propertyMappings.containsKey(p.getId())) { URI prop = createURI(propertyMappings.get(p.getId())); switch (p.getId()) { case ADR: createAddress(uri,prop,(Address)p); break; case AGENT: // distinguish text and uri agents createAgent(uri,prop,(Agent)p); break; case CATEGORIES: for(String category : p.getValue().split(",")) { Literal literal = createLiteral(category,null,null); rdfHandler.handleStatement(createStatement(uri, prop, literal)); } break; case EMAIL: URI email = createURI("mailto:"+p.getValue()); rdfHandler.handleStatement(createStatement(uri,prop,email)); break; case GEO: createLocation(uri,prop,(Geo)p); break; case LOGO: createLogo(uri,prop,(Logo)p); break; case N: createName(uri,prop,(N)p); break; case ORG: createOrganization(uri,prop,(Org)p); break; case PHOTO: createPhoto(uri, prop, (Photo) p); break; case SOUND: createSound(uri, prop, (Sound) p); break; case TEL: createTel(uri, prop, (Telephone) p); break; case URL: URI url = createURI(p.getValue()); rdfHandler.handleStatement(createStatement(uri,prop,url)); break; default: Literal literal = createLiteral(p.getValue(),null,null); rdfHandler.handleStatement(createStatement(uri, prop, literal)); } } else { log.warn("unknown property type {} with value {} not added to RDF representation",p.getId(), p.getValue()); } } } private void createAddress(URI uri, URI prop, Address adr) throws RDFHandlerException, RDFParseException { Resource r_adr = createBNode(); Resource t_adr = createURI(NS_VCARD + "Address"); URI p_type = createURI(NS_RDF + "type"); rdfHandler.handleStatement(createStatement(r_adr,p_type,t_adr)); if(adr.getCountry() != null) { URI p_country = createURI(NS_VCARD + "country-name"); Literal v_country = createLiteral(adr.getCountry(),null,null); rdfHandler.handleStatement(createStatement(r_adr,p_country,v_country)); } if(adr.getExtended() != null && !"".equals(adr.getExtended().trim())) { URI p_ext = createURI(NS_VCARD + "extended-address"); Literal v_ext = createLiteral(adr.getExtended(),null,null); rdfHandler.handleStatement(createStatement(r_adr,p_ext,v_ext)); } if(adr.getLocality() != null && !"".equals(adr.getLocality().trim())) { URI p_locality = createURI(NS_VCARD + "locality"); Literal v_locality = createLiteral(adr.getLocality(),null,null); rdfHandler.handleStatement(createStatement(r_adr,p_locality,v_locality)); } if(adr.getPoBox() != null && !"".equals(adr.getPoBox().trim())) { URI p_pobox = createURI(NS_VCARD + "post-office-box"); Literal v_pobox = createLiteral(adr.getPoBox(),null,null); rdfHandler.handleStatement(createStatement(r_adr,p_pobox,v_pobox)); } if(adr.getPostcode() != null && !"".equals(adr.getPostcode().trim())) { URI p_postcode = createURI(NS_VCARD + "postal-code"); Literal v_postcode = createLiteral(adr.getPostcode(),null,null); rdfHandler.handleStatement(createStatement(r_adr,p_postcode,v_postcode)); } if(adr.getRegion() != null && !"".equals(adr.getRegion().trim())) { URI p_region = createURI(NS_VCARD + "region"); Literal v_region = createLiteral(adr.getRegion(),null,null); rdfHandler.handleStatement(createStatement(r_adr,p_region,v_region)); } if(adr.getStreet() != null) { URI p_street = createURI(NS_VCARD + "street-address"); Literal v_street = createLiteral(adr.getStreet(),null,null); rdfHandler.handleStatement(createStatement(r_adr,p_street,v_street)); } if(adr.getParameter(Parameter.Id.TYPE) != null) { Type type = (Type)adr.getParameter(Parameter.Id.TYPE); for(String value : type.getTypes()) { if("HOME".equals(value)) { URI p_home = createURI(NS_VCARD + "homeAdr"); rdfHandler.handleStatement(createStatement(uri,p_home,r_adr)); } else if("WORK".equals(value)) { URI p_work = createURI(NS_VCARD + "workAdr"); rdfHandler.handleStatement(createStatement(uri,p_work,r_adr)); } else { rdfHandler.handleStatement(createStatement(uri,prop,r_adr)); } break; // only first one } } else { rdfHandler.handleStatement(createStatement(uri,prop,r_adr)); } } private void createAgent(URI uri, URI prop, Agent agent) throws RDFHandlerException, RDFParseException { if(agent.getUri() != null) { URI r_agent = createURI(agent.getUri().toString()); rdfHandler.handleStatement(createStatement(uri,prop,r_agent)); } else { log.warn("ignoring agent relation, since agent cannot be resolved"); } } private void createLocation(URI uri, URI prop, Geo geo) throws RDFHandlerException, RDFParseException { Resource r_location = createBNode(); Resource t_adr = createURI(NS_VCARD + "Location"); URI p_type = createURI(NS_RDF + "type"); rdfHandler.handleStatement(createStatement(r_location,p_type,t_adr)); URI p_latitute = createURI(NS_VCARD+"latitude"); URI p_longitude = createURI(NS_VCARD+"longitude"); URI t_decimal = createURI("http://www.w3.org/2001/XMLSchema#double"); Literal v_latitude = createLiteral(geo.getLatitude().toPlainString(),null,t_decimal); Literal v_longitude = createLiteral(geo.getLongitude().toPlainString(), null, t_decimal); rdfHandler.handleStatement(createStatement(r_location,p_latitute,v_latitude)); rdfHandler.handleStatement(createStatement(r_location,p_longitude,v_longitude)); rdfHandler.handleStatement(createStatement(uri,prop,r_location)); } private void createLogo(URI uri, URI prop, Logo logo) throws RDFHandlerException, RDFParseException { if(logo.getUri() != null) { URI r_logo = createURI(logo.getUri().toString()); rdfHandler.handleStatement(createStatement(uri,prop,r_logo)); } else { log.warn("ignoring logo relation, since binary logos are not supported in RDF"); } } private void createName(URI uri, URI prop, N name) throws RDFHandlerException, RDFParseException { Resource r_name = createBNode(); Resource t_name = createURI(NS_VCARD + "Name"); URI p_type = createURI(NS_RDF + "type"); rdfHandler.handleStatement(createStatement(r_name,p_type,t_name)); if(name.getFamilyName() != null) { URI p_family_name = createURI(NS_VCARD + "family-name"); Literal v_family_name = createLiteral(name.getFamilyName(),null,null); rdfHandler.handleStatement(createStatement(r_name,p_family_name,v_family_name)); } if(name.getGivenName() != null) { URI p_given_name = createURI(NS_VCARD + "given-name"); Literal v_given_name = createLiteral(name.getGivenName(),null,null); rdfHandler.handleStatement(createStatement(r_name,p_given_name,v_given_name)); } if(name.getAdditionalNames() != null && name.getAdditionalNames().length > 0) { URI p_additional_name = createURI(NS_VCARD + "additional-name"); for(String additionalName : name.getAdditionalNames()) { if(!"".equals(additionalName)) { Literal v_additional_name = createLiteral(additionalName,null,null); rdfHandler.handleStatement(createStatement(r_name,p_additional_name,v_additional_name)); } } } if(name.getPrefixes() != null && name.getPrefixes().length > 0) { URI p_prefix = createURI(NS_VCARD + "honorific-prefix"); for(String namePrefix : name.getPrefixes()) { if(!"".equals(namePrefix)) { Literal v_prefix = createLiteral(namePrefix,null,null); rdfHandler.handleStatement(createStatement(r_name,p_prefix,v_prefix)); } } } if(name.getSuffixes() != null && name.getSuffixes().length > 0) { URI p_suffix = createURI(NS_VCARD + "honorific-suffix"); for(String nameSuffix : name.getSuffixes()) { if(!"".equals(nameSuffix)) { Literal v_suffix = createLiteral(nameSuffix,null,null); rdfHandler.handleStatement(createStatement(r_name,p_suffix,v_suffix)); } } } rdfHandler.handleStatement(createStatement(uri,prop,r_name)); } private void createOrganization(URI uri, URI prop, Org org) throws RDFHandlerException, RDFParseException { for(String orgName : org.getValues()) { Resource r_name = createBNode(); Resource t_org = createURI(NS_VCARD + "Organization"); URI p_type = createURI(NS_RDF + "type"); rdfHandler.handleStatement(createStatement(r_name,p_type,t_org)); URI p_name = createURI(NS_VCARD + "organization-name"); Literal v_name = createLiteral(orgName,null,null); rdfHandler.handleStatement(createStatement(r_name,p_name,v_name)); rdfHandler.handleStatement(createStatement(uri,prop,r_name)); } } private void createPhoto(URI uri, URI prop, Photo photo) throws RDFHandlerException, RDFParseException { if(photo.getUri() != null) { URI r_logo = createURI(photo.getUri().toString()); rdfHandler.handleStatement(createStatement(uri,prop,r_logo)); } else { log.warn("ignoring photo relation, since binary photos are not supported in RDF"); } } private void createSound(URI uri, URI prop, Sound sound) throws RDFHandlerException, RDFParseException { if(sound.getUri() != null) { URI r_logo = createURI(sound.getUri().toString()); rdfHandler.handleStatement(createStatement(uri,prop,r_logo)); } else { log.warn("ignoring photo relation, since binary photos are not supported in RDF"); } } private void createTel(URI uri, URI prop, Telephone telephone) throws RDFHandlerException, RDFParseException { URI r_tel; if(telephone.getUri() != null) { r_tel = createURI(telephone.getUri().toString()); } else { r_tel = createURI("tel:"+telephone.getValue()); } if(telephone.getParameter(Parameter.Id.TYPE) != null) { Type type = (Type)telephone.getParameter(Parameter.Id.TYPE); for(String value : type.getTypes()) { if("HOME".equals(value)) { URI p_home = createURI(NS_VCARD + "homeTel"); rdfHandler.handleStatement(createStatement(uri,p_home,r_tel)); } else if("WORK".equals(value)) { URI p_work = createURI(NS_VCARD + "workTel"); rdfHandler.handleStatement(createStatement(uri,p_work,r_tel)); } else if("CELL".equals(value)) { URI p_work = createURI(NS_VCARD + "mobileTel"); rdfHandler.handleStatement(createStatement(uri,p_work,r_tel)); } else { rdfHandler.handleStatement(createStatement(uri,prop,r_tel)); } break; // only first one } } else { rdfHandler.handleStatement(createStatement(uri,prop,r_tel)); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy