Expecting top level declaration error on top level declaration - kotlin

I'm new to Kotlin, and, man, it's awesome!
I'm creating a Discord bot with it using JDA & Maven, it works, but, I created a basic command handler, and now, I get a lot of errors saying "Expecting top level declaration" on a top level declaration. 🤔
Here is my code (btw, I already found that Array<String?> error):
package com.blueslimee.kirani.listeners
import net.dv8tion.jda.core.entities.*
import net.dv8tion.jda.core.hooks.*
import net.dv8tion.jda.core.JDA
import net.dv8tion.jda.core.events.message.MessageReceivedEvent
import com.blueslimee.kirani.utils.KiraniLogging
import com.blueslimee.kirani.KiraniCommand
import com.blueslimee.kirani.utils.Registry
class MessageListener() : ListenerAdapter() {
override fun onMessageReceived (event: MessageReceivedEvent) {
val jda: JDA = event.getJDA()
// todo: cmds guild-only event.isFromType(ChannelType.TEXT)
if (!event.getAuthor().isBot()) {
var msgContent: String? = event.getMessage()
if (msgContent === null) {
return
}
var args: Array<String?> = msgContent!!.split(" ")
var firstArg: String? = args[0]
if (!firstArg!!.startsWith("k-", true)) {
return
}
firstArg = firstArg!!.replace("k-", "", true)
var cmde: KiraniCommand? = Registry.getCommand(firstArg)
if (cmde != null) {
try {
cmde!!.run(jda, event, args)
} catch (e: Exception) {
event.getChannel().sendMessage("Oopsie Woopsie, um erro ocorreu! Meu dono já foi reportado sobre, peço que aguarde.").queue()
e.printStackTrace()
}
}
}
}
}
Thanks!

Use
var args: List<String> = msgContent.split(" ").toList()
instead of
var args: Array<String?> = msgContent!!.split(" ")

Related

How to validate error body in Webflux/Webclient

I have a handler method for an endpoint, that is this one:
public Mono<ServerResponse> create(ServerRequest serverRequest) {
Validator validator = new CreateUserValidator();
Mono<UserDto> userDtoMono = serverRequest.bodyToMono(UserDto.class);
return userDtoMono.flatMap(user ->
{
Errors errors = new BeanPropertyBindingResult(user, UserDto.class.getName());
validator.validate(user, errors);
if (errors == null || errors.getAllErrors().isEmpty()) {
return userService.create(user).flatMap(aa -> ServerResponse.status(HttpStatus.CREATED)
.contentType(MediaType.APPLICATION_JSON).body(fromValue(aa))).onErrorResume(this::handleException);
} else {
Set<String> errors1 = new HashSet<String>();
errors.getAllErrors().forEach(message -> {
errors1.add(message.getDefaultMessage());
});
return handleException(new InvalidAttributesException(errors1));
}
});
}
private Mono<ServerResponse> handleException(Throwable exception) {
ErrorResponse errorResponse = new ErrorResponse();
if (exception instanceof InvalidAttributesException) {
InvalidAttributesException asd = (InvalidAttributesException) exception;
asd.getErrors().forEach(error ->
errorResponse.addMessage(messagesService.getMessage(error)));
} else {
errorResponse.addMessage(messagesService.getMessage(exception.getMessage()));
}
logger.info("Error:" + errorResponse);
return ServerResponse.status(HttpStatus.BAD_REQUEST).body(fromValue(errorResponse));
}
As you can see, if the validator fails, the method return a bad request error with a ErrorResponse as a body.
I use a WebClient in order to test it. The WebClient has a filter to get the ErrorResponse in case of a error status:
WebClient client = WebClient.builder().clientConnector(new
ReactorClientHttpConnector(HttpClient.create(ConnectionProvider.newConnection()))).filter(ExchangeFilterFunction.ofResponseProcessor(clientResponse ->
{
if (clientResponse.statusCode().isError()){
return clientResponse.bodyToMono(ErrorResponse.class).flatMap(errorResponse ->
Mono.error(new InvalidAttributesException(new HashSet<>(errorResponse.getMessages())))
);
}
return Mono.just(clientResponse);
})).baseUrl("http://localhost:8080").build();
Mono<ErrorResponse> response = (Mono<ErrorResponse>) client.post().uri(thingsEndpoint(url)).accept( MediaType.APPLICATION_JSON ).body(Mono.just(userDto),UserDto.class).ti
.exchange();
response.subscribe(as -> {
List<String> expectedMessages = new ArrayList<>();
expectedMessages.add("name is mandatory");
expectedMessages.add("email is mandatory");
assertTrue(as.getMessages().containsAll(expectedMessages));
});
But it doesn't work. When I debug the test, it seems that when the exchange() method is called returns an exception before calling the endpoint. What am I doing bad?

org.apache.fop.fo.flow.ExternalGraphic catches and logs ImageException I want to handle myself

I am transforming an Image into pdf for test purposes.
To ensure that the Image is compatible with the printing process later on, I'm running a quick test print during the upload.
I'm creating a simple Test-PDF with a transformer. When I try to print an image with an incompatible format, the ImageManager of the transformer throws an ImageException, starting in the preloadImage() function:
public ImageInfo preloadImage(String uri, Source src)
throws ImageException, IOException {
Iterator iter = registry.getPreloaderIterator();
while (iter.hasNext()) {
ImagePreloader preloader = (ImagePreloader)iter.next();
ImageInfo info = preloader.preloadImage(uri, src, imageContext);
if (info != null) {
return info;
}
}
throw new ImageException("The file format is not supported. No ImagePreloader found for "
+ uri);
}
throwing it to:
public ImageInfo needImageInfo(String uri, ImageSessionContext session, ImageManager manager)
throws ImageException, IOException {
//Fetch unique version of the URI and use it for synchronization so we have some sort of
//"row-level" locking instead of "table-level" locking (to use a database analogy).
//The fine locking strategy is necessary since preloading an image is a potentially long
//operation.
if (isInvalidURI(uri)) {
throw new FileNotFoundException("Image not found: " + uri);
}
String lockURI = uri.intern();
synchronized (lockURI) {
ImageInfo info = getImageInfo(uri);
if (info == null) {
try {
Source src = session.needSource(uri);
if (src == null) {
registerInvalidURI(uri);
throw new FileNotFoundException("Image not found: " + uri);
}
info = manager.preloadImage(uri, src);
session.returnSource(uri, src);
} catch (IOException ioe) {
registerInvalidURI(uri);
throw ioe;
} catch (ImageException e) {
registerInvalidURI(uri);
throw e;
}
putImageInfo(info);
}
return info;
}
}
throwing it to :
public ImageInfo getImageInfo(String uri, ImageSessionContext session)
throws ImageException, IOException {
if (getCache() != null) {
return getCache().needImageInfo(uri, session, this);
} else {
return preloadImage(uri, session);
}
}
Finally it gets caught and logged in the ExternalGraphic.class:
/** {#inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
src = pList.get(PR_SRC).getString();
//Additional processing: obtain the image's intrinsic size and baseline information
url = URISpecification.getURL(src);
FOUserAgent userAgent = getUserAgent();
ImageManager manager = userAgent.getFactory().getImageManager();
ImageInfo info = null;
try {
info = manager.getImageInfo(url, userAgent.getImageSessionContext());
} catch (ImageException e) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageError(this, url, e, getLocator());
} catch (FileNotFoundException fnfe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageNotFound(this, url, fnfe, getLocator());
} catch (IOException ioe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageIOError(this, url, ioe, getLocator());
}
if (info != null) {
this.intrinsicWidth = info.getSize().getWidthMpt();
this.intrinsicHeight = info.getSize().getHeightMpt();
int baseline = info.getSize().getBaselinePositionFromBottom();
if (baseline != 0) {
this.intrinsicAlignmentAdjust
= FixedLength.getInstance(-baseline);
}
}
}
That way it isn't accessible for me in my code that uses the transformer.
I tried to use a custom ErrorListener, but the transformer only registers fatalErrors to the ErrorListener.
Is there any way to access the Exception and handle it myself without changing the code of the library?
It was easier than I thought. Before I call the transformation I register a costum EventListener to the User Agent of the Fop I'm using. This Listener just stores the Information what kind of Event was triggered, so I can throw an Exception if it's an ImageError.
My Listener:
import org.apache.fop.events.Event;
import org.apache.fop.events.EventListener;
public class ImageErrorListener implements EventListener
{
private String eventKey = "";
private boolean imageError = false;
#Override
public void processEvent(Event event)
{
eventKey = event.getEventKey();
if(eventKey.equals("imageError")) {
imageError = true;
}
}
public String getEventKey()
{
return eventKey;
}
public void setEventKey(String eventKey)
{
this.eventKey = eventKey;
}
public boolean isImageError()
{
return imageError;
}
public void setImageError(boolean imageError)
{
this.imageError = imageError;
}
}
Use of the Listener:
// Start XSLT transformation and FOP processing
ImageErrorListener imageListener = new ImageErrorListener();
fop.getUserAgent().getEventBroadcaster().addEventListener(imageListener);
if (res != null)
{
transformer.transform(xmlDomStreamSource, res);
}
if(imageListener.isImageError()) {
throw new ImageException("");
}
fop is of the type Fop ,xmlDomStreamSource ist the xml-Source I want to transform and res is my SAXResult.

How to render a StreamObserver in WebUI (ktor + freemarker)

How to handle the output of a StreamObserver in freemarker ?
I have the following controller code so as to subscribe to a stream channel.
else -> {
try {
//jsonResponse = gnhc.getRequestJsonOutput(pathlist,pretty = true)
jsonResponseRaw = gnhc.subscribev1(pathlist, subId, writer).toString()
jsonResponse = jsonResponseRaw
application.log.debug("SDN_JSON_PROCESSOR: ${jsonResponse}")
} catch (e: Exception) {
jsonResponse = e.toString()
application.log.error("Failed to set channel", e)
} finally {
gnhc.shutdownNow()
}
}
}
call.respond(FreeMarkerContent("subscribe.ftl", mapOf("hostname" to hostname, "port" to port, "cmd" to cmd, "result" to jsonResponse,"rawresult" to jsonResponseRaw, "pathlist" to pathlist, "error" to error), etag = "e"))
}
The Observer is declared here:
try {
// simple observer without writer and subId
val sr: StreamObserver<Gnmi.SubscribeRequest> = stub.subscribe(GnmiStreamObserver(this))
// Writer + Id
//val sr: StreamObserver<Gnmi.SubscribeRequest> = stub.subscribe(StreamResponseWriter(_path,_id,_writer))
sr.onNext(subRequest)
waitCompleted()
sr.onCompleted()
}

Unable to initialize AdaptersAPI Object in MobileFirst V8.0 adapter which is leading to NullPointerException

I am developing the adapter in MFP V8. Below is my code to validate username and password:
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import com.ibm.mfp.adapter.api.AdaptersAPI;
import com.ibm.mfp.adapter.api.ConfigurationAPI;
import com.ibm.mfp.security.checks.base.UserAuthenticationSecurityCheck;
import com.ibm.mfp.server.registration.external.model.AuthenticatedUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
#Api(value = "Sample Adapter Resource")
#Path("/resource")
public class UserValidationSecurityCheck extends UserAuthenticationSecurityCheck{
private String displayName;
private String errorMsg;
private HashMap<String,Object> adapterReponse = null;
#Context
AdaptersAPI adaptersAPI;
#Override
protected AuthenticatedUser createUser() {
return new AuthenticatedUser(displayName, displayName, this.getName(),adapterReponse);
}
#Override
protected boolean validateCredentials(Map<String, Object> credentials) {
if(credentials!=null && credentials.containsKey("username") && credentials.containsKey("password")){
if (credentials.get("username")!=null && credentials.get("password")!=null) {
String username = credentials.get("username").toString();
String password = credentials.get("password").toString();
if (username.equals(password)) {
JSONObject loginParams = new JSONObject();
loginParams.put("username", username);
loginParams.put("password", password);
HttpUriRequest httpUriRequest = adaptersAPI.createJavascriptAdapterRequest("LoginAndWeeklyCertAdapter1", "login", loginParams);
try {
HttpResponse httpResponse = adaptersAPI.executeAdapterRequest(httpUriRequest);
adapterReponse = adaptersAPI.getResponseAsJSON(httpResponse);
System.out.println(adapterReponse.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
} else {
errorMsg = "Wrong Credentials";
}
}
}
else{
errorMsg = "Credentials not set properly";
}
return false;
}
public boolean isLoggedIn(){
return getState().equals(STATE_SUCCESS);
}
public AuthenticatedUser getRegisteredUser() {
return registrationContext.getRegisteredUser();
}
#Override
protected Map<String, Object> createChallenge() {
Map<String, Object> challenge = new HashMap<String, Object>();
challenge.put("errorMsg", errorMsg);
challenge.put("remainingAttempts", getRemainingAttempts());
return challenge;
}
#ApiOperation(value = "Returns 'Hello from resource'", notes = "A basic example of a resource returning a constant string.")
#ApiResponses(value = { #ApiResponse(code = 200, message = "Hello message returned") })
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getResourceData() {
// log message to server log
logger.info("Logging info message...");
return "Hello from resource";
}
}
When I am submitting the challenge answer I am getting NullPointerException in following line:
HttpUriRequest httpUriRequest = adaptersAPI.createJavascriptAdapterRequest("LoginAndWeeklyCertAdapter1", "login");
because adaptersAPI is null. Do I have to do any extra configuration in order to make that work? How can I initialize AdaptersAPI object?
Note: The login method and the security check both are in same adapter.
Update
I investigated more of time into it and updated the code to given above and observed the following:
1. When validateCredentials() is getting called after submitting the challenge response then I am getting null value in AdapterAPI object.
2. Where as, when I am calling the getResourceData() using the mobilefirst swagger tool then I am getting an object of AdapterAPI.
We cannot inject the adapters API into a security check object(by design - not a bug). The only way we can go is to extract the logic from Adapter into a Java code, without using adapters API.

Reload Lucene Suggester Index

How do I store and reload a Lucene suggester index?
This is how a build a Suggester index:
def buildAutoCompleteIndex(path:Path, data:List[Map[String,Any]])
:BlendedInfixSuggester = {
val directory = FSDirectory.open(path)
val autoComplete = new BlendedInfixSuggester(directory, new StandardAnalyzer())
autoComplete.build(new EntityIteratorStub())
data.map { d =>
autoComplete.add(d("text").asInstanceOf[BytesRef],
d("contexts").asInstanceOf[Set[BytesRef]],
d("weight").asInstanceOf[Long],
d("payload").asInstanceOf[BytesRef])
}
autoComplete.refresh
autoComplete
}
However, if I try to check if the index exists on, say, server restart, I get a "suggester was not built" exception.
def checkIfIndexExists(path:Path):BlendedInfixSuggester = {
val directory = FSDirectory.open(path)
val autoComplete = new BlendedInfixSuggester(directory, new StandardAnalyzer())
try {
// exception occurs here ->
if (autoComplete.lookup("a", 1, true, false).length > 0) autoComplete
else null
} catch {
case NonFatal(e) => {
println("Index does not exist, recreating at " + path)
null
}
}
}
Edit ==========================
Found this in Lucene AnalyzingInfixSuggester:
#Override
public boolean store(DataOutput in) throws IOException {
return false;
}
#Override
public boolean load(DataInput out) throws IOException {
return false;
}
Does this mean that storing-reloading of Suggester indexes cannot be done?
Using commit solved the problem.
def checkIfIndexExists(path:Path):BlendedInfixSuggester = {
val directory = FSDirectory.open(path)
val autoComplete = new BlendedInfixSuggester(directory, new StandardAnalyzer())
try {
if (autoComplete.getCount > 0) autoComplete
else null
} catch {
case NonFatal(e) => null
}
}
def buildAutoCompleteIndex(path:Path, data:List[Map[String,Any]])
:BlendedInfixSuggester = {
val directory = FSDirectory.open(path)
val autoComplete = new BlendedInfixSuggester(directory, new StandardAnalyzer())
// Just build a stub iterator to get started with
autoComplete.build(new EntityIteratorStub())
data.map { d =>
autoComplete.add(d("text").asInstanceOf[BytesRef],
d("contexts").asInstanceOf[Set[BytesRef]],
d("weight").asInstanceOf[Long],
d("payload").asInstanceOf[BytesRef])
}
autoComplete.refresh
autoComplete.commit
autoComplete
}