001/*
002 * PermissionsEx
003 * Copyright (C) zml and PermissionsEx contributors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package ca.stellardrift.permissionsex.query;
018
019import ca.stellardrift.permissionsex.context.ContextDefinition;
020import ca.stellardrift.permissionsex.context.ContextValue;
021import ca.stellardrift.permissionsex.subject.CalculatedSubject;
022import ca.stellardrift.permissionsex.subject.Segment;
023import ca.stellardrift.permissionsex.subject.SubjectRef;
024import ca.stellardrift.permissionsex.subject.SubjectType;
025import ca.stellardrift.permissionsex.util.Change;
026
027import java.util.Set;
028import java.util.concurrent.CompletableFuture;
029import java.util.function.BiFunction;
030import java.util.stream.Stream;
031
032/**
033 * A query for permissions data.
034 *
035 * <p>Queries are build in <em>stages</em>, and each stage Parameters can be applied to control
036 * almost every aspect of permissions resolution.
037 *
038 * <h2>Stages</h2>
039 * <ol>
040 *     <li>select type and/or identifier</li>
041 * </ol>
042 */
043public interface PermissionsQuery {
044
045    <I> IdentifierStage<I> inType(final SubjectType<I> type);
046
047    AllOrAnyState subject(final SubjectRef<?> ref);
048
049    AllOrAnyState anySubject();
050
051    /**
052     * Specifies an identifier for a specific subject type
053     * @param <I> the subject's identifier
054     */
055    interface IdentifierStage<I> {
056        AllOrAnyState withName(final I name);
057
058        /**
059         * Act on any subject in this type
060         *
061         * @return a stream providing all identifiers
062         */
063        AllOrAnyState anySubject();
064    }
065
066
067    interface AllOrAnyState {
068        EitherStage matchingAllOf();
069        EitherStage matchingAnyOf();
070    }
071
072    interface EitherStage {
073        
074        // Filtering operators
075
076        EitherStage hasContext(final ContextDefinition<?> definition);
077
078        EitherStage hasContext(final ContextValue<?> context);
079
080        /**
081         * Has a permission that may or may not evaluate to true
082         * @param permission
083         * @return
084         */
085        EitherStage hasPermissionSet(final String permission);
086
087        /**
088         * Has a permission that evaluates to true
089         * @param permission
090         * @return
091         */
092        EitherStage hasPermission(final String permission);
093
094        EitherStage withOption(final String option, final String value);
095
096        EitherStage isChildOf(final SubjectRef<?> parent);
097        
098        // Terminal operators
099
100        SubjectStage subjects();
101
102        SegmentsStage segments();
103
104    }
105
106    interface SubjectStage {
107
108        Stream<CalculatedSubject> loaded();
109        CompletableFuture<Set<String>> names();
110        CompletableFuture<Set<CalculatedSubject>> subjects();
111    }
112
113    interface SegmentsStage {
114        SegmentsStage containingContext(final ContextValue<?> value);
115
116        SegmentsStage contextSet(final ContextDefinition<?> definition);
117        
118        // TODO: weight, inheritability, etc
119
120        CompletableFuture<Set<Segment>> all();
121
122        Set<Segment> loaded();
123
124        CompletableFuture<Change<Segment>> update(final BiFunction<Set<ContextValue<?>>, Segment, Segment> updater);
125    }
126}