relative Path for file in struts 2 Webapplication - java

I've got one problem. I'm working on a web Application using Struts (Struts 2 Framework).
I created a Freemarker template file for every single user and save it in
webapps/mail/mailEn/customer.ftl
Now, when the page is called, I must look if a customer.ftl So I try looking after it in my java class like this:
( when i use local direcory path C://... it works)
MimeBodyPart textBodyPart = null;
try {
textBodyPart = new MimeBodyPart();
Configuration cfg = new Configuration();
//FileTemplateLoader ftl1 = new FileTemplateLoader(new File ("D:/Workspace//Projectname///web///styles/");
FileTemplateLoader ftl1 = new FileTemplateLoader (new File("\\mail\\mailEn")); TemplateLoader[] loaders = new TemplateLoader[] { ftl1 };
MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
cfg.setTemplateLoader(mtl);
cfg.setObjectWrapper(new DefaultObjectWrapper());
Template template = cfg.getTemplate("customerInfo.ftl");
Map<String, String> rootMap = new HashMap<String, String>();
rootMap.put("image1", "images/LOGO.jpg");
rootMap.put("recipient", "aaaa");
rootMap.put("address", "xxxx");
rootMap.put("contact", "yyyy");
rootMap.put("country", "uuuu");
rootMap.put("sender", "rrrrr");
Writer out = new StringWriter();
template.process(rootMap, out);
textBodyPart.setContent(out.toString(),Constants.TEXT_HTML);
}
With the absolute path (D:/....) it works without problems. But this can't be the
solution, because when Ive finished this web-app, I will have an war-file which will be put on a server and the absolute path will be wrong then. So I need a relative path which will always work!
I'm working with Eclipse at this moment. When I try to use the path above (/../.. ....),
the file I'm looking for can never be found. (I tried to go up to the home path of the
project and then to the folder mail, where the file is)
I tried out many different paths like ./web/mail/ , ../../../../../web/styles, and so on,
but I never found the file I was looking for.
If anyone could give me a hint what to do, I would be very grateful!
Thank you!

You should use WebappTemplateLoader (or maybe ClassTemplateLoader). FileTemplateLoader is not a good fit for this, as in theory you can't even know if the war file will be extracted on the server, and if it's not extracted, you surely won't have a directory to point to.

actully your file are getting stored in the temp folder (application server/os) so i suggest to you `
request.getRequestedURI() + "/" + FILE_PATH`
Say: you saved "file.txt" at "URL:PORT/file/file.txt" which refers to the tmp folder in fact and it gets deleted once the server is restarted or application undeployed. make sure the folder you are using to save is outside web-inf

Solution(adjustment)
I used request.getSession().getServletContext().getRealPath()
In a class for example MessageUtility i used
final private static String MAIL = ResourceBundle.getBundle("cfg_webapp").getString("mails.folder");
String mailpath = request.getSession().getServletContext().getRealPath(MAIL);
FileTemplateLoader ftl1 = new FileTemplateLoader(new File(mailpath));
In cfg_webapp.properties i defined
## Mails
mails.folder=mails
It gets the path from ----- src/main/webapps/mails/customer.ftl
thanks all.

Related

Including an Excel file and call once packed into a jar

I have developed an ExcelReader/Writer program that is intended to be ran on other computers. In this program, it takes in an excel.xls of hard data, reads it and writes it in a formatted way to an excel.xlsx file, and then saves it in a directory "CoC-Forms".
To reduce the steps to run my program, I have included the empty .xlsx file that it writes to in the project. However, when exporting it to an executable jar (to run on other computers), I seem to be having trouble accessing this empty form. I know this is probably a very simple answer, but I have been stuck for over a full work day and it has completely halted my progress.
Here is a snippet of my environment. On the left is my Project directory in Intellij (CoC.xlsx is the empty form) and the highlights on the right are where I am attempting to access the file and where the error is happening respectively.
JOptionPane.showMessageDialog(null,"About to look for CoC");
//fileFrom = new File(s + "/out/production/XML Reader/CoC.xlsx");
//fileFrom = new File("/XML Reader/out/production/XML Reader/CoC.xlsx");
//fileFrom = new File("CoC.xlsx");
//fileFrom = new File(ExcelWriter.class.getResource("CoC.xlsx").getPath());
CodeSource src = ExcelWriter.class.getProtectionDomain().getCodeSource();
/*if (src != null) {
URL url = new URL(src.getLocation(), "CoC.xlsx");
fileFrom = new File()
System.out.println(url);
} else {
JOptionPane.showMessageDialog(null,"Failed");
} */
fileFrom = new File(new File("."), "CoC.xlsx");
I solved my problem by having people download the whole project folder, file referencing with a ../../ from point of execution, and then going deeper into the file path to find the location at which I placed the file. Choppy, but it works and solved the problem.

Apache Wicket 7 - Application properties

Fairly new to Wicket so excuse my ignorance.
I have a Wicket app...starts with WicketApplication.class I have a WicketApplication.properties file to load some values. The properties file sits next to the class file (same package). Works fine, no issues.
Now, I would like to move the properties file outside the application WAR/JAR. Exported the app as a WAR to run on Tomcat. I have create a a folder called properties under tomcat root & moved WicketApplication.properties to this directory. Added the following to init() method in WicketApplication.class...
String realPath = getServletContext().getRealPath("/");
realPath = realPath.replaceAll("\\\\", "/");
if (realPath.toUpperCase().indexOf("WEBAPPS") != -1) {
String newRes = realPath.substring(0, realPath.toUpperCase().indexOf("WEBAPPS") -1);
System.out.println (newRes + "/properties");
getResourceSettings().getResourceFinders().add(new Path( newRes + "/properties"));
}
I get an exception thrown.
How do I "externalise" the properties file?
Also, if I could take one step further, how do I map a properties file name to class name..it, myapplication.properties -> WicketApplication.class
Thanks in advance.
You need to add new IStringResourceLoader with application.getResourceSettings().getStringResourceLoaders().add(...).
See https://github.com/apache/wicket/blob/515e2be2a5301f5caf7b1baee4a593d21c20e275/wicket-core/src/main/java/org/apache/wicket/settings/ResourceSettings.java#L220-L224 for the default ones.
IResourceFinder should be used when you want to add custom location for your HTML files.
There is no way to map myapplication.properties to WicketApplication.class. By adding an additional IStringResourceLoader you just tell Wicket to search in yet another place.

Java language detection with langdetect - how to load profiles?

I'm trying to use a Java library called langdetect hosted here. It couldn't be easier to use:
Detector detector;
String langDetected = "";
try {
String path = "C:/Users/myUser/Desktop/jars/langdetect/profiles";
DetectorFactory.loadProfile(path);
detector = DetectorFactory.create();
detector.append(text);
langDetected = detector.detect();
}
catch (LangDetectException e) {
throw e;
}
return langDetected;
Except with respect to the DetectFactory.loadProfile method. This library works great when I pass it an absolute file path, but ultimately I think I need to package my code and langdetect's companion profiles directory inside the same JAR file:
myapp.jar/
META-INF/
langdetect/
profiles/
af
bn
en
...etc.
com/
me/
myorg/
LangDetectAdaptor --> is what actually uses the code above
I will make sure that the LangDetectAdaptor which is located inside myapp.jar is supplied with both the langdetect.jar and jsonic.jar dependencies it needs for langdetect to work at runtime. However I'm confused as to what I need to pass in to DetectFactory.loadProfile in order to work:
The langdetect JAR ships with the profiles directory, but you need to initialize it from inside your JAR. So do I copy the profiles directory and put it inside my JAR (like I prescribe above), or is there a way to keep it inside langdetect.jar but access it from inside my code?
Thanks in advance for any help here!
Edit : I think the problem here is that langdetect ships with this profiles directory, but then wants you to initialize it from inside your JAR. The API would probably benefit from being changed a little bit to just consider profiles its own configuration, and to then provide methods like DetectFactory.loadProfiles().except("fr") in the event that you don't want it to initialize French, etc. But this still doesn't solve my problem!
I have the same problem. You can load the profiles from the LangDetect jar using JarUrlConnection and JarEntry. Note in this example I am using Java 7 resource management.
String dirname = "profiles/";
Enumeration<URL> en = Detector.class.getClassLoader().getResources(
dirname);
List<String> profiles = new ArrayList<>();
if (en.hasMoreElements()) {
URL url = en.nextElement();
JarURLConnection urlcon = (JarURLConnection) url.openConnection();
try (JarFile jar = urlcon.getJarFile();) {
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
String entry = entries.nextElement().getName();
if (entry.startsWith(dirname)) {
try (InputStream in = Detector.class.getClassLoader()
.getResourceAsStream(entry);) {
profiles.add(IOUtils.toString(in));
}
}
}
}
}
DetectorFactory.loadProfile(profiles);
Detector detector = DetectorFactory.create();
detector.append(text);
String langDetected = detector.detect();
System.out.println(langDetected);
Since no maven-support was available, and the mechanism to load profiles was not perfect (since you you need to define files instead of resources), I created a fork which solves that problem:
https://github.com/galan/language-detector
I mailed the original author, so he can fork/maintain the changes, but no luck - seems the project is abandoned.
Here is an example of how to use it now (own profiles can be written where necessary):
DetectorFactory.loadProfile(new DefaultProfile()); // SmProfile is also available
Detector detector = DetectorFactory.create();
detector.append(input);
String result = detector.detect();
// maybe work with detector.getProbabilities()
I don't like the static approach the DetectorFactory uses, but I won't rewrite the full project, you have to create your own fork/pull request :)
Looks like the library only accepts files. You can either change the code and try submitting the changes upstream. Or write your resource to a temp file and get it to load that.
The solution provided by Mark Butler is still valid and solved my problem, but the dirname needs to be updated as the jar content has changed.
The problem has been reported by Deepak but I have insufficient reputation to reply in comments. Here you are the two declarations you need.
In order to load short profiles:
String dirname = "profiles/shorttext/";
In order to load long profiles:
String dirname = "profiles/longtext/";
Setting the working dir for me fixed the problem.
String workingDir = System.getProperty("user.dir");
DetectorFactory.loadProfile(workingDir+"/profiles/");

Properties keep driving me crazy. Can't save it! "FileNotFound"

these properties keep driving me crazy. I'm reading everywhere, that even loading the properties should be no problem by just using:
Properties p = new Properties();
p.load(new FileInputStream("filename.properties");
Though in my case it doest work. Java is not finding the file, which is located in the class directory! Thats why i HAD TO use it with the Assetmanager:
String defaultProfileProperties = "filename.properties";
Resources resources = this.getResources();
AssetManager assetManager = resources.getAssets();
final Properties properties = new Properties();
try {
InputStream inputStream = assetManager.open(defaultProfileProperties);
properties.load(inputStream);
} catch (IOException e) {
System.err.println("Failed to open " + defaultProfileProperties + " property file");
e.printStackTrace();
}
Putting the filename.properties in the assets-folder.
Well, now I simply can't save the properties-file by using .store(out,comment) ...
I tried using a FileOutputStream with the path set to either "filename.properties", or "assets/filename.properties". Neither of them worked. I even added a slash here and there, but nothing is helping! I'm not finding any tutorials on the web, nor ppl having the same problem!
Could you please just help me? I guess this is such a simple thing, but i'm not getting a clue how to ... blah
If you open a file with FileInputStream, then the starting directory (relative path) is based on the working directory when you started java, NOT the classpath. Opening a file with resources will reference the classpath entries.
Have you tried using a full path when using FileInputStream()? Try that and see if it works, and if it does, then you'll need to either set the working directory at start up and/or reference your file via relative path from the start directory.
Try this:
InputStream in = this.getClass().getResourceAsStream("filename.properties");
Properties p = new Properties();
p.load(in);

Write file in sub-directory in Android

I'm trying to save a file in a subdirectory in Android 1.5.
I can successfully create a directory using
_context.GetFileStreamPath("foo").mkdir();
(_context is the Activity where I start the execution of saving the file) but then if I try to create a file in foo/ by
_context.GetFileStreamPath("foo/bar.txt");
I get a exception saying I can't have directory separator in a file name ("/").
I'm missing something of working with files in Android... I thought I could use the standard Java classes but they don't seem to work...
I searched the Android documentation but I couldn't fine example and google is not helping me too...
I'm asking the wrong question (to google)...
Can you help me out with this?
Thank you!
I understood what I was missing.
Java File classes works just fine, you just have to pass the absolute path where you can actually write files.
To get this "root" directory I used _context.getFilesDir(). This will give you the root of you application. With this I can create file with new File(root + "myFileName") or as Sean Owen said new File(rootDirectory, "myFileName").
You cannot use path directly, but you must make a file object about every directory.
I do not understand why, but this is the way it works.
NOTE: This code makes directories, yours may not need that...
File file = context.getFilesDir();
file.mkdir();
String[] array = filePath.split("/");
for (int t = 0; t < array.length - 1; t++) {
file = new File(file, array[t]);
file.mkdir();
}
File f = new File(file, array[array.length - 1]);
RandomAccessFileOutputStream rvalue = new RandomAccessFileOutputStream(f, append);
Use getDir() to get a handle on the "foo" directory as a File object, and create something like new File(fooDir, "bar.txt") from it.

Categories