001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.kernel.api;
007
008import static com.google.common.collect.ImmutableSet.of;
009import static org.apache.jena.rdf.model.ResourceFactory.createProperty;
010import static org.apache.jena.rdf.model.ResourceFactory.createResource;
011import static org.apache.jena.vocabulary.RDF.type;
012
013import java.util.Set;
014import java.util.function.Predicate;
015import java.util.stream.Collectors;
016
017import org.apache.jena.graph.Triple;
018import org.apache.jena.rdf.model.Property;
019import org.apache.jena.rdf.model.Resource;
020
021import com.google.common.collect.ImmutableSet;
022
023/**
024 * A lexicon of the RDF properties that the fcrepo kernel (or close-to-core modules) use
025 *
026 * @author ajs6f
027 */
028public final class RdfLexicon {
029
030    /**
031     * Repository namespace "fedora"
032    **/
033    public static final String REPOSITORY_NAMESPACE = "http://fedora.info/definitions/v4/repository#";
034
035    public static final String REPOSITORY_WEBAC_NAMESPACE = "http://fedora.info/definitions/v4/webac#";
036
037    public static final String FCREPO_API_NAMESPACE = "http://fedora.info/definitions/fcrepo#";
038
039    public static final String ACTIVITY_STREAMS_NAMESPACE = "https://www.w3.org/ns/activitystreams#";
040
041    public static final String EBUCORE_NAMESPACE = "http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#";
042
043    public static final String OA_NAMESPACE = "http://www.w3.org/ns/oa#";
044
045    public static final String PROV_NAMESPACE = "http://www.w3.org/ns/prov#";
046
047    public static final String PREMIS_NAMESPACE = "http://www.loc.gov/premis/rdf/v1#";
048
049    public static final String MEMENTO_NAMESPACE = "http://mementoweb.org/ns#";
050
051    public static final String RDF_NAMESPACE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
052
053
054    /**
055     * Namespace for the W3C WebAC vocabulary.
056     */
057    public static final String WEBAC_NAMESPACE_VALUE = "http://www.w3.org/ns/auth/acl#";
058
059    /**
060     * Linked Data Platform namespace.
061     */
062    public static final String LDP_NAMESPACE = "http://www.w3.org/ns/ldp#";
063
064    /**
065     * Is this namespace one that the repository manages?
066     */
067    public static final Predicate<String> isManagedNamespace = p -> p.equals(REPOSITORY_NAMESPACE) ||
068            p.equals(LDP_NAMESPACE) || p.equals(MEMENTO_NAMESPACE);
069
070    /**
071     * Tests if the triple has a predicate of rdf:type and an object with a managed namespace.
072     * @see RdfLexicon#isManagedNamespace
073     */
074    public static final Predicate<Triple> restrictedType = s -> s.getPredicate().equals(type.asNode()) &&
075            (s.getObject().isURI() && isManagedNamespace.test(s.getObject().getNameSpace()));
076
077    // FIXITY
078    public static final Resource PREMIS_FIXITY =
079            createResource(PREMIS_NAMESPACE + "Fixity");
080    public static final Resource PREMIS_EVENT_OUTCOME_DETAIL =
081            createResource(PREMIS_NAMESPACE + "EventOutcomeDetail");
082
083    public static final Property HAS_MESSAGE_DIGEST =
084            createProperty(PREMIS_NAMESPACE + "hasMessageDigest");
085
086    public static final Property HAS_SIZE =
087        createProperty(PREMIS_NAMESPACE + "hasSize");
088    public static final Property HAS_FIXITY_RESULT =
089        createProperty(PREMIS_NAMESPACE + "hasFixity");
090
091    private static final Set<Property> fixityProperties = of(
092            HAS_FIXITY_RESULT, HAS_MESSAGE_DIGEST);
093
094    public static final Property HAS_FIXITY_STATE =
095            createProperty(PREMIS_NAMESPACE + "hasEventOutcome");
096
097    public static final Property WRITABLE =
098            createProperty(REPOSITORY_NAMESPACE + "writable");
099
100    public static final String FEDORA_NON_RDF_SOURCE_DESCRIPTION_URI = REPOSITORY_NAMESPACE +
101            "NonRdfSourceDescription";
102
103    // Server managed properties
104    public static final Property CREATED_DATE =
105            createProperty(REPOSITORY_NAMESPACE + "created");
106    public static final Property CREATED_BY =
107            createProperty(REPOSITORY_NAMESPACE + "createdBy");
108    public static final Property LAST_MODIFIED_DATE =
109            createProperty(REPOSITORY_NAMESPACE + "lastModified");
110    public static final Property LAST_MODIFIED_BY =
111            createProperty(REPOSITORY_NAMESPACE + "lastModifiedBy");
112
113    public static final Resource FEDORA_CONTAINER =
114            createResource(REPOSITORY_NAMESPACE + "Container");
115    public static final Resource FEDORA_BINARY =
116            createResource(REPOSITORY_NAMESPACE + "Binary");
117    public static final Resource FEDORA_RESOURCE =
118            createResource(REPOSITORY_NAMESPACE + "Resource");
119    public static final Resource FEDORA_PAIR_TREE =
120            createResource(REPOSITORY_NAMESPACE + "Pairtree");
121    public static final Resource ARCHIVAL_GROUP =
122            createResource(REPOSITORY_NAMESPACE + "ArchivalGroup");
123
124    // Linked Data Platform
125    public static final Property PAGE =
126        createProperty(LDP_NAMESPACE + "Page");
127    public static final Resource CONTAINER =
128            createResource(LDP_NAMESPACE + "Container");
129    public static final Resource BASIC_CONTAINER =
130            createResource(LDP_NAMESPACE + "BasicContainer");
131    public static final Resource DIRECT_CONTAINER =
132            createResource(LDP_NAMESPACE + "DirectContainer");
133    public static final Resource INDIRECT_CONTAINER =
134            createResource(LDP_NAMESPACE + "IndirectContainer");
135    public static final Property MEMBERSHIP_RESOURCE =
136            createProperty(LDP_NAMESPACE + "membershipResource");
137    public static final Property HAS_MEMBER_RELATION =
138            createProperty(LDP_NAMESPACE + "hasMemberRelation");
139    public static final Property INSERTED_CONTENT_RELATION =
140            createProperty(LDP_NAMESPACE + "insertedContentRelation");
141    public static final Property IS_MEMBER_OF_RELATION =
142            createProperty(LDP_NAMESPACE + "isMemberOfRelation");
143    public static final Property CONTAINS =
144        createProperty(LDP_NAMESPACE + "contains");
145    public static final Property LDP_MEMBER =
146            createProperty(LDP_NAMESPACE + "member");
147    public static final Resource RESOURCE =
148            createResource(LDP_NAMESPACE + "Resource");
149    public static final Resource RDF_SOURCE =
150            createResource(LDP_NAMESPACE + "RDFSource");
151    public static final Resource NON_RDF_SOURCE =
152        createResource(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_TRANSACTION_SERVICE =
162            createProperty(REPOSITORY_NAMESPACE + "hasTransactionProvider");
163    public static final Resource REPOSITORY_ROOT =
164            createResource(REPOSITORY_NAMESPACE + "RepositoryRoot");
165
166    // OTHER SERVICES
167    public static final Property HAS_FIXITY_SERVICE =
168            createProperty(REPOSITORY_NAMESPACE + "hasFixityService");
169
170    public static final Property HAS_MIME_TYPE =
171            createProperty(EBUCORE_NAMESPACE + "hasMimeType");
172    public static final Property HAS_ORIGINAL_NAME =
173            createProperty(EBUCORE_NAMESPACE + "filename");
174
175    // EXTERNAL CONTENT
176    public static final Property EXTERNAL_CONTENT = createProperty(FCREPO_API_NAMESPACE + "ExternalContent");
177
178    // RDF EXTRACTION
179    public static final Property INBOUND_REFERENCES = createProperty(FCREPO_API_NAMESPACE + "PreferInboundReferences");
180    public static final Property PREFER_SERVER_MANAGED = createProperty(FCREPO_API_NAMESPACE + "ServerManaged");
181    public static final Property PREFER_MINIMAL_CONTAINER = createProperty(LDP_NAMESPACE +
182            "PreferMinimalContainer");
183    public static final Property PREFER_CONTAINMENT = createProperty(LDP_NAMESPACE + "PreferContainment");
184    public static final Property PREFER_MEMBERSHIP = createProperty(LDP_NAMESPACE + "PreferMembership");
185
186
187    public static final Property EMBED_CONTAINED = createProperty(OA_NAMESPACE + "PreferContainedDescriptions");
188
189
190    // WEBAC
191    public static final String WEBAC_ACCESS_CONTROL_VALUE = WEBAC_NAMESPACE_VALUE + "accessControl";
192
193    public static final String WEBAC_ACCESS_TO = WEBAC_NAMESPACE_VALUE + "accessTo";
194
195    public static final String WEBAC_ACCESS_TO_CLASS = WEBAC_NAMESPACE_VALUE + "accessToClass";
196
197    public static final Property WEBAC_ACCESS_TO_PROPERTY = createProperty(WEBAC_ACCESS_TO);
198
199    public static final String FEDORA_WEBAC_ACL_URI = REPOSITORY_WEBAC_NAMESPACE + "Acl";
200
201    // Properties which are managed by the server but are not from managed namespaces
202    private static final Set<Property> serverManagedProperties;
203    static {
204        final ImmutableSet.Builder<Property> b = ImmutableSet.builder();
205        b.addAll(fixityProperties).addAll(ldpManagedProperties);
206        serverManagedProperties = b.build();
207    }
208
209    private static final Predicate<Property> hasFedoraNamespace =
210        p -> !p.isAnon() && p.getNameSpace().startsWith(REPOSITORY_NAMESPACE);
211
212    private static Predicate<Property> hasMementoNamespace =
213        p -> !p.isAnon() && p.getNameSpace().startsWith(MEMENTO_NAMESPACE);
214
215    // Set of relaxable server managed properties
216    private static final Set<Property> serverManagedRelaxableProperties = Set.of(
217            CREATED_DATE, CREATED_BY, LAST_MODIFIED_DATE, LAST_MODIFIED_BY
218    );
219
220    /**
221     * Detects whether an RDF property is managed by the repository.
222     */
223    public static final Predicate<Property> isManagedPredicate =
224            hasFedoraNamespace.or(hasMementoNamespace).or(serverManagedProperties::contains);
225
226    /**
227     * Tests if a property is relaxable (if the server is in relaxed mode).
228     */
229    public static final Predicate<Property> isRelaxablePredicate = serverManagedRelaxableProperties::contains;
230
231    // VERSIONING
232    /**
233     * Memento TimeMap type.
234     */
235    public static final String VERSIONING_TIMEMAP_TYPE = MEMENTO_NAMESPACE + "TimeMap";
236    public static final Resource VERSIONING_TIMEMAP = createResource(VERSIONING_TIMEMAP_TYPE);
237
238    /**
239     * Memento TimeGate type.
240     */
241    public static final String VERSIONING_TIMEGATE_TYPE = MEMENTO_NAMESPACE + "TimeGate";
242
243    /**
244     * Type for memento objects.
245     */
246    public static final String MEMENTO_TYPE = MEMENTO_NAMESPACE + "Memento";
247
248    /**
249     * This is an internal RDF type for versionable resources, this may be replaced by a Memento type.
250     */
251    public static final Resource VERSIONED_RESOURCE =
252        createResource(MEMENTO_NAMESPACE + "OriginalResource");
253
254    public static final Property MEMENTO_ORIGINAL_RESOURCE =
255        createProperty(MEMENTO_NAMESPACE + "original");
256
257    /*
258     * Interaction Models.
259     */
260    public static final Set<Resource> INTERACTION_MODEL_RESOURCES = of(
261            BASIC_CONTAINER, INDIRECT_CONTAINER, DIRECT_CONTAINER, NON_RDF_SOURCE);
262
263    /**
264     * String set of valid interaction models with full LDP URI.
265     */
266    public static final Set<String> INTERACTION_MODELS_FULL = INTERACTION_MODEL_RESOURCES.stream().map(Resource::getURI)
267            .collect(Collectors.toSet());
268
269    /**
270     * This defines what we assume if you don't specify.
271     */
272    public static final Resource DEFAULT_INTERACTION_MODEL = BASIC_CONTAINER;
273
274    private RdfLexicon() {
275        // This constructor left intentionally blank.
276    }
277}