Spring Annotations - Config with Array attributes - arrays

Currently have the following configuration and the application works as expected:
#CrossOrigin(origins = { "https://localhost:5000","http://localhost:5000"})
would like to change to something that can be configured in a properties file for different environments. I Can get to work with one Value but can't figure out a way for it to work with more than one. When a properties file is application-dev.properites has:
cors.client.urls=http://localhost:5000,https://localhost:5000
The appropriates values are not loaded with the following declaration:
#CrossOrigin(origins = {"${cors.client.urls}"})
When the properties file is just one value this declaration works as expected.
I know that I am missing something extremely basic.. Appreciate any help.

You can use SpringEL here as mentioned in Reading a List from properties file and load with spring annotation #Value
#CrossOrigin(origins = {#{'${cors.client.urls}'.split(',')}})

Related

How to read a text file from resources without javaClass

I need to read a text file with readLines() and I've already found this question, but the code in the answers always uses some variation of javaClass; it seems to work only inside a class, while I'm using just a simple Kotlin file with no declared classes. Writing it like this is correct syntax-wise but it looks really ugly and it always returns null, so it must be wrong:
val lines = object {}.javaClass.getResource("file.txt")?.toURI()?.toPath()?.readLines()
Of course I could just specify the raw path like this, but I wonder if there's a better way:
val lines = File("src/main/resources/file.txt").readLines()
Thanks to this answer for providing the correct way to read the file. Currently, reading files from resources without using javaClass or similar constructs doesn't seem to be possible.
// use this if you're inside a class
val lines = this::class.java.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()
// use this otherwise
val lines = object {}.javaClass.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()
According to other similar questions I've found, the second way might also work within a lambda but I haven't tested it. Notice the need for the ?. operator and the lines?.let {} syntax needed from this point onward, because getResourceAsStream() returns null if no resource is found with the given name.
Kotlin doesn't have its own means of getting a resource, so you have to use Java's method Class.getResource. You should not assume that the resource is a file (i.e. don't use toPath) as it could well be an entry in a jar, and not a file on the file system. To read a resource, it is easier to get the resource as an InputStream and then read lines from it:
val lines = this::class.java.getResourceAsStream("file.txt").bufferedReader().readLines()
I'm not sure if my response attempts to answer your exact question, but perhaps you could do something like this:
I'm guessing in the final use case, the file names would be dynamic - Not statically declared. In which case, if you have access to or know the path to the folder, you could do something like this:
// Create an extension function on the String class to retrieve a list of
// files available within a folder. Though I have not added a check here
// to validate this, a condition can be added to assert if the extension
// called is executed on a folder or not
fun String.getFilesInFolder(): Array<out File>? = with(File(this)) { return listFiles() }
// Call the extension function on the String folder path wherever required
fun retrieveFiles(): Array<out File>? = [PATH TO FOLDER].getFilesInFolder()
Once you have a reference to the List<out File> object, you could do something like this:
// Create an extension function to read
fun File.retrieveContent() = readLines()
// You can can further expand this use case to conditionally return
// readLines() or entire file data using a buffered reader or convert file
// content to a Data class through GSON/whatever.
// You can use Generic Constraints
// Refer this article for possibilities
// https://kotlinlang.org/docs/generics.html#generic-constraints
// Then simply call this extension function after retrieving files in the folder.
listOfFiles?.forEach { singleFile -> println(singleFile.retrieveContent()) }
In order to have the same url that work for both Jar or in local, the url (or path) needs to be a relative path from the repository root.
..meaning, the location of your file or folder from your src folder.
could be "/main/resources/your-folder/" or "/client/notes/somefile.md"
The url must be a relative path from the repository root.
it must be "src/main/resources/your-folder/" or "src/client/notes/somefile.md"
Now you get the drill, and luckily for Intellij Idea users, you can get the correct path with a right-click on the folder or file -> copy Path/Reference.. -> Path From Repository Root (this is it)
Last, paste it and do your thing.

how to implement iTestContext listener without adding to method argument testng(from XML) for PDFBox utility

I am automating a salesforce application using Selenium TestNG. I am implementing a utility using apache PDFBox where i paste all my screenshots into a PDF to make client happy .
My logic is i create screenshots in each method with 1.png , 2.png etc until n.png and paste them in pdf using pdfbox methods.
The problem is my number of screenshots are variable so i implemented iTestContext where i set a variable counter to maximum number pass them to my after method where i retrieve the counter , and those number of screenshots are pasted- something like this
Class Login {
#Test
mymethod(ItestContext context){
commonfunctions.savescreenshot(1.png);
commonfunctions.savescreenshot(2.png);
commonfunctions.savescreenshot(n.png);
context.setAttribute("Counter", "n");
}
#AfterMethod
myaftermethod(){
String PATH = //Path of my test method
String MethodCounter = (String)context.getAttribute("Counter");
PDFUtility.addImagetoPDF(PATH,Integer.parseInt(MethodCounter) );
}
}
The problem is i have many methods that i need to implement and i dont want ITestContext listener as argument to each method.Can i pass it in xml file and use it for all methods?
Hope i have provided all details
If you need to get hold of the current ITestContext object (which is a representation of the current <test> tag being executed), you don't need to pass it as a parameter to your #Test method.
You can get access to it from within a #Test annotated test method via something like this:
org.testng.ITestContext context =
org.testng.Reporter.getCurrentTestResult().getTestContext();
This way you dont need to pass the org.testng.ITestContext object as a parameter to your #Test method.
Can i pass it in xml file and use it for all methods?
No you cannot pass the ITestContext object via the xml file.

How to set a context variable with dot in name?

I am trying to add a context data variable (CDV), which has a dot in its name. According to Adobe site this is correct:
s.contextData['myco.rsid'] = 'value'
Unfortunately, after calling s.t() the variable is split into two or more:
Context Variables
myco.:
rsid: value
.myco:
How can I set the variable and prevent splitting it into pieces?
You are setting it properly already. If you are referring to what you see in the request URL, that's how the Adobe library sends it. In your example, "myco" is a namespace, and "rsid" is a variable in that namespace. And you can have other variables in that namespace. For example if you have
s.contextData['myco.rsid1'] = 'value';
s.contextData['myco.rsid2'] = 'value';
You would see in the AA request URL (just showing the relevant part):
c.&myco.&rsid1=value&rsid2=value&.myco&.c
I assume you are asking because you want to more easily parse/qa AA collection request URLs from the browser network tab, extension, or some unit tester? There is no way to force AA to not behave like this when using dot syntax (namespaces) in your variables.
But, there isn't anything particularly special about using namespaces for your contextData variables; it's just there for your own organization if you choose. So if you want all variables to be "top level" and show full names in the request URL, then do not use dot syntax.
If you want to still have some measure of organization/hierarchy, I suggest you instead use an underscore _ :
s.contextData['myco_rsid1'] = 'value';
s.contextData['myco_rsid2'] = 'value';
Which will give you:
c.&myco_rsid1=value&myco_rsid2=value&.c
Side Note: You cannot do full object/dot notation syntax with s.contextData, e.g.
s.contextData = {
foo:'bar', // <--- this will properly parse
myco:{ // this will not properly parse
rsid:'value' //
} //
};
AA library does not parse this correctly; it just loops through top level properties of contextData when building the request URL. So if you do full object syntax like above, you will end up with:
c.&foo=bar&myco=%5Bobject%20Object%5D&&.c
foo would be okay, but you end up with just myco with "[object Object]" as the recorded value. Why Adobe didn't allow for full object syntax and just JSON.stringify(s.contextData) ? ¯\_(ツ)_/¯

ControlPath equivalent from DotNetNuke DnnApiController ActiveModule

Is there a way to get the module root folder (folder under DesktopModules) of the ActiveModule from a DnnApiController?
In PortalModuleBase I would use the ControlPath property to get to the same root folder I'm looking for.
As #MitchelSellers points out, it doesn't appear to be in the API so you have to figure it out yourself.
Since the API gives us the ActiveModule which is a ModuleInfo that's probably the best way to get at it.
If your modules use a pretty standard consistent naming then the following "best guess" method should work pretty well
public static string ControlPath(ModuleInfo mi, bool isMvc = false)
{
return isMvc
? $"/DesktopModules/MVC/{mi.DesktopModule.FolderName}"
: $"/DesktopModules/{mi.DesktopModule.FolderName}";
}
The other way is to look at the ModuleDefinitions of our module and grab the first ModuleControl and look at it's ControlSrc to see it's path.
public static string ControlPath(ModuleInfo mi)
{
var mdi = mi.DesktopModule.ModuleDefinitions.First().Value;
var mci = mdi.ModuleControls.First().Value; // 1st ModuleControl
return Path.GetDirectoryName(mci.ControlSrc);
}
The second method is really messy (and untested) but should give you the actual folder path where the controls are installed, over the other best guess method above.
From the API's it doesn't appear so, you should know the path for this though since you are inside of your module, the only concern is if you are inside of a child portal you need the prefix, which you should be able to get. I'd just use Server.ResolveClientUrl() to get it.

How can i achieve dictionary type data access in Chromium embedded CEF1

I would like to achieve dictionary like data pattern that can be accessed from the
java script. Something like this:
pseudo Code:
for all records:
{
rec = //Get the Record
rec["Name"]
rec["Address"]
}
I am trying to achieve with CefV8Accessor, but i am not getting near to the solution.
Kindly provide few links for the reference, as i see the documentation is very less from chromium embedded.
If I understand correctly, you're trying to create a JS "dictionary" object for CEF using C++. If so, here's a code snippet that does that:
CefRefPtr<CefV8Value> GetDictionary(__in const wstring& sName, __in const wstring& sAddress)
{
CefRefPtr<CefV8Value> objectJS = CefV8Value::CreateObject(NULL);
objectJS->SetValue(L"Name", sName, V8_PROPERTY_ATTRIBUTE_NONE);
objectJS->SetValue(L"Address", sAddress, V8_PROPERTY_ATTRIBUTE_NONE);
return objectJS;
}
The CefV8Accessor can also be used for that matter, but that's only if you want specific control over the set & get methods, to create a new type of object.
In that case you should create a class that inherits CefV8Accessor, implement the Set and Get methods (in a similar way to what appears in the code above), and pass it to the CreateObject method. The return value would be an instance of that new type of object.
I strongly suggest to browse through this link, if you haven't already.

Resources