Why is an incorrect template rendered here? - java

I'm calling render() with a few arguments, the first of which is a String argument that I got as a parameter:
public static void action(String url) {
...
render(url,...);
}
I'm getting this error:
The template http://the.contents.of/urlParameter does not exist.
Now, I'm debugging through render(), where I see this snippet:
protected static void render(Object... args) {
String templateName = null;
if (args.length > 0 && args[0] instanceof String && LocalVariablesNamesTracer.getAllLocalVariableNames(args[0]).isEmpty()) {
// I'm getting into this branch
templateName = args[0].toString();
} else {
templateName = template();
}
renderTemplate(templateName, args);
}
What is the if trying to accomplish? Why am I getting into it - is it because I'm not using a local variable for url? Is this documented? What's the reasoning here?
I'm using version 1.2.x-c40cf37 (that's somewhere after 1.2.4).

If you provide a string as the first argument, then it assumes that it is the name of the template to render.
Example:
render("#password", url);
That will render the password-template and pass the url variable to it.
In your case you could do something like this instead:
render("#action", url);
EDIT:
As an alternative you could also do something like this:
renderArgs.put("url", url);
render();
Hope it helps.

Related

By using AspectJ, how can I get 'Object' reference created by 'new' keyword?

Let me directly jump into the example.
public class Target {
public static void main(String[] args) {
Target target = new Target();
Target target2 = new Target();
}
}
I try to capture the Object references(*.hashCode()) by using AspectJ. I prepared code like below:
public aspect ObjectCreationAspect {
before() : initialization(*.new(..)) && !within(ObjectCreationAspect) {
System.out.println();
}
}
I know 'initialization' captures 'new' keyword, but I don't know how can I get the Object itself created by this 'new' keyword. I tried some 'get' methods but they just get only plain name, type(not object), and so forth. What I want is printing values same with target.hashCode() and target1.hashCode() inside this Aspect.
Please give me some hints.
I found an answer.
thisJoinPoint.getTarget().hashCode()
This code will return the reference of newly created object.

Calling a method with a variable name - possible?

I have a function for a Selenium Test that looks like this.
public static WebElement getElmObject (String locinfo, String loctype) {
try{
return driver.findElement(By.loctype(locinfo));
} catch (Throwable t){
return null;
}
The function is supposed to take in the info string and the type (the name of the method to call in the BY class - like xpath, cssselector, tagname etc.) How do I get Java to evaluate the value of "loctype"?
I come from a ColdFusion background and this is easy to do with CF but I am having a hard time trying to do this in Java. I just get a "cannot resolve method" issue and it won't compile. Is it even possible to do?
You can do this using Reflection.
public static WebElement getElmObject(String locinfo, String loctype) {
try {
Method method = By.class.getMethod(loctype, String.class);
By by = (By) method.invoke(By.class, locinfo);
return driver.findElement(by);
} catch (Throwable t) {
return null;
}
}
However I find this strange and I would recommend using different methods (getElmObjectById, getElmObjectByCss, etc.) or to use an enum (ID, CSS, XPATH, etc.) as parameter instead of the method name. Using the method name as parameter, it makes your caller dependent of the Selenium implementation. If they change the name of a method, your code will not work anymore and you will even not notice this at compile time!
we can also do it with enum like this
other than creating seperate methods for each and every locator like getElmObjectById as LaurentG said we can also achieve it as shown below
public enum avilableLocators
{
CLASS_NAME, CSS_SELECTOR, XPATH
}
and have a method with switch case or if-else if which will have a return type of By
public By locinfo(String locinfo)
{
String locatorValue=null;
switch (locType(locinfo))
{
case XPATH:
locatorValue=locinfo.split(",")[1]/*assuming that you are passing locinfo,locvalue*/
return By.xpath(locator);
}
}
public final avilableLocators locType(String loctype) {
if (loctype.contains("xpath"))
{
return avilableLocators.XPATH;
}
}
so the final usage can be like this
String locDetails="xpath,//*[#id='ComScorePingFile']"
locinfo(locDetails);

Java - Trouble Accessing ValueMap

I've got a pretty simple script that simply accesses a resources properties via a ValueMap. Except for some reason I keep getting an unexpected token error were the if statement starts. This has to be something I'm just overlooking.
public class headerComponent{
ValueMap property = resource.adaptTo(ValueMap.class);
if(property != null) {
pageHeader = property.get("pageHeader", "");
}
}
Any ideas? Thanks for the help.
Because you are using if direct inside your class. This should be inside a function.
For Ex:
public class headerComponent{
ValueMap property = resource.adaptTo(ValueMap.class);
public void getMeProp()
{
if(property != null) {
pageHeader = property.get("pageHeader", "");
}
}
}
If you want to return your string then use public String getMeProp() and in the end of the function return pageHeader. Depends how you want to implement.

Java cannot find symbol on variable

I'm pretty new to Java so bear with me. I can't for the life of me figure out why I'm getting
a cannot find symbol error on resourceResolver.resolve. When on the line above it I'm defining the variable.
Maybe this is something simple I'm missing but I can't figure this out and I feel like I've
stared at this way to long.
private static final String ROOTCHILD = "rootChild";
public void setResource(Resource resource) {
this.resource = resource;
}
public void setProperties(ValueMap properties) {
this.properties = properties;
}
public Page getRootPage() {
ResourceResolver resourceResolver = getResource().getResourceResolver();
return (this.properties != null)
? resourceResolver.resolve(
properties.get( ROOTCHILD,currentPage.getPath())).adaptTo(Page.class)
: null;
}
My guess here (never worked with sling and haven't used Java for a while):
I think the problem is you initialized the ValueMap properties so that it doesn't contain Strings or HttpServletRequests, but something else. The .resolve() method only accepts either a String or an HttpServletRequest. (Or two parameters, but you're only passing one, so that one can't be the case.) There is no .resolve() method found accepting the parameters you try to give it, so that symbol is not found!
To see the true error, rewrite your code and compile it:
public Page getRootPage() {
if( properties == null ) {
return null;
}
YYYYYY resource = getResource();
ResourceResolver resourceResolver = resource.getResourceResolver();
String path = currentPage.getPath();
String rootChild = properties.get( ROOTCHILD, path );
XXXXXX rc = resourceResolver.resolve( rootChild );
return rc.adaptTo( Page.class );
}

How to write a jUnit test for a class that uses a network connection

I would like to know what's the best approach to test the method "pushEvent()" in the following class with a jUnit test.
My problem is, that the private method "callWebsite()" always requires a connection to the network. How can I avoid this requirement or refactor my class that I can test it without a connection to the network?
class MyClass {
public String pushEvent (Event event) {
//do something here
String url = constructURL (event); //construct the website url
String response = callWebsite (url);
return response;
}
private String callWebsite (String url) {
try {
URL requestURL = new URL (url);
HttpURLConnection connection = null;
connection = (HttpURLConnection) requestURL.openConnection ();
String responseMessage = responseParser.getResponseMessage (connection);
return responseMessage;
} catch (MalformedURLException e) {
e.printStackTrace ();
return e.getMessage ();
} catch (IOException e) {
e.printStackTrace ();
return e.getMessage ();
}
}
}
Stubbing
You'll need a test double (stub) to allow isolated, easy, unit testing. The following is non tested, but demonstrates the idea. The use of Dependency Injection will allow you to inject at test time, a test version of your HttpURLConnection.
public class MyClass()
{
private IHttpURLConnection httpUrlConnection;
public MyClass(IHttpURLConnection httpUrlConnection)
{
this.httpUrlConnection = httpUrlConnection;
}
public String pushEvent(Event event)
{
String url = constructURL(event);
String response = callWebsite(url);
return response;
}
}
Then you create a stub (sometimes referred to as a mock object) to be the stand in for the concrete instance.
class TestHttpURLConnection : IHttpURLConnection { /* Methods */ }
You'll also construct a concrete version, for your production code to use.
class MyHttpURLConnection : IHttpURLConnection { /* Methods */ }
Using your test class (an adapter) you are able to specifiy what should happen during your test. A mocking framework will enable you to do this with less code, or you can manually wire this up. The end result of this for your test is that you'll set your expectations for your test, for example, in this case you may set OpenConnection to return a true boolean (This is just an example by the way). Your test will then assert that when this value is true, the return value of your PushEvent method matches some expected result. I've not touched Java properly for a while, but here are some recommended mocking frameworks as specified by StackOverflow members.
Possible solution: You can extend this class, override callWebsite (you have to make it protected for this purpose) - and the override method write some stub method implementation.
Approaching things from a slightly different angle...
I'd worry less about testing this specific class. The code in it is extremely simple and, while a functional test to make sure it's working with a connection would be helpful, a unit level test "may" not be necessary.
Instead, I'd focus on testing the methods it calls that appear to actually do something. Specifically...
I'd test constructURL method from this line:
String url = constructURL (event);
making sure that it can construct a URL properly from different Events, and throws Exceptions when it should (possibly on an invalid Event or null).
And I'd test the method from the following line:
String responseMessage = responseParser.getResponseMessage (connection);
Possibly pulling out any "get information out of the connection" logic into one proc, and leaving only "parse said information" in the original one:
String responseMessage = responseParser.getResponseMessage(responseParser.getResponseFromConnection(connection));
or something along those lines.
The idea being to put any "must deal with external data sources" code in one method, and any code logic in separate methods that can be easily tested.
As an alternative to Finglas's helpful answer with respect to mocking, consider a stubbed approach where we override the functionality of callWebsite(). This works quite well in the case where we aren't so interested in the logic of callWebsite as that of the other logic called within pushEvent(). One important thing to check is that callWebsite is calledwith the correct URL. So, first change is to the method signature of callWebsite() to become:
protected String callWebsite(String url){...}
Now we create a stubbed class like this:
class MyClassStub extends MyClass {
private String callWebsiteUrl;
public static final String RESPONSE = "Response from callWebsite()";
protected String callWebsite(String url) {
//don't actually call the website, just hold onto the url it was going to use
callWebsiteUrl = url;
return RESPONSE;
}
public String getCallWebsiteUrl() {
return callWebsiteUrl;
}
}
And finally in our JUnit test:
public class MyClassTest extends TestCase {
private MyClass classUnderTest;
protected void setUp() {
classUnderTest = new MyClassStub();
}
public void testPushEvent() { //could do with a more descriptive name
//create some Event object 'event' here
String response = classUnderTest.pushEvent(event);
//possibly have other assertions here
assertEquals("http://some.url",
(MyClassStub)classUnderTest.getCallWebsiteUrl());
//finally, check that the response from the callWebsite() hasn't been
//modified before being returned back from pushEvent()
assertEquals(MyClassStub.RESPONSE, response);
}
}
Create an abstract class WebsiteCaller which would be a parent of ConcreteWebsiteCaller and WebsiteCallerStub.
This class should have one method callWebsite (String url). Move your callWebsite method from MyClass to ConcreteWebsiteCaller. And MyClass will look like:
class MyClass {
private WebsiteCaller caller;
public MyClass (WebsiteCaller caller) {
this.caller = caller;
}
public String pushEvent (Event event) {
//do something here
String url = constructURL (event); //construct the website url
String response = caller.callWebsite (url);
return response;
}
}
and implement method callWebsite in your WebsiteCallerStub in some way appropriate for testing.
Then in your unit test do something like this:
#Test
public void testPushEvent() {
MyClass mc = new MyClass (new WebsiteCallerStub());
mc.pushEvent (new Event(...));
}

Categories