I have a spring boot project that is deployed on Tomcat 6. I have a list of files under project's resource directory and I am trying to list all files under that directory. I am able to get specific file if I specify classpath:abc.txt in the getResource() method. However I am wondering if there is a way to just list all files with a wild card or something.
You cannot do like this MyClass.class.getResource('*.txt'). The alternative to this is :
ServletContext sc = request.getSession().getServletContext();
String strPath = sc.getRealPath("/");
File[] allFiles = new File(strpath).listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".txt");
}
});
Refer this :Using File.listFiles with FileNameExtensionFilter
Related
Inbound channel adapter is created with a poller to poll files present in root directory and its sub directories
e.g.
RootDir
|_abc.txt
|_subdirectory1
|_subdirfile1.doc
The problem is inbound channel adapter is reading the directory also as message
#Bean
#InboundChannelAdapter(autoStartup = "false", value = "incomingchannel", poller = #Poller("custompoller"))
public MessageSource<File> fileReadingMessageSource(DirectoryScanner directoryScanner) {
FileReadingMessageSource sourceReader = new FileReadingMessageSource();
sourceReader.setScanner(directoryScanner);
}
#Bean
public DirectoryScanner directoryScanner() {
DirectoryScanner scanner = new RecursiveDirectoryScanner();
CompositeFileListFilter filter = new CompositeFileListFilter<>(
Arrays.asList(new AcceptOnceFileListFilter<>(), new RegexPatternFileListFilter(regex)));
scanner.setFilter(filter);
return scanner;
}
#Trasnformer(inputChannel="incomingchannel",....
torequest(Mesage<File> message) {
message.getPayload()
}
Here message.getpayLoad is printing subdirectory1 i.e. directory is also read as a file message
I can handle explicitly as file is directory or not in trasnformer and ignore, but wanted to know is there any way it can be filtered in Recursive Directory scanner attached to Inbound Channel adapter ?
This problem is probably related to this SO thread: Spring Integration + file reading message source _ Inbound Channel Adapter + Outbound Gateway.
You need to think twice if you are OK loosing file tree. It sounded for me that you would like to restore a tree in the FileWritingMessageHandler. So, it is probably better to #Filter messages with directory payload before sending to that transformer.
If you still want to skip dirs from the producing, consider to use a ChainFileListFilter instead of CompositeFileListFilter and configure a RegexPatternFileListFilter first.
This way a filtered directory from the RegexPatternFileListFilter (it is skipped by default see AbstractDirectoryAwareFileListFilter) won't go to the AcceptOnceFileListFilter at all. In your current configuration the AcceptOnceFileListFilter being first accepts a directory and really ignores the next filter in the composition.
UPDATE
What I mean should be like this:
#Bean
public DirectoryScanner directoryScanner() {
DirectoryScanner scanner = new RecursiveDirectoryScanner();
ChainFileListFilter filter = new ChainFileListFilter<>(
Arrays.asList(new RegexPatternFileListFilter(regex), new AcceptOnceFileListFilter<>()));
scanner.setFilter(filter);
return scanner;
}
Nothing more. As long as your regex is just for files, any sub-directory would be skipped and not allowed to go downstream.
I'm trying to find all the wavs in every folder that I have in a directory, for example, "Music". Right now, my code shows the wavs found in whatever folder I select, but I want it to list all the wavs found in the whole directory at once, without the user going from folder to folder. How can I do that? Here's my code:
FileChooser chooseFile = new FileChooser();
FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("Choose a file (*.wav)", "*.wav");
chooseFile.getExtensionFilters().add(filter);
File file = chooseFile.showOpenDialog(null);
directory = file.toURI().toString();
First you should use a DirectoryChooser to select a directory. You can use the NIO package to find the files:
DirectoryChooser chooser = new DirectoryChooser();
File directory = chooser.showDialog(null);
Path[] wavs = findWavs(directory);
private static Path[] findWavs(File directory) throws IOException {
Path dir = directory.toPath();
try (Stream<Path> stream = Files.find(dir, Integer.MAX_VALUE, (path, attributes) -> path.getFileName().toString().endsWith(".wav"))) {
return stream.toArray(Path[]::new);
}
}
If you need Files instead you could simply map the paths to files:
return stream.map(Path::toFile).toArray(File[]::new);
I have a main grails application that use a private Grails plugin mySearch.
the plugin Search has a file in Search\web-app\filters.json.
when the application is run with run-app : the ressource file can be accessed with :
def ressource = new File( org.codehaus.groovy.grails.plugins.GrailsPluginUtils.getPluginDirForName('mySearch')?.file?.absolutePath
+"/web-app/filters.json").text
but It doesn't work when the app is deployed in tomcat7.
I'have tried using pluginManager.getGrailsPlugin('mySearch')
but I can't access the obsolute path of the resource.
After many attempts to resolve it, I found this workaround.
It looks messy but I didn't found anything else shorter and sweeter :
// work only for a plugin installed in app deployed from a war.
String getRessourceFile(String relativePath) throws FileNotFoundException{
def pluginDir = pluginManager.getGrailsPlugin('MyPlugin')?.getPluginPath()
def pluginFileSystemName = pluginManager.getGrailsPlugin('MyPlugin')?.getFileSystemName()
def basedir = grailsApplication.parentContext.getResource("/")?.file
if(basedir.toString().endsWith("web-app")){
basedir = basedir.parent
}
ressourcefile = "$basedir$pluginDir/$relativePath"
ressource = new File(ressourcefile)?.text
}
I have some files in a specific folder into grails-app directory. During bootstrap, I would like to copy one of those files (let's say the latest, doesn't matter) and copy it into the web-app folder, to make it accessible to the grails application.
How would you do that? I wrote something like this:
class BootStrap {
GrailsApplication grailsApplication
def init = { servletContext ->
// ...
def source = new File('grails-app/myFolder/my-file-'+ grailsApplication.metadata.getApplicationVersion() +'.txt')
def destination = new File('web-app/my-current-file.txt')
source?.withInputStream { is ->
destination << is
}
// ...
}
}
But I have difficulties to identify the right path for source and destination files (getting a FileNotFoundException). I already double checked folder and files names, my problem is the starting point for relative paths.
Is the bootstrap a good place to perform this kind of operation?
As always, thanks in advance.
I made it with the Bootstrap (please read the entire answer):
class BootStrap {
GrailsApplication grailsApplication
def init = { servletContext ->
def applicationContext = grailsApplication.mainContext
String basePath = applicationContext.getResource("/").getFile().toString()
File source = new File("${basePath}/../grails-app/myFolder/" + grailsApplication.metadata.getApplicationVersion() +'.txt')
File destination = new File("${basePath}/my-current-file.txt")
source?.withInputStream {
destination << it
}
}
}
But, as suggested by Muein Muzamil, the best approach is with events.
Here's his solution applied to my example:
eventCompileEnd = {
metadata = grails.util.Metadata.getCurrent()
appVersion = metadata."app.version"
ant.copy(file: "${basedir}/grails-app/myFolder/${appVersion}.txt", tofile: "${basedir}/web-app/my-current-file.txt")
}
How about hooking onto Grails events. Currently as part of the project compilation step, I am copying my external configuration file from conf folder to class path. So you can do something similar to that.
This is what I have in _Events.groovy file: I guess you can do something similar to this.
eventCompileEnd = {
ant.copy(todir:classesDirPath) {
fileset(file:"${basedir}/grails-app/conf/override.properties")
}}
I have created a Setup Project for my Project. This project connects to a live DB server through asmx services. That URL will be determined after the client will deploy the web services on some server. So in setup project i have added a "TextBoxes" dialog in User Interface Editor section of the Setup Project where i have enabled only one TextBox to get the URL of the deployed Services. In my project i have added a file to be executed during Setup installation and i have defined it as follows:
[RunInstaller(true)]
public class InstallerHelper : System.Configuration.Install.Installer
{
// Other Code also exists that is not needed to be shown here<br/>
//.....
// The following method gets executed during setup installation
public override void Install(IDictionary stateSaver)
{
try
{
base.Install(stateSaver);
//Proceed only if the Context object has some parameters
if (Context.Parameters.Count != 0 && !string.IsNullOrEmpty(Context.Parameters["WEBSITEURL"]))
{
//Get the installation Folder's Path
string installationFolder = Context.Parameters["INSTALLFOLDER"];
// Get the Site's URL entered by Client
string websiteUrl = Context.Parameters["WEBSITEURL"];
//Create different Key Value pairs based on entered URL
string[][] keyValues = {
new string[] {"SiteUrl",websiteUrl},
new string[] {"WebServiceURL", websiteUrl + "Users.asmx" },
new string[] {"TicketsServiceURL", websiteUrl + "Tickets.asmx"},
new string[] {"CampaignsAndProjetcsServiceURL", websiteUrl + "CampaignsAndProjetcs.asmx"},
new string[] {"EntitiesURL", websiteUrl + "Entities.asmx"},
new string[] {"AccountsURL", websiteUrl + "Accounts.asmx"},
new string[] {"TransactionsURL", websiteUrl + "Transactions.asmx"},
new string[] {"RelatedReportsURL", websiteUrl + "RelatedReports.asmx"},
new string[] {"GiftAidsURL", websiteUrl + "GiftAids.asmx"}
};
// Load the app.Config file and store these values in it.
//********************************************
string configFilePath = installationFolder + #"\MyProject.exe.config";
XmlDocument configuration = new XmlDocument();
// Load App.Config File
configuration.Load(configFilePath);
//Add the values in it
Utility.UpdateValue(keyValues, configuration);
//Save configuration File
configuration.Save(configFilePath);
//********************************************<br/>
}
}
catch (Exception ex)
{
throw new InstallException("The following Error(s) occured during installation. \n " + ex.Message);
}
}
}
Here i Store the entered URL and some other generated URLs of different web services in App.Config of the Project to be used in Project for accessing data.
It works fine when i install a fresh copy of the Setup, but problem occurs when i try to Repair the installed project by again executing the Setup.exe file.
Repair process does not asks me to enter the URL again and also the Items stored in App.Config during first time installation are lost. So the whole application stops working.
Any help is greatly appreciated
A good approach is to save this custom information somewhere and retrieve it during maintenance using searches:
create some string registry entries which contain your custom properties; the registry entry value can be something like:
[WEBSITEURL]
create registry searches which read these entries and save them in your custom properties; for this use the property names for the actual searches
This way a repair will read the property values from registry and restore your original properties.
Both the Registry Editor and Launch Conditions Editor can be opened by selecting your setup project in Solution Explorer and clicking the appropriate button on its top pane.