001/**
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.kernel.api;
017
018import static com.google.common.base.Predicates.in;
019import static com.google.common.base.Predicates.or;
020import static com.google.common.collect.ImmutableSet.of;
021import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
022import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
023
024import java.util.Set;
025
026import com.google.common.base.Predicate;
027import com.google.common.collect.ImmutableSet;
028import com.hp.hpl.jena.rdf.model.Property;
029import com.hp.hpl.jena.rdf.model.Resource;
030
031/**
032 * A lexicon of the RDF properties that the fcrepo kernel (or close-to-core modules) use
033 *
034 * @author ajs6f
035 */
036public final class RdfLexicon {
037
038    /**
039     * Repository namespace "fcrepo", used for JCR properties exposed
040     * publicly.
041     * Was "info:fedora/fedora-system:def/internal#".
042    **/
043    public static final String REPOSITORY_NAMESPACE =
044            "http://fedora.info/definitions/v4/repository#";
045
046    /**
047     *  The core JCR namespace.
048     */
049    public static final String JCR_NAMESPACE = "http://www.jcp.org/jcr/1.0";
050
051    public static final String MODE_NAMESPACE = "http://www.modeshape.org/1.0";
052
053    public static final String MIX_NAMESPACE = "http://www.jcp.org/jcr/mix/1.0";
054
055    public static final String JCR_NT_NAMESPACE = "http://www.jcp.org/jcr/nt/1.0";
056
057    public static final String EBUCORE_NAMESPACE = "http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#";
058
059    /**
060     * Fedora configuration namespace "fedora-config", used for user-settable
061     * configuration properties.
062     **/
063    // TODO from UCDetector: Constant "RdfLexicon.FEDORA_CONFIG_NAMESPACE" has 0 references
064    // should be referenced again when versioning is back in REST api
065    public static final String FEDORA_CONFIG_NAMESPACE = // NO_UCD (unused code)
066            "http://fedora.info/definitions/v4/config#";
067
068    /**
069     * REST API namespace "fedora", used for internal API links and node
070     * paths.
071     * Was "info:fedora/".
072     **/
073    public static final String PREMIS_NAMESPACE =
074        "http://www.loc.gov/premis/rdf/v1#";
075
076    /**
077     * Linked Data Platform namespace.
078     */
079    public static final String LDP_NAMESPACE = "http://www.w3.org/ns/ldp#";
080
081    /**
082     * SPARQL service description namespace.
083     */
084    public static final String SPARQL_SD_NAMESPACE =
085            "http://www.w3.org/ns/sparql-service-description#";
086
087    /**
088     * The namespaces that the repository manages internally.
089     */
090    public static final Set<String> managedNamespaces = of(
091            REPOSITORY_NAMESPACE, JCR_NAMESPACE,
092            MIX_NAMESPACE, JCR_NT_NAMESPACE, MODE_NAMESPACE);
093
094    /**
095     * Is this namespace one that the repository manages?
096     */
097    public static final Predicate<String> isManagedNamespace =
098        in(managedNamespaces);
099
100    public static final String RDF_NAMESPACE =
101            "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
102
103    public static final String INDEXING_NAMESPACE =
104            "http://fedora.info/definitions/v4/indexing#";
105
106    public static final String DC_NAMESPACE =
107            "http://purl.org/dc/elements/1.1/";
108
109    // MEMBERSHIP
110    public static final Property HAS_PARENT =
111            createProperty(REPOSITORY_NAMESPACE + "hasParent");
112    public static final Property HAS_CHILD =
113            createProperty(REPOSITORY_NAMESPACE + "hasChild");
114    public static final Property HAS_CHILD_COUNT =
115            createProperty(REPOSITORY_NAMESPACE + "numberOfChildren");
116
117    public static final Set<Property> membershipProperties = of(HAS_PARENT, HAS_CHILD, HAS_CHILD_COUNT);
118
119    // FIXITY
120
121    public static final Resource FIXITY_TYPE = createResource(PREMIS_NAMESPACE + "Fixity");
122    public static final Property HAS_MESSAGE_DIGEST =
123        createProperty(PREMIS_NAMESPACE + "hasMessageDigest");
124    public static final Property HAS_SIZE =
125        createProperty(PREMIS_NAMESPACE + "hasSize");
126    public static final Property HAS_FIXITY_RESULT =
127        createProperty(PREMIS_NAMESPACE + "hasFixity");
128
129    public static final Property HAS_FIXITY_STATE =
130            createProperty(REPOSITORY_NAMESPACE + "status");
131
132    public static final Property HAS_FIXITY_CHECK_COUNT =
133            createProperty(REPOSITORY_NAMESPACE + "numFixityChecks");
134    public static final Property HAS_FIXITY_ERROR_COUNT =
135            createProperty(REPOSITORY_NAMESPACE + "numFixityErrors");
136    public static final Property HAS_FIXITY_REPAIRED_COUNT =
137            createProperty(REPOSITORY_NAMESPACE + "numFixityRepaired");
138
139    public static final Set<Property> fixityProperties = of(
140            HAS_FIXITY_RESULT, HAS_MESSAGE_DIGEST, HAS_SIZE, HAS_FIXITY_STATE,
141            HAS_FIXITY_CHECK_COUNT, HAS_FIXITY_ERROR_COUNT, HAS_FIXITY_REPAIRED_COUNT);
142
143    public static final Property WRITABLE =
144            createProperty(REPOSITORY_NAMESPACE + "writable");
145
146    // Linked Data Platform
147    public static final Property PAGE =
148        createProperty(LDP_NAMESPACE + "Page");
149    public static final Property PAGE_OF =
150        createProperty(LDP_NAMESPACE + "pageOf");
151    public static final Property FIRST_PAGE =
152        createProperty(LDP_NAMESPACE + "firstPage");
153    public static final Property NEXT_PAGE =
154            createProperty(LDP_NAMESPACE + "nextPage");
155    public static final Resource CONTAINER =
156            createResource(LDP_NAMESPACE + "Container");
157    public static final Resource BASIC_CONTAINER =
158            createResource(LDP_NAMESPACE + "BasicContainer");
159    public static final Resource DIRECT_CONTAINER =
160            createResource(LDP_NAMESPACE + "DirectContainer");
161    public static final Resource INDIRECT_CONTAINER =
162            createResource(LDP_NAMESPACE + "IndirectContainer");
163    public static final Property MEMBERSHIP_RESOURCE =
164            createProperty(LDP_NAMESPACE + "membershipResource");
165    public static final Property HAS_MEMBER_RELATION =
166            createProperty(LDP_NAMESPACE + "hasMemberRelation");
167    public static final Property CONTAINS =
168        createProperty(LDP_NAMESPACE + "contains");
169    public static final Property LDP_MEMBER =
170            createProperty(LDP_NAMESPACE + "member");
171    public static final Property RDF_SOURCE =
172            createProperty(LDP_NAMESPACE + "RDFSource");
173    public static final Property NON_RDF_SOURCE =
174        createProperty(LDP_NAMESPACE + "NonRDFSource");
175    public static final Property CONSTRAINED_BY =
176            createProperty(LDP_NAMESPACE + "constrainedBy");
177    public static final Property MEMBER_SUBJECT =
178            createProperty(LDP_NAMESPACE + "MemberSubject");
179
180    public static final Set<Property> ldpProperties = of(PAGE, PAGE_OF,
181            FIRST_PAGE, NEXT_PAGE, CONTAINS, LDP_MEMBER);
182    public static final Set<Resource> ldpResources = of(CONTAINER,
183            DIRECT_CONTAINER);
184
185    // REPOSITORY INFORMATION
186    public static final Property HAS_OBJECT_COUNT =
187            createProperty(REPOSITORY_NAMESPACE + "objectCount");
188    public static final Property HAS_OBJECT_SIZE =
189            createProperty(REPOSITORY_NAMESPACE + "objectSize");
190    public static final Property HAS_TRANSACTION_SERVICE =
191            createProperty(REPOSITORY_NAMESPACE + "hasTransactionProvider");
192    public static final Property HAS_ACCESS_ROLES_SERVICE =
193            createProperty(REPOSITORY_NAMESPACE + "hasAccessRoles");
194
195    public static final Set<Property> repositoryProperties = of(
196            HAS_OBJECT_COUNT, HAS_OBJECT_SIZE, HAS_TRANSACTION_SERVICE);
197
198    // NAMESPACES
199    public static final Property HAS_NAMESPACE_PREFIX =
200            createProperty("http://purl.org/vocab/vann/preferredNamespacePrefix");
201    public static final Property HAS_NAMESPACE_URI =
202            createProperty("http://purl.org/vocab/vann/preferredNamespaceUri");
203    public static final Property VOAF_VOCABULARY = createProperty("http://purl.org/vocommons/voaf#Vocabulary");
204
205    public static final Set<Property> namespaceProperties = of(
206            HAS_NAMESPACE_PREFIX, HAS_NAMESPACE_URI, VOAF_VOCABULARY);
207
208    // OTHER SERVICES
209    public static final Property HAS_SERIALIZATION =
210            createProperty(REPOSITORY_NAMESPACE + "exportsAs");
211    public static final Property HAS_VERSION_HISTORY =
212            createProperty(REPOSITORY_NAMESPACE + "hasVersions");
213    public static final Property HAS_FIXITY_SERVICE =
214            createProperty(REPOSITORY_NAMESPACE + "hasFixityService");
215    public static final Property HAS_FEED =
216            createProperty(
217                    "http://www.whatwg.org/specs/web-apps/current-work/#",
218                    "feed0");
219    public static final Property HAS_SUBSCRIPTION_SERVICE =
220            createProperty("http://microformats.org/wiki/rel-subscription");
221    public static final Property HAS_SPARQL_ENDPOINT =
222        createProperty(SPARQL_SD_NAMESPACE + "endpoint");
223
224    public static final Set<Property> otherServiceProperties = of(
225            HAS_SERIALIZATION, HAS_VERSION_HISTORY, HAS_FIXITY_SERVICE,
226            HAS_FEED, HAS_SUBSCRIPTION_SERVICE);
227
228
229    // BINARY DESCRIPTIONS
230    public static final Property DESCRIBES =
231            createProperty("http://www.iana.org/assignments/relation/describes");
232    public static final Property DESCRIBED_BY =
233            createProperty("http://www.iana.org/assignments/relation/describedby");
234
235    public static final Set<Property> structProperties = of(DESCRIBES, DESCRIBED_BY);
236
237    // CONTENT
238    public static final Resource CONTENT_LOCATION_TYPE =
239            createResource(PREMIS_NAMESPACE + "ContentLocation");
240    public static final Property HAS_CONTENT_LOCATION =
241            createProperty(PREMIS_NAMESPACE + "hasContentLocation");
242    public static final Property HAS_CONTENT_LOCATION_VALUE =
243        createProperty(PREMIS_NAMESPACE + "hasContentLocationValue");
244    public static final Property HAS_MIME_TYPE =
245            createProperty(EBUCORE_NAMESPACE + "hasMimeType");
246    public static final Property HAS_ORIGINAL_NAME =
247            createProperty(EBUCORE_NAMESPACE + "filename");
248
249    public static final Set<Property> contentProperties = of(HAS_CONTENT_LOCATION, HAS_CONTENT_LOCATION_VALUE,
250            HAS_SIZE);
251
252
253    // VERSIONING
254    public static final Property HAS_VERSION =
255            createProperty(REPOSITORY_NAMESPACE + "hasVersion");
256    public static final Property HAS_VERSION_LABEL =
257            createProperty(REPOSITORY_NAMESPACE + "hasVersionLabel");
258
259    public static final Set<Property> versioningProperties = of(HAS_VERSION,
260            HAS_VERSION_LABEL);
261
262    // RDF EXTRACTION
263    public static final Property COULD_NOT_STORE_PROPERTY =
264            createProperty(REPOSITORY_NAMESPACE + "couldNotStoreProperty");
265    public static final Property INBOUND_REFERENCES = createProperty(REPOSITORY_NAMESPACE + "InboundReferences");
266    public static final Property EMBED_CONTAINS = createProperty(REPOSITORY_NAMESPACE + "EmbedResources");
267    public static final Property SERVER_MANAGED = createProperty(REPOSITORY_NAMESPACE + "ServerManaged");
268
269    // IMPORTANT JCR PROPERTIES
270    public static final Property HAS_PRIMARY_IDENTIFIER =
271            createProperty(REPOSITORY_NAMESPACE + "uuid");
272    public static final Property HAS_PRIMARY_TYPE =
273            createProperty(REPOSITORY_NAMESPACE + "primaryType");
274    public static final Property HAS_NODE_TYPE =
275            createProperty(REPOSITORY_NAMESPACE + "hasNodeType");
276    public static final Property HAS_MIXIN_TYPE =
277            createProperty(REPOSITORY_NAMESPACE + "mixinTypes");
278    public static final Property CREATED_DATE =
279            createProperty(REPOSITORY_NAMESPACE + "created");
280    public static final Property CREATED_BY =
281            createProperty(REPOSITORY_NAMESPACE + "createdBy");
282    public static final Property LAST_MODIFIED_DATE =
283            createProperty(REPOSITORY_NAMESPACE + "lastModified");
284    public static final Property LAST_MODIFIED_BY =
285            createProperty(REPOSITORY_NAMESPACE + "lastModifiedBy");
286
287    public static final Set<Property> jcrProperties = of(
288            HAS_PRIMARY_IDENTIFIER, HAS_PRIMARY_TYPE, HAS_NODE_TYPE,
289            HAS_MIXIN_TYPE, CREATED_DATE, CREATED_BY, LAST_MODIFIED_DATE,
290            LAST_MODIFIED_BY);
291
292    public static final Property RDFS_LABEL =
293            createProperty("http://www.w3.org/2000/01/rdf-schema#label");
294    public static final Property DC_TITLE =
295            createProperty("http://purl.org/dc/elements/1.1/title");
296    public static final Property DCTERMS_TITLE =
297            createProperty("http://purl.org/dc/terms/title");
298    public static final Property SKOS_PREFLABEL =
299            createProperty("http://www.w3.org/2004/02/skos/core#prefLabel");
300
301    public static final Set<Property> managedProperties;
302
303    static {
304        final ImmutableSet.Builder<Property> b = ImmutableSet.builder();
305        b.addAll(membershipProperties).addAll(fixityProperties).addAll(ldpProperties).addAll(
306                repositoryProperties).addAll(namespaceProperties).addAll(
307                otherServiceProperties).addAll(structProperties).addAll(contentProperties).addAll(
308                versioningProperties).addAll(jcrProperties);
309        managedProperties = b.build();
310    }
311
312    private static Predicate<Property> hasJcrNamespace =
313        new Predicate<Property>() {
314
315            @Override
316            public boolean apply(final Property p) {
317                return !p.isAnon() && p.getNameSpace().equals(JCR_NAMESPACE);
318
319            }
320        };
321
322    private static Predicate<Property> hasFedoraNamespace =
323        new Predicate<Property>() {
324
325            @Override
326            public boolean apply(final Property p) {
327                return !p.isAnon()
328                        && p.getNameSpace().startsWith(REPOSITORY_NAMESPACE);
329
330            }
331        };
332
333    /**
334     * Detects whether an RDF property is managed by the repository.
335     */
336    @SuppressWarnings("unchecked")
337    public static final Predicate<Property> isManagedPredicate = or(
338            in(managedProperties), hasJcrNamespace, hasFedoraNamespace);
339
340    /**
341     * Detects whether an RDF predicate URI is managed by the repository.
342    **/
343    public static Predicate<String> isManagedPredicateURI =
344        new Predicate<String>() {
345            @Override
346            public boolean apply(final String uri) {
347                return isManagedPredicate.apply( createProperty(uri) );
348            }
349        };
350
351    private RdfLexicon() {
352
353    }
354}