// CabUtil.java -- utilities for access cabinets
import java.io.*;
import java.util.*;
import java.net.*;
import java.rmi.*;
import org.okip.util.agents.RemoteAgent;
import org.okip.util.romi.client.api.Client;
import org.okip.service.filing.api.*;
import org.okip.service.shared.api.FactoryManager;
import org.okip.service.shared.api.Agent;
public class CabUtil
{
public static final CapabilityType FSReadWrite = new CapabilityType("MIT", "readwrite");
public static final CapabilityType FSMetaCaching = new CapabilityType("MIT", "metaDataCache");
public static final CapabilityType FSLocalAccess = new CapabilityType("MIT", "localAccess");
public static final CapabilityType FSRemoteAccess = new CapabilityType("MIT", "remoteAccess");
public static boolean USE_CACHING_FILESYSTEM = true;
public static boolean NEW_FILESYSTEMS = true;
private static CabinetFactory lfsFactory = null;
private static boolean verbose = false;
public static Cabinet getCabinetFromDirectory(String path)
{
return getCabinet(path);
}
public static Cabinet getCabinet(String path)
{
return (Cabinet) getCabinetEntry(path, true);
}
public static ByteStore getByteStore(String path)
{
return (ByteStore) getCabinetEntry(path, false);
}
public static CabinetEntry getCabinetEntry(String path, boolean isCabinet)
{
if (path.indexOf(':') >= 0) {
URL url;
try {
url = new URL(path);
} catch (MalformedURLException e) {
errout(e);
return null;
}
if (url.getProtocol().equals("ftp")) {
// "ftp" means use passthru RFS code with no actual connection
return getRfsCabinetFromDirectory(url.getPath());
} else
return getRfsCabinetEntryFromURL(url, isCabinet);
} else {
return getEntryFromJavaFile(new File(path), isCabinet);
}
}
/*
* Get a Cabinet given a directory in the local filesystem
*/
public static CabinetEntry getEntryFromJavaFile(File file, boolean isCabinet)
{
if (isCabinet && !file.isDirectory()) {
errout("not a directory: " + file);
return null;
} else if (!isCabinet && !file.isFile()) {
errout("not a file: " + file);
return null;
}
if (lfsFactory == null)
lfsFactory = getLfsCabinetFactory();
CabinetEntry entry = null;
outln("Fetching local entry [" + file + "] thru " + lfsFactory.getClass());
try {
String path = file.getPath();
ID id = lfsFactory.idFromString(path);
if (verbose) outln("Got ID [" + id + "] from path '" + path + "'");
if (isCabinet)
entry = lfsFactory.getCabinet(id);
else
entry = lfsFactory.getByteStore(id);
} catch (Exception e) {
errout(e);
return null;
}
if (verbose) outln("Got local file '" + file + "' as CabinetEntry " + entry);
return entry;
}
/*
* Get a Cabinet given a directory in the local filesystem,
* yet get it through a client-less RFS Cabinet. (Any
* reason we'd ever do this except for testing?)
*/
public static Cabinet getRfsCabinetFromDirectory(String path)
{
//outln("Fetching RFS passthru cabinet from path: [" + path + "]");
File directory = new File(path);
if (!directory.isDirectory()) {
errout("not a directory: " + directory);
return null;
}
outln("Fetching RFS passthru cabinet from directory: [" + directory + "]");
CabinetFactory rfsFactory = getRfsCabinetFactory(null);
Cabinet cabinet = null;
try {
cabinet = rfsFactory.getCabinet(rfsFactory.idFromString(directory.getPath()));
} catch (Exception e) {
errout(e);
return null;
}
if (verbose) outln("Got remote dir [" + directory + "] thru cabinet [" + cabinet + "]");
return cabinet;
}
/*
* Get a Local FilesSystem Cabinet Factory
*/
public static CabinetFactory getLfsCabinetFactory()
{
org.okip.service.filing.api.Factory fileFactory = getFilingServiceFactory();
CabinetFactory lfsFactory = null;
try {
/*
* Here's an example of getting a cabinet factory by type
*/
if (NEW_FILESYSTEMS)
lfsFactory = fileFactory.getCabinetFactoryByType(new org.okip.service.filing.impl.rfs.RfsType());
else
lfsFactory = fileFactory.getCabinetFactoryByType(new org.okip.service.filing.impl.localfilesystem.LfsType());
if (false && verbose) { // listRoots debug
outln("got lfsFactory by type [" + lfsFactory + "]");
Cabinet[] roots = lfsFactory.listRoots();
System.err.println("root count: " + roots.length);
for (int i=0;i<roots.length;i++)
System.err.println("root cabinet #" + i + ": " + roots[i]);
}
return lfsFactory;
} catch (Exception e) {
errout(e);
return null;
}
}
private static Factory getFilingServiceFactory()
{
org.okip.service.filing.api.Factory fileFactory;
try {
fileFactory = (Factory)
FactoryManager.getDefaultFactory("org.okip.service.filing.api", getUserAgent());
} catch (Exception e) {
errout(e);
return null;
}
return fileFactory;
}
private static Agent getUserAgent()
{
Agent userAgent = new Agent();
String userName = System.getProperty("user.name");
try {
String hostName = java.net.InetAddress.getLocalHost().toString();
userName += "@" + hostName;
} catch (java.net.UnknownHostException e) {}
userAgent.setName(userName);
return userAgent;
}
/*
* Get a RemoteFileSystem Cabinet Factory
*/
public static CabinetFactory getRfsCabinetFactory(Agent agent)
{
Factory fileFactory = getFilingServiceFactory();
try{
java.util.Map props = new java.util.Hashtable();
props.put(FSReadWrite, Boolean.TRUE);
props.put(FSLocalAccess, Boolean.TRUE);
props.put(FSRemoteAccess, Boolean.TRUE);
if (USE_CACHING_FILESYSTEM)
props.put(FSMetaCaching, Boolean.TRUE);
else
props.put(FSMetaCaching, Boolean.FALSE);
//System.err.println("looking for props: " + props);
CabinetFactory[] matches = fileFactory.getCabinetFactory(props);
if (matches.length == 0 && USE_CACHING_FILESYSTEM) {
if (verbose) outln("couldn't find factory that supports " + FSMetaCaching);
props.remove(FSMetaCaching);
matches = fileFactory.getCabinetFactory(props);
}
/*
System.err.println("matches=" + matches.length);
for (int i = 0; i < matches.length; i++)
System.err.println("match " + i + " = " + matches[i]);
*/
CabinetFactory rfsFactory = matches[0];
Agent userAgent = getUserAgent();
if (agent != null)
userAgent.addProxy(agent);
rfsFactory.setOwner(userAgent);
if (verbose) outln("got RfsFactory [" + rfsFactory + "] that matched properties " + props);
return rfsFactory;
} catch (Exception e) {
errout(e);
return null;
}
}
private static void ensureSecurityManager()
{
Properties sysProps = System.getProperties();
if (sysProps.get("java.security.policy") == null) {
String defaultPolicyFile = "all.policy";
if (new File(defaultPolicyFile).exists()) {
sysProps.put("java.security.policy", defaultPolicyFile);
} else {
try {
File tmpPolicy = File.createTempFile(defaultPolicyFile, null);
String allPermission = "grant { permission java.security.AllPermission \"\",\"\"; };\n";
FileOutputStream fout = new FileOutputStream(tmpPolicy);
fout.write(allPermission.getBytes());
fout.close();
tmpPolicy.deleteOnExit();
sysProps.put("java.security.policy", tmpPolicy.getPath());
} catch (Exception e) {
errout(e);
}
}
if (verbose) outln("defaulted: java.security.policy=" + sysProps.get("java.security.policy"));
}
System.setSecurityManager(new RMISecurityManager());
if (verbose) outln("RMISecurityManager in place.");
securityManagerSet = true;
}
/*
* Get a Cabinet given a directory in a REMOTE filesystem
*/
private static boolean securityManagerSet = false;
public static CabinetEntry getRfsCabinetEntryFromURL(URL url, boolean cabinet)
{
if (!securityManagerSet)
ensureSecurityManager();
CabinetFactory rfsFactory = getRfsCabinetFactory(new RemoteAgent(url));
outln("Fetching RFS cabinet from URL: [" + url + "] thru " + rfsFactory.getClass());
CabinetEntry entry = null;
try {
if (cabinet)
entry = rfsFactory.getCabinet(rfsFactory.idFromString(url.getPath()));
else
entry = rfsFactory.getByteStore(rfsFactory.idFromString(url.getPath()));
} catch (Exception e) {
errout(e);
return null;
}
if (verbose) outln("Got REMOTE url [" + url + "] as [" + entry + "]");
return entry;
}
private static void getAllCabinetFactories()
{
outln("getAllCabinetFactories");
try {
CabinetFactory cabinetFactory = null;
// get factory for implmentation
Factory fileFactory = (Factory)
FactoryManager.getDefaultFactory("org.okip.service.filing.api", null);
List cfs = fileFactory.getAvailableCabinetFactories( (org.okip.service.shared.api.Agent) null );
Iterator iter = cfs.iterator();
int i = -1;
while (iter.hasNext()) {
Object o = iter.next();
i++;
outln("CF#" + i + ": " + o + " (" + o.getClass() + ")");
try {
CabinetFactory cf = (CabinetFactory) o;
outln("CF#" + i + ": props=" + cf.getProperties());
} catch (Exception e) { errout(e.toString()); }
}
} catch (Exception e) {
errout(e);
}
}
/*
* example code that gets a cabinet factory via capabilities
* -- note that as written and with the current underlying implementation,
* this method will currently return the local filesystem factory.
*/
private static CabinetFactory getCabinetFactoryByProps()
{
try {
CabinetFactory cabinetFactory = null;
// get factory for implmentation
Factory fileFactory = (Factory)
FactoryManager.getDefaultFactory("org.okip.service.filing.api", null);
// if I get this by TYPE, representable as a string,
java.util.Map desiredProperties = new java.util.Hashtable();
desiredProperties.put(new CapabilityType("MIT", "readwrite"), new Boolean(true));
CabinetFactory cabinetFactories[] = fileFactory.getCabinetFactory(desiredProperties);
outln("got " + cabinetFactories.length + " cabinetFactory matching properties " + desiredProperties);
if (cabinetFactories.length <= 0) {
errout("unable to obtain CabinetFactory with properties [" + desiredProperties + "]");
return null;
}
for (int i = 0; i < cabinetFactories.length; i++) {
outln("CF#" + i + ": " + cabinetFactories[i]);
outln("CF#" + i + ": props=" + cabinetFactories[i].getProperties());
}
cabinetFactory = cabinetFactories[0];
//outln("roots of cabinetFactory " + cabinetFactory + " are " + cabinetFactory.listRoots());
outln("returning cabinetFactory " + cabinetFactory + " PROPS=" + cabinetFactory.getProperties());
return cabinetFactory;
} catch (Exception e) {
errout(e);
return null;
}
}
public static void printCabinet(Cabinet cabinet)
{
outln("The cabinet " + cabinet + " has the following entries:");
try {
Iterator i = cabinet.entries();
while (i.hasNext())
printCabinetEntry((CabinetEntry) i.next());
} catch (FilingException e) {
System.err.println(e);
}
}
public static void printCabinetEntry(CabinetEntry ce)
throws FilingException
{
printCabinetEntry(ce, System.out);
}
public static void printCabinetEntry(CabinetEntry ce, PrintStream ps)
throws FilingException
{
ps.print((ce.isByteStore() ? " ByteStore " : " Cabinet "));
char type = '?';
if (ce.isCabinet())
type = 'd';
else if (ce.isByteStore())
type = '-';
ps.print(type);
ps.print(ce.canRead() ? 'r' : '-');
ps.print(ce.canWrite() ? 'w' : '-');
ps.print(" [" + ce.getName() + "]");
//for (int i = 0; i < (12 - ce.getName().length()); i++) ps.print(' ');
ps.print('\t');
if (ce.isByteStore())
{
try {
ByteStore bs = (ByteStore) ce;
ps.print(new Date(bs.getLastModifiedTime()) + " ");
long len = bs.length();
for (int i = 100000; i > 1; i /= 10)
if (len < i) ps.print(' ');
ps.print(" " + len + " bytes");
// ps.print(bs.getOwner().getName()); unimplemented
// ps.print(bs.getManifestAttributes()); no toString
//ps.print(" MimeType " + bs.getMimeType());
// OkiInputStream is = bs.getOkiInputStream();
// byte[] b = new byte[16];
// int nRead = is.read(b);
// if (nRead >= 0) {
// ps.print("\tContents=["
// + formatForSource(new String(b, 0, nRead))
// + "]");
// }
} catch (Exception e) {
errout("error on " + ce + ": " + e);
ps.println("error: " + ce + ": " + e);
}
}
ps.println();
}
public static ArrayList parseCommandLine(String args[])
{
String laf = null;
if (System.getProperty("CABUTIL_OLDFS", "false").equalsIgnoreCase("true"))
USE_CACHING_FILESYSTEM = NEW_FILESYSTEMS = false;
ArrayList words = new ArrayList();
for (int i = 0; i < args.length; i++) {
String a = args[i];
if (a.equals("-laf_java"))
laf = javax.swing.UIManager.getCrossPlatformLookAndFeelClassName();
else if (a.equals("-laf_windows"))
laf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
else if (a.equals("-verbose"))
verbose = true;
else if (a.equals("-newfs")) {
USE_CACHING_FILESYSTEM = true;
NEW_FILESYSTEMS = true;
} else if (a.equals("-oldfs")) {
USE_CACHING_FILESYSTEM = false;
NEW_FILESYSTEMS = false;
}
else if (a.equals("-debug"))
verbose = true;
else if (a.charAt(0) != '-')
words.add(a);
}
if (NEW_FILESYSTEMS)
errout("Using the new filesystem implementation.");
else
errout("Using OLD filesystem implementations.");
if (laf != null) {
try {
outln("Setting look & feel to: " + laf);
javax.swing.UIManager.setLookAndFeel(laf);
} catch (Exception e) {
errout(e);
}
}
return words;
}
private static void outln(String s) { System.err.println("CabUtil: " + s); }
private static void errout(String s) { System.err.println("CabUtil: " + s); }
private static void errout(Exception e)
{
if (e instanceof org.okip.service.shared.api.Exception)
((org.okip.service.shared.api.Exception)e).printChainedTrace();
else {
errout(e.toString());
e.printStackTrace();
}
}
}