mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-01-27 01:39:09 +01:00
Add queryable store with SQLite implementation
This adds the new "queryable store" API, that allows complex queries and is backed by SQLite. This new API can be used for entities annotated with the new QueryableType annotation.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
class AnnotationHelper {
|
||||
|
||||
public Optional<? extends AnnotationValue> findAnnotationValue(AnnotationMirror annotationMirror, String name) {
|
||||
return annotationMirror.getElementValues()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> entry.getKey().getSimpleName().toString().equals(name))
|
||||
.map(Map.Entry::getValue)
|
||||
.findFirst();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.Element;
|
||||
import java.util.Optional;
|
||||
|
||||
class AnnotationProcessor {
|
||||
Optional<? extends AnnotationMirror> findAnnotation(Element element, Class<?> annotationClass) {
|
||||
return element.getAnnotationMirrors()
|
||||
.stream()
|
||||
.filter(annotationMirror -> annotationMirror.getAnnotationType().toString().equals(annotationClass.getCanonicalName()))
|
||||
.findFirst();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.JavaFile;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import jakarta.inject.Inject;
|
||||
import sonia.scm.ModelObject;
|
||||
import sonia.scm.store.QueryableStoreFactory;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
class FactoryClassCreator {
|
||||
|
||||
private static final String STORE_PACKAGE_NAME = "sonia.scm.store";
|
||||
private static final String QUERYABLE_MUTABLE_STORE_CLASS_NAME = "QueryableMutableStore";
|
||||
private static final String QUERYABLE_STORE_CLASS_NAME = "QueryableStore";
|
||||
|
||||
private final ProcessingEnvironment processingEnv;
|
||||
|
||||
FactoryClassCreator(ProcessingEnvironment processingEnv) {
|
||||
this.processingEnv = processingEnv;
|
||||
}
|
||||
|
||||
void createFactoryClass(Element element, String packageName, TypeElement dataClassTypeElement) throws IOException {
|
||||
TypeName typeNameOfDataClass = TypeName.get(dataClassTypeElement.asType());
|
||||
TypeSpec.Builder builder =
|
||||
TypeSpec
|
||||
.classBuilder(element.getSimpleName() + "StoreFactory")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addJavadoc("Generated queryable store factory for type {@link $T}.\nTo create conditions in queries, use the static fields in the class {@link $TQueryFields}.\n", typeNameOfDataClass, typeNameOfDataClass);
|
||||
|
||||
createStoreFactoryField(builder);
|
||||
createConstructor(builder);
|
||||
|
||||
List<ParentSpec> parents = determineParentSpecs(dataClassTypeElement);
|
||||
if (parents.isEmpty()) {
|
||||
createGetterForDataTypeWithoutParent(builder, typeNameOfDataClass);
|
||||
} else {
|
||||
createOverallGetterForDataTypeWithParents(builder, typeNameOfDataClass);
|
||||
createMutableGetterForDataTypeWithParents(typeNameOfDataClass, parents, builder);
|
||||
createPartialGetterForDataTypeWithParents(builder, typeNameOfDataClass, parents);
|
||||
}
|
||||
|
||||
JavaFile.builder(packageName, builder.build())
|
||||
.build()
|
||||
.writeTo(processingEnv.getFiler());
|
||||
}
|
||||
|
||||
private void createMutableGetterForDataTypeWithParents(TypeName typeNameOfDataClass, List<ParentSpec> parents, TypeSpec.Builder builder) {
|
||||
builder.addMethod(
|
||||
createGetMutableMethodSpec(
|
||||
typeNameOfDataClass,
|
||||
"Returns a store to modify elements of the type {@link $T}.\nTo do so, an id has to be specified for each parent type.\n",
|
||||
parents,
|
||||
ParentSpec::buildParameterNameWithIdSuffix,
|
||||
ParentSpec::appendParentAsIdStringArgument
|
||||
)
|
||||
);
|
||||
|
||||
if (isEveryParentModelObject(parents)) {
|
||||
builder.addMethod(
|
||||
createGetMutableMethodSpec(
|
||||
typeNameOfDataClass,
|
||||
"Returns a store to modify elements of the type {@link $T}.\nTo do so, an instance of each parent type has to be specified.\n",
|
||||
parents,
|
||||
ParentSpec::buildIdGetterWithParameterName,
|
||||
ParentSpec::appendParentAsObjectArgument
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private MethodSpec createGetMutableMethodSpec(TypeName typeNameOfDataClass,
|
||||
String javaDoc,
|
||||
List<ParentSpec> parents,
|
||||
Function<ParentSpec, String> parentIdProcessor,
|
||||
BiConsumer<MethodSpec.Builder, ParentSpec> parentArgumentProcessor) {
|
||||
MethodSpec.Builder getMutableBuilder = MethodSpec
|
||||
.methodBuilder("getMutable")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addJavadoc(javaDoc, typeNameOfDataClass)
|
||||
.returns(ParameterizedTypeName.get(ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_MUTABLE_STORE_CLASS_NAME), typeNameOfDataClass))
|
||||
.addStatement(
|
||||
"return storeFactory.getMutable($T.class, $L)",
|
||||
typeNameOfDataClass,
|
||||
parents.stream().map(parentIdProcessor).reduce((s1, s2) -> s1 + ", " + s2).orElseThrow()
|
||||
);
|
||||
|
||||
parents.forEach(
|
||||
parent -> parentArgumentProcessor.accept(getMutableBuilder, parent)
|
||||
);
|
||||
|
||||
return getMutableBuilder.build();
|
||||
}
|
||||
|
||||
private boolean isEveryParentModelObject(List<ParentSpec> parents) {
|
||||
return parents.stream().allMatch(ParentSpec::isModelObject);
|
||||
}
|
||||
|
||||
private void createPartialGetterForDataTypeWithParents(TypeSpec.Builder builder, TypeName typeNameOfDataClass, List<ParentSpec> parents) {
|
||||
for (int i = 0; i < parents.size(); i++) {
|
||||
String javaDocParentDescriptor;
|
||||
if (i == 0) {
|
||||
javaDocParentDescriptor = "only to the first parent";
|
||||
} else if (i < parents.size() - 1) {
|
||||
javaDocParentDescriptor = "only to the first " + (i + 1) + "parents";
|
||||
} else {
|
||||
javaDocParentDescriptor = "to all parents";
|
||||
}
|
||||
|
||||
int currentParentLimit = i + 1;
|
||||
builder.addMethod(
|
||||
createPartialGetterMethodSpec(
|
||||
typeNameOfDataClass,
|
||||
"Returns a store to query elements of the type {@link $T} limited " + javaDocParentDescriptor + " specified by their ids.\n",
|
||||
parents,
|
||||
currentParentLimit,
|
||||
ParentSpec::buildParameterNameWithIdSuffix,
|
||||
ParentSpec::appendParentAsIdStringArgument
|
||||
)
|
||||
);
|
||||
|
||||
if (isEveryParentModelObject(parents)) {
|
||||
builder.addMethod(
|
||||
createPartialGetterMethodSpec(
|
||||
typeNameOfDataClass,
|
||||
"Returns a store to query elements of the type {@link $T} limited " + javaDocParentDescriptor + " specified as instances of the parent type.\n",
|
||||
parents,
|
||||
currentParentLimit,
|
||||
ParentSpec::buildIdGetterWithParameterName,
|
||||
ParentSpec::appendParentAsObjectArgument
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MethodSpec createPartialGetterMethodSpec(TypeName typeNameOfDataClass,
|
||||
String javaDoc,
|
||||
List<ParentSpec> parents,
|
||||
int parentLimit,
|
||||
Function<ParentSpec, String> parentIdProcessor,
|
||||
BiConsumer<MethodSpec.Builder, ParentSpec> parentArgumentProcessor) {
|
||||
MethodSpec.Builder getBuilder = MethodSpec
|
||||
.methodBuilder(parentLimit == parents.size() ? "get" : "getOverlapping")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.returns(ParameterizedTypeName.get(ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME), typeNameOfDataClass))
|
||||
.addJavadoc(javaDoc, typeNameOfDataClass)
|
||||
.addStatement(
|
||||
"return storeFactory.getReadOnly($T.class, $L)",
|
||||
typeNameOfDataClass,
|
||||
parents.stream()
|
||||
.limit(parentLimit)
|
||||
.map(parentIdProcessor)
|
||||
.reduce((s1, s2) -> s1 + ", " + s2)
|
||||
.orElseThrow()
|
||||
);
|
||||
|
||||
parents.stream()
|
||||
.limit(parentLimit)
|
||||
.forEach(parent -> parentArgumentProcessor.accept(getBuilder, parent));
|
||||
|
||||
return getBuilder.build();
|
||||
}
|
||||
|
||||
private void createOverallGetterForDataTypeWithParents(TypeSpec.Builder builder, TypeName typeNameOfDataClass) {
|
||||
builder.addMethod(
|
||||
MethodSpec.methodBuilder("getOverall")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.returns(ParameterizedTypeName.get(ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME), typeNameOfDataClass))
|
||||
.addStatement("return storeFactory.getReadOnly($T.class)", typeNameOfDataClass)
|
||||
.addJavadoc("Returns a store to overall query elements of the type {@link $T} independent of any parent.\n", typeNameOfDataClass)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void createGetterForDataTypeWithoutParent(TypeSpec.Builder builder, TypeName typeNameOfDataClass) {
|
||||
builder.addMethod(
|
||||
MethodSpec.methodBuilder("get")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.returns(ParameterizedTypeName.get(ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME), typeNameOfDataClass))
|
||||
.addStatement("return storeFactory.getReadOnly($T.class)", typeNameOfDataClass)
|
||||
.addJavadoc("Returns a store to query elements of the type {@link $T}.\n", typeNameOfDataClass)
|
||||
.build());
|
||||
builder.addMethod(
|
||||
MethodSpec.methodBuilder("getMutable")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.returns(ParameterizedTypeName.get(ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_MUTABLE_STORE_CLASS_NAME), typeNameOfDataClass))
|
||||
.addStatement("return storeFactory.getMutable($T.class)", typeNameOfDataClass)
|
||||
.addJavadoc("Returns a store to modify elements of the type {@link $T}.\n", typeNameOfDataClass)
|
||||
.build());
|
||||
}
|
||||
|
||||
private List<ParentSpec> determineParentSpecs(TypeElement typeElement) {
|
||||
return new QueryableTypeParentProcessor().getQueryableTypeValues(typeElement)
|
||||
.stream()
|
||||
.map(queryableType -> {
|
||||
String parentClassPackage = queryableType.substring(0, queryableType.lastIndexOf("."));
|
||||
String parentClassName = queryableType.substring(queryableType.lastIndexOf(".") + 1);
|
||||
String parameterName = lowercaseFirstLetter(parentClassName);
|
||||
return new ParentSpec(parentClassPackage, parentClassName, parameterName, isParentModelObject(queryableType));
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
|
||||
private boolean isParentModelObject(String parentType) {
|
||||
try {
|
||||
Class<?> parentClass = Class.forName(parentType);
|
||||
return Arrays.stream(parentClass.getInterfaces()).anyMatch(parentInterface -> parentInterface.getName().equals(ModelObject.class.getName()));
|
||||
} catch (ClassNotFoundException e) {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, String.format("Failed to find class of parent '%s'. Unable to determine whether this is a ModelObject or not. Will not generate factory methods for parent objects, only for ids.", parentType));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String lowercaseFirstLetter(String parentClassName) {
|
||||
return parentClassName.substring(0, 1).toLowerCase(Locale.ENGLISH) + parentClassName.substring(1);
|
||||
}
|
||||
|
||||
private void createConstructor(TypeSpec.Builder builder) {
|
||||
builder.addMethod(
|
||||
MethodSpec
|
||||
.constructorBuilder()
|
||||
.addParameter(QueryableStoreFactory.class, "storeFactory")
|
||||
.addStatement("this.storeFactory = storeFactory")
|
||||
.addAnnotation(Inject.class)
|
||||
.addJavadoc("Instances should not be created manually, but injected by dependency injection using {@link $T}.\n", Inject.class)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void createStoreFactoryField(TypeSpec.Builder builder) {
|
||||
builder.addField(QueryableStoreFactory.class, "storeFactory", Modifier.PRIVATE, Modifier.FINAL);
|
||||
}
|
||||
|
||||
private record ParentSpec(String classPackage, String className, String parameterName, boolean isModelObject) {
|
||||
String buildParameterNameWithIdSuffix() {
|
||||
return parameterName + "Id";
|
||||
}
|
||||
|
||||
String buildIdGetterWithParameterName() {
|
||||
return parameterName + ".getId()";
|
||||
}
|
||||
|
||||
static void appendParentAsIdStringArgument(MethodSpec.Builder builder, ParentSpec parent) {
|
||||
builder.addParameter(String.class, parent.buildParameterNameWithIdSuffix());
|
||||
}
|
||||
|
||||
static void appendParentAsObjectArgument(MethodSpec.Builder builder, ParentSpec parent) {
|
||||
builder.addParameter(ClassName.get(parent.classPackage(), parent.className()), parent.parameterName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import com.squareup.javapoet.FieldSpec;
|
||||
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
interface FieldInitializer {
|
||||
void initialize(FieldSpec.Builder fieldBuilder, TypeElement element, String fieldClass, String fieldName);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
|
||||
class NumberQueryFieldHandler extends QueryFieldHandler {
|
||||
public NumberQueryFieldHandler(String packageName, String className) {
|
||||
this(packageName, className, null);
|
||||
}
|
||||
|
||||
public NumberQueryFieldHandler(String packageName, String className, String suffix) {
|
||||
super(
|
||||
"NumberQueryField",
|
||||
new TypeName[]{ClassName.get(packageName, className)},
|
||||
(fieldBuilder, element, fieldClass, fieldName) -> fieldBuilder
|
||||
.initializer(
|
||||
"new $T<>($S)",
|
||||
ClassName.get("sonia.scm.store", "QueryableStore").nestedClass(fieldClass),
|
||||
fieldName
|
||||
),
|
||||
suffix
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import com.google.auto.common.MoreElements;
|
||||
import com.google.auto.common.MoreTypes;
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.FieldSpec;
|
||||
import com.squareup.javapoet.JavaFile;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
|
||||
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class QueryFieldClassCreator {
|
||||
|
||||
private static final String SIZE_SUFFIX = "SIZE";
|
||||
private static final String STORE_PACKAGE_NAME = "sonia.scm.store";
|
||||
private static final String QUERYABLE_STORE_CLASS_NAME = "QueryableStore";
|
||||
private static final String ID_QUERY_FIELD_CLASS_NAME = "IdQueryField";
|
||||
|
||||
private static final FieldInitializer SIMPLE_INITIALIZER = (fieldBuilder, element, fieldClass, fieldName) -> fieldBuilder
|
||||
.initializer(
|
||||
"new $T<>($S)",
|
||||
ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME).nestedClass(fieldClass),
|
||||
fieldName
|
||||
);
|
||||
|
||||
private final ProcessingEnvironment processingEnv;
|
||||
|
||||
QueryFieldClassCreator(ProcessingEnvironment processingEnv) {
|
||||
this.processingEnv = processingEnv;
|
||||
}
|
||||
|
||||
void createQueryFieldClass(Element element, String packageName, TypeElement typeElement) throws IOException {
|
||||
TypeSpec.Builder builder =
|
||||
TypeSpec
|
||||
.classBuilder(element.getSimpleName() + "QueryFields")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||
.addJavadoc("Generated query fields for type {@link $T}.\nTo create a queryable store for this, use an injected instance of the {@link $TStoreFactory}.\n", TypeName.get(typeElement.asType()), TypeName.get(typeElement.asType()));
|
||||
|
||||
createPrivateConstructor(builder);
|
||||
processParents(typeElement, builder);
|
||||
processId(typeElement, builder);
|
||||
processFields(typeElement, builder);
|
||||
|
||||
JavaFile.builder(packageName, builder.build())
|
||||
.build()
|
||||
.writeTo(processingEnv.getFiler());
|
||||
}
|
||||
|
||||
private void createPrivateConstructor(TypeSpec.Builder builder) {
|
||||
builder.addMethod(
|
||||
MethodSpec
|
||||
.constructorBuilder()
|
||||
.addModifiers(Modifier.PRIVATE)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void processParents(TypeElement typeElement, TypeSpec.Builder builder) {
|
||||
new QueryableTypeParentProcessor().getQueryableTypeValues(typeElement)
|
||||
.forEach(queryableType -> {
|
||||
String parentClassPackage = queryableType.substring(0, queryableType.lastIndexOf("."));
|
||||
String parentClassName = queryableType.substring(queryableType.lastIndexOf(".") + 1);
|
||||
builder.addField(
|
||||
FieldSpec
|
||||
.builder(
|
||||
ParameterizedTypeName.get(
|
||||
ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME)
|
||||
.nestedClass(ID_QUERY_FIELD_CLASS_NAME),
|
||||
TypeName.get(typeElement.asType())),
|
||||
parentClassName.toUpperCase(Locale.ENGLISH) + "_ID"
|
||||
)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
||||
.initializer(
|
||||
"new $T<>($T.class)",
|
||||
ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME).nestedClass(ID_QUERY_FIELD_CLASS_NAME),
|
||||
ClassName.get(parentClassPackage, parentClassName))
|
||||
.build());
|
||||
});
|
||||
}
|
||||
|
||||
private void processId(TypeElement typeElement, TypeSpec.Builder builder) {
|
||||
builder.addField(
|
||||
FieldSpec
|
||||
.builder(
|
||||
ParameterizedTypeName.get(
|
||||
ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME)
|
||||
.nestedClass(ID_QUERY_FIELD_CLASS_NAME),
|
||||
TypeName.get(typeElement.asType())),
|
||||
"INTERNAL_ID"
|
||||
)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
||||
.initializer(
|
||||
"new $T<>()",
|
||||
ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME).nestedClass(ID_QUERY_FIELD_CLASS_NAME))
|
||||
.build());
|
||||
}
|
||||
|
||||
private void processFields(TypeElement typeElement, TypeSpec.Builder builder) {
|
||||
processFields(typeElement, typeElement, builder);
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
private void processFields(TypeElement typeElement, TypeElement superTypeElement, TypeSpec.Builder builder) {
|
||||
processingEnv
|
||||
.getElementUtils()
|
||||
.getAllMembers(typeElement)
|
||||
.stream()
|
||||
.filter(member -> member.getKind() == ElementKind.FIELD)
|
||||
.filter(member -> !member.getModifiers().contains(Modifier.STATIC))
|
||||
.filter(member -> !member.getModifiers().contains(Modifier.TRANSIENT))
|
||||
.flatMap(field ->
|
||||
createFieldSpec(
|
||||
superTypeElement,
|
||||
MoreElements.asVariable(field))
|
||||
)
|
||||
.forEach(builder::addField);
|
||||
TypeElement superclass = (TypeElement) processingEnv.getTypeUtils().asElement(typeElement.getSuperclass());
|
||||
if (superclass != null && !superclass.getQualifiedName().toString().equals(Object.class.getCanonicalName())) {
|
||||
processFields(superclass, typeElement, builder);
|
||||
}
|
||||
}
|
||||
|
||||
private Stream<FieldSpec> createFieldSpec(TypeElement element, VariableElement field) {
|
||||
TypeMirror effectiveFieldType = determineFieldType(field);
|
||||
return createFieldHandler(effectiveFieldType).stream()
|
||||
.map(queryFieldHandler -> {
|
||||
String fieldName = field.getSimpleName().toString();
|
||||
String fieldClass = queryFieldHandler.getClazz();
|
||||
TypeName[] furtherGenerics = queryFieldHandler.getGenerics();
|
||||
TypeName[] generics = new TypeName[furtherGenerics.length + 1];
|
||||
generics[0] = TypeName.get(element.asType());
|
||||
System.arraycopy(furtherGenerics, 0, generics, 1, furtherGenerics.length);
|
||||
FieldSpec.Builder fieldBuilder = FieldSpec
|
||||
.builder(
|
||||
ParameterizedTypeName.get(
|
||||
ClassName
|
||||
.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME)
|
||||
.nestedClass(fieldClass),
|
||||
generics),
|
||||
determineFieldNameWithSuffix(fieldName, queryFieldHandler).toUpperCase(Locale.ENGLISH)
|
||||
)
|
||||
.addJavadoc("Generated query field to create conditions for field {@link $L#$L} of type {@link $L}.\n", TypeName.get(element.asType()), fieldName, effectiveFieldType)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
|
||||
queryFieldHandler.getInitializer().initialize(fieldBuilder, element, fieldClass, fieldName);
|
||||
return fieldBuilder.build();
|
||||
});
|
||||
}
|
||||
|
||||
private TypeMirror determineFieldType(VariableElement field) {
|
||||
return new AnnotationProcessor().findAnnotation(field, XmlJavaTypeAdapter.class)
|
||||
.map(this::determineTypeFromAdapter)
|
||||
.orElseGet(field::asType);
|
||||
}
|
||||
|
||||
private TypeMirror determineTypeFromAdapter(AnnotationMirror annotationMirror) {
|
||||
AnnotationValue value = new AnnotationHelper().findAnnotationValue(annotationMirror, "value").orElseThrow();
|
||||
TypeMirror adapterType = (TypeMirror) value.getValue();
|
||||
TypeMirror xmlAdapterType = processingEnv.getTypeUtils()
|
||||
.directSupertypes(adapterType)
|
||||
.stream()
|
||||
.filter(typeMirror -> processingEnv.getTypeUtils()
|
||||
.isAssignable(
|
||||
processingEnv.getTypeUtils().erasure(typeMirror),
|
||||
processingEnv.getElementUtils().getTypeElement(XmlAdapter.class.getCanonicalName()).asType()
|
||||
))
|
||||
.findFirst()
|
||||
.orElseThrow(RuntimeException::new);
|
||||
DeclaredType declaredType = MoreTypes.asDeclared(xmlAdapterType);
|
||||
return declaredType.getTypeArguments().get(0);
|
||||
}
|
||||
|
||||
private Collection<QueryFieldHandler> createFieldHandler(TypeMirror fieldType) {
|
||||
TypeMirror collectionType = processingEnv.getElementUtils().getTypeElement(Collection.class.getCanonicalName()).asType();
|
||||
TypeMirror erasure = processingEnv.getTypeUtils().erasure(fieldType);
|
||||
if (processingEnv.getTypeUtils().isAssignable(erasure, collectionType)) {
|
||||
return List.of(
|
||||
new QueryFieldHandler(
|
||||
"CollectionQueryField",
|
||||
new TypeName[]{},
|
||||
SIMPLE_INITIALIZER
|
||||
),
|
||||
new QueryFieldHandler(
|
||||
"CollectionSizeQueryField",
|
||||
new TypeName[]{},
|
||||
SIMPLE_INITIALIZER,
|
||||
SIZE_SUFFIX
|
||||
)
|
||||
);
|
||||
}
|
||||
TypeMirror mapType = processingEnv.getElementUtils().getTypeElement(Map.class.getCanonicalName()).asType();
|
||||
if (processingEnv.getTypeUtils().isAssignable(erasure, mapType)) {
|
||||
return List.of(
|
||||
new QueryFieldHandler(
|
||||
"MapQueryField",
|
||||
new TypeName[]{},
|
||||
SIMPLE_INITIALIZER
|
||||
),
|
||||
new QueryFieldHandler(
|
||||
"MapSizeQueryField",
|
||||
new TypeName[]{},
|
||||
SIMPLE_INITIALIZER,
|
||||
SIZE_SUFFIX
|
||||
)
|
||||
);
|
||||
}
|
||||
Element fieldAsElement = processingEnv.getTypeUtils().asElement(fieldType);
|
||||
if (fieldAsElement != null && fieldAsElement.getKind() == ElementKind.ENUM) {
|
||||
return List.of(new QueryFieldHandler(
|
||||
"EnumQueryField",
|
||||
new TypeName[]{TypeName.get(fieldAsElement.asType())},
|
||||
(fieldBuilder, element, fieldClass, fieldName) -> fieldBuilder
|
||||
.initializer(
|
||||
"new $T<>($S)",
|
||||
ClassName.get(STORE_PACKAGE_NAME, QUERYABLE_STORE_CLASS_NAME).nestedClass(fieldClass),
|
||||
fieldName
|
||||
)
|
||||
));
|
||||
}
|
||||
return switch (fieldType.toString()) {
|
||||
case "java.lang.String" -> List.of(
|
||||
new QueryFieldHandler(
|
||||
"StringQueryField",
|
||||
new TypeName[]{},
|
||||
SIMPLE_INITIALIZER));
|
||||
case "boolean", "java.lang.Boolean" -> List.of(
|
||||
new QueryFieldHandler(
|
||||
"BooleanQueryField",
|
||||
new TypeName[]{},
|
||||
SIMPLE_INITIALIZER));
|
||||
case "int", "java.lang.Integer" -> List.of(
|
||||
new NumberQueryFieldHandler(
|
||||
"java.lang",
|
||||
"Integer"));
|
||||
case "long", "java.lang.Long" -> List.of(
|
||||
new NumberQueryFieldHandler(
|
||||
"java.lang",
|
||||
"Long"));
|
||||
case "float", "java.lang.Float" -> List.of(
|
||||
new NumberQueryFieldHandler(
|
||||
"java.lang",
|
||||
"Float"));
|
||||
case "double", "java.lang.Double" -> List.of(
|
||||
new NumberQueryFieldHandler(
|
||||
"java.lang",
|
||||
"Double"));
|
||||
case "java.util.Date", "java.time.Instant" -> List.of(
|
||||
new QueryFieldHandler(
|
||||
"InstantQueryField",
|
||||
new TypeName[]{},
|
||||
SIMPLE_INITIALIZER));
|
||||
default -> List.of();
|
||||
};
|
||||
}
|
||||
|
||||
private String determineFieldNameWithSuffix(String fieldName, QueryFieldHandler fieldHandler) {
|
||||
return fieldHandler.getSuffix()
|
||||
.map(suffix -> String.format("%s_%s", fieldName, suffix))
|
||||
.orElse(fieldName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
class QueryFieldHandler {
|
||||
private final String clazz;
|
||||
private final TypeName[] generics;
|
||||
private final FieldInitializer initializer;
|
||||
private final String suffix;
|
||||
|
||||
public QueryFieldHandler(String clazz, TypeName[] generics, FieldInitializer initializer) {
|
||||
this(clazz, generics, initializer, null);
|
||||
}
|
||||
|
||||
public Optional<String> getSuffix() {
|
||||
return Optional.ofNullable(suffix);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import com.google.auto.common.MoreElements;
|
||||
import org.kohsuke.MetaInfServices;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.Processor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Optional.empty;
|
||||
import static java.util.Optional.of;
|
||||
|
||||
@SupportedAnnotationTypes("sonia.scm.store.QueryableType")
|
||||
@MetaInfServices(Processor.class)
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_17)
|
||||
public class QueryableTypeAnnotationProcessor extends AbstractProcessor {
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
|
||||
for (TypeElement annotation : annotations) {
|
||||
log("Found annotation: " + annotation.getQualifiedName());
|
||||
roundEnvironment.getElementsAnnotatedWith(annotation).forEach(element -> {
|
||||
log("Found annotated element: " + element.getSimpleName());
|
||||
tryToCreateQueryFieldClass(element);
|
||||
tryToCreateFactoryClass(element);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
private void tryToCreateQueryFieldClass(Element element) {
|
||||
TypeElement typeElement = MoreElements.asType(element);
|
||||
getPackageName(typeElement)
|
||||
.ifPresent(packageName -> {
|
||||
try {
|
||||
new QueryFieldClassCreator(processingEnv).createQueryFieldClass(element, packageName, typeElement);
|
||||
} catch (IOException e) {
|
||||
error("Failed to create query field class for type " + typeElement + ": " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
private void tryToCreateFactoryClass(Element element) {
|
||||
TypeElement typeElement = MoreElements.asType(element);
|
||||
getPackageName(typeElement)
|
||||
.ifPresent(packageName -> {
|
||||
try {
|
||||
new FactoryClassCreator(processingEnv).createFactoryClass(element, packageName, typeElement);
|
||||
} catch (IOException e) {
|
||||
error("Failed to create factory class for type " + typeElement + ": " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
private Optional<String> getPackageName(TypeElement typeElement) {
|
||||
Element enclosingElement = typeElement.getEnclosingElement();
|
||||
try {
|
||||
return of(MoreElements.asPackage(enclosingElement).getQualifiedName().toString());
|
||||
} catch (IllegalArgumentException e) {
|
||||
error("Could not determine package name for " + typeElement + ". QueryableType annotation does not support inner classes. Exception: " + e.getMessage());
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
|
||||
private void log(String message) {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, message);
|
||||
}
|
||||
|
||||
private void error(String message) {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
class QueryableTypeParentProcessor {
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> getQueryableTypeValues(TypeElement typeElement) {
|
||||
return new AnnotationProcessor().findAnnotation(typeElement, QueryableType.class)
|
||||
.map(annotationMirror -> {
|
||||
Optional<? extends AnnotationValue> value = new AnnotationHelper().findAnnotationValue(annotationMirror, "value");
|
||||
if (value.isEmpty()) {
|
||||
return new ArrayList<String>();
|
||||
}
|
||||
List<AnnotationValue> parentClassTypes = (List<AnnotationValue>) value.orElseThrow().getValue();
|
||||
return parentClassTypes.stream()
|
||||
.map(AnnotationValue::getValue)
|
||||
.map(Object::toString)
|
||||
.toList();
|
||||
})
|
||||
.orElseGet(List::of);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
sonia.scm.annotation.QueryableTypeAnnotationProcessor,isolating
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.annotation;
|
||||
|
||||
import com.google.common.truth.Truth;
|
||||
import com.google.testing.compile.JavaFileObjects;
|
||||
import com.google.testing.compile.JavaSourcesSubjectFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("java:S115") // we do not heed enum naming conventions for better readability in the test
|
||||
class QueryableTypeAnnotationProcessorTest {
|
||||
|
||||
enum FieldScenario {
|
||||
A("empty class"),
|
||||
B("string query field"),
|
||||
C("boolean query fields"),
|
||||
D("number query fields"),
|
||||
E("enum query field"),
|
||||
F("collection query field"),
|
||||
G("map query field"),
|
||||
H("unknown field"),
|
||||
I("instant field mapped to string"),
|
||||
K("parent id field"),
|
||||
L("unmapped instant field"),
|
||||
M("unmapped java util date field"),
|
||||
N("static field"),
|
||||
O("transient field"),
|
||||
BSub("fields from super class");
|
||||
|
||||
private final String description;
|
||||
|
||||
FieldScenario(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "should test field scenario for {0}")
|
||||
@EnumSource(FieldScenario.class)
|
||||
void shouldTest(FieldScenario scenario) {
|
||||
JavaFileObject someObject = JavaFileObjects.forResource(String.format("sonia/scm/testing/%s.java", scenario.name()));
|
||||
Truth.assert_()
|
||||
.about(JavaSourcesSubjectFactory.javaSources())
|
||||
.that(List.of(someObject))
|
||||
.processedWith(new QueryableTypeAnnotationProcessor())
|
||||
.compilesWithoutError()
|
||||
.and()
|
||||
.generatesSources(JavaFileObjects.forResource(String.format("sonia/scm/testing/%sQueryFields.java", scenario.name())));
|
||||
}
|
||||
|
||||
enum FactoryScenario {
|
||||
A("class without parent"),
|
||||
OneParent("class with one parent"),
|
||||
TwoParents("class with two parents"),
|
||||
ThreeParents("class with three parents"),
|
||||
OneNonModelObjectParent("class with one model object parent and one non model object parent");
|
||||
|
||||
private final String description;
|
||||
|
||||
FactoryScenario(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "should test factory scenario for {0}")
|
||||
@EnumSource(FactoryScenario.class)
|
||||
void shouldTest(FactoryScenario scenario) {
|
||||
JavaFileObject someObject = JavaFileObjects.forResource(String.format("sonia/scm/testing/%s.java", scenario.name()));
|
||||
Truth.assert_()
|
||||
.about(JavaSourcesSubjectFactory.javaSources())
|
||||
.that(List.of(someObject))
|
||||
.processedWith(new QueryableTypeAnnotationProcessor())
|
||||
.compilesWithoutError()
|
||||
.and()
|
||||
.generatesSources(JavaFileObjects.forResource(String.format("sonia/scm/testing/%sStoreFactory.java", scenario.name())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleInnerClasses() {
|
||||
JavaFileObject someObject = JavaFileObjects.forResource("sonia/scm/testing/InnerA.java");
|
||||
Truth.assert_()
|
||||
.about(JavaSourcesSubjectFactory.javaSources())
|
||||
.that(List.of(someObject))
|
||||
.processedWith(new QueryableTypeAnnotationProcessor())
|
||||
.failsToCompile();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType
|
||||
public class A {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class AQueryFields {
|
||||
public static final QueryableStore.IdQueryField<A> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
private AQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import sonia.scm.store.QueryableMutableStore;
|
||||
import sonia.scm.store.QueryableStore;
|
||||
import sonia.scm.store.QueryableStoreFactory;
|
||||
|
||||
public class AStoreFactory {
|
||||
|
||||
private final QueryableStoreFactory storeFactory;
|
||||
|
||||
@Inject
|
||||
AStoreFactory(QueryableStoreFactory storeFactory) {
|
||||
this.storeFactory = storeFactory;
|
||||
}
|
||||
|
||||
public QueryableStore<A> get() {
|
||||
return storeFactory.getReadOnly(A.class);
|
||||
}
|
||||
|
||||
public QueryableMutableStore<A> getMutable() {
|
||||
return storeFactory.getMutable(A.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType
|
||||
public class B {
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class BQueryFields {
|
||||
public static final QueryableStore.IdQueryField<B> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.StringQueryField<B> NAME =
|
||||
new QueryableStore.StringQueryField<>("name");
|
||||
|
||||
private BQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType
|
||||
public class BSub extends B {
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class BSubQueryFields {
|
||||
public static final QueryableStore.IdQueryField<BSub> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.StringQueryField<BSub> NAME =
|
||||
new QueryableStore.StringQueryField<>("name");
|
||||
|
||||
private BSubQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType
|
||||
public class C {
|
||||
private boolean active;
|
||||
private Boolean enabled;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class CQueryFields {
|
||||
public static final QueryableStore.IdQueryField<C> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.BooleanQueryField<C> ACTIVE =
|
||||
new QueryableStore.BooleanQueryField<>("active");
|
||||
|
||||
public static final QueryableStore.BooleanQueryField<C> ENABLED =
|
||||
new QueryableStore.BooleanQueryField<>("enabled");
|
||||
|
||||
private CQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType
|
||||
public class D {
|
||||
private int age;
|
||||
private Integer weight;
|
||||
|
||||
private long creationTime;
|
||||
private Long lastModified;
|
||||
|
||||
private float height;
|
||||
private Float width;
|
||||
|
||||
private double price;
|
||||
private Double margin;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import java.lang.Double;
|
||||
import java.lang.Float;
|
||||
import java.lang.Integer;
|
||||
import java.lang.Long;
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class DQueryFields {
|
||||
public static final QueryableStore.IdQueryField<D> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.NumberQueryField<D, Integer> AGE =
|
||||
new QueryableStore.NumberQueryField<>("age");
|
||||
public static final QueryableStore.NumberQueryField<D, Integer> WEIGHT =
|
||||
new QueryableStore.NumberQueryField<>("weight");
|
||||
|
||||
public static final QueryableStore.NumberQueryField<D, Long> CREATIONTIME =
|
||||
new QueryableStore.NumberQueryField<>("creationTime");
|
||||
public static final QueryableStore.NumberQueryField<D, Long> LASTMODIFIED =
|
||||
new QueryableStore.NumberQueryField<>("lastModified");
|
||||
|
||||
public static final QueryableStore.NumberQueryField<D, Float> HEIGHT =
|
||||
new QueryableStore.NumberQueryField<>("height");
|
||||
public static final QueryableStore.NumberQueryField<D, Float> WIDTH =
|
||||
new QueryableStore.NumberQueryField<>("width");
|
||||
|
||||
public static final QueryableStore.NumberQueryField<D, Double> PRICE =
|
||||
new QueryableStore.NumberQueryField<>("price");
|
||||
public static final QueryableStore.NumberQueryField<D, Double> MARGIN =
|
||||
new QueryableStore.NumberQueryField<>("margin");
|
||||
|
||||
private DQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.Stage;
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType
|
||||
public class E {
|
||||
private Stage stage;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.Stage;
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class EQueryFields {
|
||||
public static final QueryableStore.IdQueryField<E> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.EnumQueryField<E, Stage> STAGE =
|
||||
new QueryableStore.EnumQueryField<>("stage");
|
||||
|
||||
private EQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.Stage;
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@QueryableType
|
||||
public class F {
|
||||
private List<String> names;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class FQueryFields {
|
||||
public static final QueryableStore.IdQueryField<F> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.CollectionQueryField<F> NAMES =
|
||||
new QueryableStore.CollectionQueryField<>("names");
|
||||
|
||||
public static final QueryableStore.CollectionSizeQueryField<F> NAMES_SIZE =
|
||||
new QueryableStore.CollectionSizeQueryField<>("names");
|
||||
|
||||
private FQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
import java.util.Map;
|
||||
|
||||
@QueryableType
|
||||
public class G {
|
||||
private Map<String, Object> dictionary;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class GQueryFields {
|
||||
public static final QueryableStore.IdQueryField<G> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.MapQueryField<G> DICTIONARY =
|
||||
new QueryableStore.MapQueryField<>("dictionary");
|
||||
|
||||
public static final QueryableStore.MapSizeQueryField<G> DICTIONARY_SIZE =
|
||||
new QueryableStore.MapSizeQueryField<>("dictionary");
|
||||
|
||||
private GQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
import java.util.Map;
|
||||
|
||||
@QueryableType
|
||||
public class H {
|
||||
private Object somethingStrange;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class HQueryFields {
|
||||
public static final QueryableStore.IdQueryField<H> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
private HQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import sonia.scm.store.QueryableType;
|
||||
import sonia.scm.xml.XmlInstantAdapter;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@QueryableType
|
||||
public class I {
|
||||
@XmlJavaTypeAdapter(XmlInstantAdapter.class)
|
||||
private Instant birthday;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class IQueryFields {
|
||||
public static final QueryableStore.IdQueryField<I> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.StringQueryField<I> BIRTHDAY =
|
||||
new QueryableStore.StringQueryField<>("birthday");
|
||||
|
||||
private IQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
public class InnerA {
|
||||
|
||||
|
||||
|
||||
@QueryableType
|
||||
public static class A {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.Stage;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType(Repository.class)
|
||||
public class K {
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class KQueryFields {
|
||||
public static final QueryableStore.IdQueryField<K> REPOSITORY_ID =
|
||||
new QueryableStore.IdQueryField<>(Repository.class);
|
||||
|
||||
public static final QueryableStore.IdQueryField<K> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
private KQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import sonia.scm.store.QueryableType;
|
||||
import sonia.scm.xml.XmlInstantAdapter;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@QueryableType
|
||||
public class L {
|
||||
private Instant birthday;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class LQueryFields {
|
||||
public static final QueryableStore.IdQueryField<L> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.InstantQueryField<L> BIRTHDAY =
|
||||
new QueryableStore.InstantQueryField<>("birthday");
|
||||
|
||||
private LQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@QueryableType
|
||||
public class M {
|
||||
private Date birthday;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class MQueryFields {
|
||||
public static final QueryableStore.IdQueryField<M> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
public static final QueryableStore.InstantQueryField<M> BIRTHDAY =
|
||||
new QueryableStore.InstantQueryField<>("birthday");
|
||||
|
||||
private MQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType
|
||||
public class N {
|
||||
private static String someField;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class NQueryFields {
|
||||
public static final QueryableStore.IdQueryField<N> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
private NQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType
|
||||
public class O {
|
||||
private transient String transientField;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.store.QueryableStore;
|
||||
|
||||
public final class OQueryFields {
|
||||
public static final QueryableStore.IdQueryField<O> INTERNAL_ID =
|
||||
new QueryableStore.IdQueryField<>();
|
||||
|
||||
private OQueryFields() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType({NamespaceAndName.class, Repository.class})
|
||||
public class OneNonModelObjectParent {
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import java.lang.String;
|
||||
import sonia.scm.store.QueryableMutableStore;
|
||||
import sonia.scm.store.QueryableStore;
|
||||
import sonia.scm.store.QueryableStoreFactory;
|
||||
|
||||
public class OneNonModelObjectParentStoreFactory {
|
||||
|
||||
private final QueryableStoreFactory storeFactory;
|
||||
|
||||
@Inject
|
||||
OneNonModelObjectParentStoreFactory(QueryableStoreFactory storeFactory) {
|
||||
this.storeFactory = storeFactory;
|
||||
}
|
||||
|
||||
public QueryableStore<OneNonModelObjectParent> getOverall() {
|
||||
return storeFactory.getReadOnly(OneNonModelObjectParent.class);
|
||||
}
|
||||
|
||||
public QueryableMutableStore<OneNonModelObjectParent> getMutable(String namespaceAndNameId, String repositoryId) {
|
||||
return storeFactory.getMutable(OneNonModelObjectParent.class, namespaceAndNameId, repositoryId);
|
||||
}
|
||||
|
||||
public QueryableStore<OneNonModelObjectParent> getOverlapping(String namespaceAndNameId) {
|
||||
return storeFactory.getReadOnly(OneNonModelObjectParent.class, namespaceAndNameId);
|
||||
}
|
||||
|
||||
public QueryableStore<OneNonModelObjectParent> get(String namespaceAndNameId, String repositoryId) {
|
||||
return storeFactory.getReadOnly(OneNonModelObjectParent.class, namespaceAndNameId, repositoryId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType(Repository.class)
|
||||
public class OneParent {
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import java.lang.String;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.store.QueryableMutableStore;
|
||||
import sonia.scm.store.QueryableStore;
|
||||
import sonia.scm.store.QueryableStoreFactory;
|
||||
|
||||
public class OneParentStoreFactory {
|
||||
|
||||
private final QueryableStoreFactory storeFactory;
|
||||
|
||||
@Inject
|
||||
OneParentStoreFactory(QueryableStoreFactory storeFactory) {
|
||||
this.storeFactory = storeFactory;
|
||||
}
|
||||
|
||||
public QueryableStore<OneParent> getOverall() {
|
||||
return storeFactory.getReadOnly(OneParent.class);
|
||||
}
|
||||
|
||||
public QueryableMutableStore<OneParent> getMutable(String repositoryId) {
|
||||
return storeFactory.getMutable(OneParent.class, repositoryId);
|
||||
}
|
||||
|
||||
public QueryableMutableStore<OneParent> getMutable(Repository repository) {
|
||||
return storeFactory.getMutable(OneParent.class, repository.getId());
|
||||
}
|
||||
|
||||
public QueryableStore<OneParent> get(String repositoryId) {
|
||||
return storeFactory.getReadOnly(OneParent.class, repositoryId);
|
||||
}
|
||||
|
||||
public QueryableStore<OneParent> get(Repository repository) {
|
||||
return storeFactory.getReadOnly(OneParent.class, repository.getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType({Repository.class, User.class, Group.class})
|
||||
public class ThreeParents {
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import java.lang.String;
|
||||
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.store.QueryableMutableStore;
|
||||
import sonia.scm.store.QueryableStore;
|
||||
import sonia.scm.store.QueryableStoreFactory;
|
||||
import sonia.scm.user.User;
|
||||
|
||||
public class ThreeParentsStoreFactory {
|
||||
|
||||
private final QueryableStoreFactory storeFactory;
|
||||
|
||||
@Inject
|
||||
ThreeParentsStoreFactory(QueryableStoreFactory storeFactory) {
|
||||
this.storeFactory = storeFactory;
|
||||
}
|
||||
|
||||
public QueryableStore<ThreeParents> getOverall() {
|
||||
return storeFactory.getReadOnly(ThreeParents.class);
|
||||
}
|
||||
|
||||
public QueryableMutableStore<ThreeParents> getMutable(String repositoryId, String userId, String groupId) {
|
||||
return storeFactory.getMutable(ThreeParents.class, repositoryId, userId, groupId);
|
||||
}
|
||||
|
||||
public QueryableMutableStore<ThreeParents> getMutable(Repository repository, User user, Group group) {
|
||||
return storeFactory.getMutable(ThreeParents.class, repository.getId(), user.getId(), group.getId());
|
||||
}
|
||||
|
||||
public QueryableStore<ThreeParents> getOverlapping(String repositoryId) {
|
||||
return storeFactory.getReadOnly(ThreeParents.class, repositoryId);
|
||||
}
|
||||
|
||||
public QueryableStore<ThreeParents> getOverlapping(Repository repository) {
|
||||
return storeFactory.getReadOnly(ThreeParents.class, repository.getId());
|
||||
}
|
||||
|
||||
public QueryableStore<ThreeParents> getOverlapping(String repositoryId, String userId) {
|
||||
return storeFactory.getReadOnly(ThreeParents.class, repositoryId, userId);
|
||||
}
|
||||
|
||||
public QueryableStore<ThreeParents> getOverlapping(Repository repository, User user) {
|
||||
return storeFactory.getReadOnly(ThreeParents.class, repository.getId(), user.getId());
|
||||
}
|
||||
|
||||
public QueryableStore<ThreeParents> get(String repositoryId, String userId, String groupId) {
|
||||
return storeFactory.getReadOnly(ThreeParents.class, repositoryId, userId, groupId);
|
||||
}
|
||||
|
||||
public QueryableStore<ThreeParents> get(Repository repository, User user, Group group) {
|
||||
return storeFactory.getReadOnly(ThreeParents.class, repository.getId(), user.getId(), group.getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.store.QueryableType;
|
||||
|
||||
@QueryableType({Repository.class, User.class})
|
||||
public class TwoParents {
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
package sonia.scm.testing;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import java.lang.String;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.store.QueryableMutableStore;
|
||||
import sonia.scm.store.QueryableStore;
|
||||
import sonia.scm.store.QueryableStoreFactory;
|
||||
import sonia.scm.user.User;
|
||||
|
||||
public class TwoParentsStoreFactory {
|
||||
|
||||
private final QueryableStoreFactory storeFactory;
|
||||
|
||||
@Inject
|
||||
TwoParentsStoreFactory(QueryableStoreFactory storeFactory) {
|
||||
this.storeFactory = storeFactory;
|
||||
}
|
||||
|
||||
public QueryableStore<TwoParents> getOverall() {
|
||||
return storeFactory.getReadOnly(TwoParents.class);
|
||||
}
|
||||
|
||||
public QueryableMutableStore<TwoParents> getMutable(String repositoryId, String userId) {
|
||||
return storeFactory.getMutable(TwoParents.class, repositoryId, userId);
|
||||
}
|
||||
|
||||
public QueryableMutableStore<TwoParents> getMutable(Repository repository, User user) {
|
||||
return storeFactory.getMutable(TwoParents.class, repository.getId(), user.getId());
|
||||
}
|
||||
|
||||
public QueryableStore<TwoParents> getOverlapping(String repositoryId) {
|
||||
return storeFactory.getReadOnly(TwoParents.class, repositoryId);
|
||||
}
|
||||
|
||||
public QueryableStore<TwoParents> getOverlapping(Repository repository) {
|
||||
return storeFactory.getReadOnly(TwoParents.class, repository.getId());
|
||||
}
|
||||
|
||||
public QueryableStore<TwoParents> get(String repositoryId, String userId) {
|
||||
return storeFactory.getReadOnly(TwoParents.class, repositoryId, userId);
|
||||
}
|
||||
|
||||
public QueryableStore<TwoParents> get(Repository repository, User user) {
|
||||
return storeFactory.getReadOnly(TwoParents.class, repository.getId(), user.getId());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user