Repository: any23 Updated Branches: refs/heads/master f44be91f9 -> 2b91bbf42
ANY23-298 Revisit the OGP.java vocabulary and update it Project: http://git-wip-us.apache.org/repos/asf/any23/repo Commit: http://git-wip-us.apache.org/repos/asf/any23/commit/025fccd6 Tree: http://git-wip-us.apache.org/repos/asf/any23/tree/025fccd6 Diff: http://git-wip-us.apache.org/repos/asf/any23/diff/025fccd6 Branch: refs/heads/master Commit: 025fccd62312d6196e38ccc352668cc765c287cf Parents: bcd87e5 Author: Lewis John McGibbney <[email protected]> Authored: Wed Dec 13 10:26:04 2017 -0800 Committer: Lewis John McGibbney <[email protected]> Committed: Wed Dec 13 10:26:04 2017 -0800 ---------------------------------------------------------------------- .../main/java/org/apache/any23/vocab/OGP.java | 160 +++++++++++++++++-- .../java/org/apache/any23/vocab/OGPArticle.java | 83 ++++++++++ .../java/org/apache/any23/vocab/OGPBook.java | 75 +++++++++ .../java/org/apache/any23/vocab/OGPMusic.java | 110 +++++++++++++ .../java/org/apache/any23/vocab/OGPProfile.java | 75 +++++++++ .../java/org/apache/any23/vocab/OGPVideo.java | 90 +++++++++++ .../rdfa/AbstractRDFaExtractorTestCase.java | 1 - .../extractor/rdfa/RDFa11ExtractorTest.java | 48 ++++-- .../apache/any23/vocab/RDFSchemaUtilsTest.java | 4 +- .../rdfa/opengraph-music-song-object-type.html | 18 +++ .../rdfa/opengraph-structured-properties.html | 67 ++++++-- 11 files changed, 701 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/api/src/main/java/org/apache/any23/vocab/OGP.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/any23/vocab/OGP.java b/api/src/main/java/org/apache/any23/vocab/OGP.java index dde75bb..503cd08 100644 --- a/api/src/main/java/org/apache/any23/vocab/OGP.java +++ b/api/src/main/java/org/apache/any23/vocab/OGP.java @@ -26,18 +26,26 @@ import org.eclipse.rdf4j.model.IRI; */ public class OGP extends Vocabulary { + private OGP() { + super(NS); + } + public static final String NS = "http://ogp.me/ns#"; /* BEGIN: Basic Metadata. */ - /** The title of your object as it should appear within the graph (Facebook Graph API). */ + /** The title of your object as it should appear within the graph, e.g., "The Rock". */ public static final String TITLE = "title"; - /** The type of your object, e.g., <code>video.movie</code>. - * Depending on the type you specify, other properties may also be required. */ + + /** The type of your object, e.g., "video.movie". Depending on the + * type you specify, other properties may also be required. */ public static final String TYPE = "type"; - /** An image URL which should represent your object within the graph. */ + + /** The canonical URL of your object that will be used as its permanent ID in the + * graph, e.g., "http://www.imdb.com/title/tt0117500/". */ public static final String URL = "url"; - /** The canonical URL of your object that will be used as its permanent ID in the graph (Facebook Graph API). */ + + /** An image URL which should represent your object within the graph. */ public static final String IMAGE = "image"; /* END: Basic Metadata. */ @@ -46,19 +54,25 @@ public class OGP extends Vocabulary { /** A URL to an audio file to accompany this object. */ public static final String AUDIO = "audio"; + /** A one to two sentence description of your object. */ public static final String DESCRIPTION = "description"; + /** The word that appears before this object's title in a sentence. An enum of (a, an, the, "", auto). * If auto is chosen, the consumer of your data should chose between "a" or "an". Default is "" (blank). */ public static final String DETERMINER = "determiner"; + /** The locale these tags are marked up in. Of the format <code>language_TERRITORY</code>. * Default is <code>en_US</code>. */ public static final String LOCALE = "locale"; + /** An array of other locales this page is available in. */ public static final String LOCALE__ALTERNATE = "locale:alternate"; + /** If your object is part of a larger web site, the name which should be * displayed for the overall site. e.g., <b>IMDb</b>. */ public static final String SITE_NAME = "site_name"; + /** A URL to a video file that complements this object. */ public static final String VIDEO = "video"; @@ -68,33 +82,135 @@ public class OGP extends Vocabulary { /** Identical to <code>og:image</code>. */ public static final String IMAGE__URL = "image:url"; + /** An alternate url to use if the webpage requires <b>HTTPS</b>. */ public static final String IMAGE__SECURE_URL = "image:secure_url"; + /** A <i>MIME type</i> for this image. */ public static final String IMAGE__TYPE = "image:type"; + /** The number of pixels wide. */ public static final String IMAGE__WIDTH = "image:width"; + /** The number of pixels high. */ public static final String IMAGE__HEIGHT = "image:height"; + /** A description of what is in the image (not a caption). + * If the page specifies an og:image it should specify og:image:alt.*/ + public static final String IMAGE__ALT = "image:alt"; + /** Video URL. */ public static final String VIDEO__URL = "video:url"; + /** An alternate url to use if the webpage requires <b>HTTPS</b>. */ public static final String VIDEO__SECURE_URL = "video:secure_url"; + /** A <i>MIME type</i> for this video. */ public static final String VIDEO__TYPE = "video:type"; + /** The number of pixels wide. */ public static final String VIDEO__WIDTH = "video:width"; + /** The number of pixels height. */ public static final String VIDEO__HEIGHT = "video:height"; + /** A description of what is in the video (not a caption). + * If the page specifies an og:video it should specify og:video:alt.*/ + public static final String VIDEO__ALT = "video:alt"; + /** An alternate url to use if the webpage requires <b>HTTPS</b>. */ public static final String AUDIO__SECURE_URL = "audio:secure_url"; + /** A <i>MIME type</i> for this audio. */ public static final String AUDIO__TYPE = "audio:type"; + /** A description of what is in the audio file (not a caption). + * If the page specifies an og:audio it should specify og:audio:alt.*/ + public static final String AUDIO__ALT = "audio:alt"; + /* END: Structured Properties. */ + /* BEGIN: ogp.me/#type_video.movie */ + + /** Actors in the movie. */ + public static final String VIDEO__ACTOR = "video:actor"; + + /** The role they played. */ + public static final String VIDEO__ACTOR_ROLE = "video:actor:role"; + + /** Directors of the movie. */ + public static final String VIDEO__DIRECTOR = "video:director"; + + /** Writers of the movie. */ + public static final String VIDEO__WRITER = "video:writer"; + + /** The movie's length in seconds. */ + public static final String VIDEO__DURATION = "video:duration"; + + /** The date the movie was released. */ + public static final String VIDEO__RELEASE_DATE = "video:release_date"; + + /** Tag words associated with this movie. */ + public static final String VIDEO__TAG = "video:tag"; + + /** Which series this episode belongs to. */ + public static final String VIDEO__SERIES = "video:series"; + /* END: ogp.me/#type_video.movie */ + + /* BEGIN: http://ogp.me/#type_article */ + + /** When the article was first published. */ + public static final String ARTICLE__PUBLISHED_TIME = "article:published_time"; + + /** When the article was last changed. */ + public static final String ARTICLE__MODIFIED_TIME = "article:modified_time"; + + /** When the article is out of date after. */ + public static final String ARTICLE__EXPIRATION_TIME = "article:expiration_time"; + + /** Writers of the article. */ + public static final String ARTICLE__AUTHOR = "article:author"; + + /** A high-level section name. E.g. Technology */ + public static final String ARTICLE__SECTION = "article:section"; + + /** Tag words associated with this article. */ + public static final String ARTICLE__TAG = "article:tag"; + + /* END: http://ogp.me/#type_article */ + + /* BEGIN: http://ogp.me/#type_book */ + + /** Who wrote this book. */ + public static final String BOOK__AUTHOR = "book:author"; + + /** The ISBN */ + public static final String BOOK__ISBN = "book:isbn"; + + /** The date the book was released. */ + public static final String BOOK__RELEASE_DATE = "book:release_date"; + + /** Tag words associated with this book. */ + public static final String BOOK__TAG = "book:tag"; + + /* END: http://ogp.me/#type_book */ + + /* BEGIN: http://ogp.me/#type_profile */ + + /** A name normally given to an individual by a parent or self-chosen. */ + public static final String PROFILE__FIRST_NAME = "profile:first_name"; + + /** A name inherited from a family or marriage and by which the individual is commonly known. */ + public static final String PROFILE__LAST_NAME = "profile:last_name"; + + /** A short unique string to identify them. */ + public static final String PROFILE__USERNAME = "profile:username"; + + /** Their gender. */ + public static final String PROFILE__GENDER = "profile:gender"; + + /* END: http://ogp.me/#type_profile */ + private static OGP instance; public static OGP getInstance() { @@ -123,17 +239,47 @@ public class OGP extends Vocabulary { public final IRI imageType = createProperty(IMAGE__TYPE); public final IRI imageWidth = createProperty(IMAGE__WIDTH); public final IRI imageHeight = createProperty(IMAGE__HEIGHT); + public final IRI imageAlt = createProperty(IMAGE__ALT); public final IRI videoURL = createProperty(VIDEO__URL); public final IRI videoSecureURL = createProperty(VIDEO__SECURE_URL); public final IRI videoType = createProperty(VIDEO__TYPE); public final IRI videoWidth = createProperty(VIDEO__WIDTH); public final IRI videoHeight = createProperty(VIDEO__HEIGHT); + public final IRI videoAlt = createProperty(VIDEO__ALT); public final IRI audio = createProperty(AUDIO); public final IRI audioSecureURL = createProperty(AUDIO__SECURE_URL); public final IRI audioType = createProperty(AUDIO__TYPE); + public final IRI audioAlt = createProperty(AUDIO__ALT); + + public final IRI videoActor = createProperty(VIDEO__ACTOR); + public final IRI videoActorRole = createProperty(VIDEO__ACTOR_ROLE); + public final IRI videoDirector = createProperty(VIDEO__DIRECTOR); + public final IRI videoWriter = createProperty(VIDEO__WRITER); + public final IRI videoDuration = createProperty(VIDEO__DURATION); + public final IRI videoReleaseDate = createProperty(VIDEO__RELEASE_DATE); + public final IRI videoTag = createProperty(VIDEO__TAG); + public final IRI videoSeries = createProperty(VIDEO__SERIES); + + public final IRI articlePublishedTime = createProperty(ARTICLE__PUBLISHED_TIME); + public final IRI articleModifiedTime = createProperty(ARTICLE__MODIFIED_TIME); + public final IRI articleExpirationTime = createProperty(ARTICLE__EXPIRATION_TIME); + public final IRI articleAuthor = createProperty(ARTICLE__AUTHOR); + public final IRI articleSection = createProperty(ARTICLE__SECTION); + public final IRI articleTag = createProperty(ARTICLE__TAG); + + public final IRI bookAuthor = createProperty(BOOK__AUTHOR); + public final IRI bookIsbn = createProperty(BOOK__ISBN); + public final IRI bookReleaseDate = createProperty(BOOK__RELEASE_DATE); + public final IRI bookTag = createProperty(BOOK__TAG); + + public final IRI profileFirstName = createProperty(PROFILE__FIRST_NAME); + public final IRI profileLastName = createProperty(PROFILE__LAST_NAME); + public final IRI profileUsername = createProperty(PROFILE__USERNAME); + public final IRI profileGender = createProperty(PROFILE__GENDER); + @SuppressWarnings("unused") private IRI createClass(String localName) { return createClass(NS, localName); } @@ -142,8 +288,4 @@ public class OGP extends Vocabulary { return createProperty(NS, localName); } - private OGP() { - super(NS); - } - } http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/api/src/main/java/org/apache/any23/vocab/OGPArticle.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/any23/vocab/OGPArticle.java b/api/src/main/java/org/apache/any23/vocab/OGPArticle.java new file mode 100644 index 0000000..0381bd4 --- /dev/null +++ b/api/src/main/java/org/apache/any23/vocab/OGPArticle.java @@ -0,0 +1,83 @@ +/* + * 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.vocab; + +import org.eclipse.rdf4j.model.IRI; + +/** + * The <a href="http://ogp.me/">Open Graph Protocol Article Type</a> + * vocabulary. + */ +public class OGPArticle extends Vocabulary { + + private OGPArticle() { + super(NS); + } + + public static final String NS = "http://ogp.me/ns/article#"; + + /* BEGIN: http://ogp.me/#type_article */ + + /** When the article was first published. */ + public static final String ARTICLE__PUBLISHED_TIME = "article:published_time"; + + /** When the article was last changed. */ + public static final String ARTICLE__MODIFIED_TIME = "article:modified_time"; + + /** When the article is out of date after. */ + public static final String ARTICLE__EXPIRATION_TIME = "article:expiration_time"; + + /** Writers of the article. */ + public static final String ARTICLE__AUTHOR = "article:author"; + + /** A high-level section name. E.g. Technology */ + public static final String ARTICLE__SECTION = "article:section"; + + /** Tag words associated with this article. */ + public static final String ARTICLE__TAG = "article:tag"; + + /* END: http://ogp.me/#type_article */ + + private static OGPArticle instance; + + public static OGPArticle getInstance() { + if(instance == null) { + instance = new OGPArticle(); + } + return instance; + } + + public final IRI NAMESPACE = createIRI(NS); + + public final IRI articlePublishedTime = createProperty(ARTICLE__PUBLISHED_TIME); + public final IRI articleModifiedTime = createProperty(ARTICLE__MODIFIED_TIME); + public final IRI articleExpirationTime = createProperty(ARTICLE__EXPIRATION_TIME); + public final IRI articleAuthor = createProperty(ARTICLE__AUTHOR); + public final IRI articleSection = createProperty(ARTICLE__SECTION); + public final IRI articleTag = createProperty(ARTICLE__TAG); + + @SuppressWarnings("unused") + private IRI createClass(String localName) { + return createClass(NS, localName); + } + + private IRI createProperty(String localName) { + return createProperty(NS, localName); + } + +} http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/api/src/main/java/org/apache/any23/vocab/OGPBook.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/any23/vocab/OGPBook.java b/api/src/main/java/org/apache/any23/vocab/OGPBook.java new file mode 100644 index 0000000..2f2debc --- /dev/null +++ b/api/src/main/java/org/apache/any23/vocab/OGPBook.java @@ -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. + */ + +package org.apache.any23.vocab; + +import org.eclipse.rdf4j.model.IRI; + +/** + * The <a href="http://ogp.me/#type_book">Open Graph Protocol Book Type</a> + * vocabulary. + */ +public class OGPBook extends Vocabulary { + + private OGPBook() { + super(NS); + } + + public static final String NS = "http://ogp.me/ns/book#"; + + /* BEGIN: http://ogp.me/#type_book */ + + /** Who wrote this book. */ + public static final String BOOK__AUTHOR = "book:author"; + + /** The ISBN */ + public static final String BOOK__ISBN = "book:isbn"; + + /** The date the book was released. */ + public static final String BOOK__RELEASE_DATE = "book:release_date"; + + /** Tag words associated with this book. */ + public static final String BOOK__TAG = "book:tag"; + + /* END: http://ogp.me/#type_book */ + + private static OGPBook instance; + + public static OGPBook getInstance() { + if(instance == null) { + instance = new OGPBook(); + } + return instance; + } + + public final IRI NAMESPACE = createIRI(NS); + + public final IRI bookAuthor = createProperty(BOOK__AUTHOR); + public final IRI bookIsbn = createProperty(BOOK__ISBN); + public final IRI bookReleaseDate = createProperty(BOOK__RELEASE_DATE); + public final IRI bookTag = createProperty(BOOK__TAG); + + @SuppressWarnings("unused") + private IRI createClass(String localName) { + return createClass(NS, localName); + } + + private IRI createProperty(String localName) { + return createProperty(NS, localName); + } + +} http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/api/src/main/java/org/apache/any23/vocab/OGPMusic.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/any23/vocab/OGPMusic.java b/api/src/main/java/org/apache/any23/vocab/OGPMusic.java new file mode 100644 index 0000000..405b85e --- /dev/null +++ b/api/src/main/java/org/apache/any23/vocab/OGPMusic.java @@ -0,0 +1,110 @@ +/* + * 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.vocab; + +import org.eclipse.rdf4j.model.IRI; + +/** + * The <a href="http://ogp.me/#type_music">Open Graph Protocol Music Type</a> + * vocabulary. + * + */ +public class OGPMusic extends Vocabulary { + + private OGPMusic() { + super(NS); + } + + public static final String NS = "http://ogp.me/ns/music#"; + + /* BEGIN: http://ogp.me/#type_music.song */ + + /** The song's length in seconds. */ + public static final String MUSIC__DURATION = "music:duration"; + + /** The album this song is from. */ + public static final String MUSIC__ALBUM = "music:album"; + + /** Which disc of the album this song is on. */ + public static final String MUSIC__ALBUM_DISC = "music:album:disc"; + + /** Which disc of the album this song is on. */ + public static final String MUSIC__ALBUM_TRACK = "music:album:track"; + + /** Which disc of the album this song is on. */ + public static final String MUSIC__MUSICIAN = "music:musician"; + + /* END: http://ogp.me/#type_music.song */ + + /* BEGIN: http://ogp.me/#type_music.album */ + + /** The song on this album. */ + public static final String MUSIC__SONG = "music:song"; + + /** The same as music:album:disc but in reverse. */ + public static final String MUSIC__SONG_DISC = "music:song:disc"; + + /** The same as music:album:track but in reverse. */ + public static final String MUSIC__SONG_TRACK = "music:song:track"; + + /** The date the album was released. */ + public static final String MUSIC__RELEASE_DATE = "music:release_date"; + + /* END: http://ogp.me/#type_music.album */ + + /* BEGIN: http://ogp.me/#type_music.playlist */ + + /** The creator of this playlist if 'music.playlist' or the + * creator of this station if 'music.radio_station' */ + public static final String MUSIC__CREATOR = "music:creator"; + + /* END: http://ogp.me/#type_music.playlist */ + + private static OGPMusic instance; + + public static OGPMusic getInstance() { + if(instance == null) { + instance = new OGPMusic(); + } + return instance; + } + + public final IRI NAMESPACE = createIRI(NS); + + public final IRI musicDuration = createProperty(MUSIC__DURATION); + public final IRI musicAlbum = createProperty(MUSIC__ALBUM); + public final IRI musicAlbumDisc = createProperty(MUSIC__ALBUM_DISC); + public final IRI musicAlbumTrack = createProperty(MUSIC__ALBUM_TRACK); + public final IRI musicMusician = createProperty(MUSIC__MUSICIAN); + + public final IRI musicSong = createProperty(MUSIC__SONG); + public final IRI musicSongDisc = createProperty(MUSIC__SONG_DISC); + public final IRI musicSongTrack = createProperty(MUSIC__SONG_TRACK); + public final IRI musicReleaseDate = createProperty(MUSIC__RELEASE_DATE); + + public final IRI musicCreator = createProperty(MUSIC__CREATOR); + + @SuppressWarnings("unused") + private IRI createClass(String localName) { + return createClass(NS, localName); + } + + private IRI createProperty(String localName) { + return createProperty(NS, localName); + } +} http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/api/src/main/java/org/apache/any23/vocab/OGPProfile.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/any23/vocab/OGPProfile.java b/api/src/main/java/org/apache/any23/vocab/OGPProfile.java new file mode 100644 index 0000000..48b0b3b --- /dev/null +++ b/api/src/main/java/org/apache/any23/vocab/OGPProfile.java @@ -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. + */ + +package org.apache.any23.vocab; + +import org.eclipse.rdf4j.model.IRI; + +/** + * The <a href="http://ogp.me/">Open Graph Protocol Profile Type</a> + * vocabulary. + */ +public class OGPProfile extends Vocabulary { + + private OGPProfile() { + super(NS); + } + + public static final String NS = "http://ogp.me/ns/profile#"; + + /* BEGIN: http://ogp.me/#type_profile */ + + /** A name normally given to an individual by a parent or self-chosen. */ + public static final String PROFILE__FIRST_NAME = "profile:first_name"; + + /** A name inherited from a family or marriage and by which the individual is commonly known. */ + public static final String PROFILE__LAST_NAME = "profile:last_name"; + + /** A short unique string to identify them. */ + public static final String PROFILE__USERNAME = "profile:username"; + + /** Their gender. */ + public static final String PROFILE__GENDER = "profile:gender"; + + /* END: http://ogp.me/#type_profile */ + + private static OGPProfile instance; + + public static OGPProfile getInstance() { + if(instance == null) { + instance = new OGPProfile(); + } + return instance; + } + + public final IRI NAMESPACE = createIRI(NS); + + public final IRI profileFirstName = createProperty(PROFILE__FIRST_NAME); + public final IRI profileLastName = createProperty(PROFILE__LAST_NAME); + public final IRI profileUsername = createProperty(PROFILE__USERNAME); + public final IRI profileGender = createProperty(PROFILE__GENDER); + + @SuppressWarnings("unused") + private IRI createClass(String localName) { + return createClass(NS, localName); + } + + private IRI createProperty(String localName) { + return createProperty(NS, localName); + } + +} http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/api/src/main/java/org/apache/any23/vocab/OGPVideo.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/any23/vocab/OGPVideo.java b/api/src/main/java/org/apache/any23/vocab/OGPVideo.java new file mode 100644 index 0000000..774c7fd --- /dev/null +++ b/api/src/main/java/org/apache/any23/vocab/OGPVideo.java @@ -0,0 +1,90 @@ +/* + * 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.vocab; + +import org.eclipse.rdf4j.model.IRI; + +/** + * The <a href="http://ogp.me/#type_video">Open Graph Protocol Video Type</a> + * vocabulary. + */ +public class OGPVideo extends Vocabulary { + + private OGPVideo() { + super(NS); + } + + public static final String NS = "http://ogp.me/ns/video#"; + + /* BEGIN: ogp.me/#type_video.movie */ + + /** Actors in the movie. */ + public static final String VIDEO__ACTOR = "video:actor"; + + /** The role they played. */ + public static final String VIDEO__ACTOR_ROLE = "video:actor:role"; + + /** Directors of the movie. */ + public static final String VIDEO__DIRECTOR = "video:director"; + + /** Writers of the movie. */ + public static final String VIDEO__WRITER = "video:writer"; + + /** The movie's length in seconds. */ + public static final String VIDEO__DURATION = "video:duration"; + + /** The date the movie was released. */ + public static final String VIDEO__RELEASE_DATE = "video:release_date"; + + /** Tag words associated with this movie. */ + public static final String VIDEO__TAG = "video:tag"; + + /** Which series this episode belongs to. */ + public static final String VIDEO__SERIES = "video:series"; + /* END: ogp.me/#type_video.movie */ + + private static OGPVideo instance; + + public static OGPVideo getInstance() { + if(instance == null) { + instance = new OGPVideo(); + } + return instance; + } + + public final IRI NAMESPACE = createIRI(NS); + + public final IRI videoActor = createProperty(VIDEO__ACTOR); + public final IRI videoActorRole = createProperty(VIDEO__ACTOR_ROLE); + public final IRI videoDirector = createProperty(VIDEO__DIRECTOR); + public final IRI videoWriter = createProperty(VIDEO__WRITER); + public final IRI videoDuration = createProperty(VIDEO__DURATION); + public final IRI videoReleaseDate = createProperty(VIDEO__RELEASE_DATE); + public final IRI videoTag = createProperty(VIDEO__TAG); + public final IRI videoSeries = createProperty(VIDEO__SERIES); + + @SuppressWarnings("unused") + private IRI createClass(String localName) { + return createClass(NS, localName); + } + + private IRI createProperty(String localName) { + return createProperty(NS, localName); + } + +} http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/core/src/test/java/org/apache/any23/extractor/rdfa/AbstractRDFaExtractorTestCase.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/any23/extractor/rdfa/AbstractRDFaExtractorTestCase.java b/core/src/test/java/org/apache/any23/extractor/rdfa/AbstractRDFaExtractorTestCase.java index 0e31b33..a187077 100644 --- a/core/src/test/java/org/apache/any23/extractor/rdfa/AbstractRDFaExtractorTestCase.java +++ b/core/src/test/java/org/apache/any23/extractor/rdfa/AbstractRDFaExtractorTestCase.java @@ -21,7 +21,6 @@ import org.apache.any23.extractor.html.AbstractExtractorTestCase; import org.apache.any23.rdf.RDFUtils; import org.apache.any23.vocab.DCTerms; import org.apache.any23.vocab.FOAF; -import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/core/src/test/java/org/apache/any23/extractor/rdfa/RDFa11ExtractorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/any23/extractor/rdfa/RDFa11ExtractorTest.java b/core/src/test/java/org/apache/any23/extractor/rdfa/RDFa11ExtractorTest.java index 67f3f8c..d2034b3 100644 --- a/core/src/test/java/org/apache/any23/extractor/rdfa/RDFa11ExtractorTest.java +++ b/core/src/test/java/org/apache/any23/extractor/rdfa/RDFa11ExtractorTest.java @@ -22,6 +22,7 @@ import org.apache.any23.extractor.ExtractorFactory; import org.apache.any23.rdf.RDFUtils; import org.apache.any23.vocab.FOAF; import org.apache.any23.vocab.OGP; +import org.apache.any23.vocab.OGPMusic; import org.junit.Assert; import org.junit.Test; import org.eclipse.rdf4j.model.Literal; @@ -98,12 +99,12 @@ public class RDFa11ExtractorTest extends AbstractRDFaExtractorTestCase { logger.debug(dumpModelToTurtle()); assertContains( - RDFUtils.uri( baseIRI.toString(),"#me"), + RDFUtils.iri( baseIRI.toString(),"#me"), FOAF.getInstance().name, "John Doe" ); assertContains( - RDFUtils.uri( baseIRI.toString(),"#me"), + RDFUtils.iri( baseIRI.toString(),"#me"), FOAF.getInstance().homepage, RDFUtils.iri("http://example.org/blog/") ); @@ -142,12 +143,12 @@ public class RDFa11ExtractorTest extends AbstractRDFaExtractorTestCase { logger.debug(dumpModelToTurtle()); assertContains( - RDFUtils.uri(baseIRI.toString(), "#me"), + RDFUtils.iri(baseIRI.toString(), "#me"), RDFUtils.iri("http://xmlns.com/foaf/0.1/name"), RDFUtils.literal("John Doe") ); assertContains( - RDFUtils.uri(baseIRI.toString(), "#me"), + RDFUtils.iri(baseIRI.toString(), "#me"), RDFUtils.iri("http://xmlns.com/foaf/0.1/homepage"), RDFUtils.iri("http://example.org/blog/") ); @@ -204,8 +205,11 @@ public class RDFa11ExtractorTest extends AbstractRDFaExtractorTestCase { } /** - * Tests the correct support of the new <em>Open Graph Protocol</em> - * <a href="http://ogp.me/#structured">Structured Properties</a>. + * Tests the correct support of <a href="http://ogp.me/">Open Graph Protocol's</a> + * <a href="http://ogp.me/#metadata">Basic Metadata</a>, + * <a href="http://ogp.me/#optional">Optional Metadata</a>, + * <a href="http://ogp.me/#structured">Structured Properties</a> and + * <a href="http://ogp.me/#array">Arrays</a>. * * @throws IOException * @throws org.apache.any23.extractor.ExtractionException @@ -216,9 +220,9 @@ public class RDFa11ExtractorTest extends AbstractRDFaExtractorTestCase { assertExtract("/html/rdfa/opengraph-structured-properties.html"); logger.info( dumpHumanReadableTriples() ); - Assert.assertEquals(8, getStatementsSize(null, null, null) ); + Assert.assertEquals(31, getStatementsSize(null, null, null) ); final OGP vOGP = OGP.getInstance(); - assertContains(baseIRI, vOGP.audio, RDFUtils.literal("http://example.com/bond/theme.mp3") ); + assertContains(baseIRI, vOGP.audio, RDFUtils.literal("http://example.com/sound.mp3") ); assertContains( baseIRI, vOGP.description, @@ -227,7 +231,7 @@ public class RDFa11ExtractorTest extends AbstractRDFaExtractorTestCase { ) ); assertContains(baseIRI, vOGP.determiner, RDFUtils.literal("the") ); - assertContains(baseIRI, vOGP.locale, RDFUtils.literal("en_UK") ); + assertContains(baseIRI, vOGP.locale, RDFUtils.literal("en_GB") ); assertContains(baseIRI, vOGP.localeAlternate, RDFUtils.literal("fr_FR") ); assertContains(baseIRI, vOGP.localeAlternate, RDFUtils.literal("es_ES") ); assertContains(baseIRI, vOGP.siteName, RDFUtils.literal("IMDb") ); @@ -239,4 +243,30 @@ public class RDFa11ExtractorTest extends AbstractRDFaExtractorTestCase { return new RDFa11ExtractorFactory(); } + /** + * Tests the correct support of alternate + * <a href="http://ogp.me/#types">Open Graph Protocol Object Types</a> + * + * @throws IOException + * @throws org.apache.any23.extractor.ExtractionException + * @throws RepositoryException + */ + @Test + public void testOpenGraphAlternateObjectTypes() throws IOException, ExtractionException, RepositoryException { + assertExtract("/html/rdfa/opengraph-music-song-object-type.html"); + logger.info( dumpHumanReadableTriples() ); + + Assert.assertEquals(9, getStatementsSize(null, null, null) ); + final OGPMusic vOGPMusic = OGPMusic.getInstance(); + assertContains(baseIRI, vOGPMusic.musicDuration, RDFUtils.literal("447") ); + assertContains( + baseIRI, + vOGPMusic.musicMusician, + RDFUtils.literal( + "Jono Grant / Tony McGuinness / Ashley Tomberlin" + ) + ); + assertContains(baseIRI, vOGPMusic.musicAlbum, RDFUtils.literal("Tri-State") ); + } + } http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/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 f1afd4a..9f85c42 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, 2102); + serializeVocabularies(RDFFormat.NTRIPLES, 2216); } /** @@ -53,7 +53,7 @@ public class RDFSchemaUtilsTest { */ @Test public void testSerializeVocabulariesRDFXML() { - serializeVocabularies(RDFFormat.RDFXML, 5489); // Effective lines + separators. + serializeVocabularies(RDFFormat.RDFXML, 5804); // Effective lines + separators. } private void serializeVocabularies(RDFFormat format, int expectedLines) { http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/test-resources/src/test/resources/html/rdfa/opengraph-music-song-object-type.html ---------------------------------------------------------------------- diff --git a/test-resources/src/test/resources/html/rdfa/opengraph-music-song-object-type.html b/test-resources/src/test/resources/html/rdfa/opengraph-music-song-object-type.html new file mode 100644 index 0000000..c7d35ab --- /dev/null +++ b/test-resources/src/test/resources/html/rdfa/opengraph-music-song-object-type.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html prefix="og: http://ogp.me/ns/music#" > +<head> +<meta charset="UTF-8"/> +<meta property="og:title" content="Can't Sleep" /> +<meta property="og:type" content="music.song" /> +<meta property="og:image" content="https://cps-static.rovicorp.com/3/JPG_500/MI0002/215/MI0002215458.jpg?partner=allrovi.com" /> +<meta property="og:url" content="https://www.allmusic.com/song/cant-sleep-mt0014803829" /> +<meta property="og:music:duration" content="447" /> +<meta property="og:music:album" content="Tri-State" /> +<meta property="og:music:album:disc" content="1" /> +<meta property="og:music:album:track" content="5" /> +<meta property="og:music:musician" content="Jono Grant / Tony McGuinness / Ashley Tomberlin" /> +</head> +<body> + +</body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/any23/blob/025fccd6/test-resources/src/test/resources/html/rdfa/opengraph-structured-properties.html ---------------------------------------------------------------------- diff --git a/test-resources/src/test/resources/html/rdfa/opengraph-structured-properties.html b/test-resources/src/test/resources/html/rdfa/opengraph-structured-properties.html index 3cafd8a..365ddac 100644 --- a/test-resources/src/test/resources/html/rdfa/opengraph-structured-properties.html +++ b/test-resources/src/test/resources/html/rdfa/opengraph-structured-properties.html @@ -16,15 +16,64 @@ --> <html xmlns="http://www.w3.org/1999/xhtml" prefix="og: http://ogp.me/ns#"> <head> - <meta property="og:audio" content="http://example.com/bond/theme.mp3"/> - <meta property="og:description" - content="Sean Connery found fame and fortune as the suave, sophisticated British agent, James Bond."/> - <meta property="og:determiner" content="the"/> - <meta property="og:locale" content="en_UK"/> - <meta property="og:locale:alternate" content="fr_FR"/> - <meta property="og:locale:alternate" content="es_ES"/> - <meta property="og:site_name" content="IMDb"/> - <meta property="og:video" content="http://example.com/bond/trailer.swf"/> + <!-- All of the content below is based on the OGP examples provided at + http://ogp.me/, this ensures that thw Any23 coverage is suffciently up-to-date. + --> + + <!-- Begin Basic Metadata --> + <title>The Rock (1996)</title> + <meta property="og:title" content="The Rock" /> + <meta property="og:type" content="video.movie" /> + <meta property="og:url" content="http://www.imdb.com/title/tt0117500/" /> + <meta property="og:image" content="http://ia.media-imdb.com/images/rock.jpg" /> + <!-- End Basic Metadata --> + + <!-- Start Optional Metadata --> + <meta property="og:audio" content="http://example.com/bond/theme.mp3" /> + <meta property="og:description" content="Sean Connery found fame and fortune as the suave, sophisticated British agent, James Bond." /> + <meta property="og:determiner" content="the" /> + <meta property="og:locale" content="en_GB" /> + <meta property="og:locale:alternate" content="fr_FR" /> + <meta property="og:locale:alternate" content="es_ES" /> + <meta property="og:site_name" content="IMDb" /> + <meta property="og:video" content="http://example.com/bond/trailer.swf" /> + <!-- End Optional Metadata --> + + <!-- Start full Image Example --> + <meta property="og:image" content="http://example.com/ogp.jpg" /> + <meta property="og:image:secure_url" content="https://secure.example.com/ogp.jpg" /> + <meta property="og:image:type" content="image/jpeg" /> + <meta property="og:image:width" content="400" /> + <meta property="og:image:height" content="300" /> + <meta property="og:image:alt" content="A shiny red apple with a bite taken out" /> + <!-- End full Image example --> + + <!-- Start full video example --> + <meta property="og:video" content="http://example.com/movie.swf" /> + <meta property="og:video:secure_url" content="https://secure.example.com/movie.swf" /> + <meta property="og:video:type" content="application/x-shockwave-flash" /> + <meta property="og:video:width" content="400" /> + <meta property="og:video:height" content="300" /> + <!-- End full image example --> + + <!-- Start full audio example --> + <meta property="og:audio" content="http://example.com/sound.mp3" /> + <meta property="og:audio:secure_url" content="https://secure.example.com/sound.mp3" /> + <meta property="og:audio:type" content="audio/mpeg" /> + <!-- End full audio example --> + + <!-- Start Array example --> + <!-- If correctly extracted, HTML snippet below indicates there are 3 images, + the first of three is 300x300, the middle one has unspecified dimensions, + and the third one is 1000px tall.--> + <meta property="og:image" content="http://example.com/rock.jpg" /> + <meta property="og:image:width" content="300" /> + <meta property="og:image:height" content="300" /> + <meta property="og:image" content="http://example.com/rock2.jpg" /> + <meta property="og:image" content="http://example.com/rock3.jpg" /> + <meta property="og:image:height" content="1000" /> + <!-- End Array example --> + </head> <body></body> </html> \ No newline at end of file
