I'm attempting to provide a StreamingResponse for files stored under Lifts resources/toserve directory, in order to authorize access for different users.
I can access an image for example with:
localhost:8080/classpath/images/test.jpg
But when I try and actually read the file using scala I keep getting file not found exceptions:
val file = new java.io.FileInputStream("/classpath/images/test.jpg")
Is there a specific method to reading files located on classpath?
Thanks in advance, much appreciated :)
To read resources from the toserve-directory you need to do a call like
LiftRules.getResource("/toserve/images/test.jpg")
If you try to use 'classpath' instead of 'toserve' you will receive an empty box.
By default, Lift uses two different path-prefixes to locate resources either programmatically within the server or through a link-element from HTML. For the former, you will use the 'toserve'-prefix, for the latter the 'classpath'-prefix.
This behavior is specified in the objects net.liftweb.http.LiftRules and net.liftweb.http.ResourceServer. In particular, you can there specify (i.e. replace) the path to the resources. The relevant code is:
/** (from net.liftweb.http.ResourceServer)
* The base package for serving resources. This way, resource names can't be spoofed
*/
var baseResourceLocation = "toserve"
You might also want to look at the following method in LiftRules, which allows you to redefine the name used to serve resources through the server:
/** (from net.liftweb.http.LiftRules)
* The path to handle served resources
*/
#volatile var resourceServerPath = "classpath"
If you wish to use the same prefix to refer both to resources you can use either (or both) of these settings to achieve your purpose.
Have you tried:
LiftRules.getResource("/classpath/images/test.jpg")
That should return a java.net.URL to the item you are looking for.
This may also have more information on what you are looking to do: http://exploring.liftweb.net/master/index-9.html#lst:streaming-download
Related
I'm having some trouble figuring out how to migrate my code to use org.stringtemplate.v4 . I have a single template file in a 'templates' folder under src/main/resources. Nothing fancy going on. I just need to load the template, set a few attributes, and pass it along in my html response. The problem is, the template is getting bundled into the deployed jar, which means I can't do a normal classpath lookup. Usually in a case like this, I would use an InputStream, but I can't find any way of doing that with the available constructors for ST and STGroup. Does anyone know how to do this? is there an easier way I'm just overlooking?
Here is what my code looks like:
STGroup group = new STGroupDir("templates");
ST template = group.getInstanceOf("smartSubmitResponse");
template.add("errors", results.exceptions.asMap());
template.add("plannedDates", results.plannedDates);
return Response.status(Response.Status.OK).header("smartSubmitFileUrl", url)
.header("errors", errorHeaders.toString()).entity(template.toString()).build();
Currently, it is failing with a null pointer exception since template is not being set correctly.
I finally figured it out. I needed to use org.stringtemplate.v4.STRawGroupDir since my template was using the older format with no wrapping characters. My result ended up looking like this:
STGroup group = new STRawGroupDir("templates",'$','$');
ST template = group.getInstanceOf("smartSubmitResponse");
I am developing a web application using the full stack framework focframework, and I want to know what are the properties that I can control in my config.properties file. Is there a doc for this?
I tried searching the doc but dodn't find anything
Obviously we can figure out some of then from the sample on GitHub by looking at the config.properties file:
jdbc.drivers=org.h2.Driver
jdbc.url=jdbc:h2:./myfocapplication_data_h2
jdbc.username=sa
jdbc.password=
gui.rtl=0
allowAddInsideComboBox=0
focWebServerClassName=com.focframework.sample.myfocapplication.MyFocAppWebServer
dataSourceClass=b01.focDataSourceDB.FocDataSource_DB
cloudStorageClass=com.focCloudStorage.FocCloudStorageS3
cloudStorageClass=com.foc.cloudStorage.FocCloudStorage_LocalDisc
devMode=1
unitDevMode=0
unitAllowed=1
log.dir=c:/01barmaja/log
log.ConsoleActive=1
log.fileActive=1
log.popupExceptionDialog=1
log.dbRequest=1
log.dbSelect=1
debug.showStatusColumn=0
log.debug=1
perf.active=0
Is there any hint on how to get all of them? And what if I want to add my own to be used in my code?
The ConfigInfo.java file is the one responsible of reading all the properties and storing them in variables. It is straight forward to understand and check the variables names and usage. Yet I agree that someone should work on the documentation and add these parameters.
To add your own without modifying the ConfigInfo.java you can simply use this method in the middle of your code.
String myProperty = ConfigInfo.getProperty("my.property.with.a.meanignful.name");
I want to move few assets by creating a new folder using only the workflow in java.I dont want to create the folders manually and then move the assets as there are 10000s of assets that are to be moved to different folders.
If you are looking at creating folder using workflow - A folder in AEM is nothing but a node of jcr:primaryType either sling:Folder or sling:OrderedFolder. If you have com.day.cq.commons.jcr in your classpath, createPath method will help you create a node if it does not exist.
You could also use addNode method followed by setProperty method from javax.jcr.Node api to create this folder of appropriate primary type.
Moving assets to this newly created node(folder), can proceed after this. You could use the clone method from javax.jcr.WorkSpace which has an option to remove the existing node.
There is another straight forward way to move assets.
I would recommend you to use built-in com.adobe.granite.asset.api.AssetManager api to perform CRUD operations on DAM assets.
session = resourceResolver.adaptTo(Session.class);
String assetPath = "/content/dam/folderA/asset1.jpg";
String movePath = "/content/dam/folderB/asset1.jpg";
assetManager.moveAsset(assetPath, copyPath);
session.save()
session.logout()
Further references for AssetManager API.
HelpX Article
API Details
Moving large number of assets might cause the move operation to fail if there no appropriate indexes in place. Monitor logs for warning messages like The query read or traversed more than X nodes.. You might have to add oak based properties to the out-of-the-box /oak:index/ntBaseLucene index to fix this.
More details here.
Is there any method to create a file in java that cannot be deleted.
I have googled it and found processes involving the cmd.
However, I require a pure "java" way that can be done on any platform.
Thanks in advance.
Thank you for your help.
I finally got it right.
I used the following code to deny access to user
public static void main() throws IOException
{
Path file = Paths.get("c:/b.txt");
AclFileAttributeView aclAttr = Files.getFileAttributeView(file, AclFileAttributeView.class);
//System.out.println();
UserPrincipalLookupService upls = file.getFileSystem().getUserPrincipalLookupService();
UserPrincipal user = upls.lookupPrincipalByName(System.getProperty("user.name"));
AclEntry.Builder builder = AclEntry.newBuilder();
builder.setPermissions(EnumSet.of(AclEntryPermission.APPEND_DATA, AclEntryPermission.DELETE, AclEntryPermission.DELETE_CHILD, AclEntryPermission.EXECUTE, AclEntryPermission.READ_ACL, AclEntryPermission.READ_ATTRIBUTES, AclEntryPermission.READ_DATA, AclEntryPermission.READ_NAMED_ATTRS, AclEntryPermission.SYNCHRONIZE, AclEntryPermission.WRITE_ACL, AclEntryPermission.WRITE_ATTRIBUTES, AclEntryPermission.WRITE_DATA, AclEntryPermission.WRITE_NAMED_ATTRS, AclEntryPermission.WRITE_OWNER));
builder.setPrincipal(user);
builder.setType(AclEntryType.DENY);
aclAttr.setAcl(Collections.singletonList(builder.build()));
}
Try the method setPosixFilePermissions() and set the permissions to read only for all the classes of users. Refer this - http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#setPosixFilePermissions%28java.nio.file.Path,%20java.util.Set%29
If you want to create a file that can't be accidentally overwritten, then look at the various answers to this: How do i programmatically change file permissions?
If you want to create a file that the current program cannot delete at all (but a privileged one could), it might be possible by setting permissions appropriately on the parent directory, or possibly using SELinux Mandatory Access Control cleverness.
If you want to create a truly undeleteable file, then you are out of luck. I am not aware of any operating system that supports creation of files that can never be deleted. It would be an "anti-feature".
I would also agree with #Teifi's comment. Create a file that cannot ever be deleted on the user's machine is not acceptable ... unless done by, or with the authorization of the system's administrators. I would call any software that did that "malicious" too.
Background:
I have a requirement that messages displayed to the user must vary both by language and by company division. Thus, I can't use out of the box resource bundles, so I'm essentially writing my own version of resource bundles using PropertiesConfiguration files.
In addition, I have a requirement that messages must be modifiable dynamically in production w/o doing restarts.
I'm loading up three different iterations of property files:
-basename_division.properties
-basename_2CharLanguageCode.properties
-basename.properties
These files exist in the classpath. This code is going into a tag library to be used by multiple portlets in a Portal.
I construct the possible .properties files, and then try to load each of them via the following:
PropertiesConfiguration configurationProperties;
try {
configurationProperties = new PropertiesConfiguration(propertyFileName);
configurationProperties.setReloadingStrategy(new FileChangedReloadingStrategy());
} catch (ConfigurationException e) {
/* This is ok -- it just means that the specific configuration file doesn't
exist right now, which will often be true. */
return(null);
}
If it did successfully locate a file, it saves the created PropertiesConfiguration into a hashmap for reuse, and then tries to find the key. (Unlike regular resource bundles, if it doesn't find the key, it then tries to find the more general file to see if the key exists in that file -- so that only override exceptions need to be put into language/division specific property files.)
The Problem:
If a file did not exist the first time it was checked, it throws the expected exception. However, if at a later time a file is then later dropped into the classpath and this code is then re-run, the exception is still thrown. Restarting the portal obviously clears the problem, but that's not useful to me -- I need to be able to allow them to drop new messages in place for language/companyDivision overrides w/o a restart. And I'm not that interested in creating blank files for all possible divisions, since there are quite a few divisions.
I'm assuming this is a classLoader issue, in that it determines that the file did not exist in the classpath the first time, and caches that result when trying to reload the same file. I'm not interested in doing anything too fancy w/ the classLoader. (I'd be the only one who would be able to understand/maintain that code.) The specific environment is WebSphere Portal.
Any ways around this or am I stuck?
My guess is that I am not sure if Apache's FileChangedReloadingStrategy also reports the events of ENTRY_CREATE on a file system directory.
If you're using Java 7, I propose to try the following. Simply, implement a new ReloadingStrategy using Java 7 WatchService. In this way, every time either a file is changed in your target directories or a new property file is placed there, you poll for the event and able to add the properties to your application.
If not on Java 7, maybe using a library such as JNotify would be a better solution to get the event of a new entry in a directory. But again, you need to implement the ReloadingStrategy.
UPDATE for Java 6:
PropertiesConfiguration configurationProperties;
try {
configurationProperties = new PropertiesConfiguration(propertyFileName);
configurationProperties.setReloadingStrategy(new FileChangedReloadingStrategy());
} catch (ConfigurationException e) {
JNotify.addWatch(propertyFileDirectory, JNotify.FILE_CREATED, false, new FileCreatedListener());
}
where
class FileCreatedListener implements JNotifyListener {
// other methods
public void fileCreated(int watchId, String rootPath, String fileName) {
configurationProperties = new PropertiesConfiguration(rootPath + "/" + fileName);
configurationProperties.setReloadingStrategy(new FileChangedReloadingStrategy());
// or any other business with configurationProperties
}
}