I want to add an ImageCell in a CellTable. my code is the following:
Column<Message, String> myColumn = new Column<Message, String>(new ImageCell()) {
#Override
public String getValue(Message details) {
Image image = new Image (ClientResources.of().image1());
return image.getUrl();
}
};
It shows the following warnning when I run it:
[WARN] [adminportal] - Template with variable in URL attribute context: The template code generator cannot guarantee HTML-safety of the template -- please inspect manually or use SafeUri to specify arguments in a URL attribute context
My question is that how I can return the url as string value safely. I saw an example about using imagecell before and the return value is string. I cannot find it now. Could anyone tell me how to fix this.
Note: I just want to know how to fix this if I want to use imagecell in celltable and return value is string. I know how to use imageresourcecell to achieve the same goal. Also, I know I can change the type of getValue() from string to safeHtml to achieve the goal. But i am really wondering how to achieve this by using imagecell and string type of getValue() because I saw an example about this before and I tried it successfully. Just cannot remember what I did wrong here.
There's no way to fix this (remove the warning): using a String as part of a template is inherently unsafe, and GWT warns you about it. If you're absolutely certain of the safety of your values, then you can safely ignore the warnings, but they'll still be emitted.
The only way to not have those warnings is to use a SafeUri, i.e. use the SafeImagecell. It's then up to you to guarantee the safety of your URL, depending on the method you use to construct the SafeUri (have a look at UriUtils)
Related
In the context of using the OWLAPI 4.0 API, this following line of code:
ontologyIRI = IRI.create(o.getOntologyID().getOntologyIRI().toString());
returns the following string :
"Optional.of(http://www.indytion.com/music/composition)".
What I need is the sole string "http://www.indytion.com/music/composition".
I tried to declare ontologyIRI as Optional and use .get() method, .orElse(), etc. to no avail. I still have the returned string that includes the 'optional.of()' part.
My question is : How could I get the internal string?
Thank you very much for your help.
Edit : The full code the method
private void LoadOntology(String ontologyPath)
{
OWLOntologyManager man = OWLManager.createOWLOntologyManager();
OWLOntology o;
File ontologyFile = new File(ontologyPath);
Optional<IRI> ontologyIRI;
try {
o = man.loadOntologyFromOntologyDocument(ontologyFile);
ontologyIRI = Optional.of(IRI.create(String.valueOf(o.getOntologyID().getOntologyIRI()).toString()));
System.out.println("Ontology IRI is: " + ontologyIRI.get());
} catch (OWLOntologyCreationException e) {
e.printStackTrace();
}
}
The System.out.println() returns exactly this string:
"Ontology IRI = Optional.of(http://www.indytion.com/music/composition)"
Use .get() instead of toString()
//Returns 'Optional[example]'
Optional.of("example").toString();
//Returns 'example'
Optional.of("example").get();
Short answer: Replace
Optional.of(IRI.create(String.valueOf(o.getOntologyID().getOntologyIRI()).toString()));
with
o.getOntologyID().getOntologyIRI().get();
Longer answer: you're doing an awful lot of back-and forth that's pointless at best and actively harmful in some cases:
In no particular order:
others have already commented that IRI instances are immutable, so creating a new one from an existing one is kind of pointless (if harmless).
calling Optional.of() if you don't intend to actually return an Optional is almost always a bad idea.
String.valueOf() is used to get a string-representation of some value and is usually most useful for debugging, but should not be relied on to fully round-trip everything about an object (the same applies to toString().
So basically what you're left with is this:
o.getOntologyID().getOntologyIRI() gives you an Optional<IRI>
you want an IRI.
Optional::get returns the value contained in the optional, if one exists, so you simply need to call get()
If, however the Optional is empty (i.e. there is no underlying value) then get() will throw a NoSuchElementException. This might or might not be what you want. To work around this either call isPresent() before calling get() to check if a value exists or use any of the multitude of other accessor methods, some of which have "built-in checks" in a way.
Finally, it seems that the problem was not the code itself. This is how the problem has been solved. But I don't understand why it has been solved :
I copy/paste (in the same file) the "shouldAddObjectPropertyAssertions()" example from OWLAPI4 examples -> This example code runs OK (but does not use the getOntologyID() method as I do).
Change SDKs to another minor version '1.8.0_61'
Change again with initial and desired SDK '1.8.0_131'
Invalidate caches and restart the IDE
Problem solved. The exactly same code :
ontologyIRI = o.getOntologyID().getOntologyIRI().get();
System.out.println("Ontology IRI is: " + ontologyIRI);
Now returns the expected string value : "http://www.indytion.com/music/composition" and not "Optional.of(http://www.indytion.com/music/composition)" anymore.
If someone can explain why it has been fixed, I would be very glad.
Thank you again for your help.
I'm trying to set a string to receive a value from other elements. I'm currently using selenium java. I don't understand why I get NullPointerException.
The method used for setString is that,
public void setString(String name, String value) {
this.configuration.setString(name, value);
}
Basically, this method set using HashMaps.
But when I use debug mode on IntelliJ
element(EXAMPLE_1).getText()
I get that:
That's the string that I want to save.
But when I do :
setString(VAR_EXAMPLE, Selenium.getInstance().getCurrentDriver()
.findElements(By.xpath(EXAMPLE_1)).getText())
I get this error
Can anyone help me out? Really appreciate :)
Can you try with findElement instead of findElements, get Text is only applicable on particular element not on all elements
.findElement(By.xpath(EXAMPLE_1)).getText())
I migrating a Vaadin 8 project to Vaadin 14 and i try to show HTML in a grid column.
I figured out, that i have to use a TemplateRenderer, but how can i use it?
Here is the code from Vaadin 8:
grid.addColumn(e -> {
return ((Data) e).getValues()[index];
}).setCaption(myCaption).setRenderer(new HtmlRenderer());
In Vaadin 14 i did this:
gird.addColumn(e -> {
return TemplateRenderer.<Data>of((String) e.getValues()[index])
}).setHeader(myCaption);
e.getValues()[index] includes HTML, for example: <FONT SIZE = 4 COLOR = BLACK> ⚫</FONT>
In Vaadin 14 it always returns com.vaadin.flow.data.renderer.
Before we get to how to use a TemplateRenderer with Grid, I first need to point out that what you're trying to do is potentially dangerous because of the way it can lead to XSS vulnerabilities if the HTML strings that you want to show may be supplied by application users.
Using the Html component is indeed one potential solution to this problem, but it causes some overhead because there will be one component instance in memory for each row in the grid. There's also the same problem with potentially causing XSS vulnerabilities.
The first thing to notice with TemplateRenderer is that the renderer needs to be supplied directly as a parameter to addColumn. Wrapping it in a lambda will instead use that lambda as a value provider, which means that the toString() value of the renderer instance will be used with the default plain text renderer.
All rows should use the same renderer instance, configured with the same template string. The trick is that you can pass the data to show as a per-row property that the template will render for you. The last piece of the puzzle is that the template syntax tries to protect you against accidental XSS vulnerabilities, so you need to use a slightly contrived syntax to actually make it render the data as HTML.
Putting everything together, and also using JSoup to remove any dangerous stuff from your HTML strings, the working solution looks like this:
grid.addColumn(TemplateRenderer
.<Data> of("<div inner-h-t-m-l='[[item.html]]'></div>")
.withProperty("html", e -> {
String unsafeHtml = e.getValues()[index];
String safeHtml = Jsoup.clean(unsafeHtml, Whitelist.basic());
return safeHtml;
})).setHeader(myCaption);
I found a solution.
Instead of using the TemplateRenderer I used a ComponentRenderer.
The migration documentation recomented to use a TempleteRenderer or an ComponentRenderer instead of the htmlRenderer.
https://vaadin.com/docs/v14/flow/migration/8-migration-example.html#step-4-product-grid
Here is the code that worked for me:
grid.addColumn(new ComponentRenderer<>(e -> {
String value = (String) e.getValues()[index];
return new Html(value);
})).setHeader(String.valueOf(col + 1));
Comparing your attempts with TemplateRenderer and the documentation, I would assume it will have to look like this:
grid.addColumn(e ->
TemplateRenderer.<Data>of("[[item.customValue]]")
.withProperty("customValue", (String) e.getValues()[index])
).setHeader(myCaption);
I recently got a report that a few Google Analytics event category names were being recorded with an i character with out a dot on top.
Pageviews and events occurring twice, once without dots over the i.
I had to look to believe it. Sure enough, I had an event called favorite and there was a handful called favorıte. Copy and paste that weird character into a terminal or a monospace font just to see how weird it is. favorıte
My first suspicion is my code where I generate the strings for the category names using toString on an enum.
public enum AnalyticsEvent {
SCREEN_VIEW,
FAVORITE,
UN_FAVORITE,
CLICK_EVENT,
... reduced for brevity;
public String val() {
return this.toString().toLowerCase();
}
}
Example of how that enum is used:
#Override
public void logSearchTag(String type, String value) {
...
logGAEvent(AnalyticsEvent.SEARCH_TAG.val(), type, value);
}
private void logGAEvent(String category, String action, String label) {
... // mGATracker = instance of com.google.android.gms.analytics.Tracker;
mGATracker.send(addCustomDimensions(new HitBuilders.EventBuilder()
.setCategory(category)
.setAction(action)
.setLabel(label))
.build());
...
}
I am going to solve this by actually assigning a string to the enums and instead return that in the val() function.
Though, I am curious if anyone knows why on a small handful of devices Enum.toString returns the enum name with that weird character replacing the i. I mean small. 8 out 50,000 is the average. Or is it possible that assumption is wrong and the error is on analytics service end somewhere? Really highly doubt that.
The String#toLowerCase method uses the default locale of the system. This use locale specific characters such as ı instead of i. In order to fix this problem call toLowerCase with a locale:
String test = "testString";
test.toLowerCase(java.util.Locale.ENGLISH) // Or your preferred locale
In my web application I'm trying to prevent users from inserting JavaScript in the freeText parameter when they're running a search.
To do this, I've written code in the header Velocity file to check whether the query string contains a parameter called freeText, and if so, use the replace method to replace the characters within the parameter value. However, when you load the page, it still displays the original query string - I'm unsure on how to replace the original query string with my new one which has the replaced characters.
This is my code:
#set($freeTextParameter = "$request.getParameter('freeText')")
freeTextParameter: $freeTextParameter
#if($freeTextParameter)
##Do the replacement:
#set($replacedQueryString = "$freeTextParameter.replace('confirm','replaced')")
replacedQueryString after doing the replace: $replacedQueryString
The query string now: $request.getQueryString()
The freeText parameter now: $request.getParameter('freeText')
#end
In the code above, the replacedQueryString variable has changed as expected (ie the replacement has been carried out as expected), but the $request.getQueryString() and $request.getParameter('freeText') are still the same as before, as if the replacement had never happened.
Seeing as there is a request.getParameter method which works fine for getting the parameters, I assumed there would be a request.setParameter method to do the same thing in reverse, but there isn't.
The Java String is an immutable object, which means that the replace() method will return an altered string, without changing the original one.
Since the parameters map given by the HttpServletRequest object cannot be modified, this approach doesn't work well if your templates rely on $request.getParameter('freeText').
Instead, if you rely on VelocityTools, then you can rather rely on $params.freeText in your templates. Then, you can tune your WEB-INF/tools.xml file to make this parameters map alterable:
<?xml version="1.0">
<tools>
<toolbox scope="request">
<tool key="params" readOnly="false"/>
...
</toolbox>
...
</tools>
(Version 2.0+ of the tools is required).
Then, in your header, you can do:
#set($params.freeText = params.freeText.replace('confirm','replaced'))
I managed to fix the issue myself - it turned out that there was another file (which gets called on every page) in which the $!request.getParameter('freeText')" variable is used. I have updated that file so that it uses the new $!replacedQueryString variable (ie the one with the JavaScript stripped out) instead of the existing "$!request.getParameter('freeText')" variable. This now prevents the JavaScript from being executed on every page.
So, this is the final working code in the header Velocity file:
#set($freeTextParameter = "$!m.request.httpRequest.getParameter('freeText')")
#if($freeTextParameter)
#set($replacedQueryString = "$freeTextParameter.replace('confirm','').replace('<','').replace('>','').replace('(','').replace(')','').replace(';','').replace('/','').replace('\"','').replace('&','').replace('+','').replace('script','').replace('prompt','').replace('*','').replace('.','')")
#end