Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
Generate Persistence Find methods by fields
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Bluhm <bluhmdj@ornl.gov>
  • Loading branch information
dbluhm committed Jun 4, 2020
1 parent fa04b70 commit 3e26f7e
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 52 deletions.
@@ -1,6 +1,16 @@
package org.eclipse.ice.dev.annotations;

import java.util.UUID;

public interface IPersistenceHandler {
public <T extends IDataElement> void save(T element) throws Exception;
public <T extends IDataElement> T findByID(String id) throws Exception;
}
public <T extends IDataElement> T findByUUID(UUID uuid) throws Exception;
public <T extends IDataElement> Iterable<T> findById(long id) throws Exception;
public <T extends IDataElement> Iterable<T> findByName(String name) throws Exception;
public <T extends IDataElement> Iterable<T> findByDescription(String description) throws Exception;
public <T extends IDataElement> Iterable<T> findByComment(String comment) throws Exception;
public <T extends IDataElement> Iterable<T> findByContext(String context) throws Exception;
public <T extends IDataElement> Iterable<T> findByRequired(boolean required) throws Exception;
public <T extends IDataElement> Iterable<T> findBySecret(boolean secret) throws Exception;
public long clear() throws Exception;
}
Expand Up @@ -135,7 +135,7 @@ public boolean process(final Set<? extends TypeElement> annotations, final Round
// Check if Persistence should be generated.
if (dataElement.hasAnnotation(Persisted.class)) {
String collectionName = getCollectionName(dataElement);
writePersistence(dataElement, collectionName);
writePersistence(dataElement, collectionName, fields);
}
} catch (final IOException | UnexpectedValueError | InvalidDataElementRoot e) {
messager.printMessage(Diagnostic.Kind.ERROR, stackTraceToString(e));
Expand Down Expand Up @@ -265,7 +265,11 @@ private void writeClass(DataElementRoot element, final List<Field> fields) throw
* @param fields the fields extracted from DataField annotations on interface
* @throws IOException
*/
private void writePersistence(DataElementRoot element, final String collectionName) throws IOException {
private void writePersistence(
DataElementRoot element,
final String collectionName,
List<Field> fields
) throws IOException {
// Prepare context of template
final VelocityContext context = new VelocityContext();
context.put(
Expand All @@ -288,6 +292,10 @@ private void writePersistence(DataElementRoot element, final String collectionNa
PersistenceHandlerTemplateProperty.IMPLEMENTATION.getKey(),
element.getImplName()
);
context.put(
PersistenceHandlerTemplateProperty.FIELDS.getKey(),
fields
);

// Write to file
final JavaFileObject generatedClassFile = processingEnv.getFiler()
Expand Down
Expand Up @@ -29,6 +29,7 @@ public class DefaultFields {
.getter(true)
.build()
)
.defaultField(true)
.build();

/**
Expand All @@ -39,6 +40,7 @@ public class DefaultFields {
.type(long.class)
.docString("A unique identifier for this element.")
.defaultValue(0L)
.defaultField(true)
.build();

/**
Expand All @@ -49,6 +51,7 @@ public class DefaultFields {
.type(String.class)
.docString("A simple name for the data.")
.defaultValue("name")
.defaultField(true)
.build();

/**
Expand All @@ -59,6 +62,7 @@ public class DefaultFields {
.type(String.class)
.docString("A simple description of the data")
.defaultValue("description")
.defaultField(true)
.build();

/**
Expand All @@ -69,6 +73,7 @@ public class DefaultFields {
.type(String.class)
.docString("A comment that annotates the data in a meaningful way.")
.defaultValue("no comment")
.defaultField(true)
.build();

/**
Expand All @@ -79,6 +84,7 @@ public class DefaultFields {
.type(String.class)
.docString("The context (a tag) in which the data should be considered.")
.defaultValue("default")
.defaultField(true)
.build();

/**
Expand All @@ -89,6 +95,7 @@ public class DefaultFields {
.type(boolean.class)
.docString("This value is true if the element should be regarded by the client as required.")
.defaultValue(false)
.defaultField(true)
.build();

/**
Expand All @@ -100,6 +107,7 @@ public class DefaultFields {
.type(boolean.class)
.docString("This value is true if the element should be regarded as a secret by the client, such as for passwords.")
.defaultValue(false)
.defaultField(true)
.build();

/**
Expand All @@ -110,6 +118,8 @@ public class DefaultFields {
.type(Field.raw("JavascriptValidator<$class>"))
.docString("The validator used to check the correctness of the data.")
.nullable(true)
.defaultField(true)
.search(false)
.build();

/**
Expand Down
Expand Up @@ -4,8 +4,10 @@
import java.util.List;

import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
Expand Down Expand Up @@ -75,6 +77,17 @@ public class Field {
*/
@Builder.Default boolean setter = true;

/**
* Whether this field is considered a "default" or included in all
* DataElements.
*/
boolean defaultField;

/**
* Whether this field should be searchable with PersistenceHandler.
*/
@Builder.Default boolean search = true;

/**
* A list of alternate names for this field.
*/
Expand Down Expand Up @@ -110,6 +123,15 @@ private static Class<?> getClassOrNull(String cls) {
}
}

/**
* Return this Fields name ready for use in a method.
* @return capitalized name
*/
@JsonIgnore
public String getNameForMethod() {
return StringUtils.capitalize(this.name);
}

/**
* Reverse the escaping performed on defaultValues when the type of the field is
* a String. This is only used when serializing to JSON and will render a string
Expand All @@ -118,6 +140,9 @@ private static Class<?> getClassOrNull(String cls) {
*/
@JsonProperty("defaultValue")
public String unescapeDefaultValue() {
if (this.type == null) {
return this.defaultValue;
}
Class<?> cls = getClassOrNull(this.type);
if (this.defaultValue != null && cls != null && cls.equals(String.class)) {
return this.defaultValue.substring(1, this.defaultValue.length() - 1);
Expand Down Expand Up @@ -249,6 +274,9 @@ public FieldBuilder jsonName(String name) {
*/
@JsonAlias({"fieldType"})
public FieldBuilder jsonType(String type) {
if (type == null) {
return this;
}
Class<?> cls = getClassOrNull(type);
if (cls == null) {
cls = getClassOrNull("java.lang." + type);
Expand All @@ -273,6 +301,9 @@ public FieldBuilder jsonType(String type) {
* @return builder
*/
public FieldBuilder jsonDefaultValue(String defaultValue) {
if (defaultValue == null) {
return this;
}
this.defaultValue(raw(defaultValue));
if (shouldEscapeDefaultValue()) {
this.defaultValue(defaultValue);
Expand Down Expand Up @@ -334,5 +365,23 @@ public FieldBuilder jsonGetter(boolean getter) {
public FieldBuilder jsonSetter(boolean setter) {
return this.setter(setter);
}

/**
* DefaultField builder for use in Deserialization.
* @param defaultField
* @return
*/
public FieldBuilder jsonDefaultField(boolean defaultField) {
return this.defaultField(defaultField);
}

/**
* Search builder for use in Deserialization.
* @param search
* @return
*/
public FieldBuilder jsonSearch(boolean search) {
return this.search(search);
}
}
}
Expand Up @@ -13,7 +13,8 @@ enum PersistenceHandlerTemplateProperty {
ELEMENT_INTERFACE("elementInterface"),
CLASS("class"),
COLLECTION("collection"),
IMPLEMENTATION("implementation");
IMPLEMENTATION("implementation"),
FIELDS("fields");

@Getter private String key;
}
Expand Up @@ -55,57 +55,26 @@ public class $class implements $interface {
return (T) element;
}

@Override
public <T extends IDataElement> Iterable<T> findById(long id) throws Exception {
return this.collection.find(Filters.eq("id", id))
.map(doc -> new ${implementation}().fromJSON(doc));
}

@Override
public <T extends IDataElement> Iterable<T> findByName(String name) throws Exception {
return this.collection.find(Filters.eq("name", name))
.map(doc -> new ${implementation}().fromJSON(doc));
}

@Override
public <T extends IDataElement> Iterable<T> findByDescription(String description) throws Exception {
return this.collection.find(Filters.eq("description", description))
.map(doc -> new ${implementation}().fromJSON(doc));
}

@Override
public <T extends IDataElement> Iterable<T> findByComment(String comment) throws Exception {
return this.collection.find(Filters.eq("comment", comment))
.map(doc -> new ${implementation}().fromJSON(doc));
}

@Override
public <T extends IDataElement> Iterable<T> findByContext(String context) throws Exception {
return this.collection.find(Filters.eq("context", context))
.map(doc -> new ${implementation}().fromJSON(doc));
}

@Override
public <T extends IDataElement> Iterable<T> findRequired() throws Exception {
return this.collection.find(Filters.eq("required", true))
.map(doc -> new ${implementation}().fromJSON(doc));
}

@Override
public <T extends IDataElement> Iterable<T> findNotRequired() throws Exception {
return this.collection.find(Filters.eq("required", false))
.map(doc -> new ${implementation}().fromJSON(doc));
}
#foreach($field in $fields)
#if(${field.Getter} && ${field.Search})

/**
* Find $elementInterface by ${field.Name}.
* @param ${field.Name}
* @return Iterator of results
*/
#if(${field.DefaultField})
@Override
public <T extends IDataElement> Iterable<T> findSecret() throws Exception {
return this.collection.find(Filters.eq("secret", true))
#end
public <T extends IDataElement> Iterable<T> findBy${field.NameForMethod}(${field.Type} ${field.Name}) throws Exception {
return this.collection.find(Filters.eq("${field.Name}", ${field.Name}))
.map(doc -> new ${implementation}().fromJSON(doc));
}
#end
#end

@Override
public <T extends IDataElement> Iterable<T> findNotSecret() throws Exception {
return this.collection.find(Filters.eq("secret", false))
.map(doc -> new ${implementation}().fromJSON(doc));
public long clear() throws Exception {
return this.collection.deleteMany(new Document()).getDeletedCount();
}
}
Expand Up @@ -2,11 +2,14 @@

import org.eclipse.ice.dev.annotations.DataElement;
import org.eclipse.ice.dev.annotations.DataField;
import org.eclipse.ice.dev.annotations.IDataElement;
import org.eclipse.ice.dev.annotations.Persisted;

@DataElement
@DataField(fieldName = "age", fieldType = int.class, docString = "The age of the person.")
@DataField(fieldName = "firstName", fieldType = String.class, docString = "The first name of the person.")
@DataField(fieldName = "lastName", fieldType = String.class, docString = "The last name of the Person.")
public interface Person {
@Persisted(collection = "people")
public interface Person extends IDataElement {
//void foo();
}

0 comments on commit 3e26f7e

Please sign in to comment.