Extended File-Attribute

D

DN

Hi,

I'm searching for a way to modify the extended File-Attributes for
Windows XP OS.
If you right-click on the attribute-colums in the windows-explorer
there are several attribute available the java.io.File class does not
offer access to.
 
M

mromarkhan

Peace be unto you.

Disclaimer: Use at own risk. Prototype only.
This is more or less a hack.
I guess J2SE 1.5.1 Dragonfly (dragon),
J2SE 1.6.0 Mustang,
or Apache might provide solutions.
http://java.sun.com/j2se/codenames.html
"Writing properties is possible at a low level only at the moment."
- http://jakarta.apache.org/poi/hpsf/how-to.html



See screenshot
http://members.rogers.com/mromarkhan/nntp-test/Poi.jpg
[caption: Page number is set to a 100 thousand]

I looked at the source code, so I guess I
am bounded by the Apache license.
Well I am no legal expert so here goes.
My part is released in the public domain.


This software uses Jakarta POI (written in pure Java) to retrieve
and change the properties of an ole compound document.

Jakarta POI - Java API To Access Microsoft Format Files
http://jakarta.apache.org/poi/
The Horrible Property Set Format (HPSF)
http://www.rainer-klute.de/~klute/Software/poibrowser/doc/HPSF-Description.html


At the time of writing, I needed to
download some files that were missing from the
library destribution. So I used
cvs to grab them.

Using cvs
http://jakarta.apache.org/site/cvsonwin32.html
http://jakarta.apache.org/site/cvsindex.html

1.
Download jCVS
http://www.gjt.org/
Is a simple cvs grabber/checkout
written in Java.

2.
Change shortcut to point to jdk
or
javaw.exe -jar jcvsii.jar

3.
Change temp to c:/windows/temp if does not exist

4.
Click Checkout tab

***Given***
<fromWebSite>
cvs -d :pserver:[email protected]:/home/cvspublic login
password: anoncvs
"Modules available for access are (click the links to view the CVS tree via ViewCVS):
jakarata-poi"
"src/java" in http://cvs.apache.org/viewcvs/jakarta-poi/
</fromWebSite>

5.
CVS Settings
------------
PServer Checked
Username:anoncvs
Password:anoncvs
CVS Module:jakarta-poi
CVS Server:cvs.apache.org
CVS Repository:/home/cvspublic
Checkout Directory:/jakarta-poi-src

All files are stored in C:\jakarta-poi-src

Now you can use the org directory as part of your classpath.

Files
-----
ParseFs.java
Proof of concept file.
Iterates through a directory structure
retrieving the title and application
name of the document.

TestMutation.java
Proof of concept file.
Changes the extended
properties of a file.

XProperty.java
A helper class.

XSummaryInformation.java
A helper class to store XProperties
about a file.

XFile.java
extends java.io.File so
can be used with existing code

ModifySICopyTheRest.java
A helper class stripped
from Apache source code.

I deleted a lot of important comments and
changed the integrity of the following files.

This product includes software developed by
The Apache Software Foundation (http://www.apache.org/

/* ====================================================================
Copyright 2002-2004 Apache Software Foundation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */


<code filename="TestMutation.java">
import java.io.*;
import java.util.*;
import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.hpsf.MutablePropertySet;
import org.apache.poi.hpsf.MutableSection;
import org.apache.poi.hpsf.wellknown.PropertyIDMap;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.wellknown.SectionIDMap;
import org.apache.poi.hpsf.Variant;
import org.apache.poi.hpsf.PropertySetFactory;
public class TestMutation
{
public static void main(String [] args) throws Exception
{
String fileName = "C:/Windows/Desktop/Test.doc"; //input
File tempFile = new File("TestMutation.doc"); //output
String descName = tempFile.getCanonicalPath();
XFile myFile = new XFile(fileName);
XSummaryInformation xsi = new XSummaryInformation();
xsi.setTitle("This is a title");
xsi.setAuthor("John Aaron");
xsi.setLastPrinted(new Date());
xsi.setPageCount(113323123);
xsi.setComments("This is a comment");
myFile.setXSummaryInformation(xsi, descName);
}
}
</code>

<code filename="ParseFs.java">
import java.io.*;
import java.util.*;
class ParseFs
{
static String linkURL = "";
static String baseString = "C:/My Documents/Omar";

public static void main(String args[])
throws Exception
{
XFile root = new XFile("C:/My Documents/Omar");
String [] assertListing = root.list();
if(assertListing != null)
{
driller(root.getPath(), assertListing);
}
}

public static void driller(String path, String[] dirListing)
throws Exception
{
for(int i = 0; i < dirListing.length;++i)
{
XFile child = new XFile(path + "/" + dirListing);
if(child != null)
{
if(child.isFile())
{

String urlString = "";
urlString = baseString + linkURL + "/" + dirListing;
if(child.getExtension() != null)
{
if(child.getExtension().equals(".doc") ||
child.getExtension().equals(".xls") ||
child.getExtension().equals(".ppt") )
{
try
{
System.out.println("Title:" + child.getSummaryInformation().getTitle());
System.out.println("Author:" + child.getSummaryInformation().getAuthor());
System.out.println("Application Name:" + child.getSummaryInformation().getApplicationName() );
System.out.println("Page Count:" + child.getSummaryInformation().getPageCount());
System.out.println("Word Count:" + child.getSummaryInformation().getWordCount());
System.out.println("--------------------------");
}
catch(Exception e)
{
}
}
}

}
else
{
String urlString = "";
urlString = baseString + linkURL + "/" + dirListing;
String [] assertListing = child.list();
if(assertListing != null)
{
linkURL = linkURL + "/" + dirListing;
driller(child.getPath(), assertListing);
int nSIndex = linkURL.lastIndexOf("/");
if(nSIndex == -1)
{
}
else
{
linkURL = linkURL.substring(0,nSIndex);
}
}
}
}
}
}
}
</code>

<code filename="XFile.java">
import java.io.*;
import java.util.*;
import java.net.*;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.HPSFRuntimeException;
import org.apache.poi.hpsf.MarkUnsupportedException;
import org.apache.poi.hpsf.MutablePropertySet;
import org.apache.poi.hpsf.MutableSection;
import org.apache.poi.hpsf.NoPropertySetStreamException;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.Util;
import org.apache.poi.hpsf.Variant;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.hpsf.WritingNotSupportedException;
import org.apache.poi.hpsf.wellknown.PropertyIDMap;
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.poifs.filesystem.Entry;
public class XFile extends File
{
private SummaryInformation summaryInformation;
public XFile(File parent, String child)
{
super(parent,child);
}
public XFile(String pathname)
{
super(pathname);
}
public XFile(String parent, String child)
{
super(parent,child);
}
public XFile(URI uri)
{
super(uri);
}

public DocumentSummaryInformation getDocumentSummaryInformation() throws Exception
{
// Alternative way of reading information from a file
String fileName = getCanonicalPath();
InputStream inputStream = new FileInputStream(fileName);
POIFSFileSystem fs = new POIFSFileSystem(inputStream);
DirectoryEntry dir = fs.getRoot();
Entry dsiEntry = dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
DocumentEntry dsiDocumentEntry = null;
DocumentInputStream dsiDocumentInputStream = null ;
DocumentEntry dsiTestDocumentEntry = null;
dsiDocumentEntry = (DocumentEntry) dsiEntry;
dsiDocumentInputStream = new DocumentInputStream(dsiDocumentEntry);
DocumentSummaryInformation dsi = null;
dsi = (DocumentSummaryInformation) PropertySetFactory.create(dsiDocumentInputStream );
return dsi;
}

private class ReadFileForSummaryInformation implements POIFSReaderListener
{
public void processPOIFSReaderEvent(final POIFSReaderEvent event)
{
try
{
summaryInformation = (SummaryInformation) PropertySetFactory.create(event.getStream());
}
catch(Exception e)
{
}
}
}

public SummaryInformation getSummaryInformation() throws Exception
{
if(summaryInformation == null)
{
String fileName = getCanonicalPath();
POIFSReader r = new POIFSReader();
r.registerListener(new ReadFileForSummaryInformation(),
"\005SummaryInformation");
r.read(new FileInputStream(fileName));
}
return summaryInformation;
}

public void setXSummaryInformation(XSummaryInformation xsi, String dstName ) throws Exception
{
String srcName = getCanonicalPath();
POIFSReader r = new POIFSReader();
ModifySICopyTheRest msrl = new ModifySICopyTheRest(dstName, xsi);
r.registerListener(msrl);
r.read(new FileInputStream(srcName));
msrl.close();
}

public String getExtension() throws Exception
{
String path = getCanonicalPath();
int lastPeriod = path.lastIndexOf(".");
if(lastPeriod != -1)
{
return path.substring(lastPeriod, path.length());
}
else
{
return null;
}
}
}
</code>

<code filename="XProperty.java">
public class XProperty
{
private int id;
private long variantType;
private Object value;
public XProperty(int id, long variantType, Object value)
{
this.id = id;
this.variantType = variantType;
this.value = value;
}
public int getId()
{
return id;
}
public long getVariantType()
{
return variantType;
}
public Object getValue()
{
return value;
}
}
</code>

<code filename="XSummaryInformation.java">
import java.util.*;
import org.apache.poi.hpsf.wellknown.PropertyIDMap;
import org.apache.poi.hpsf.Variant;

public class XSummaryInformation
{
XProperty titleProperty;
XProperty subjectProperty;
XProperty authorProperty;
XProperty keywordsProperty;
XProperty commentsProperty;
XProperty templateProperty;
XProperty lastauthorProperty;
XProperty revnumberProperty;
XProperty edittimeProperty;
XProperty lastprintedProperty;
XProperty createdatetimeProperty;
XProperty lastsavedatetimeProperty;
XProperty pagecountProperty;
XProperty wordcountProperty;
XProperty charcountProperty;
XProperty thumbnailProperty;
XProperty applicationnameProperty;
XProperty securityProperty;
public Iterator getChangedProperties()
{
ArrayList arr = new ArrayList();
if(titleProperty != null)
{
arr.add(titleProperty);
}
if(subjectProperty!= null)
{
arr.add(subjectProperty);
}
if(authorProperty != null)
{
arr.add(authorProperty);
}
if(keywordsProperty != null)
{
arr.add(keywordsProperty );
}
if(commentsProperty != null)
{
arr.add(commentsProperty );
}
if(templateProperty!= null)
{
arr.add(templateProperty );
}
if(lastauthorProperty != null)
{
arr.add(lastauthorProperty );
}
if(revnumberProperty != null)
{
arr.add(revnumberProperty );
}
if(edittimeProperty != null)
{
arr.add(edittimeProperty );
}
if(lastprintedProperty!= null)
{
arr.add(lastprintedProperty );
}
if(createdatetimeProperty != null)
{
arr.add(createdatetimeProperty );
}
if(lastsavedatetimeProperty != null)
{
arr.add(lastsavedatetimeProperty );
}
if(pagecountProperty != null)
{
arr.add(pagecountProperty);
}
if(wordcountProperty!= null)
{
arr.add(wordcountProperty );
}
if(charcountProperty != null)
{
arr.add(charcountProperty );
}
if(thumbnailProperty != null)
{
arr.add(thumbnailProperty);
}
if(applicationnameProperty != null)
{
arr.add(applicationnameProperty );
}
if(securityProperty != null)
{
arr.add(securityProperty );
}
return arr.iterator();
}

public void setTitle(String v) throws Exception
{
int id = PropertyIDMap.PID_TITLE;
long variantType = Variant.VT_LPSTR;
Object value = v;
titleProperty = new XProperty(id,variantType,v);
}


public void setSubject(String v) throws Exception
{
int id = PropertyIDMap.PID_SUBJECT;
long variantType = Variant.VT_LPSTR;
Object value = v;
subjectProperty = new XProperty(id,variantType,v);
}


public void setAuthor(String v) throws Exception
{
int id = PropertyIDMap.PID_AUTHOR;
long variantType = Variant.VT_LPSTR;
Object value = v;
authorProperty = new XProperty(id,variantType,v);
}

public void setKeywords(String v) throws Exception
{
int id = PropertyIDMap.PID_KEYWORDS;
long variantType = Variant.VT_LPSTR;
Object value = v;
keywordsProperty = new XProperty(id,variantType,v);
}


public void setComments(String v) throws Exception
{
int id = PropertyIDMap.PID_COMMENTS;
long variantType = Variant.VT_LPSTR;
Object value = v;
commentsProperty = new XProperty(id,variantType,v);
}

public void setTemplate(String v) throws Exception
{
int id = PropertyIDMap.PID_TEMPLATE;
long variantType = Variant.VT_LPSTR;
Object value = v;
templateProperty = new XProperty(id,variantType,v);
}


public void setLastAuthor(String v) throws Exception
{
int id = PropertyIDMap.PID_LASTAUTHOR;
long variantType = Variant.VT_LPSTR;
Object value = v;
lastauthorProperty = new XProperty(id,variantType,v);
}


public void setRevNumber(String v) throws Exception
{
int id = PropertyIDMap.PID_REVNUMBER;
long variantType = Variant.VT_LPSTR;
Object value = v;
revnumberProperty = new XProperty(id,variantType,v);
}

public void setEditTime(long longValue) throws Exception
{
Date v = new Date(longValue);
int id = PropertyIDMap.PID_EDITTIME;
long variantType = Variant.VT_FILETIME;
Object value = v;
edittimeProperty = new XProperty(id,variantType,v);
}


public void setLastPrinted(Date v) throws Exception
{
int id = PropertyIDMap.PID_LASTPRINTED;
long variantType = Variant.VT_FILETIME;
Object value = v;
lastprintedProperty = new XProperty(id,variantType,v);
}


public void setCreateDateTime(Date v) throws Exception
{
int id = PropertyIDMap.PID_CREATE_DTM;
long variantType = Variant.VT_FILETIME;
Object value = v;
createdatetimeProperty = new XProperty(id,variantType,v);
}

public void setLastSaveDateTime(Date v) throws Exception
{
int id = PropertyIDMap.PID_LASTSAVE_DTM;
long variantType = Variant.VT_FILETIME;
Object value = v;
lastsavedatetimeProperty = new XProperty(id,variantType,v);
}

public void setPageCount(int inv) throws Exception
{
Integer vAsInt = new Integer( inv);
long vAsLong = vAsInt.longValue();
Long v = new Long(vAsLong);
int id = PropertyIDMap.PID_PAGECOUNT;
long variantType = Variant.VT_I4;
Object value = v;
pagecountProperty = new XProperty(id,variantType,v);
}
public void setWordCount(int inv) throws Exception
{
Integer vAsInt = new Integer( inv);
long vAsLong = vAsInt.longValue();
Long v = new Long(vAsLong);
int id = PropertyIDMap.PID_WORDCOUNT;
long variantType = Variant.VT_I4;
Object value = v;
wordcountProperty = new XProperty(id,variantType,v);
}
public void setCharCount(int inv) throws Exception
{
Integer vAsInt = new Integer( inv);
long vAsLong = vAsInt.longValue();
Long v = new Long(vAsLong);
int id = PropertyIDMap.PID_CHARCOUNT;
long variantType = Variant.VT_I4;
Object value = v;
charcountProperty = new XProperty(id,variantType,v);
}

public void setThumbnail(byte [] v) throws Exception
{
int id = PropertyIDMap.PID_THUMBNAIL;
long variantType = Variant.VT_CF;
Object value = v;
thumbnailProperty = new XProperty(id,variantType,v);
}

public void setApplicationName(String v) throws Exception
{
int id = PropertyIDMap.PID_APPNAME;
long variantType = Variant.VT_LPSTR;
Object value = v;
applicationnameProperty = new XProperty(id,variantType,v);
}
public void setSecurity(int inv) throws Exception
{
Integer vAsInt = new Integer( inv);
long vAsLong = vAsInt.longValue();
Long v = new Long(vAsLong);
int id = PropertyIDMap.PID_SECURITY;
long variantType = Variant.VT_I4;
Object value = v;
securityProperty = new XProperty(id,variantType,v);
}
}
</code>

<code filename="ModifySICopyTheRest.java">
import java.io.*;
import java.util.*;
import java.net.*;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.HPSFRuntimeException;
import org.apache.poi.hpsf.MarkUnsupportedException;
import org.apache.poi.hpsf.MutablePropertySet;
import org.apache.poi.hpsf.MutableSection;
import org.apache.poi.hpsf.NoPropertySetStreamException;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.Util;
import org.apache.poi.hpsf.Variant;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.hpsf.WritingNotSupportedException;
import org.apache.poi.hpsf.wellknown.PropertyIDMap;
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.poifs.filesystem.Entry;

public class ModifySICopyTheRest implements POIFSReaderListener
{
Map paths = new HashMap();
String dstName;
OutputStream out;
POIFSFileSystem poiFs;
XSummaryInformation xSummaryInformation;

public ModifySICopyTheRest(String dstName, XSummaryInformation xSummaryInformation)
{
this.xSummaryInformation = xSummaryInformation;
this.dstName = dstName;
poiFs = new POIFSFileSystem();
}
public void processPOIFSReaderEvent(POIFSReaderEvent event)
{
POIFSDocumentPath path = event.getPath();
String name = event.getName();
DocumentInputStream stream = event.getStream();
try
{
if (PropertySet.isPropertySetStream(stream))
{
PropertySet ps = null;
ps = PropertySetFactory.create(stream);
if (ps.isSummaryInformation())
{
editSI(poiFs, path, name, ps);
}
else
{
copy(poiFs, path, name, ps);
}
}
else
{
copy(poiFs, event.getPath(), event.getName(), stream);
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public void editSI(POIFSFileSystem poiFs,POIFSDocumentPath path,String name,
PropertySet si) throws WritingNotSupportedException, IOException
{
DirectoryEntry de = getPath(poiFs, path);
MutablePropertySet mps = new MutablePropertySet(si);
MutableSection s = (MutableSection) mps.getSections().get(0);
// changed CHANGED
System.out.println("Hello World");
for(Iterator c = xSummaryInformation.getChangedProperties();c.hasNext();)
{
XProperty xp = (XProperty)c.next();
s.setProperty(xp.getId(), xp.getVariantType(),xp.getValue());
System.out.println(xp.getId()+" "+xp.getVariantType()+" "+xp.getValue());
}

InputStream pss = mps.toInputStream();
de.createDocument(name, pss);
}
public void copy(POIFSFileSystem poiFs,
POIFSDocumentPath path,
String name,
PropertySet ps) throws WritingNotSupportedException, IOException
{
DirectoryEntry de = getPath(poiFs, path);
MutablePropertySet mps = new MutablePropertySet(ps);
de.createDocument(name, mps.toInputStream());
}
public void copy(POIFSFileSystem poiFs,
POIFSDocumentPath path,
String name,
DocumentInputStream stream) throws IOException
{
DirectoryEntry de = getPath(poiFs, path);
ByteArrayOutputStream out = new ByteArrayOutputStream();
int c;
while ((c = stream.read()) != -1)
{
out.write(c);
}
stream.close();
out.close();
InputStream in = new ByteArrayInputStream(out.toByteArray());
de.createDocument(name, in);
}
public void close() throws FileNotFoundException, IOException
{
out = new FileOutputStream(dstName);
poiFs.writeFilesystem(out);
out.close();
}
public DirectoryEntry getPath(POIFSFileSystem poiFs,POIFSDocumentPath path)
{
try
{
String s = path.toString();
DirectoryEntry de = (DirectoryEntry) paths.get(s);
if (de != null)
{
return de;
}
int l = path.length();
if (l == 0)
{
de = poiFs.getRoot();
}
else
{
de = getPath(poiFs, path.getParent());
de = de.createDirectory(path.getComponent(path.length() - 1));
}
paths.put(s, de);
return de;
}
catch (IOException ex)
{
ex.printStackTrace(System.err);
throw new RuntimeException(ex.toString());
}
}
}
</code>


Build
-----
javac -classpath "C:\jakarta-poi-src\jakarta-poi\src\java;." *.java
java -classpath "C:\jakarta-poi-src\jakarta-poi\src\java;." TestMutation


References
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top