public static void findAll(Handler<AsyncResult<ChannelInfo[]>> ar)
{
//getConnection().query("SELECT &", arg1)
getConnection().queryWithParams("SELECT * FROM Servers", new JsonObject(), res -> {
if (res.succeeded() && res.result().size() > 0) {
ChannelInfo[] channels = new ChannelInfo[res.result().size()];
int count = 0;
for (JsonObject row : res.result()) {
channels[count++] = new ChannelInfo()
.setId(row.getInteger("srv_id"))
.setName(row.getString("srv_name"))
.setIp(row.getString("srv_ip"))
.setServerDomain(row.getString("srv_domain"))
.setPort(row.getInteger("srv_port"))
.setPosition(row.getInteger("srv_position"))
.setPromiseToFightFlag(row.getBoolean("srv_promise_to_fight_flag"))
.setMoreServerFlag(row.getBoolean("srv_more_server_flag"))
.setMaxRoom(row.getInteger("srv_max_room"))
.setNumber(row.getInteger("srv_number"))
.setAllowedRoomTypeId(row.getInteger("srv_allowed_room_type_id"))
.setLimitMinLV(row.getInteger("srv_limit_min_lv"))
.setLimitMaxLV(row.getInteger("srv_limit_max_lv"))
.setMaxClient(row.getInteger("srv_max_client"));
}
ar.handle(Future.succeededFuture(channels));
} else {
logger.error("Erro ao obter um usuário pelo nome", res.cause());
ar.handle(Future.failedFuture(res.cause()));
}
});
}
error: The method queryWithParams(String, JsonArray, Handler>) in the type SQLConnection is not applicable for the arguments (String, JsonObject, ( res) -> {})
Replace ...
getConnection().queryWithParams("SELECT * FROM Servers", new JsonObject(), res ...
... with:
getConnection().queryWithParams("SELECT * FROM Servers", new JsonArray(), res ...
The method queryWithParams expects the following arguments:
the query string
the query parameters
a handler for dealing with the response
The second argument must be a JsonArray not a JsonObject. In your case you don't appear to be passing in any parameters so supplying an empty JsonArray (e.g. new JsonArray()) should suffice.
Related
What I am trying to accomplish is to return a simple Mono Response.
I am calling different backends API's in the method detailsHandler.fetchDetailsValue
Since this is a Synchronous blocking call, I am wrapping it in Mono.fromCallable as suggested in the documentation.
But I am facing this error upon compiling -
error: local variables referenced from a lambda expression must be final or effectively final
Actually, inside .subscribe lambda I am trying to assign to Response object which is declared outside the lambda. Since I need to assign the object returned from the fetchDetailsValue method upon subscription, how can I return this response object ?
Please correct me if wrong below and suggest how to fix this. Appreciate any inputs. Thanks!
Below is the sample code -
#Override
public Mono<Response> getDetails(Mono<RequestDO> requestDO) {
return requestDO.flatMap(
request -> {
Response response = new Response();
Mono<List<Object>> optionalMono = Mono.fromCallable(() -> {
return detailsHandler.fetchDetailsValue(request);
});
optionalMono. subscribeOn(Schedulers.boundedElastic())
.subscribe(result -> {
Cat1 cat1Object = null;
Cat2 cat2Object = null;
for(Object obj : result) {
if (obj instanceof Cat1) {
cat1Object = (Cat1) obj;
response.addResponseObj(cat1Object); // error: local variables referenced from a lambda expression must be final or effectively final
}
if (obj instanceof Cat2) {
cat2Object = (Cat2) obj;
response.addResponseObj(cat2Object); // error: local variables referenced from a lambda expression must be final or effectively final
}
}
});
return Mono.just(response);
});
}
When I tried to declare that Response object inside subscribe method and tried to return as and when value is received. But getting the error - Void methods cannot return a value
Below is the code -
#Override
public Mono<Response> getDetails(Mono<RequestDO> requestDO) {
return requestDO.flatMap(
request -> {
Mono<List<Object>> optionalMono = Mono.fromCallable(() -> {
return detailsHandler.fetchDetailsValue(request);
});
optionalMono. subscribeOn(Schedulers.boundedElastic())
.subscribe(result -> {
Response response = new Response(); // Added this inside subscribe lambda. But now getting - Void methods cannot return a value
Cat1 cat1Object = null;
Cat2 cat2Object = null;
for(Object obj : result) {
if (obj instanceof Cat1) {
cat1Object = (Cat1) obj;
response.addResponseObj(cat1Object);
}
if (obj instanceof Cat2) {
cat2Object = (Cat2) obj;
response.addResponseObj(cat2Object);
}
}
return Mono.just(response); // Added this inside subscribe lambda. But now getting - Void methods cannot return a value
});
});
}
UPDATE:
When I tried like below, I am getting errors. Please correct if anything I am doing wrong.
public Mono<Response> getDetails(Mono<RequestDO> requestDO) {
return requestDO
.flatMap(request -> Mono.fromCallable(() -> detailsHandler.fetchDetailsValue(request)))
.map(result -> {
Response response = new Response();
for (Object obj : result) {
if (obj instanceof Cat1) {
response.addResponseObj((Cat1) obj);
}
if (obj instanceof Cat2) {
response.addResponseObj((Cat2) obj);
}
}
return response;
})
.map(result1 -> {
Response response = resultnew;
requestDO.flatMap(request -> Mono.fromCallable(() -> detailsHandler.fetchAdditionalValue(request, response)))
.map(result2 -> {
return result2;
});
}
You should not call subscribe inside your Reactor pipeline. Subscribe should be considered a terminal operation that starts the pipeline asynchronously in an unknown time in the future, and should only serve to connect to some other part of your system.
What you want is to transform your List<Object> into a new Response using a simple synchronous function, the map operator is made for this:
public Mono<Response> getDetails(Mono<RequestDO> requestDO) {
return requestDO
.flatMap(request -> Mono.fromCallable(() -> detailsHandler.fetchDetailsValue(request)))
.map(result -> {
Response response = new Response();
for (Object obj : result) {
if (obj instanceof Cat1) {
response.addResponseObj((Cat1) obj);
}
if (obj instanceof Cat2) {
response.addResponseObj((Cat2) obj);
}
}
return response;
});
}
Update
For your updated question you want to use both request and response to call another Mono. You can do this by first pulling the map inside the flatMap, then add another flatMap to it:
public Mono<Response> getDetails(Mono<RequestDO> requestDO) {
return requestDO
.flatMap(request -> Mono.fromCallable(() -> detailsHandler.fetchDetailsValue(request))
.map(result -> {
Response response = new Response();
for (Object obj : result) {
if (obj instanceof Cat1) {
response.addResponseObj((Cat1) obj);
}
if (obj instanceof Cat2) {
response.addResponseObj((Cat2) obj);
}
}
return response;
})
.flatMap(response -> Mono.fromCallable(() -> detailsHandler.fetchAdditionalValue(request, response))));
}
i use spring boot's RedisTemplate with scala, and i write this code:
redisTemplate1.executePipelined(new RedisCallback[String] {
override def doInRedis(connection: RedisConnection): String = {
MyCode......
null
}
}, redisTemplate1.getValueSerializer)
usually, it's can be wrote like this:
redisTemplate1.executePipelined((connection: RedisConnection) => {
MyCode......
null
}, redisTemplate1.getValueSerializer)
and this style is running well in java:
redisTemplate1.executePipelined((RedisConnection conn) -> {
MyCode......
return null;
}, redisTemplate1.getValueSerializer());
but when i compile in this style with scala, i get an error, so why this happend and how can i use single abstract method in this case?
overloaded method value executePipelined with alternatives:
(x$1: org.springframework.data.redis.core.RedisCallback[_],x$2: org.springframework.data.redis.serializer.RedisSerializer[_])java.util.List[Object] <and>
(x$1: org.springframework.data.redis.core.SessionCallback[_],x$2: org.springframework.data.redis.serializer.RedisSerializer[_])java.util.List[Object]
cannot be applied to (org.springframework.data.redis.connection.RedisConnection => Null, org.springframework.data.redis.serializer.RedisSerializer[?0(in method syncSegmentSrc)])
redisTemplate1.executePipelined((connection: RedisConnection) => {
the executePipelined function source code like this:
#Override
public List<Object> executePipelined(SessionCallback<?> session, #Nullable RedisSerializer<?> resultSerializer) {
Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
Assert.notNull(session, "Callback object must not be null");
RedisConnectionFactory factory = getRequiredConnectionFactory();
// bind connection
RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
try {
return execute((RedisCallback<List<Object>>) connection -> {
connection.openPipeline();
boolean pipelinedClosed = false;
try {
Object result = executeSession(session);
if (result != null) {
throw new InvalidDataAccessApiUsageException(
"Callback cannot return a non-null value as it gets overwritten by the pipeline");
}
List<Object> closePipeline = connection.closePipeline();
pipelinedClosed = true;
return deserializeMixedResults(closePipeline, resultSerializer, hashKeySerializer, hashValueSerializer);
} finally {
if (!pipelinedClosed) {
connection.closePipeline();
}
}
});
} finally {
RedisConnectionUtils.unbindConnection(factory);
}
}
#Override
public List<Object> executePipelined(RedisCallback<?> action, #Nullable RedisSerializer<?> resultSerializer) {
return execute((RedisCallback<List<Object>>) connection -> {
connection.openPipeline();
boolean pipelinedClosed = false;
try {
Object result = action.doInRedis(connection);
if (result != null) {
throw new InvalidDataAccessApiUsageException(
"Callback cannot return a non-null value as it gets overwritten by the pipeline");
}
List<Object> closePipeline = connection.closePipeline();
pipelinedClosed = true;
return deserializeMixedResults(closePipeline, resultSerializer, hashKeySerializer, hashValueSerializer);
} finally {
if (!pipelinedClosed) {
connection.closePipeline();
}
}
});
}
In cases like this, it should help to specify the type explicitly:
redisTemplate1.executePipelined({ connection =>
YourCode…
}: RedisCallback[String], redisTemplate1.getValueSerializer)
Note the type ascription : RedisCallback[String].
I have an extension method for ordering, the sortExpression can be something like "Description" or "Description DESC", it is working perfectly for columns at the same table:
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string sortExpression)
{
if (source == null)
throw new ArgumentNullException("source");
if (string.IsNullOrEmpty(sortExpression))
return source;
var parts = sortExpression.Split(' ');
var isDescending = false;
var propertyName = "";
var type = typeof(T);
if (parts.Length > 0 && parts[0] != "")
{
propertyName = parts[0];
if (parts.Length > 1)
isDescending = parts[1].ToLower().Contains("esc");
var prop = type.GetProperty(propertyName);
if (prop == null)
throw new ArgumentException(string.Format("No property '{0}' on type '{1}'", propertyName, type.Name));
var funcType = typeof(Func<,>)
.MakeGenericType(type, prop.PropertyType);
var lambdaBuilder = typeof(Expression)
.GetMethods()
.First(x => x.Name == "Lambda" && x.ContainsGenericParameters && x.GetParameters().Length == 2)
.MakeGenericMethod(funcType);
var parameter = Expression.Parameter(type);
var propExpress = Expression.Property(parameter, prop);
var sortLambda = lambdaBuilder
.Invoke(null, new object[] { propExpress, new ParameterExpression[] { parameter } });
var sorter = typeof(Queryable)
.GetMethods()
.FirstOrDefault(x => x.Name == (isDescending ? "OrderByDescending" : "OrderBy") && x.GetParameters().Length == 2)
.MakeGenericMethod(new[] { type, prop.PropertyType });
var result = (IQueryable<T>)sorter
.Invoke(null, new object[] { source, sortLambda });
return result;
}
return source;
}
Working Example:
var query = db.Audit.Include("AccessLevel").AsQueryable();
query = query.OrderBy("Description");
Please note that the "Description" column exists at the same table "Audit".
What I'm trying to do is to sort by a column in a relation table:
Like the following
var query = db.Audit.Include("AccessLevel").AsQueryable();
query = query.OrderBy("AccessLevel.Name");
Which is equivalent to:
query = query.OrderBy(o => o.AccessLevel.Name);
What is the required modification on my extension method ?
I solved it by using the following code:
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string property)
{
return ApplyOrder<T>(source, parts[0], "OrderBy");
}
public static IQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string property)
{
return ApplyOrder<T>(source, property, "OrderByDescending");
}
public static IQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string property)
{
return ApplyOrder<T>(source, property, "ThenBy");
}
public static IQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string property)
{
return ApplyOrder<T>(source, property, "ThenByDescending");
}
static IQueryable<T> ApplyOrder<T>(IQueryable<T> source, string property, string methodName)
{
if (source == null)
throw new ArgumentNullException("source");
if (string.IsNullOrEmpty(property))
return source;
string[] props = property.Split('.');
Type type = typeof(T);
ParameterExpression arg = Expression.Parameter(type, "x");
Expression expr = arg;
foreach (string prop in props)
{
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);
object result = typeof(Queryable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), type)
.Invoke(null, new object[] { source, lambda });
return (IQueryable<T>)result;
}
I've Been Trying to change the order of nodes through quickfix, but something is wrong.
Here's my code in xtend:
#Fix(org.xtext.custom.conventions.validation.ConventionsValidator::CONVENTION_NOT_ORDERED)
def fixFeatureName( Issue issue, IssueResolutionAcceptor acceptor){
acceptor.accept(issue, 'Sort', "Sort '" + issue.data.head + "'", null)[
element, context |
var gr=(element as Greeting)
if (gr.name === null || gr.name.length === 0)
return;
var econt=gr.eContainer.eContents
var comparator = [ EObject obj1, EObject obj2 |
var o1 = (obj1 as Greeting)
var o2 = (obj2 as Greeting)
return o1.name.compareTo(o2.name)
]
ECollections::sort(econt, comparator)
]
}
No exception is being thrown to console, in debug I found an UnsupportedOperationException is thrown and handled by xtext.
I suspect that EList is immutable.
So how can I sort the AST?
(Here is the generated code: )
#Fix(ConventionsValidator.CONVENTION_NOT_ORDERED)
public void fixFeatureName(final Issue issue, final IssueResolutionAcceptor acceptor) {
String[] _data = issue.getData();
String _head = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(_data)));
String _plus = ("Sort \'" + _head);
String _plus_1 = (_plus + "\'");
final ISemanticModification _function = new ISemanticModification() {
public void apply(final EObject element, final IModificationContext context) throws Exception {
Greeting gr = ((Greeting) element);
boolean _or = false;
String _name = gr.getName();
boolean _tripleEquals = (_name == null);
if (_tripleEquals) {
_or = true;
} else {
String _name_1 = gr.getName();
int _length = _name_1.length();
boolean _tripleEquals_1 = (Integer.valueOf(_length) == Integer.valueOf(0));
_or = (_tripleEquals || _tripleEquals_1);
}
if (_or) {
return;
}
EObject _eContainer = gr.eContainer();
EList<EObject> econt = _eContainer.eContents();
final Function2<EObject,EObject,Integer> _function = new Function2<EObject,EObject,Integer>() {
public Integer apply(final EObject obj1, final EObject obj2) {
Greeting o1 = ((Greeting) obj1);
Greeting o2 = ((Greeting) obj2);
String _name = o1.getName();
String _name_1 = o2.getName();
return _name.compareTo(_name_1);
}
};
Function2<EObject,EObject,Integer> comparator = _function;
final Function2<EObject,EObject,Integer> _converted_comparator = (Function2<EObject,EObject,Integer>)comparator;
ECollections.<EObject>sort(econt, new Comparator<EObject>() {
public int compare(EObject o1,EObject o2) {
return _converted_comparator.apply(o1,o2);
}
});
}
};
acceptor.accept(issue, "Sort", _plus_1, null, _function);
}
thanks!
Sorting a temporary collection which will then replace econt didn't work. but I managed to solve it in a different way.
so one solution was to force a cast of eContainer as it's runtime element (which is Model), and then getting a list with it's getGreetings getter, and with that element the sorting works, but I didn't want to involve non-generic code, for technical reasons.
So after a lot of experiments I finally found that element without involving any other elements or keywords from the grammar:
var econt = (gr.eContainer.eGet(gr.eContainingFeature) as EObjectContainmentEList<Greeting>)
and that is exactly what was looking for. Sorting is successful!
Here's the resulting Xtend code (got rid of casing in the comperator as well):
#Fix(ConventionsValidator::CONVENTION_NOT_ORDERED)
def fixFeatureName(Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, 'Sort', "Sort '" + issue.data.head + "'", null) [
element, context |
var gr = (element as Greeting)
if (gr.name === null || gr.name.length === 0)
return;
var econt = (gr.eContainer.eGet(gr.eContainingFeature) as EObjectContainmentEList<Greeting>)
var comparator = [ Greeting o1, Greeting o2 |
return o1.name.compareTo(o2.name)
]
ECollections::sort(econt, comparator)
]
}
and the generated java:
#Fix(ConventionsValidator.CONVENTION_NOT_ORDERED)
public void fixFeatureName(final Issue issue, final IssueResolutionAcceptor acceptor) {
String[] _data = issue.getData();
String _head = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(_data)));
String _plus = ("Sort \'" + _head);
String _plus_1 = (_plus + "\'");
final ISemanticModification _function = new ISemanticModification() {
public void apply(final EObject element, final IModificationContext context) throws Exception {
Greeting gr = ((Greeting) element);
boolean _or = false;
String _name = gr.getName();
boolean _tripleEquals = (_name == null);
if (_tripleEquals) {
_or = true;
} else {
String _name_1 = gr.getName();
int _length = _name_1.length();
boolean _tripleEquals_1 = (Integer.valueOf(_length) == Integer.valueOf(0));
_or = (_tripleEquals || _tripleEquals_1);
}
if (_or) {
return;
}
EObject _eContainer = gr.eContainer();
EStructuralFeature _eContainingFeature = gr.eContainingFeature();
Object _eGet = _eContainer.eGet(_eContainingFeature);
EObjectContainmentEList<Greeting> econt = ((EObjectContainmentEList<Greeting>) _eGet);
final Function2<Greeting,Greeting,Integer> _function = new Function2<Greeting,Greeting,Integer>() {
public Integer apply(final Greeting o1, final Greeting o2) {
String _name = o1.getName();
String _name_1 = o2.getName();
return _name.compareTo(_name_1);
}
};
Function2<Greeting,Greeting,Integer> comparator = _function;
final Function2<Greeting,Greeting,Integer> _converted_comparator = (Function2<Greeting,Greeting,Integer>)comparator;
ECollections.<Greeting>sort(econt, new Comparator<Greeting>() {
public int compare(Greeting o1,Greeting o2) {
return _converted_comparator.apply(o1,o2);
}
});
}
};
acceptor.accept(issue, "Sort", _plus_1, null, _function);
}
Thanks.
public class ParameterNameConvention extends AbstractJavaRule {
private final static String PATTERN = "[p][a-zA-Z]+";
public Object visit(ASTMethodDeclaration node, Object data) {
RuleContext result = (RuleContext) data;
String rulePattern = (!getStringProperty("rulePattern")
.equalsIgnoreCase("")) ? getStringProperty("rulePattern")
: PATTERN;
if (node.containsChildOfType(ASTFormalParameter.class)) {
Iterator iterator = node.findChildrenOfType(
ASTFormalParameter.class).iterator();
while (iterator.hasNext()) {
ASTFormalParameter element = (ASTFormalParameter) iterator
.next();
Iterator decIdIterator = element.findChildrenOfType(
ASTVariableDeclaratorId.class).iterator();
while (decIdIterator.hasNext()) {
ASTVariableDeclaratorId decElement = (ASTVariableDeclaratorId) decIdIterator
.next();
if (!decElement.getImage().matches(rulePattern)) {
result.getReport()
.addRuleViolation(
new RuleViolation(
this,
node.getBeginLine(),
"Parameter '"
+ decElement.getImage()
+ "' should match regular expression pattern '"
+ rulePattern + "'",
result));
}
}
}
}
return result;
}
}
For the new RuleViolation there is a problem:
The constructor RuleViolation(ParameterNameConvention, int, String, RuleContext) is undefined
Why?
What version of PMD are you using? IN PMD 4.2.5, the constructors for RuleViolation are:
RuleViolation(Rule rule, RuleContext ctx, SimpleNode node)
RuleViolation(Rule rule, RuleContext ctx, SimpleNode node, java.lang.String specificMsg)
Your code doesn't match either of these.