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 org.apache.jena.rdf.model.ResourceFactory.createProperty;
022import static org.apache.jena.rdf.model.ResourceFactory.createResource;
023
024import java.util.Set;
025import java.util.function.Predicate;
026
027import com.google.common.collect.ImmutableSet;
028import org.apache.jena.rdf.model.Property;
029import org.apache.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 "fedora"
040    **/
041    public static final String REPOSITORY_NAMESPACE = "http://fedora.info/definitions/v4/repository#";
042
043    public static final String EVENT_NAMESPACE = "http://fedora.info/definitions/v4/event#";
044
045    public static final String EBUCORE_NAMESPACE = "http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#";
046
047    public static final String PROV_NAMESPACE = "http://www.w3.org/ns/prov#";
048
049    public static final String PREMIS_NAMESPACE = "http://www.loc.gov/premis/rdf/v1#";
050
051    /**
052     * Fedora configuration namespace "fedora-config", used for user-settable
053     * configuration properties.
054     **/
055    // TODO from UCDetector: Constant "RdfLexicon.FEDORA_CONFIG_NAMESPACE" has 0 references
056    // should be referenced again when versioning is back in REST api
057    public static final String FEDORA_CONFIG_NAMESPACE = // NO_UCD (unused code)
058            "info:fedoraconfig/";
059
060    /**
061     * Linked Data Platform namespace.
062     */
063    public static final String LDP_NAMESPACE = "http://www.w3.org/ns/ldp#";
064
065    /**
066     * SPARQL service description namespace.
067     */
068    public static final String SPARQL_SD_NAMESPACE =
069            "http://www.w3.org/ns/sparql-service-description#";
070
071    /**
072     * Is this namespace one that the repository manages?
073     */
074    public static final Predicate<String> isManagedNamespace = p -> p.equals(REPOSITORY_NAMESPACE);
075
076    // MEMBERSHIP
077    public static final Property HAS_PARENT =
078            createProperty(REPOSITORY_NAMESPACE + "hasParent");
079    public static final Property HAS_CHILD =
080            createProperty(REPOSITORY_NAMESPACE + "hasChild");
081
082    public static final Set<Property> membershipProperties = of(HAS_PARENT, HAS_CHILD);
083
084    // FIXITY
085
086    public static final Resource FIXITY_TYPE = createResource(PREMIS_NAMESPACE + "Fixity");
087
088    public static final Property HAS_MESSAGE_DIGEST_ALGORITHM =
089            createProperty(PREMIS_NAMESPACE + "hasMessageDigestAlgorithm");
090
091    public static final Property HAS_MESSAGE_DIGEST =
092            createProperty(PREMIS_NAMESPACE + "hasMessageDigest");
093
094    public static final Property HAS_SIZE =
095        createProperty(PREMIS_NAMESPACE + "hasSize");
096    public static final Property HAS_FIXITY_RESULT =
097        createProperty(PREMIS_NAMESPACE + "hasFixity");
098
099    public static final Property HAS_FIXITY_CHECK_COUNT =
100            createProperty(REPOSITORY_NAMESPACE + "numFixityChecks");
101    public static final Property HAS_FIXITY_ERROR_COUNT =
102            createProperty(REPOSITORY_NAMESPACE + "numFixityErrors");
103    public static final Property HAS_FIXITY_REPAIRED_COUNT =
104            createProperty(REPOSITORY_NAMESPACE + "numFixityRepaired");
105
106    public static final Set<Property> fixityProperties = of(
107            HAS_FIXITY_RESULT, HAS_MESSAGE_DIGEST, HAS_SIZE,
108            HAS_FIXITY_CHECK_COUNT, HAS_FIXITY_ERROR_COUNT, HAS_FIXITY_REPAIRED_COUNT);
109
110    public static final Resource EVENT_OUTCOME_INFORMATION = createResource(PREMIS_NAMESPACE + "EventOutcomeDetail");
111
112    public static final Property HAS_FIXITY_STATE =
113            createProperty(PREMIS_NAMESPACE + "hasEventOutcome");
114
115    public static final Property WRITABLE =
116            createProperty(REPOSITORY_NAMESPACE + "writable");
117
118    // Server managed properties
119    public static final Property CREATED_DATE =
120            createProperty(REPOSITORY_NAMESPACE + "created");
121    public static final Property CREATED_BY =
122            createProperty(REPOSITORY_NAMESPACE + "createdBy");
123    public static final Property LAST_MODIFIED_DATE =
124            createProperty(REPOSITORY_NAMESPACE + "lastModified");
125    public static final Property LAST_MODIFIED_BY =
126            createProperty(REPOSITORY_NAMESPACE + "lastModifiedBy");
127    public static final Set<Property> serverManagedProperties = of(
128            CREATED_DATE, CREATED_BY, LAST_MODIFIED_DATE, LAST_MODIFIED_BY);
129
130    // Linked Data Platform
131    public static final Property PAGE =
132        createProperty(LDP_NAMESPACE + "Page");
133    public static final Resource CONTAINER =
134            createResource(LDP_NAMESPACE + "Container");
135    public static final Resource BASIC_CONTAINER =
136            createResource(LDP_NAMESPACE + "BasicContainer");
137    public static final Resource DIRECT_CONTAINER =
138            createResource(LDP_NAMESPACE + "DirectContainer");
139    public static final Resource INDIRECT_CONTAINER =
140            createResource(LDP_NAMESPACE + "IndirectContainer");
141    public static final Property MEMBERSHIP_RESOURCE =
142            createProperty(LDP_NAMESPACE + "membershipResource");
143    public static final Property HAS_MEMBER_RELATION =
144            createProperty(LDP_NAMESPACE + "hasMemberRelation");
145    public static final Property CONTAINS =
146        createProperty(LDP_NAMESPACE + "contains");
147    public static final Property LDP_MEMBER =
148            createProperty(LDP_NAMESPACE + "member");
149    public static final Property RDF_SOURCE =
150            createProperty(LDP_NAMESPACE + "RDFSource");
151    public static final Property NON_RDF_SOURCE =
152        createProperty(LDP_NAMESPACE + "NonRDFSource");
153    public static final Property CONSTRAINED_BY =
154            createProperty(LDP_NAMESPACE + "constrainedBy");
155    public static final Property MEMBER_SUBJECT =
156            createProperty(LDP_NAMESPACE + "MemberSubject");
157
158    private static final Set<Property> ldpManagedProperties = of(CONTAINS);
159
160    // REPOSITORY INFORMATION
161    public static final Property HAS_OBJECT_COUNT =
162            createProperty(REPOSITORY_NAMESPACE + "objectCount");
163    public static final Property HAS_OBJECT_SIZE =
164            createProperty(REPOSITORY_NAMESPACE + "objectSize");
165    public static final Property HAS_TRANSACTION_SERVICE =
166            createProperty(REPOSITORY_NAMESPACE + "hasTransactionProvider");
167    public static final Property HAS_ACCESS_ROLES_SERVICE =
168            createProperty(REPOSITORY_NAMESPACE + "hasAccessRoles");
169
170    public static final Set<Property> repositoryProperties = of(
171            HAS_OBJECT_COUNT, HAS_OBJECT_SIZE, HAS_TRANSACTION_SERVICE);
172
173    // NAMESPACES
174    public static final Property HAS_NAMESPACE_PREFIX =
175            createProperty("http://purl.org/vocab/vann/preferredNamespacePrefix");
176    public static final Property HAS_NAMESPACE_URI =
177            createProperty("http://purl.org/vocab/vann/preferredNamespaceUri");
178
179    public static final Set<Property> namespaceProperties = of(
180            HAS_NAMESPACE_PREFIX, HAS_NAMESPACE_URI);
181
182    // OTHER SERVICES
183    public static final Property HAS_VERSION_HISTORY =
184            createProperty(REPOSITORY_NAMESPACE + "hasVersions");
185    public static final Property HAS_FIXITY_SERVICE =
186            createProperty(REPOSITORY_NAMESPACE + "hasFixityService");
187    public static final Property HAS_SPARQL_ENDPOINT =
188        createProperty(SPARQL_SD_NAMESPACE + "endpoint");
189
190    public static final Set<Property> otherServiceProperties = of(
191            HAS_VERSION_HISTORY, HAS_FIXITY_SERVICE);
192
193
194    // BINARY DESCRIPTIONS
195    public static final Property DESCRIBES =
196            createProperty("http://www.iana.org/assignments/relation/describes");
197    public static final Property DESCRIBED_BY =
198            createProperty("http://www.iana.org/assignments/relation/describedby");
199
200    public static final Set<Property> structProperties = of(DESCRIBES, DESCRIBED_BY);
201
202    // CONTENT
203    public static final Resource CONTENT_LOCATION_TYPE =
204            createResource(PREMIS_NAMESPACE + "ContentLocation");
205    public static final Resource INACCESSIBLE_RESOURCE =
206            createResource(REPOSITORY_NAMESPACE + "inaccessibleResource");
207    public static final Property HAS_CONTENT_LOCATION =
208            createProperty(PREMIS_NAMESPACE + "hasContentLocation");
209    public static final Property HAS_CONTENT_LOCATION_VALUE =
210        createProperty(PREMIS_NAMESPACE + "hasContentLocationValue");
211    public static final Property HAS_MIME_TYPE =
212            createProperty(EBUCORE_NAMESPACE + "hasMimeType");
213    public static final Property HAS_ORIGINAL_NAME =
214            createProperty(EBUCORE_NAMESPACE + "filename");
215
216    public static final Set<Property> contentProperties = of(HAS_CONTENT_LOCATION, HAS_CONTENT_LOCATION_VALUE,
217            HAS_SIZE);
218
219
220    // VERSIONING
221    public static final Property HAS_VERSION =
222            createProperty(REPOSITORY_NAMESPACE + "hasVersion");
223    public static final Property HAS_VERSION_LABEL =
224            createProperty(REPOSITORY_NAMESPACE + "hasVersionLabel");
225
226    public static final Set<Property> versioningProperties = of(HAS_VERSION,
227            HAS_VERSION_LABEL);
228
229    // RDF EXTRACTION
230    public static final Property COULD_NOT_STORE_PROPERTY =
231            createProperty(REPOSITORY_NAMESPACE + "couldNotStoreProperty");
232    public static final Property INBOUND_REFERENCES = createProperty(REPOSITORY_NAMESPACE + "InboundReferences");
233    public static final Property EMBED_CONTAINS = createProperty(REPOSITORY_NAMESPACE + "EmbedResources");
234    public static final Property SERVER_MANAGED = createProperty(REPOSITORY_NAMESPACE + "ServerManaged");
235
236    public static final Set<Property> managedProperties;
237
238    static {
239        final ImmutableSet.Builder<Property> b = ImmutableSet.builder();
240        b.addAll(membershipProperties).addAll(fixityProperties).addAll(ldpManagedProperties).addAll(
241                repositoryProperties).addAll(namespaceProperties).addAll(
242                otherServiceProperties).addAll(structProperties).addAll(contentProperties).addAll(
243                versioningProperties).addAll(serverManagedProperties);
244        managedProperties = b.build();
245    }
246
247    public static final Set<Property> relaxableProperties
248            = of(LAST_MODIFIED_BY, LAST_MODIFIED_DATE, CREATED_BY, CREATED_DATE);
249
250    public static final String SERVER_MANAGED_PROPERTIES_MODE = "fcrepo.properties.management";
251
252    private static Predicate<Property> hasFedoraNamespace =
253        p -> !p.isAnon() && p.getNameSpace().startsWith(REPOSITORY_NAMESPACE);
254
255    public static final Predicate<Property> isRelaxed =
256            p -> relaxableProperties.contains(p)
257                    && ("relaxed".equals(System.getProperty(SERVER_MANAGED_PROPERTIES_MODE)));
258
259    /**
260     * Detects whether an RDF property is managed by the repository.
261     */
262    public static final Predicate<Property> isManagedPredicate =
263        hasFedoraNamespace.or(p -> managedProperties.contains(p));
264
265    private RdfLexicon() {
266
267    }
268}