Unverified Commit b0b41691 authored by Daniel Bluhm's avatar Daniel Bluhm Committed by GitHub

Merge pull request #476 from dbluhm/feature/writer-improvements

Use metadata classes in writers directly
parents 4ddedec2 fa187fbd
...@@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory; ...@@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory;
/** /**
* Abstract base class for AnnotationExtractors providing common methods to * Abstract base class for AnnotationExtractors providing common methods to
* all extractors. * all extractors.
* *
* @author Daniel Bluhm * @author Daniel Bluhm
* *
* @param <T> Type of data extracted from element. * @param <T> Type of data extracted from element.
...@@ -78,11 +78,11 @@ public abstract class AbstractAnnotationExtractor<T> implements AnnotationExtrac ...@@ -78,11 +78,11 @@ public abstract class AbstractAnnotationExtractor<T> implements AnnotationExtrac
/** /**
* Find and return annotation mirror of a given type if present. * Find and return annotation mirror of a given type if present.
* *
* When an annotation value is a Class, Annotation Mirrors must be used to * When an annotation value is a Class, Annotation Mirrors must be used to
* retrieve a TypeMirror to the class (using {@link * retrieve a TypeMirror to the class (using {@link
* Elements#getElementValuesWithDefaults(AnnotationMirror)}). * Elements#getElementValuesWithDefaults(AnnotationMirror)}).
* *
* If the annotation in question has no Class values, it is recommended to * If the annotation in question has no Class values, it is recommended to
* use the Annotation directly with {@link #getAnnotation(Element, Class)}. * use the Annotation directly with {@link #getAnnotation(Element, Class)}.
* *
......
...@@ -11,7 +11,13 @@ ...@@ -11,7 +11,13 @@
package org.eclipse.ice.dev.annotations.processors; package org.eclipse.ice.dev.annotations.processors;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Builder; import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
/** /**
...@@ -20,21 +26,68 @@ import lombok.Getter; ...@@ -20,21 +26,68 @@ import lombok.Getter;
* *
* @author Daniel Bluhm * @author Daniel Bluhm
*/ */
@Getter
@Builder @Builder
@Getter
@EqualsAndHashCode
@JsonDeserialize(builder = DataElementMetadata.DataElementMetadataBuilder.class)
@JsonAutoDetect(
fieldVisibility = Visibility.ANY,
getterVisibility = Visibility.NONE,
isGetterVisibility = Visibility.NONE,
setterVisibility = Visibility.NONE
)
public class DataElementMetadata { public class DataElementMetadata {
/**
* Suffix for Implementation name.
*/
private static final String IMPL_SUFFIX = "Implementation";
/** /**
* Base name of classes to be generated. * Base name of classes to be generated.
*/ */
protected String name; @JsonProperty
private String name;
/** /**
* Package of classes to be generated. * Package of classes to be generated.
*/ */
protected String packageName; @JsonProperty("package")
private String packageName;
/** /**
* Collected fields of the DataElement. * Collected fields of the DataElement.
*/ */
protected Fields fields; @JsonProperty
private Fields fields;
/**
* Fully qualified name of this DataElement.
* @return fully qualified name.
*/
public String getFullyQualifiedName() {
String value = null;
if (packageName != null) {
value = String.format("%s.%s", packageName, name);
} else {
value = name;
}
return value;
}
/**
* Name of implementation for this DataElement.
* @return Implementation name.
*/
public String getImplementationName() {
return name + IMPL_SUFFIX;
}
/**
* Fully qualified name of this DataElement's implementation.
* @return fully qualified implementation name.
*/
public String getFullyQualifiedImplName() {
return getFullyQualifiedName() + IMPL_SUFFIX;
}
} }
\ No newline at end of file
...@@ -42,26 +42,10 @@ public class DataElementWriterGenerator implements WriterGenerator { ...@@ -42,26 +42,10 @@ public class DataElementWriterGenerator implements WriterGenerator {
@Override @Override
public List<GeneratedFileWriter> generate() { public List<GeneratedFileWriter> generate() {
List<GeneratedFileWriter> writers = new ArrayList<>(); List<GeneratedFileWriter> writers = new ArrayList<>();
Fields nonDefaults = data.getFields().getNonDefaultFields(); writers.add(new InterfaceWriter(data));
writers.add(InterfaceWriter.builder() writers.add(new ImplementationWriter(data));
.packageName(data.getPackageName())
.interfaceName(data.getName())
.fields(nonDefaults)
.types(nonDefaults.getTypes())
.build());
writers.add(ImplementationWriter.builder()
.packageName(data.getPackageName())
.interfaceName(data.getName())
.className(data.getName() + "Implementation")
.fields(data.getFields())
.types(data.getFields().getTypes())
.build());
try { try {
writers.add(TypeScriptWriter.builder() writers.add(new TypeScriptWriter(data));
.name(data.getName())
.fields(nonDefaults)
.types(nonDefaults.getTypes())
.build());
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
logger.info("Failed to create typescript writer for element:", e); logger.info("Failed to create typescript writer for element:", e);
} }
......
...@@ -17,20 +17,27 @@ import java.util.Iterator; ...@@ -17,20 +17,27 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.EqualsAndHashCode;
/** /**
* A collection of Field objects to be used especially in template rendering. * A collection of Field objects to be used especially in template rendering.
* *
* @author Daniel Bluhm * @author Daniel Bluhm
*/ */
@EqualsAndHashCode
public class Fields implements Iterable<Field> { public class Fields implements Iterable<Field> {
/** /**
* The collection of fields on which views will be retrieved. * The collection of fields on which views will be retrieved.
*/ */
private List<Field> fields; @JsonValue
private List<Field> list;
public Fields() { public Fields() {
this.fields = new ArrayList<>(); this.list = new ArrayList<>();
} }
/** /**
...@@ -38,9 +45,10 @@ public class Fields implements Iterable<Field> { ...@@ -38,9 +45,10 @@ public class Fields implements Iterable<Field> {
* *
* @param fields initial fields * @param fields initial fields
*/ */
@JsonCreator
public Fields(Collection<Field> fields) { public Fields(Collection<Field> fields) {
this.fields = new ArrayList<>(); this.list = new ArrayList<>();
this.fields.addAll(fields); this.list.addAll(fields);
} }
/** /**
...@@ -49,7 +57,7 @@ public class Fields implements Iterable<Field> { ...@@ -49,7 +57,7 @@ public class Fields implements Iterable<Field> {
* @param fields to add * @param fields to add
*/ */
public void collect(Collection<Field> fields) { public void collect(Collection<Field> fields) {
this.fields.addAll(fields); this.list.addAll(fields);
} }
/** /**
...@@ -59,7 +67,7 @@ public class Fields implements Iterable<Field> { ...@@ -59,7 +67,7 @@ public class Fields implements Iterable<Field> {
* @see Field#isConstant() * @see Field#isConstant()
*/ */
public Iterator<Field> getConstants() { public Iterator<Field> getConstants() {
return fields.stream() return list.stream()
.filter(Field::isConstant) .filter(Field::isConstant)
.iterator(); .iterator();
} }
...@@ -71,7 +79,7 @@ public class Fields implements Iterable<Field> { ...@@ -71,7 +79,7 @@ public class Fields implements Iterable<Field> {
* @see Field#isConstant() * @see Field#isConstant()
*/ */
public Iterator<Field> getMutable() { public Iterator<Field> getMutable() {
return fields.stream() return list.stream()
.filter(field -> !field.isConstant()) .filter(field -> !field.isConstant())
.iterator(); .iterator();
} }
...@@ -83,7 +91,7 @@ public class Fields implements Iterable<Field> { ...@@ -83,7 +91,7 @@ public class Fields implements Iterable<Field> {
* @see org.eclipse.ice.data.IDataElement#matches(Object) * @see org.eclipse.ice.data.IDataElement#matches(Object)
*/ */
public Iterator<Field> getMatch() { public Iterator<Field> getMatch() {
return fields.stream() return list.stream()
.filter(Field::isMatch) .filter(Field::isMatch)
.iterator(); .iterator();
} }
...@@ -96,7 +104,7 @@ public class Fields implements Iterable<Field> { ...@@ -96,7 +104,7 @@ public class Fields implements Iterable<Field> {
* @see Field#isVarDifferent() * @see Field#isVarDifferent()
*/ */
public Iterator<Field> getVarNamesDiffer() { public Iterator<Field> getVarNamesDiffer() {
return fields.stream() return list.stream()
.filter(Field::isVarNameDifferent) .filter(Field::isVarNameDifferent)
.iterator(); .iterator();
} }
...@@ -106,7 +114,7 @@ public class Fields implements Iterable<Field> { ...@@ -106,7 +114,7 @@ public class Fields implements Iterable<Field> {
* @return Iterable of fields needed for interface. * @return Iterable of fields needed for interface.
*/ */
public Iterable<Field> getInterfaceFields() { public Iterable<Field> getInterfaceFields() {
return fields.stream() return list.stream()
.filter(field -> !field.isDefaultField()) .filter(field -> !field.isDefaultField())
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
...@@ -117,7 +125,7 @@ public class Fields implements Iterable<Field> { ...@@ -117,7 +125,7 @@ public class Fields implements Iterable<Field> {
*/ */
public Fields getNonDefaultFields() { public Fields getNonDefaultFields() {
return new Fields( return new Fields(
fields.stream() list.stream()
.filter(field -> !field.isDefaultField()) .filter(field -> !field.isDefaultField())
.collect(Collectors.toList()) .collect(Collectors.toList())
); );
......
...@@ -12,9 +12,6 @@ ...@@ -12,9 +12,6 @@
package org.eclipse.ice.dev.annotations.processors; package org.eclipse.ice.dev.annotations.processors;
import lombok.Builder;
import lombok.NonNull;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
...@@ -74,22 +71,14 @@ public class ImplementationWriter ...@@ -74,22 +71,14 @@ public class ImplementationWriter
* @param fields * @param fields
* @param generatedFile * @param generatedFile
*/ */
@Builder public ImplementationWriter(DataElementMetadata data) {
public ImplementationWriter(
String packageName, String interfaceName, String className,
@NonNull Fields fields, @NonNull Types types
) {
super(IMPL_TEMPLATE); super(IMPL_TEMPLATE);
if (packageName != null) { this.fqn = data.getFullyQualifiedImplName();
this.fqn = String.format("%s.%s", packageName, className); this.context.put(PACKAGE, data.getPackageName());
} else { this.context.put(INTERFACE, data.getName());
this.fqn = className; this.context.put(CLASS, data.getImplementationName());
} this.context.put(FIELDS, data.getFields());
this.context.put(PACKAGE, packageName); this.context.put(TYPES, data.getFields().getTypes());
this.context.put(INTERFACE, interfaceName);
this.context.put(CLASS, className);
this.context.put(FIELDS, fields);
this.context.put(TYPES, types);
} }
@Override @Override
......
...@@ -17,9 +17,6 @@ import java.io.Writer; ...@@ -17,9 +17,6 @@ import java.io.Writer;
import javax.annotation.processing.Filer; import javax.annotation.processing.Filer;
import lombok.Builder;
import lombok.NonNull;
/** /**
* Writer for DataElement Interfaces. * Writer for DataElement Interfaces.
* *
...@@ -72,21 +69,16 @@ public class InterfaceWriter ...@@ -72,21 +69,16 @@ public class InterfaceWriter
* @param fields * @param fields
* @param generatedFile * @param generatedFile
*/ */
@Builder
public InterfaceWriter( public InterfaceWriter(
String packageName, String interfaceName, @NonNull Fields fields, DataElementMetadata data
@NonNull Types types
) { ) {
super(TEMPLATE); super(TEMPLATE);
if (packageName != null) { this.fqn = data.getFullyQualifiedName();
this.fqn = String.format("%s.%s", packageName, interfaceName); Fields fields = data.getFields().getNonDefaultFields();
} else { context.put(PACKAGE, data.getPackageName());
this.fqn = interfaceName; context.put(INTERFACE, data.getName());
}
context.put(PACKAGE, packageName);
context.put(INTERFACE, interfaceName);
context.put(FIELDS, fields); context.put(FIELDS, fields);
context.put(TYPES, types); context.put(TYPES, fields.getTypes());
} }
@Override @Override
......
...@@ -17,9 +17,6 @@ import java.io.Writer; ...@@ -17,9 +17,6 @@ import java.io.Writer;
import javax.annotation.processing.Filer; import javax.annotation.processing.Filer;
import lombok.Builder;
import lombok.NonNull;
/** /**
* Writer for DataElement Persistence classes. * Writer for DataElement Persistence classes.
* *
...@@ -45,11 +42,6 @@ public class PersistenceHandlerWriter ...@@ -45,11 +42,6 @@ public class PersistenceHandlerWriter
*/ */
private static final String CLASS = "class"; private static final String CLASS = "class";
/**
* Context key for interface of PersistenceHandlers
*/
private static final String INTERFACE = "interface";
/** /**
* Context key for collection. * Context key for collection.
*/ */
...@@ -79,38 +71,27 @@ public class PersistenceHandlerWriter ...@@ -79,38 +71,27 @@ public class PersistenceHandlerWriter
* Fully qualified name of the class for file output. * Fully qualified name of the class for file output.
*/ */
private String fqn; private String fqn;
/** /**
* Constructor * Create instance of persistence handler writer from metadata.
* * @param dataElement DataElementMetadata
* @param packageName * @param persistence PersistenceMetadata
* @param elementInterface
* @param className
* @param interfaceName
* @param implementation
* @param collection
* @param fields
* @param generatedFile
*/ */
@Builder
public PersistenceHandlerWriter( public PersistenceHandlerWriter(
String packageName, String elementInterface, String className, String DataElementMetadata dataElement,
interfaceName, String implementation, String collection, @NonNull Fields PersistenceMetadata persistence
fields, @NonNull Types types
) { ) {
super(TEMPLATE); super(TEMPLATE);
if (packageName != null) { this.fqn = persistence.getHandlerName(
this.fqn = String.format("%s.%s", packageName, className); dataElement.getFullyQualifiedName()
} else { );
this.fqn = className; this.context.put(PACKAGE, dataElement.getPackageName());
} this.context.put(ELEMENT_INTERFACE, dataElement.getName());
this.context.put(PACKAGE, packageName); this.context.put(CLASS, persistence.getHandlerName(dataElement.getName()));
this.context.put(ELEMENT_INTERFACE, elementInterface); this.context.put(COLLECTION, persistence.getCollection());
this.context.put(CLASS, className); this.context.put(IMPLEMENTATION, dataElement.getImplementationName());
this.context.put(INTERFACE, interfaceName); this.context.put(FIELDS, dataElement.getFields());
this.context.put(COLLECTION, collection); this.context.put(TYPES, dataElement.getFields().getTypes());
this.context.put(IMPLEMENTATION, implementation);
this.context.put(FIELDS, fields);
this.context.put(TYPES, types);
} }
@Override @Override
......
...@@ -21,8 +21,22 @@ import lombok.Getter; ...@@ -21,8 +21,22 @@ import lombok.Getter;
@Getter @Getter
@Builder @Builder
public class PersistenceMetadata { public class PersistenceMetadata {
/**
* Suffix to PersistenceHandler class names.
*/
private static final String SUFFIX = "PersistenceHandler";
/** /**
* Collection name for persistence. * Collection name for persistence.
*/ */
private String collection; private String collection;
/**