Commit db4acc8b by Tuomas Riihimäki

Initial graphql api implementation

1 parent 42d57068
Showing with 565 additions and 30 deletions
...@@ -2,6 +2,7 @@ package fi.codecrew.moya.beans; ...@@ -2,6 +2,7 @@ package fi.codecrew.moya.beans;
import fi.codecrew.moya.model.Allergy; import fi.codecrew.moya.model.Allergy;
import fi.codecrew.moya.model.EventUser; import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.model.UsersAllergy; import fi.codecrew.moya.model.UsersAllergy;
import javax.ejb.Local; import javax.ejb.Local;
...@@ -13,6 +14,7 @@ public interface AllergyBeanLocal { ...@@ -13,6 +14,7 @@ public interface AllergyBeanLocal {
List<Allergy> getAllergies(); List<Allergy> getAllergies();
List<UsersAllergy> getUserAllergies(User currentUser);
List<UsersAllergy> getUserAllergies(EventUser currentUser); List<UsersAllergy> getUserAllergies(EventUser currentUser);
List<UsersAllergy> saveAllergies(ArrayList<UsersAllergy> allergylist); List<UsersAllergy> saveAllergies(ArrayList<UsersAllergy> allergylist);
......
...@@ -208,4 +208,12 @@ public interface UserBeanLocal { ...@@ -208,4 +208,12 @@ public interface UserBeanLocal {
* @return EventUser with the matching code * @return EventUser with the matching code
*/ */
EventUser findUserByCodeToken(String code); EventUser findUserByCodeToken(String code);
/**
* Return eventusers of all events for user
* This function can only be used by users themselves, and superadmins.
* @param user User to fetch eventusers for
* @return Eventusers for all events this user has been associated to.
*/
List<EventUser> findAllEventusers(User user);
} }
...@@ -4,6 +4,7 @@ import fi.codecrew.moya.facade.AllergyFacade; ...@@ -4,6 +4,7 @@ import fi.codecrew.moya.facade.AllergyFacade;
import fi.codecrew.moya.facade.UsersAllergyFacade; import fi.codecrew.moya.facade.UsersAllergyFacade;
import fi.codecrew.moya.model.Allergy; import fi.codecrew.moya.model.Allergy;
import fi.codecrew.moya.model.EventUser; import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.model.UsersAllergy; import fi.codecrew.moya.model.UsersAllergy;
import javax.ejb.EJB; import javax.ejb.EJB;
...@@ -27,11 +28,16 @@ public class AllergyBean implements AllergyBeanLocal { ...@@ -27,11 +28,16 @@ public class AllergyBean implements AllergyBeanLocal {
} }
@Override @Override
public List<UsersAllergy> getUserAllergies(EventUser user) { public List<UsersAllergy> getUserAllergies(User user) {
return userAllergyFacade.findForUser(user); return userAllergyFacade.findForUser(user);
} }
@Override @Override
public List<UsersAllergy> getUserAllergies(EventUser user) {
return userAllergyFacade.findForUser(user.getUser());
}
@Override
public List<UsersAllergy> saveAllergies(ArrayList<UsersAllergy> allergylist) { public List<UsersAllergy> saveAllergies(ArrayList<UsersAllergy> allergylist) {
ArrayList<UsersAllergy> ret = new ArrayList<>(); ArrayList<UsersAllergy> ret = new ArrayList<>();
for (UsersAllergy a : allergylist) { for (UsersAllergy a : allergylist) {
......
...@@ -1180,6 +1180,17 @@ public class UserBean implements UserBeanLocal { ...@@ -1180,6 +1180,17 @@ public class UserBean implements UserBeanLocal {
return eventUser; return eventUser;
} }
@Override
@RolesAllowed(SpecialPermission.S_USER)
public List<EventUser> findAllEventusers(User user) {
user = userFacade.reload(user);
if (!permbean.isCurrentUser(user) && !permbean.getCurrentUser().isSuperadmin()) {
throw new EJBAccessException("Only users themselves can fetch all eventusers for all events");
}
return eventUserFacade.findForUser(user);
}
@Override @Override
@RolesAllowed(EventPermission.S_MANAGE_EVENT) @RolesAllowed(EventPermission.S_MANAGE_EVENT)
......
...@@ -211,6 +211,14 @@ public class EventUserFacade extends IntegerPkGenericFacade<EventUser> { ...@@ -211,6 +211,14 @@ public class EventUserFacade extends IntegerPkGenericFacade<EventUser> {
return getSingleNullableResult(getEm().createQuery(cq)); return getSingleNullableResult(getEm().createQuery(cq));
} }
public List<EventUser> findForUser(User user) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<EventUser> cq = cb.createQuery(EventUser.class);
Root<EventUser> root = cq.from(EventUser.class);
cq.where(cb.equal(root.get(EventUser_.user), user));
return getEm().createQuery(cq).getResultList();
}
// private Predicate addAcPredicate(CriteriaBuilder cb, UserSearchQuery // private Predicate addAcPredicate(CriteriaBuilder cb, UserSearchQuery
// query, Root<AccountEvent> root) { // query, Root<AccountEvent> root) {
// Expression<BigDecimal> sum = // Expression<BigDecimal> sum =
......
...@@ -18,10 +18,7 @@ ...@@ -18,10 +18,7 @@
*/ */
package fi.codecrew.moya.facade; package fi.codecrew.moya.facade;
import fi.codecrew.moya.model.Allergy; import fi.codecrew.moya.model.*;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.UsersAllergy;
import fi.codecrew.moya.model.UsersAllergy_;
import javax.ejb.LocalBean; import javax.ejb.LocalBean;
import javax.ejb.Stateless; import javax.ejb.Stateless;
...@@ -39,12 +36,12 @@ public class UsersAllergyFacade extends IntegerPkGenericFacade<UsersAllergy> { ...@@ -39,12 +36,12 @@ public class UsersAllergyFacade extends IntegerPkGenericFacade<UsersAllergy> {
} }
public List<UsersAllergy> findForUser(EventUser user) { public List<UsersAllergy> findForUser(User user) {
CriteriaBuilder cb = getEm().getCriteriaBuilder(); CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<UsersAllergy> cq = cb.createQuery(UsersAllergy.class); CriteriaQuery<UsersAllergy> cq = cb.createQuery(UsersAllergy.class);
Root<UsersAllergy> root = cq.from(UsersAllergy.class); Root<UsersAllergy> root = cq.from(UsersAllergy.class);
cq.where(cb.equal(root.get(UsersAllergy_.user), user.getUser())); cq.where(cb.equal(root.get(UsersAllergy_.user), user));
return getEm().createQuery(cq).getResultList(); return getEm().createQuery(cq).getResultList();
} }
......
...@@ -25,6 +25,9 @@ public class LanguageAwareString { ...@@ -25,6 +25,9 @@ public class LanguageAwareString {
} }
return ret; return ret;
} }
public String getDefaultValue(){
return getValue(defaultLanguage);
}
public String getDefaultLanguage() { public String getDefaultLanguage() {
return defaultLanguage; return defaultLanguage;
......
...@@ -3,34 +3,35 @@ package fi.codecrew.moya.model; ...@@ -3,34 +3,35 @@ package fi.codecrew.moya.model;
import javax.persistence.*; import javax.persistence.*;
import java.util.Date; import java.util.Date;
@Table(name="user_allergies") @Table(name = "user_allergies")
@Entity @Entity
public class UsersAllergy extends GenericEntity { public class UsersAllergy extends GenericEntity {
@Column(nullable=false, name = "selected") @Column(nullable = false, name = "selected")
private boolean selected = false; private boolean selected = false;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(name="severity") @Column(name = "severity")
private AllergySeverity severity = AllergySeverity.NORMAL; private AllergySeverity severity = AllergySeverity.NORMAL;
@ManyToOne @ManyToOne
@JoinColumn(name="user_id", updatable = false, referencedColumnName = "id", nullable = false) @JoinColumn(name = "user_id", updatable = false, referencedColumnName = "id", nullable = false)
private User user; private User user;
@ManyToOne @ManyToOne
@JoinColumn(name="allergy_id", updatable = false, referencedColumnName = "id", nullable = false) @JoinColumn(name = "allergy_id", updatable = false, referencedColumnName = "id", nullable = false)
private Allergy allergy; private Allergy allergy;
@Column(name="created") @Column(name = "created")
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
private Date created; private Date created;
@Lob @Lob
@Column(name="notes") @Column(name = "notes")
private String notes; private String notes;
public UsersAllergy() { public UsersAllergy() {
super(); super();
} }
...@@ -80,4 +81,12 @@ public class UsersAllergy extends GenericEntity { ...@@ -80,4 +81,12 @@ public class UsersAllergy extends GenericEntity {
public void setSelected(boolean selected) { public void setSelected(boolean selected) {
this.selected = selected; this.selected = selected;
} }
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
} }
...@@ -170,6 +170,11 @@ ...@@ -170,6 +170,11 @@
<version>${findbugs.version}</version> <version>${findbugs.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>9.0</version>
</dependency>
</dependencies> </dependencies>
<reporting> <reporting>
<plugins> <plugins>
......
...@@ -20,6 +20,7 @@ package fi.codecrew.moya; ...@@ -20,6 +20,7 @@ package fi.codecrew.moya;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.Principal; import java.security.Principal;
import java.util.Base64; import java.util.Base64;
...@@ -185,7 +186,7 @@ public class HostnameFilter implements Filter { ...@@ -185,7 +186,7 @@ public class HostnameFilter implements Filter {
if (!restAuth(httpRequest, response) && RestApplicationEntrypoint.REST_PATH.equals(httpRequest.getServletPath())) { if (!restAuth(httpRequest, response) && RestApplicationEntrypoint.REST_PATH.equals(httpRequest.getServletPath())) {
response.reset(); response.reset();
response.getOutputStream().write("Rest auth failed! ".getBytes( Charsets.UTF_8)); response.getOutputStream().write("Rest auth failed! ".getBytes( StandardCharsets.UTF_8));
if (response instanceof HttpServletResponse) { if (response instanceof HttpServletResponse) {
HttpServletResponse httpResp = (HttpServletResponse) response; HttpServletResponse httpResp = (HttpServletResponse) response;
......
package fi.codecrew.moya.graphql;
public class AlreadyBuiltException extends RuntimeException {
public AlreadyBuiltException(String s) {
super(s);
}
}
package fi.codecrew.moya.graphql;
import graphql.schema.*;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.PluralAttribute;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import static graphql.Scalars.*;
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
import static graphql.schema.GraphQLObjectType.newObject;
public class EntityGQLBuilder<T> {
private final GraphQLObjectType.Builder builder;
private final GraphQLBuilder parent;
private final String typeName;
private final List<GraphQLFieldDefinition.Builder> fields = new ArrayList<>();
private GraphQLObjectType builtObject;
public EntityGQLBuilder(String name, GraphQLBuilder bld) {
this.typeName = name;
this.parent = bld;
this.builder = newObject().name(name);
}
public GraphQLFieldDefinition.Builder addField() {
if (builtObject != null) {
throw new AlreadyBuiltException("This method can not be called after 'build()'-function has been called");
}
GraphQLFieldDefinition.Builder ret = newFieldDefinition();
fields.add(ret);
return ret;
}
public GraphQLFieldDefinition.Builder addField(Class<?> clz) {
return addField()
.type(typeForClass(clz))
.name(clz.getSimpleName().toLowerCase());
}
public GraphQLFieldDefinition.Builder addListField(Class<?> clz) {
return addField()
.type(GraphQLList.list(typeForClass(clz)))
.name((clz.getSimpleName() + "s").toLowerCase());
}
/**
* Add a field to graphql schema from JPA metamodel.
* This function will set a name and DataFetcher to the fieldDefinition builder,
* which then can be overriden from the returned builder, if needed
*
* @param field JPA metamodel field to be added to the graphql schema
* @return Field definition builder, where type, name and data fetcher are set according to the {@param field}
*/
public GraphQLFieldDefinition.Builder addField(Attribute<? super T, ?> field) {
GraphQLOutputType type = typeForClass(field.getJavaType());
if (field instanceof PluralAttribute) {
type = GraphQLList.list(typeForClass(((PluralAttribute) field).getBindableJavaType()));
}
return addField()
.type(type)
.name(field.getName().toLowerCase())
.dataFetcher(new PropertyDataFetcher<>(field.getName()));
}
private GraphQLOutputType typeForClass(Class<?> type) {
if (Boolean.class.isAssignableFrom(type) || boolean.class.isAssignableFrom(type)) {
return GraphQLBoolean;
}
if (Double.class.isAssignableFrom(type) || double.class.isAssignableFrom(type)) {
return GraphQLFloat;
}
if (Byte.class.isAssignableFrom(type) || byte.class.isAssignableFrom(type)) {
return GraphQLByte;
}
if (Character.class.isAssignableFrom(type) || char.class.isAssignableFrom(type)) {
return GraphQLChar;
}
if (Short.class.isAssignableFrom(type) || short.class.isAssignableFrom(type)) {
return GraphQLShort;
}
if (Integer.class.isAssignableFrom(type) || int.class.isAssignableFrom(type)) {
return GraphQLInt;
}
if (Long.class.isAssignableFrom(type) || long.class.isAssignableFrom(type)) {
return GraphQLLong;
}
if (BigInteger.class.isAssignableFrom(type)) {
return GraphQLBigInteger;
}
if (BigDecimal.class.isAssignableFrom(type)) {
return GraphQLBigDecimal;
}
if (String.class.isAssignableFrom(type)) {
return GraphQLString;
}
if (byte[].class.isAssignableFrom(type) || Byte[].class.isAssignableFrom(type)) {
return GraphQLUtils.GRAPHQL_BYTE_TO_BASE64_TYPE;
}
if (Enum.class.isAssignableFrom(type)) {
return parent.getEnum((Class<Enum>) type);
}
if (Date.class.isAssignableFrom(type)
|| Calendar.class.isAssignableFrom(type)
|| OffsetDateTime.class.isAssignableFrom(type)
|| LocalDateTime.class.isAssignableFrom(type)
|| LocalDate.class.isAssignableFrom(type)) {
return GraphQLUtils.GRAPHQL_DATE_TYPE;
}
return parent.typeFor(type);
}
public GraphQLObjectType build() {
if (builtObject == null) {
fields.forEach(f -> builder.field(f));
builtObject = builder.build();
}
return builtObject;
}
public GraphQLObjectType.Builder getRawTypeBuilder() {
return builder;
}
public EntityGQLBuilder<T> description(String s) {
builder.description(s);
return this;
}
public GraphQLType getRef() {
return parent.typeFor(typeName);
}
}
package fi.codecrew.moya.graphql;
public class GRPDException extends RuntimeException {
public GRPDException(String reason) {
super(reason);
}
}
package fi.codecrew.moya.graphql;
import graphql.schema.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.stream.Collectors;
import static graphql.schema.GraphQLEnumType.newEnum;
public class GraphQLBuilder {
private final Map<String, EntityGQLBuilder<?>> entities = new HashMap<>();
private final Map<String, GraphQLEnumType> enums = new HashMap<>();
private final Set<String> uncheckedTypes = new HashSet<>();
private static final Logger logger = LoggerFactory.getLogger(GraphQLBuilder.class);
public <T> EntityGQLBuilder<T> createEntity(Class<T> entityClass) {
return createEntity(entityClass.getSimpleName());
}
public <T> EntityGQLBuilder<T> createEntity(String name) {
EntityGQLBuilder<T> ret = new EntityGQLBuilder<>(name, this);
entities.put(name, ret);
return ret;
}
public Set<GraphQLType> getTypes() {
Set<GraphQLType> ret = new HashSet<>(enums.values());
List<GraphQLObjectType> retEnt = entities.values().stream().map(v -> v.build()).collect(Collectors.toList());
logger.warn("Returning entities", retEnt);
ret.addAll(retEnt);
logger.warn("Enums {}, entities {}", enums, entities);
logger.warn("Builder returning types: {}", ret);
return ret;
}
public GraphQLTypeReference typeFor(String typeName) {
logger.warn("Adding typeFor: {}", typeName);
if (!entities.containsKey(typeName) && !enums.containsKey(typeName)) {
logger.warn("Adding unknown type: this might be an error!"+ typeName, new RuntimeException().fillInStackTrace());
uncheckedTypes.add(typeName);
}
return GraphQLTypeReference.typeRef(typeName);
}
public GraphQLTypeReference typeFor(Class<?> clz) {
return typeFor(clz.getSimpleName());
}
public <X extends Enum> GraphQLOutputType getEnum(Class<X> type) {
String name = type.getSimpleName();
if (name == null) {
throw new NullPointerException("Trying to get enum with type " + type);
}
if (!enums.containsKey(name)) {
GraphQLEnumType.Builder ret = newEnum().name(name);
for (Enum c : type.getEnumConstants()) {
ret.value(c.name());
}
enums.put(name, ret.build());
}
return typeFor(type);
}
}
package fi.codecrew.moya.graphql;
import graphql.schema.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class GraphQLUtils {
public static final GraphQLScalarType GRAPHQL_BYTE_TO_BASE64_TYPE = new GraphQLScalarType("Base64Data", "Binary data in base64 format", new Coercing<byte[], String>() {
@Override
public String serialize(Object dataFetcherResult) throws CoercingSerializeException {
byte[] data = (byte[]) dataFetcherResult;
if (data == null || data.length == 0) {
return "";
}
return Base64.getEncoder().encodeToString(data);
}
@Override
public byte[] parseValue(Object input) throws CoercingParseValueException {
return Base64.getDecoder().decode(input.toString());
}
@Override
public byte[] parseLiteral(Object input) throws CoercingParseLiteralException {
return Base64.getDecoder().decode(input.toString());
}
});
public static final GraphQLScalarType GRAPHQL_DATE_TYPE = new GraphQLScalarType("Date", "Date in ISO-8601 format: yyyymmddThhmmssZ (for example: 2011-12-03T10:15:30Z')", new Coercing<Object, String>() {
@Override
public String serialize(Object dataFetcherResult) throws CoercingSerializeException {
if (dataFetcherResult == null) {
return null;
}
try {
if (dataFetcherResult instanceof Date) {
return Instant
.ofEpochMilli(((Date) dataFetcherResult).getTime())
.atZone(ZoneId.systemDefault())
.toOffsetDateTime()
.format(DateTimeFormatter.ISO_INSTANT);
} else if (dataFetcherResult instanceof Calendar) {
return Instant
.ofEpochMilli(((Calendar) dataFetcherResult).getTime().getTime())
.atZone(ZoneId.systemDefault())
.toOffsetDateTime()
.format(DateTimeFormatter.ISO_INSTANT);
} else if (dataFetcherResult instanceof OffsetDateTime) {
return ((OffsetDateTime) dataFetcherResult).format(DateTimeFormatter.ISO_INSTANT);
} else if (dataFetcherResult instanceof LocalDateTime) {
return ((LocalDateTime) dataFetcherResult).format(DateTimeFormatter.ISO_INSTANT);
} else if (dataFetcherResult instanceof LocalDate) {
return ((LocalDate) dataFetcherResult).format(DateTimeFormatter.ISO_INSTANT);
}
} catch (Exception e) {
throw new CoercingSerializeException("Error converting detected dateformat: " + dataFetcherResult, e);
}
throw new CoercingSerializeException("Unknonw date type " + dataFetcherResult.getClass());
}
@Override
public Object parseValue(Object input) throws CoercingParseValueException {
throw new UnsupportedOperationException("Not yet implemented... TODO... ");
}
@Override
public Object parseLiteral(Object input) throws CoercingParseLiteralException {
throw new UnsupportedOperationException("Not yet implemented... TODO... ");
}
});
}
package fi.codecrew.moya.graphql.util;
import graphql.execution.ExecutionContext;
import graphql.execution.ExecutionId;
import graphql.execution.ExecutionTypeInfo;
import graphql.language.Field;
import graphql.language.FragmentDefinition;
import graphql.schema.*;
import java.util.List;
import java.util.Map;
public class DataFetchingEnvironmentWrapper<SRCT> implements DataFetchingEnvironment {
private final SRCT source;
private final DataFetchingEnvironment env;
public DataFetchingEnvironmentWrapper(DataFetchingEnvironment environment, SRCT source) {
this.env = environment;
this.source = source;
}
@Override
public SRCT getSource() {
return source;
}
@Override
public Map<String, Object> getArguments() {
return env.getArguments();
}
@Override
public boolean containsArgument(String name) {
return env.containsArgument(name);
}
@Override
public <T> T getArgument(String name) {
return env.getArgument(name);
}
@Override
public <T> T getContext() {
return env.getContext();
}
@Override
public <T> T getRoot() {
return env.getRoot();
}
@Override
public GraphQLFieldDefinition getFieldDefinition() {
return env.getFieldDefinition();
}
@Override
public List<Field> getFields() {
return env.getFields();
}
@Override
public Field getField() {
return env.getField();
}
@Override
public GraphQLOutputType getFieldType() {
return env.getFieldType();
}
@Override
public ExecutionTypeInfo getFieldTypeInfo() {
return env.getFieldTypeInfo();
}
@Override
public GraphQLType getParentType() {
return env.getParentType();
}
@Override
public GraphQLSchema getGraphQLSchema() {
return env.getGraphQLSchema();
}
@Override
public Map<String, FragmentDefinition> getFragmentsByName() {
return env.getFragmentsByName();
}
@Override
public ExecutionId getExecutionId() {
return env.getExecutionId();
}
@Override
public DataFetchingFieldSelectionSet getSelectionSet() {
return env.getSelectionSet();
}
@Override
public ExecutionContext getExecutionContext() {
return env.getExecutionContext();
}
}
package fi.codecrew.moya.graphql.util;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import graphql.schema.PropertyDataFetcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.json.JsonObject;
public class JSONPropertyDataFetcher implements DataFetcher<String> {
private static final Logger logger = LoggerFactory.getLogger(JSONPropertyDataFetcher.class);
private final PropertyDataFetcher<JsonObject> fetcher;
private final String[] path;
public JSONPropertyDataFetcher(String field, String... path) {
fetcher = new PropertyDataFetcher<>(field);
this.path = path;
}
@Override
public String get(DataFetchingEnvironment environment) {
JsonObject obj = fetcher.get(environment);
for (int i = 0; i < path.length; ++i) {
if (obj == null || !obj.containsKey(path[i])) {
logger.debug("Json Object null, or key null {}, path {}", obj, path[i] );
return null;
}
if(i + 1 == path.length){
return obj.getString(path[i]);
} else {
obj = obj.getJsonObject(path[i]);
}
}
return null;
}
}
package fi.codecrew.moya.graphql.util;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import graphql.schema.PropertyDataFetcher;
public class PropertyFetchWrapper<T, INNER> implements DataFetcher<T> {
private final DataFetcher<INNER> fetcher;
private final DataFetcher<T> innerFetcher;
public PropertyFetchWrapper(String field, DataFetcher<T> innerFetcher) {
this.fetcher = new PropertyDataFetcher<>(field);
this.innerFetcher = innerFetcher;
}
@Override
public T get(DataFetchingEnvironment environment) {
INNER field = fetcher.get(environment);
return innerFetcher.get(new DataFetchingEnvironmentWrapper(environment, field));
}
}
...@@ -22,7 +22,7 @@ public class PojoFactoryV2 implements Serializable { ...@@ -22,7 +22,7 @@ public class PojoFactoryV2 implements Serializable {
*/ */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public UserPojo createUserPojo(EventUser eventUser) { public static UserPojo createUserPojo(EventUser eventUser) {
User user = eventUser.getUser(); User user = eventUser.getUser();
UserPojo pojo = new UserPojo(); UserPojo pojo = new UserPojo();
pojo.eventuserId = eventUser.getId(); pojo.eventuserId = eventUser.getId();
......
/* /*
* Copyright Codecrew Ry * Copyright Codecrew Ry
* *
* All rights reserved. * All rights reserved.
* *
* This license applies to any software containing a notice placed by the * This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software. * copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software. * This license covers modification, distribution and use of the Software.
* *
* Any distribution and use in source and binary forms, with or without * Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the * modification is not permitted without explicit written permission from the
* copyright owner. * copyright owner.
* *
* A non-exclusive royalty-free right is granted to the copyright owner of the * A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in * Software to use, modify and distribute all modifications to the Software in
* future versions of the Software. * future versions of the Software.
* *
*/ */
package fi.codecrew.moya.web.cdiview.voting; package fi.codecrew.moya.web.cdiview.voting;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!