Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Eclipse Projects
The Eclipse Integrated Computational Environment
ice
Commits
ff18c728
Unverified
Commit
ff18c728
authored
Jul 27, 2020
by
Gregory Cage
Committed by
GitHub
Jul 27, 2020
Browse files
Merge pull request
#3
from eclipse/next
Next
parents
1ae7dae1
dd3d5f82
Changes
76
Hide whitespace changes
Inline
Side-by-side
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/Field.java
View file @
ff18c728
...
...
@@ -43,7 +43,7 @@ public class Field {
*
* This handles cases like the default field {@link DefaultFields#privateId}
* being accessible through the method
* {@link org.eclipse.ice.d
ev.annotations
.IDataElement#getUUID()} rather than
* {@link org.eclipse.ice.d
ata
.IDataElement#getUUID()} rather than
* {@code getPrivateId()}. In that example, the variable name would be
* {@code privateId} and the field name would be {@code UUID}.
*/
...
...
@@ -103,7 +103,7 @@ public class Field {
/**
* Whether this field should be searchable with PersistenceHandler.
*/
@Builder
.
Default
boolean
search
=
true
;
@Builder
.
Default
boolean
search
able
=
true
;
/**
* Whether this field should return only one from PersistenceHandler.
...
...
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/Fields.java
View file @
ff18c728
...
...
@@ -65,7 +65,7 @@ public class Fields implements Iterable<Field> {
* Return iterator over fields that are set to be used in matches.
*
* @return iterator over the fields
* @see org.eclipse.ice.d
ev.annotations
.IDataElement#matches(Object)
* @see org.eclipse.ice.d
ata
.IDataElement#matches(Object)
*/
public
Iterator
<
Field
>
getMatch
()
{
return
fields
.
stream
()
...
...
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/PersistenceHandlerWriter.java
View file @
ff18c728
...
...
@@ -43,6 +43,11 @@ public class PersistenceHandlerWriter extends VelocitySourceWriter {
*/
private
static
final
String
CLASS
=
"class"
;
/**
* Context key for interface of PersistenceHandlers
*/
private
static
final
String
INTERFACE
=
"interface"
;
/**
* Context key for collection.
*/
...
...
@@ -60,14 +65,16 @@ public class PersistenceHandlerWriter extends VelocitySourceWriter {
@Builder
public
PersistenceHandlerWriter
(
String
packageName
,
String
elementInterface
,
String
className
,
String
implementation
,
String
collection
,
@NonNull
Fields
fields
String
packageName
,
String
elementInterface
,
String
interfaceName
,
String
className
,
String
implementation
,
String
collection
,
@NonNull
Fields
fields
)
{
super
();
this
.
template
=
PERSISTENCE_HANDLER_TEMPLATE
;
this
.
context
.
put
(
PACKAGE
,
packageName
);
this
.
context
.
put
(
ELEMENT_INTERFACE
,
elementInterface
);
this
.
context
.
put
(
CLASS
,
className
);
this
.
context
.
put
(
INTERFACE
,
interfaceName
);
this
.
context
.
put
(
COLLECTION
,
collection
);
this
.
context
.
put
(
IMPLEMENTATION
,
implementation
);
this
.
context
.
put
(
FIELDS
,
fields
);
...
...
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/webform/FinishLoadHook.java
0 → 100644
View file @
ff18c728
/******************************************************************************
* Copyright (c) 2020- UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Initial API and implementation and/or initial documentation -
* Jay Jay Billings, Daniel Bluhm
*****************************************************************************/
package
org.eclipse.ice.dev.annotations.webform
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
*
* @author Jay Jay Billings and Daniel Bluhm
*
*/
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
SOURCE
)
public
@interface
FinishLoadHook
{
}
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/webform/StartLoadHook.java
0 → 100644
View file @
ff18c728
/******************************************************************************
* Copyright (c) 2020- UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Initial API and implementation and/or initial documentation -
* Jay Jay Billings, Daniel Bluhm
*****************************************************************************/
package
org.eclipse.ice.dev.annotations.webform
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
*
* @author Jay Jay Billings and Daniel Bluhm
*
*/
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
SOURCE
)
public
@interface
StartLoadHook
{
}
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/webform/WebForm.java
0 → 100644
View file @
ff18c728
/******************************************************************************
* Copyright (c) 2020- UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Initial API and implementation and/or initial documentation -
* Jay Jay Billings, Daniel Bluhm
*****************************************************************************/
package
org.eclipse.ice.dev.annotations.webform
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.Target
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.RetentionPolicy
;
/**
* Mark a class as a WebForm Specification.
*
* Classes marked as {@code @WebForm} are expected to ....
* * need to have required methods annotated
* * declare hooks
*
* Discuss lifecycle when appropriate and injection of dependencies
*
*
* For example:
*
* <pre>
* {@literal @WebForm}(name = "Talk Submission Page")
* public class TalkFormSpec {
* ...
* }
* </pre>
*
* Will generate an interface like the following:
*
* <pre>
* public interface TalkForm extends ... {
* .... FIXME
* }
* </pre>
*
* And an associated implementing class (in this case, the class would be called
* {@code TalkFormImplementation}) that implements that interface.
*
* @author Jay Jay Billings and Daniel Bluhm
*/
@Target
(
ElementType
.
TYPE
)
@Retention
(
RetentionPolicy
.
SOURCE
)
public
@interface
WebForm
{
/**
* Name of the DataElement to generate
* @return name annotation value
*/
String
name
();
}
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/resources/templates/DataElement.vm
View file @
ff18c728
...
...
@@ -22,6 +22,8 @@ import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;
import org.eclipse.ice.data.JavascriptValidator;
/**
* This is an implementation of
$
interface
that satisfies the dependencies of
* the @DataElement Annotation and was auto-generated by the ICE Framework.
...
...
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/resources/templates/ElementInterface.vm
View file @
ff18c728
...
...
@@ -3,7 +3,7 @@
package
$
package
;
#
end
import org.eclipse.ice.d
ev.annotations
.IDataElement;
import org.eclipse.ice.d
ata
.IDataElement;
/**
* This interface satisfies the dependencies of the @DataElement Annotation and
...
...
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/resources/templates/PersistenceHandler.vm
View file @
ff18c728
## Declarations
#
set
($
interface
=
"IPersistenceHandler"
)
##
#
if
($
package
)
package
$
package
;
#
end
import java.util.Map;
import java.util.UUID;
import org.bson.Document;
import org.eclipse.ice.dev.annotations.IDataElement;
import org.eclipse.ice.dev.annotations.IPersistenceHandler;
import org.eclipse.ice.data.IPersistenceHandler;
import org.eclipse.ice.dev.annotations.PersistenceFilters;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
...
...
@@ -46,7 +38,6 @@ public class $class implements $interface<$elementInterface> {
/**
* Save the
$
elementInterface
.
* @param
<T>
Object extending IDataElement
* @param element
* @throws Exception
*/
...
...
@@ -57,7 +48,6 @@ public class $class implements $interface<$elementInterface> {
/**
* Find and retrieve all
$
elementInterface
from the collection.
* @param
<T>
* @return an iterable of the retrieved elements.
* @throws Exception
*/
...
...
@@ -74,26 +64,26 @@ public class $class implements $interface<$elementInterface> {
*/
@Override
public long clear() throws Exception
{
long count = this.collection.count();
long count = this.collection.count
Documents
();
this.collection.drop();
return count;
}
#
macro
(
findmethod
$
var
$
type
$
docName
)
#
if
(${
var
.
Getter
}
&&
${
var
.
Search
})
#
if
(${
var
.
Unique
})
#
foreach
($
field
in
$
fields
)
#
if
(${
field
.
Getter
}
&&
${
field
.
Search
able
})
#
if
(${
field
.
Unique
})
/**
* Find
$
elementInterface
by
${
var
.
Name
}
.
* @param
${
var
.
VarName
}
* Find
$
elementInterface
by
${
field
.
Name
}
.
* @param
${
field
.
VarName
}
* @return found element or null
*/
#
if
(${
var
.
DefaultField
})
#
if
(${
field
.
DefaultField
})
@Override
#
end
public
$
elementInterface
findBy
${
var
.
NameForMethod
}
(
$
type
${
var
.
VarName
}
) throws Exception
{
public
$
elementInterface
findBy
${
field
.
NameForMethod
}
(
#
field
type
${
field
.
VarName
}
) throws Exception
{
Document doc = this.collection
.find(PersistenceFilters.eq("
${
doc
Name
}
",
${
var
.
VarName
}
))
.find(PersistenceFilters.eq("
${
field
.
Var
Name
}
",
${
field
.
VarName
}
))
.first();
if (doc == null)
{
return null;
...
...
@@ -104,21 +94,18 @@ public class $class implements $interface<$elementInterface> {
#
else
/**
* Find
$
elementInterface
by
${
var
.
Name
}
.
* @param
${
var
.
VarName
}
* Find
$
elementInterface
by
${
field
.
Name
}
.
* @param
${
field
.
VarName
}
* @return Iterator of results
*/
#
if
(${
var
.
DefaultField
})
#
if
(${
field
.
DefaultField
})
@Override
#
end
public Iterable
<
$
elementInterface
>
findBy
${
var
.
NameForMethod
}
(
${
var
.
T
ype
}
${
var
.
VarName
}
) throws Exception
{
return this.collection.find(PersistenceFilters.eq("
${
var
.
VarName
}
",
${
var
.
VarName
}
))
public Iterable
<
$
elementInterface
>
findBy
${
field
.
NameForMethod
}
(
#
fieldt
ype
${
field
.
VarName
}
) throws Exception
{
return this.collection.find(PersistenceFilters.eq("
${
field
.
VarName
}
",
${
field
.
VarName
}
))
.map(doc -> mapper.convertValue(doc,
${
implementation
}
.class));
}
#
end
## if unique
#
end
## if getter and search
#
end
## macro findmethod
#
foreach
($
field
in
$
fields
)
#
findmethod
($
field
${
field
.
Type
}
${
field
.
VarName
})
#
end
#
end
## foreach
}
\ No newline at end of file
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/test/java/org/eclipse/ice/tests/dev/annotations/processors/DataElementAnnotationTestHelper.java
0 → 100644
View file @
ff18c728
/*******************************************************************************
* Copyright (c) 2020- UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Daniel Bluhm - Initial implementation
*******************************************************************************/
package
org.eclipse.ice.tests.dev.annotations.processors
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.InvocationTargetException
;
import
javax.annotation.processing.Processor
;
import
javax.tools.JavaFileObject
;
import
org.eclipse.ice.dev.annotations.processors.DataElementProcessor
;
import
com.google.testing.compile.Compilation
;
import
static
com
.
google
.
testing
.
compile
.
Compiler
.*;
/**
* Helper class for testing DataElement related annotations.
* @author Daniel Bluhm
*/
public
class
DataElementAnnotationTestHelper
{
/**
* Retrieve an instance of Lombok's Annotation Processor.
*
* This is a nasty method that violates the accessibility of the Processor by
* reflection but is necessary to correctly process and test the generated code.
* @return lombok annotation processor
*/
private
Processor
getLombokAnnotationProcessor
()
{
Processor
p
=
null
;
try
{
Class
<?>
c
=
Class
.
forName
(
"lombok.launch.AnnotationProcessorHider$AnnotationProcessor"
);
Constructor
<?>
constructor
=
c
.
getConstructor
();
constructor
.
setAccessible
(
true
);
p
=
(
Processor
)
constructor
.
newInstance
();
}
catch
(
ClassNotFoundException
|
InstantiationException
|
IllegalAccessException
|
IllegalArgumentException
|
InvocationTargetException
|
NoSuchMethodException
|
SecurityException
e
)
{
System
.
err
.
println
(
"Failed to get Lombok AnnotationProcessor!"
);
e
.
printStackTrace
();
}
return
p
;
}
/**
* Compile the sources with needed processors.
* @param sources to compile
* @return Compilation result
*/
public
Compilation
compile
(
JavaFileObject
...
sources
)
{
return
javac
()
.
withProcessors
(
getLombokAnnotationProcessor
(),
new
DataElementProcessor
()
).
compile
(
sources
);
}
}
org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/test/java/org/eclipse/ice/tests/dev/annotations/processors/DataElementProcessorTest.java
View file @
ff18c728
package
org.eclipse.ice.tests.dev.annotations.processors
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
fail
;
/*******************************************************************************
* Copyright (c) 2020- UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Daniel Bluhm - Initial implementation
*******************************************************************************/
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.InvocationTargetException
;
package
org.eclipse.ice.tests.dev.annotations.processors
;
import
static
com
.
google
.
testing
.
compile
.
Compiler
.*;
import
static
com
.
google
.
testing
.
compile
.
CompilationSubject
.*;
import
javax.annotation.processing.Processor
;
import
javax.tools.JavaFileObject
;
import
org.eclipse.ice.dev.annotations.processors.DataElementProcessor
;
import
org.junit.jupiter.api.Test
;
import
com.google.testing.compile.Compilation
;
import
com.google.testing.compile.JavaFileObjects
;
import
lombok.AllArgsConstructor
;
...
...
@@ -38,6 +40,12 @@ import lombok.AllArgsConstructor;
*/
class
DataElementProcessorTest
{
/**
* Helper for testing DataElement related annotations.
*/
private
static
DataElementAnnotationTestHelper
helper
=
new
DataElementAnnotationTestHelper
();
/**
* Fully qualified name of the generated interface.
*/
...
...
@@ -53,7 +61,7 @@ class DataElementProcessorTest {
* @author Daniel Bluhm
*/
@AllArgsConstructor
private
static
enum
Inputs
{
private
static
enum
Inputs
implements
JavaFileObjectResource
{
HELLO_WORLD
(
"HelloWorld.java"
),
NAME_MISSING
(
"DataElementNameMissing.java"
),
ON_ENUM
(
"DataElementOnEnum.java"
),
...
...
@@ -75,19 +83,16 @@ class DataElementProcessorTest {
/**
* Parent directory of inputs. Prepended to all paths.
*/
private
static
final
String
PARENT
=
"input/"
;
private
static
final
String
PARENT
=
"input/
DataElement/
"
;
/**
* Path to inputs.
*/
private
String
path
;
private
String
filename
;
/**
* Retrieve the JavaFileObject corresponding to this input.
* @return input as a JavaFileObject
*/
public
JavaFileObject
get
()
{
return
JavaFileObjects
.
forResource
(
PARENT
+
this
.
path
);
@Override
public
String
getPath
()
{
return
PARENT
+
this
.
filename
;
}
}
...
...
@@ -96,7 +101,7 @@ class DataElementProcessorTest {
* @author Daniel Bluhm
*/
@AllArgsConstructor
private
static
enum
Patterns
{
private
static
enum
Patterns
implements
JavaFileObjectResource
{
DEFAULTS_INT
(
"Defaults.java"
),
DEFAULTS_IMPL
(
"DefaultsImplementation.java"
),
SINGLE_INT
(
"Single.java"
),
...
...
@@ -116,61 +121,19 @@ class DataElementProcessorTest {
/**
* Parent directory of inputs. Prepended to all paths.
*/
private
static
final
String
PARENT
=
"patterns/"
;
private
static
final
String
PARENT
=
"patterns/
DataElement/
"
;
/**
* Path to inputs.
*/
private
String
path
;
private
String
filename
;
/**
* Retrieve the JavaFileObject corresponding to this pattern.
* @return input as a JavaFileObject
*/
public
JavaFileObject
get
()
{
return
JavaFileObjects
.
forResource
(
PARENT
+
this
.
path
);
@Override
public
String
getPath
()
{
return
PARENT
+
this
.
filename
;
}
}
/**
* Retrieve an instance of Lombok's Annotation Processor.
*
* This is a nasty method that violates the accessibility of the Processor by
* reflection but is necessary to correctly process and test the generated code.
* @return lombok annotation processor
*/
private
static
Processor
getLombokAnnotationProcessor
()
{
Processor
p
=
null
;
try
{
Class
<?>
c
=
Class
.
forName
(
"lombok.launch.AnnotationProcessorHider$AnnotationProcessor"
);
Constructor
<?>
constructor
=
c
.
getConstructor
();
constructor
.
setAccessible
(
true
);
p
=
(
Processor
)
constructor
.
newInstance
();
}
catch
(
ClassNotFoundException
|
InstantiationException
|
IllegalAccessException
|
IllegalArgumentException
|
InvocationTargetException
|
NoSuchMethodException
|
SecurityException
e
)
{
System
.
err
.
println
(
"Failed to get Lombok AnnotationProcessor!"
);
e
.
printStackTrace
();
}
return
p
;
}
/**
* Compile the sources with needed processors.
* @param sources to compile
* @return Compilation result
*/
private
static
Compilation
compile
(
JavaFileObject
...
sources
)
{
return
javac
()
.
withProcessors
(
getLombokAnnotationProcessor
(),
new
DataElementProcessor
()
).
compile
(
sources
);
}
/**
* Assert that the interface generated in this compilation matches the given
* pattern.
...
...
@@ -213,7 +176,7 @@ class DataElementProcessorTest {
*/
@Test
void
testNoAnnotationsToProcessSucceeds
()
{
Compilation
compilation
=
compile
(
Inputs
.
HELLO_WORLD
.
get
());
Compilation
compilation
=
helper
.
compile
(
Inputs
.
HELLO_WORLD
.
get
());
assertThat
(
compilation
).
succeeded
();
}
...
...
@@ -223,7 +186,7 @@ class DataElementProcessorTest {
*/
@Test
void
testMissingNameFails
()
{
Compilation
compilation
=
compile
(
Inputs
.
NAME_MISSING
.
get
());
Compilation
compilation
=
helper
.
compile
(
Inputs
.
NAME_MISSING
.
get
());
assertThat
(
compilation
)
.
hadErrorContaining
(
"missing a default value for the element 'name'"
...
...
@@ -235,7 +198,7 @@ class DataElementProcessorTest {
*/
@Test
void
testAnnotateInterfaceFails
()
{
Compilation
compilation
=
compile
(
Inputs
.
ON_INTERFACE
.
get
());
Compilation
compilation
=
helper
.
compile
(
Inputs
.
ON_INTERFACE
.
get
());
assertThat
(
compilation
)
.
hadErrorContaining
(
"DataElementSpec must be class"
);
}
...
...
@@ -245,7 +208,7 @@ class DataElementProcessorTest {
*/
@Test
void
testAnnotateEnumFails
()
{