I use Spring with embeded Tomcat and a War file in prodution.
I need to list all files in the "static" directory. It's like 4 days I m on it
This kind of code not working :
Stream.of(new File(dir).listFiles()
It lists the files where the war is located but the static directory is inside the war
With this code I arrive to read a file inside the war :
Thread.currentThread().contextClassLoader?.getResourceAsStream(path)?.bufferedReader()?.use(BufferedReader::readText)
But it's not working with a directory
And now i have no idea how i can list all files inside the static directory
I found a solution
Not sure it's the best and clean but it's worked
I use 2 way to do it, one for developpment and the other when it's package inside war
loadFilesFromDirectory("/static")
fun listFilesFromDirectory(path: String, request: HttpServletRequest? = null): List<String> {
return if (request == null || request.requestURL.contains("localhost")) {
//Don't work on war but work on IDE
Thread.currentThread().contextClassLoader?.getResourceAsStream(path)
?.bufferedReader()?.use(BufferedReader::readText)?.split("\n")
?.filter { it.endsWith(".html") }
?: throw Exception("Non trouvé :$path")
} else {
//Not work on IDE but work on war
val root: URL = request.servletContext.getResource("/WEB-INF/classes/$path")
var rootPath: String = root.path
rootPath = rootPath.substring(rootPath.indexOf("/WEB-INF"), rootPath.length)
return request.servletContext.getResourcePaths(rootPath).map {
it.replace(".*/", "")
}.filter { it.endsWith(".html") }
}
}
Related
I'm using property expansion in Gradle. All works fine but for file-paths.
I am using the processResources task in Gradle
processResources {
filesMatching ('**/application.properties') {
expand project.properties
}
}
I have a property in my Spring application.properties as follows:
root.location = ${rootDir}
In my build.gradle I have defined the following:
ext['rootDir'] = rootProject.buildDir.path + File.separator + "tmp"
Result I get in application.properties is
root.location = D:\Projects\myproject\build\tmp
Which turns into D:Projectsmyprojectbuild\tmp in my Spring class when doing:
#Value("${cpm.repository.root.location}") String rootLocation;
I need the property to be expanded to:
root.location = D:\\projects\\myproject\\build\\tmp
Because that would result in D:\projects\myproject\build\tmp
What am I doing wrong? Expansion does work as intended, it's just that the '\' in the path are not escapped when expanded.
Thanks in advance
I think you should use processResources task to modify your resources.
We are using it that way (with application.yml and Gradle Kotlin DSL):
tasks {
named<ProcessResources>("processResources") {
outputs.upToDateWhen { false }
filesMatching("**/application.yml") {
filter {
it.replace("#project.version#", version as String)
}
filter {
it.replace("#spring.profiles.active#", profiles)
}
}
}
}
And of course #spring.profiles.active# is a string you want to replace in your file.
Integration.xml - this will take all files in the directory
<int-file:inbound-channel-adapter id="delFiles" channel="delFiles"
directory="C:/abc/abc" use-watch-service="true" prevent-duplicates="false" auto-startup="true"
watch-events="CREATE,MODIFY">
<int:poller fixed-delay="1000"/>
<int-file:nio-locker/>
</int-file:inbound-channel-adapter>
I need to delete all files older than 10 days in that folder and sub folder. Can some one pls help?
Listener
#Transformer(inputChannel="delFiles")
public JobLaunchRequest deleteJob(Message<File> message) throws IOException {
Long timeStamp = message.getHeaders().getTimestamp();
return JobHandler.deleteJob(message.getPayload(), jobRepository, fileProcessor, timeStamp);
}
Handler
public static JobLaunchRequest deleteJob(File file, JobRepository jobRepository, Job fileProcessor, Long timeStamp) throws IOException {
//Is there a way in spring integration whether I can check this easily?
//How to check for folder and subfolders?
// This will check for files once it's dropped.
// How to run this job daily to check the file's age and delete?
}
This is not a <int-file:inbound-channel-adapter> responsibility. This one is really about polling files from the directory according filtering setting you provide.
If you are not interested in old files, you can implement a custom FileListFilter to skip files which are really so old.
If you still would like to delete those old files as some application functionality, you need to take a look into some other solution, something like #Scheduled method it iterate through files in that dir and remove them, e.g. once a day let's say at midnight.
You also can just remove processed files in the and of your logic. Since you use prevent-duplicates="false", you are going to poll the same file again and again.
To perform directory clean up you don't need Spring Integration:
public void recursiveDelete(File file) {
if (file != null && file.exists()) {
File[] files = file.listFiles();
if (files != null) {
for (File fyle : files) {
if (fyle.isDirectory()) {
recursiveDelete(fyle);
}
else {
if (fyle.lastModified() > 10 * 24 * 60 * 60 * 1000) {
fyle.delete();
}
}
}
}
}
}
(You might to improve this function a bit: haven't tested...)
i am trying to use the HotSwapAgent in our Project.
We are using a Wildfly 10.x and our Project is deployed as an exploded EAR in which there is an exploded war.
I've added the following JVM-options:
-XXaltjvm=dcevm -javaagent:c:\dev\hotswap-agent.jar
When my WildFly is deploying i get the following Error:
HOTSWAP AGENT: 14:42:40.479 ERROR (org.hotswap.agent.plugin.spring.scanner.XmlBeanDefinationScannerAgent) - failed to convert filePath /C:/dev/projects/project_abc/abc/ABC/target/ABC_Exploded.ear/ABCWeb.war/WEB-INF/config/spring/soap-context.xml to classPath path
When i let the Wildfly run, later the following Error is shown and the Deployment fails.
rror creating bean with name 'systemConfigurationService' defined in ServletContext resource [/WEB-INF/config/spring/service-maintenance-context.xml]: Invocation of init method failed; nested exception is java.lang.reflect.UndeclaredThrowableException
Does anyone know how to configure this right ?
I've read that you can put an extraClassPath into the properties of the HotswapAgent but i've no clue what i should set.
You have to change the convertToClasspathURL in org.hotswap.agent.plugin.spring.scanner.XmlBeanDefinationScannerAgent in order to your needs.
Seems in your case above just the following to the method:
paths = filePath.split("WEB-INF/config/spring");
if (paths.length == 2) {
return paths[1];
}
convertToClasspathURL ( after modifying it for your classpath needs ) :
private static String convertToClasspathURL(String filePath) {
String[] paths = filePath.split("src/main/resources/");
if (paths.length == 2) {
return paths[1];
}
paths = filePath.split("WEB-INF/classes/");
if (paths.length == 2) {
return paths[1];
}
paths = filePath.split("target/classes/");
if (paths.length == 2) {
return paths[1];
}
paths = filePath.split("target/test-classes/");
if (paths.length == 2) {
return paths[1];
}
paths = filePath.split("WEB-INF/config/spring");
if (paths.length == 2) {
return paths[1];
}
LOGGER.error("failed to convert filePath {} to classPath path", filePath);
return filePath;
}
Hope it solves your problem!
I am trying to download files in the root directory only. Currently I am not specifying any folders as I do not know how to so it downloads the most recent files that are in other folders that aren't the root. All I would like are the files in the root. The code that is getting the files and the download URLs is below:
public static void startDownload() throws IOException, ParseException {
Drive serv = getDriveService();
FileList result = serv.files().list().setMaxResults(10).execute(); //there are 10 files in the root folder
List<File> listA = result.getItems();
if (listA == null || listA.isEmpty()) {
System.out.println("No files found.");
} else {
System.out.println("Files:"+lista.size());
for (File file : listA) {
System.out.printf("%s (%s)\n", file.getTitle(), file.getDownloadUrl());
downloadFile(serv, file);
}
}
}
I would like to download all files in the root file only and not in any other folders. Any help would be appreciated.
You need to use the Q parameter to search
q string A query for filtering the file results. See the "Search for
Files" guide for supported syntax.
Sending something like the following will return everything that is not a folder with the parent of root.
mimeType != 'application/vnd.google-apps.folder' and 'root' in parents
There are a number of considerations.
Your line 3 needs to be
String q = "trashed = false and 'root' in parents and mimeType != 'application/vnd.google-apps.folder' "
FileList result = serv.files().list().setFields("*").setQ(q).setMaxResults(10).execute();
You need to be aware that this will return a maximum of 10 results, but even more so, you need to be aware that there is no minimum number of results. This means that if you have 11 files, you might get 10 in the first iteration and 1 in the 2nd. However, you could also get 1 and 10, or 3 and 6 and 2, or 0 and 0 and 1 and 10. You need to keep fetching results until the value of getNextPageToken() == null. So your line
if (listA == null || listA.isEmpty()) {
should be something like
if (result.getNextPageToken() == null) {
I realise that you've copy/pasted from the official documentation, but sadly that documentation is wrong.
I'm developing a plugin for my software that will manage Microsoft TFS. Each plugin operation(check out, create label, check in, etc.) has to be run individually. My checkout operation creates a workspace, downloads that workspace, and then deletes the workspace mapping, but leaves the files behind to be built or modified.
Now, once the files are modified I need to check them back in. Since I deleted the workspace already, I'll have to make a new one.
I'm having trouble making a PendingChange[] object from the files in the workspace. Could anyone give any samples on how this would be done?
This is the code I'm using to create my workspace, if it helps:
public Workspace createWorkspace(String pWorkspaceName, String pLocalPath, String pServerPath)
{
WorkingFolder[] foldersToMap = null;
if (pServerPath != null && pLocalPath != null)
{
final List<WorkingFolder> folderList = new ArrayList<WorkingFolder>();
folderList.add(new WorkingFolder(pServerPath, LocalPath.canonicalize(pLocalPath), WorkingFolderType.MAP, RecursionType.FULL));
foldersToMap = folderList.toArray(EMPTY_WORKING_FOLDER_ARRAY);
}
else if (pServerPath == null || pServerPath.isEmpty())
{
//throw
}
else if (pLocalPath == null || pLocalPath.isEmpty())
{
//throw
}
Workspace w =
mVersionControlClient.createWorkspace(foldersToMap, pWorkspaceName, VersionControlConstants.AUTHENTICATED_USER, VersionControlConstants.AUTHENTICATED_USER, null /*Comment*/,
WorkspaceLocation.SERVER, WorkspaceOptions.NONE);
return w;
}
Microsoft's documentation isn't great on the java sdk, so any help is appreciated.
P.S. If there's anything wrong with my question, or if you want clarification, leave a comment and let me know before you downvote, I'll get it fixed.
Workspace ws = vcc.getWorkspace(workspaceName, ownerName);
PendingSet pendings = ws.getPendingChanges();
for (PendingChange pending : pendings.getPendingChanges()) {
ItemType type = pending.getItemType();
/*Don't download if it is a Folder*/
if (type.getWebServiceObject().getName()
.equals("Folder"))
continue;
ChangeType change = pending.getChangeType();
Item item = vcc.getItem(pending.getServerItem());
String itemName = StringUtils.getItemName(item.getServerItem());
/*My business rule: can't download if isn't in Lock with owner*/
if (!change.toString().contains("(512): Lock")) {
returns.add(new Return("ERROR", "The object "
+ item.getServerItem()
+ " isn't in Lock with " + owner
+ "."));
continue;
}
String destinationFile = destinationPath + "\\" + itemName;
item.downloadFile(vcc, destinationFile);
}
Hope to be helpful.