Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ build
.classpath
.project
.settings/
.DS_Store
34 changes: 34 additions & 0 deletions trellis-api/src/main/java/org/trellisldp/api/AppendService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed 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.trellisldp.api;

import java.util.concurrent.Future;

/**
* A service that persists resources by appending to their records. Nothing that
* is recorded by {@link #add(Object)} will be deleted by using {@code add} again.
*
* @author ajs6f
*
* @param <T> the type of resource that can be persisted by this service
*/
public interface AppendService<T> {

/**
* @param resource a resource to persist
* @return whether the resource was successfully persisted
*/
Future<Boolean> add(T resource);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*
* @author acoburn
*/
public interface AuditService {
public interface AuditService extends AppendService<Resource> {

/**
* Generate the audit quads for a Create event.
Expand Down
102 changes: 94 additions & 8 deletions trellis-api/src/main/java/org/trellisldp/api/RDFUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,22 @@
*/
package org.trellisldp.api;

import static java.util.Collections.newSetFromMap;
import static java.util.Collections.unmodifiableSet;
import static java.util.EnumSet.of;
import static java.util.stream.Collector.Characteristics.CONCURRENT;
import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH;
import static java.util.stream.Collector.Characteristics.UNORDERED;
import static java.util.stream.Collector.of;

import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Stream;

import org.apache.commons.rdf.api.Dataset;
import org.apache.commons.rdf.api.Graph;
Expand Down Expand Up @@ -71,7 +82,7 @@ public static RDF getInstance() {
* @return a graph
*/
public static Collector<Triple, ?, Graph> toGraph() {
return of(rdf::createGraph, Graph::add, (left, right) -> {
return Collector.of(rdf::createGraph, Graph::add, (left, right) -> {
right.iterate().forEach(left::add);
return left;
}, UNORDERED);
Expand All @@ -80,13 +91,88 @@ public static RDF getInstance() {
/**
* Collect a stream of Quads into a Dataset.
*
* @return a dataset
* @return a {@link Collector} that accumulates a {@link Stream} of
* {@link Quad}s into a {@link Dataset}
*/
public static Collector<Quad, ?, Dataset> toDataset() {
return of(rdf::createDataset, Dataset::add, (left, right) -> {
right.iterate().forEach(left::add);
return left;
}, UNORDERED);
public static DatasetCollector toDataset() {
return new DatasetCollector();
}

static class DatasetCollector implements Collector<Quad, Dataset, Dataset> {

@Override
public Supplier<Dataset> supplier() {
return rdf::createDataset;
}

@Override
public BiConsumer<Dataset, Quad> accumulator() {
return Dataset::add;
}

@Override
public BinaryOperator<Dataset> combiner() {
return (left, right) -> {
right.iterate().forEach(left::add);
return left;
};
}

@Override
public Function<Dataset, Dataset> finisher() {
return x -> x;
}

@Override
public Set<Characteristics> characteristics() {
return unmodifiableSet(of(UNORDERED, IDENTITY_FINISH));
}

/**
* Collect a stream of {@link Quad}s into a {@link Dataset} with concurrent
* operation.
*
* @return a {@link Collector} that accumulates a {@link Stream} of
* {@link Quad}s into a {@link Dataset}
*/
public ConcurrentDatasetCollector concurrent() {
return new ConcurrentDatasetCollector();
}
}

private static class ConcurrentDatasetCollector implements Collector<Quad, Set<Quad>, Dataset> {

@Override
public Supplier<Set<Quad>> supplier() {
return () -> newSetFromMap(new ConcurrentHashMap<>());
}

@Override
public BiConsumer<Set<Quad>, Quad> accumulator() {
return Set::add;
}

@Override
public BinaryOperator<Set<Quad>> combiner() {
return (s1, s2) -> {
s1.addAll(s2);
return s1;
};
}

@Override
public Function<Set<Quad>, Dataset> finisher() {
return set -> {
final Dataset dataset = rdf.createDataset();
set.forEach(dataset::add);
return dataset;
};
}

@Override
public Set<Characteristics> characteristics() {
return unmodifiableSet(of(UNORDERED, CONCURRENT));
}
}

private RDFUtils() {
Expand Down
34 changes: 34 additions & 0 deletions trellis-api/src/main/java/org/trellisldp/api/ReplaceService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed 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.trellisldp.api;

import java.util.concurrent.Future;

/**
* A service that persists resources by <i>replacing</i> their records.
*
* @author ajs6f
*
* @param <T> the type of resource that can be persisted by this service
*/
public interface ReplaceService<T> extends RetrievalService<T> {

/**
* @param resource a resource to persist
* @return whether the resource was successfully persisted
*/
Future<Boolean> put(T resource);

}
23 changes: 6 additions & 17 deletions trellis-api/src/main/java/org/trellisldp/api/ResourceService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static org.trellisldp.api.RDFUtils.TRELLIS_BNODE_PREFIX;
import static org.trellisldp.api.RDFUtils.TRELLIS_DATA_PREFIX;
import static org.trellisldp.api.RDFUtils.getInstance;
import static org.trellisldp.api.RDFUtils.toDataset;

import java.time.Instant;
import java.util.Collection;
Expand All @@ -40,24 +41,12 @@
*
* @author acoburn
*/
public interface ResourceService {
public interface ResourceService extends ReplaceService<Resource> {

/**
* Get a resource from the given location.
*
* @param identifier the resource identifier
* @return the resource
*/
Optional<? extends Resource> get(IRI identifier);

/**
* Get a resource from the given location and time.
*
* @param identifier the resource identifier
* @param time the time
* @return the resource
*/
Optional<? extends Resource> get(IRI identifier, Instant time);
@Override
default Future<Boolean> put(Resource res) {
return put(res.getIdentifier(), res.getInteractionModel(), res.stream().collect(toDataset().concurrent()));
}

/**
* Put a resource into the server.
Expand Down
50 changes: 50 additions & 0 deletions trellis-api/src/main/java/org/trellisldp/api/RetrievalService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed 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.trellisldp.api;

import java.time.Instant;
import java.util.Optional;

import org.apache.commons.rdf.api.IRI;

/**
* A service that can retrieve resources of some type, featuring optional
* retrieval by time.
*
* @author ajs6f
*
* @param <T> the type of resource available from this service
*/
public interface RetrievalService<T> {

/**
* Get a resource by the given identifier.
*
* @param identifier the resource identifier
* @return the resource
*/
Optional<? extends T> get(IRI identifier);

/**
* Get a resource by the given identifier and time.
*
* @param identifier the resource identifier
* @param time the time
* @return the resource
*/
default Optional<? extends T> get(IRI identifier, Instant time) {
return get(identifier);
}
}
6 changes: 6 additions & 0 deletions trellis-audit/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,9 @@ jar {
}
}

javadoc {
options.tags = ["apiNote:a:API Note:",
"implSpec:a:Implementation Requirements:",
"implNote:a:Implementation Note:"]
}

Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,32 @@

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

import org.apache.commons.rdf.api.BlankNode;
import org.apache.commons.rdf.api.IRI;
import org.apache.commons.rdf.api.Quad;
import org.apache.commons.rdf.api.RDF;
import org.trellisldp.api.AuditService;
import org.trellisldp.api.Resource;
import org.trellisldp.api.Session;
import org.trellisldp.vocabulary.AS;
import org.trellisldp.vocabulary.PROV;
import org.trellisldp.vocabulary.XSD;

/**
* An {@link AuditService} that generates Audit-related {@link Quad}s for various write operations.
*
* <p>This class makes use of the {@link PROV} vocabulary and {@link BlankNode} objects in a
* {@code http://www.trellisldp.org/ns/trellis#PreferAudit} named graph.
* An {@link AuditService} that generates Audit-related {@link Quad}s for
* various write operations.
*
* <p>This class makes use of the {@link PROV} vocabulary and {@link BlankNode}
* objects in a {@code http://www.trellisldp.org/ns/trellis#PreferAudit} named
* graph.
*
* @implSpec This implementation of AuditService does not persist audit
* information. Subclass and override {@link #add(Resource)} to add
* persistence.
*
* @author acoburn
*/
public class DefaultAuditService implements AuditService {
Expand Down Expand Up @@ -70,4 +79,14 @@ private List<Quad> auditData(final IRI subject, final Session session, final Lis
data.add(rdf.createQuad(PreferAudit, bnode, PROV.actedOnBehalfOf, delegate)));
return data;
}

/*
* Override to provide persistence for audit information.
*
* @see org.trellisldp.api.AppendService#add(java.lang.Object)
*/
@Override
public Future<Boolean> add(final Resource resource) {
return CompletableFuture.completedFuture(false);
}
}
1 change: 1 addition & 0 deletions trellis-karaf/src/main/resources/features.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@

<feature>commons-rdf-jena</feature>
<feature>trellis-api</feature>
<feature>trellis-audit</feature>
<feature>trellis-vocabulary</feature>

<bundle>mvn:org.trellisldp/trellis-triplestore/${project.version}</bundle>
Expand Down
Loading