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