Accessing XML Files from the DAM in CQ5 - java

I need to fetch a user uploaded XML file from the DAM, parse this file and store the contents in the JCR. Here's what I have so far
public class foo implements Runnable {
private static final Logger log = LoggerFactory
.getLogger(foo.class);
#Reference
ResourceResolverFactory resourceResolverFactory;
#Reference
ResourceProvider resourceProvider;
ResourceResolver resourceResolver = null;
#Reference
SlingRepository repository;
Session session;
// private static ReadXMLFileUsingDomparserTest readxml;
File tempFile;
public void run(){
log.info("\n *** Seems okay ***\n");
ResourceResolver resourceResolver = null;
try {
resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
Resource resource = resourceResolver.getResource("/content/dam/foo/file.xml");
Node node = resource.adaptTo(Node.class);
boolean isAssest = DamUtil.isAsset(resource);
if (isAssest) {
Asset asset = resource.adaptTo(Asset.class);
List<Rendition> rendition = asset.getRenditions();
for (Rendition re : rendition) {
InputStream in = re.getStream();
File xmlFile = copy(in,tempFile);
if(filetest.exists()){
ReadXMLFileUsingDomparserTest.parseXML(filetest,null);
}else {
log.info("File not found at all");
}
}
}
File xmlFile = copy(in,tempFile);*/
}catch (Exception e) {
log.error("Exception while running foo" , e);
}
}
private File copy(InputStream in, File file) {
try {
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
}
Although I'm able to pick up the Node object correctly (doing Node.getPath() returns the correct path), I am not able to translate this node into a File object. (cannot be Adapted). I want to access this in terms of a File object for parsing. This is why I went through the renditions of the asset and used the stream to copy it into a file.
However, this always shows null for the above code; the output is always File not found at all.
What is the correct way to get a File object with the requisite data from the DAM so that I can successfully parse it?

Uploaded xml file should have an nt:file node, which has a jcr:content node with jcr:data property. You can read the xml from jcr:data i.e: jcrContent.getProperty("jcr:data").getBinary().getStream();
Here are the build in adapters: http://dev.day.com/docs/en/cq/current/developing/sling-adapters.html
I think you can use InputStream here...

Related

Duplicate file and rename with different file extension during runtime [duplicate]

I have one file example.tar.gz and I need to copy it to another location with different name
example _test.tar.gz. I have tried with
private void copyFile(File srcFile, File destFile) throws IOException {
InputStream oInStream = new FileInputStream(srcFile);
OutputStream oOutStream = new FileOutputStream(destFile);
// Transfer bytes from in to out
byte[] oBytes = new byte[1024];
int nLength;
BufferedInputStream oBuffInputStream = new BufferedInputStream(oInStream);
while((nLength = oBuffInputStream.read(oBytes)) > 0) {
oOutStream.write(oBytes, 0, nLength);
}
oInStream.close();
oOutStream.close();
}
where
String from_path = new File("example.tar.gz");
File source = new File(from_path);
File destination = new File("/temp/example_test.tar.gz");
if(!destination.exists())
destination.createNewFile();
and then
copyFile(source, destination);
It doesn't work. The path is correct. It prints that the file exists. Can anybody help me?
Why to reinvent the wheel, just use FileUtils.copyFile(File srcFile, File destFile) , this will handle many scenarios for you
I would suggest Apache commons FileUtils or NIO (direct OS calls)
or Just this
Credits to Josh - standard-concise-way-to-copy-a-file-in-java
File source=new File("example.tar.gz");
File destination=new File("/temp/example_test.tar.gz");
copyFile(source,destination);
Updates:
Changed to transferTo from #bestss
public static void copyFile(File sourceFile, File destFile) throws IOException {
if(!destFile.exists()) {
destFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
try {
source = new RandomAccessFile(sourceFile,"rw").getChannel();
destination = new RandomAccessFile(destFile,"rw").getChannel();
long position = 0;
long count = source.size();
source.transferTo(position, count, destination);
}
finally {
if(source != null) {
source.close();
}
if(destination != null) {
destination.close();
}
}
}
There is Files class in package java.nio.file. You can use the copy method.
Example: Files.copy(sourcePath, targetPath).
Create a targetPath object (which is an instance of Path) with the new name of your file.

how to get the path of project directory in spring?

i am trying to upload an image file with my jsp form. i am successfully being able to upload it but not in the directory that i want.
#Controller
public class ProductController {
private Path path;
#Autowired
private ProductService productService;
#RequestMapping(value="/admin/addProduct")
public String addProduct() {
return "addProduct";
}
#RequestMapping(value="/admin/addProduct", method= RequestMethod.POST)
public String addNewProduct(#ModelAttribute("product") Product products,
BindingResult result,HttpServletRequest request,#RequestParam("prodImage")
MultipartFile file) {
System.out.println("adding product");
System.out.println(path);
if(result.hasErrors()) {
return "addProduct";
}
productService.saveProduct(products);
MultipartFile productImage = file;
String rootDir = request.getSession().getServletContext().getRealPath("/");
System.out.println(rootDir);
path = Paths.get(rootDir+"//WEB-INF//resources//images//"+products.getId()+
".jpg");
System.out.println("path :"+path);
if(productImage != null && !productImage.isEmpty()) {
System.out.println("inside not null product image");
try {
productImage.transferTo(new File(path.toString()));
System.out.println("after saving image");
}catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException("product image saving failed",ex);
}
}
return "redirect:/admin/productInventory";
}
#RequestMapping("/admin/productInventory")
public String productInventory() {
return "productInventory";
}
}
this is the current dir location being printed:-
/mnt/7A46BE1454633621/eclipseworkspace/ecommerce/target/ecommerce/
path :/mnt/7A46BE1454633621/eclipseworkspace/ecommerce/target/ecommerce/
WEB-INF/resources/images/5.jpg
i want to upload my image inside WEB-INF/resources/images. how can i do that?
you need to check class path is set or not then you can use classpath:/WEB-INF/resources/images/ path to image upload and download.
You can use the below code to upload image to your images folder. Here multipartFile is the reference of MultipartFile interface
InputStream inputStream = multipartFile.getInputStream();
byte[] buf = new byte[1024];
String path = servletContext.getRealPath("WEB-INF/resources/images");
File file = new File(path);
String basePath = file.getCanonicalPath();
String fileName = multipartFile.getOriginalFilename();
FileOutputStream fileOutputStream = new FileOutputStream(basePath+"/"+fileName);
int numRead = 0;
while ((numRead = inputStream.read(buf)) >= 0) {
fileOutputStream.write(buf, 0, numRead);
}
inputStream.close();
fileOutputStream.close();
Also to get servletContext reference autowire ServeletContext interface like this:
#Autowired
ServletContext servletContext;

Copying images from JAR file to a folder outside

My file structure:
This is how it looks using netbeans project:
-src
-images
-*.jpg
-stock
-*.java
-images (exact copy of -images)
and here is my jar
-jar
-images
-*.jpg
-stock
-*.java
-images (folder is created but files don't get copied)
My files imagesCopy is the one that I create and ImagesOrg is the one inside .jar / src
File imagesCopy = new File("images");
File imagesOrg = new File(URLDecoder.decode(getClass().getResource("/images").getPath()));
if (!imagesCopy.exists()) {
imagesCopy.mkdir();
for(final File child : imagesOrg.listFiles()) {
try{
Files.copy(child.toPath(), Paths.get(imagesCopy.getAbsolutePath()+"/"+child.getName()), REPLACE_EXISTING);
}catch(Exception e){
System.out.println(e);
}
}
}
The problem definitely lies with:
File imagesOrg = new File(URLDecoder.decode(getClass().getResource("/images").getPath()));
When compiling it it gives me, which is the proper directory
D:\Code\build\classes\images
which is the right directory, but when using this program from jar file I get:
D:\Code\dist\file:\D:\Code\dist\egz.jar!\images
and I assume that it should just be:
D:\Code\dist\egz.jar!\images
without that first part
Probably the simplest way to do it is like this:
public static void main(String[] args) throws URISyntaxException, IOException {
File imagesCopy = new File("C:\\Users\\<YOURNAMEHERE>\\images");
URI uri = ImageCopy.class.getResource("/images").toURI();
if (!uri.toString().startsWith("file:")) {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
FileSystems.newFileSystem(uri, env);
}
Path imagesOrg = Paths.get(uri);
System.out.println(imagesOrg);
if (!imagesCopy.exists()) {
imagesCopy.mkdir();
try(DirectoryStream<Path> paths = Files.newDirectoryStream(imagesOrg)) {
for (final Path child : paths) {
System.out.println(child);
try {
String targetPath = imagesCopy.getAbsolutePath() + File.separator + child.getFileName().toString();
System.out.println(targetPath);
Files.copy(child, Paths.get(targetPath), StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
It's not super-pretty, but it works. Might need to fiddle with the code if you have nested directories.
Note that you must create the FileSystem before accessing it (as per the Oracle Docs). I don't know why this is required, but there we go.
I've tested this and it will copy files from inside your JAR to wherever you would like.
Here is a simple code to do it. You can adapt as you need.
package br.com.jjcampos.main;
//imports here
public class CopyImage {
private static ClassLoader loader = CopyImage.class.getClassLoader();
public static void main(String[] args) throws IOException {
InputStream stream = loader.getResourceAsStream("br/com/jjcampos/images/test.jpg");
OutputStream outputStream =
new FileOutputStream(new File("c:/temp/newImage.jpg"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
}
}
Understand that you can't copy a source from a stream (your jar) as a list of files. Unless you want to unpack it first. My suggestion is you to add a txt file with the list of your images then you read this file and use suggested code to copy each one.
Something like this:
public class CopyImage {
private static ClassLoader loader = CopyImage.class.getClassLoader();
public static void main(String[] args) throws IOException {
copyImages("c:/temp/");
}
public static void copyImages(String pathDestiny) throws IOException{
InputStream listOfFiles = loader
.getResourceAsStream("br/com/jjcampos/images/listImages.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(listOfFiles));
String line;
while ( (line = reader.readLine())!=null ){
InputStream stream = loader.getResourceAsStream("br/com/jjcampos/images/"
+ line);
OutputStream outputStream =
new FileOutputStream(new File(pathDestiny + line));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
}
}
}
And your listImages.txt with
test.jpg
And you should decide if you put the full path on the text file or not to use in your code.

pdf,doc,xls file upload in mysql database

How to upload all document files Like PDF, DOCX,XLS to mysql Database using java and JPA and Spring
Thanks in advance
I did come across a similar situation but with Minor Modifications of your requirement.., like
DB - Oracle 11g (Instead of mySql)
IDE - jDeveloper 11 (To take care of Java, Swings - MVC)
If you'r cool with this modification plz have a look how I developed this,
Flow: UI(Pass the file)--->(Processing by IDE)--->DB(Data Saved)
Create a DB Schema:(2 Coloumns)
Info - Varchar 2 (Data Type)
Media - Blob
Now that done with DB, Come to IDE & create a .jspx Page (Without Backing Bean!), Drag & Drop InputFile Component from Component Palette. Create a Managed bean and write the following code to recieve the file as Parameter from UI & process further.
Code:-
public class Upload()
{
private UploadedFile _file;
public void setFile(UploadedFile _file) {
this._file = _file;
}
public UploadedFile getFile() {
return _file;
}
public String UploadMedia(){
UploadedFile myFile = (UploadedFile)this.getFile();
System.out.println("****************************************************");
BindingContext bc = BindingContext.getCurrent();
BindingContainer bindings = bc.getCurrentBindingsEntry();
DCBindingContainer dbc = (DCBindingContainer)bindings;
DCIteratorBinding iter = dbc.findIteratorBinding("MediadbVO1Iterator");
Row row = iter.getCurrentRow();
row.setAttribute("Media", createBlobDomain(myFile));
return null;
}
private BlobDomain createBlobDomain(UploadedFile file) {
InputStream in = null;
BlobDomain blobDomain = null;
OutputStream out = null;
try {
in = file.getInputStream();
blobDomain = new BlobDomain();
out = blobDomain.getBinaryOutputStream();
byte[] buffer = new byte[8192];
int bytesRead = 0;
while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
out.write(buffer, 0, bytesRead);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.fillInStackTrace();
}
return blobDomain;
}
}
Set the "Value" field of InputFile Component as "#{backing_Upload.file}"
where backing_Upload is my bean name with file as Paramater.
Now Drag & Drop a Command Button & set its Action Field as "#{backing_Upload.UploadMedia}"
where backing_Upload is my bean name and UploadMedia is my method.
Hope you achieve what you desired on selecting file & clicking Button the file gets stored to DB.
You cannot store files in a DATABASE, but can store their location in the table.

Java Large file to be saved in database - Object design

I am trying to figure out object design to implement large file(~600 MB) respository in the Database using hibernate.
Please suggest a correct approach/design?
class ModelClass{
String name; //meta data
...
Option 1.
byte[] file; // dont want to load the content of the entire file
// in memory by using this but hibernate recognizes
// this datatype
Option 2.
InputStream inputStream;
OutputStream outputStream;
// I can have the methods to provide the input or output stream
// but i dont think its a clean approach. I am not sure how
// I will be able to work with hibernate with streams
Option 3.
File fileHandle;
}
Any other options??
I would like to call save(Object) method of hibernateTemplate to save the object in Database. Dont know if I should have just the meta-data in the class and handle the file save and retreive seperately.
Thanks in advance.
Another workable solution is to use "Work" Interface. The purpose was to avoid loading the file content into memory.
session.doWork(new Work(){
#Override
public void execute(Connection conn) {
//direct sql queries go here
}
});
I have written a SerializableFile class that keeps data in a file. When the object is read, it creates a temporary file.
Here it is:
public class SerializableFile implements Serializable {
private static final File TEMP_DIR = getTempDir();
private transient boolean temporary;
private transient String name;
private transient File file;
public SerializableFile() {
}
public SerializableFile(File file) {
this.file = file;
this.name = file.getName();
this.temporary = false;
}
#Override
protected void finalize() throws Throwable {
dispose();
super.finalize();
}
public void dispose() {
if (temporary && file != null) {
file.delete();
file = null;
}
}
public File keep(String name) throws IOException {
if (temporary) {
temporary = false;
} else {
File newFile = new File(TEMP_DIR, name);
keepAs(newFile);
file = newFile;
}
return file;
}
public void keepAs(File outFile) throws IOException {
if ((temporary || file.equals(outFile)) && file.renameTo(outFile)) {
temporary = false;
file = outFile;
} else {
InputStream in = new FileInputStream(file);
try {
OutputStream out = new FileOutputStream(outFile);
try {
byte buf[] = new byte[4096];
for (int n = in.read(buf); n > 0; n = in.read(buf)) {
out.write(buf, 0, n);
}
} finally {
out.close();
}
} finally {
in.close();
}
outFile.setLastModified(file.lastModified());
}
}
public String getName() {
return name;
}
public File getFile() {
return file;
}
public long lastModified() {
return file.lastModified();
}
private void writeObject(ObjectOutputStream out) throws IOException {
int size = (int)file.length();
long date = file.lastModified();
out.writeUTF(name);
out.writeInt(size);
out.writeLong(date);
InputStream in = new FileInputStream(file);
try {
byte buf[] = new byte[4096];
while (size > 0) {
int n = in.read(buf);
if (n <= 0 || n > size) {
throw new IOException("Unexpected file size");
}
out.write(buf, 0, n);
size -= n;
}
} finally {
in.close();
}
}
private void readObject(ObjectInputStream in) throws IOException {
name = in.readUTF();
int size = in.readInt();
long date = in.readLong();
file = File.createTempFile("tmp", ".tmp", TEMP_DIR);
OutputStream out = new FileOutputStream(file);
try {
byte buf[] = new byte[4096];
while (size > 0) {
int n = in.read(buf, 0, size <= buf.length ? size : buf.length);
if (n <= 0 || n > size) {
throw new IOException("Unexpected file size");
}
out.write(buf, 0, n);
size -= n;
}
} finally {
out.close();
}
file.setLastModified(date);
temporary = true;
}
private static File getTempDir() {
File dir;
String temp = System.getProperty("com.lagalerie.live.temp-dir");
if (temp != null) {
dir = new File(temp);
} else {
String home = System.getProperty("user.home");
dir = new File(home, "temp");
}
if (!dir.isDirectory() && !dir.mkdirs()) {
throw new RuntimeException("Could not create temp dir " + dir);
}
return dir;
}
}
Open JPA supports a #Persistent annotation with some databases:
MySQL
Oracle
PostgreSQL
SQL Server
DB2
Even if you are still using an RDBMS as a data store, you should consider storing this binary data into a file system, and saving the directory / location of the path into the database, instead of storing this as a BLOB or CLOB into the database.

Categories