package org.w3c.tools.resources ;
import java.util.*;
import java.io.*;
import org.w3c.tools.resources.indexer.*;
import org.w3c.tools.resources.event.*;
public class DirectoryResource extends ContainerResource {
protected static int ATTR_DIRECTORY = -1 ;
protected static int ATTR_DIRSTAMP = -1 ;
protected static int ATTR_INDEXER = -1;
protected static int ATTR_EXTENSIBLE = -1 ;
static {
Attribute a = null ;
Class cls = null ;
try {
cls = Class.forName("org.w3c.tools.resources.DirectoryResource") ;
} catch (Exception ex) {
ex.printStackTrace() ;
System.exit(1) ;
}
a = new FileAttribute("directory"
, null
, Attribute.COMPUTED|Attribute.DONTSAVE);
ATTR_DIRECTORY = AttributeRegistry.registerAttribute(cls, a) ;
a = new DateAttribute("dirstamp"
, null
, Attribute.COMPUTED) ;
ATTR_DIRSTAMP = AttributeRegistry.registerAttribute(cls, a) ;
a = new StringAttribute("indexer"
, null
, Attribute.EDITABLE) ;
ATTR_INDEXER = AttributeRegistry.registerAttribute(cls, a) ;
a = new BooleanAttribute("extensible"
, Boolean.TRUE
, Attribute.EDITABLE) ;
ATTR_EXTENSIBLE = AttributeRegistry.registerAttribute(cls, a) ;
}
@return
protected ResourceReference getIndexer(ResourceContext c) {
IndexerModule m = (IndexerModule) c.getModule(IndexerModule.NAME);
ResourceReference rr = m.getIndexer(c);
return rr;
}
public void setValue(int idx, Object value) {
super.setValue(idx, value);
if ( idx == ATTR_INDEXER ) {
String indexer = getString(ATTR_INDEXER, null);
if ( indexer != null ) {
ResourceContext c = null;
IndexerModule m = null;
c = getContext();
m = (IndexerModule) c.getModule(IndexerModule.NAME);
m.registerIndexer(c, indexer);
}
}
}
@return
public File getDirectory() {
return (File) getValue(ATTR_DIRECTORY, null) ;
}
@return
public long getDirStamp() {
return getLong(ATTR_DIRSTAMP, -1) ;
}
@return
public boolean getExtensibleFlag() {
return getBoolean(ATTR_EXTENSIBLE, true) ;
}
@param evt
public void resourceRemoved(StructureChangedEvent evt) {
super.resourceRemoved(evt);
markModified();
}
@param name@return
public ResourceReference createDirectoryResource(String name) {
File file = new File(getDirectory(), name) ;
boolean created = false ;
boolean exists_before = false ;
try {
if (file.exists()) {
if (! file.isDirectory())
created = false;
else
exists_before = true;
} else {
file.mkdir();
created = true;
}
} catch (Exception ex) {
created = false;
}
if (! created)
return null;
ResourceReference rr = createDefaultResource(name);
if (rr == null) {
if (!exists_before)
file.delete();
return null;
}
try {
Resource r = rr.lock();
if (! (r instanceof DirectoryResource)) {
try {
r.delete();
} catch (MultipleLockException ex) {
}
if (!exists_before)
file.delete();
return null;
}
} catch (InvalidResourceException ex) {
if (!exists_before)
file.delete();
return null;
} finally {
rr.unlock();
}
return rr;
}
@param name@return
public ResourceReference createResource(String name) {
return createResource(name, null);
}
@param name@param req@return
public ResourceReference createResource(String name,
RequestInterface req)
{
File file = new File(getDirectory(), name) ;
boolean created = false ;
if ( ! file.exists() ) {
try {
(new RandomAccessFile(file, "rw")).close() ;
created = true ;
} catch (Exception ex) {
created = false ;
}
}
if (! created)
return null;
ResourceReference rr = createDefaultResource(name, req);
if (rr == null)
file.delete();
return rr;
}
@param name@param defs@return @see org.w3c.tools.resources.indexer.SampleResourceIndexer
private Resource index(String name, Hashtable defs) {
return index(name, defs, null);
}
@param name@param defs@param req@return @see org.w3c.tools.resources.indexer.SampleResourceIndexer
protected Resource index(String name,
Hashtable defs,
RequestInterface req)
{
defs.put("identifier", name);
updateDefaultChildAttributes(defs);
ResourceContext context = getContext();
Resource resource = null;
ResourceReference rr_indexer = null;
ResourceReference rr_lastidx = null;
while ( context != null ) {
do {
rr_indexer = getIndexer(context);
context = context.getParent();
} while ((rr_indexer == rr_lastidx) && (context != null));
if ((rr_lastidx = rr_indexer) != null ) {
try {
ResourceIndexer indexer =
(ResourceIndexer)rr_indexer.lock();
resource = indexer.createResource(this,
req,
getDirectory(),
name,
defs) ;
if ( resource != null )
break;
} catch (InvalidResourceException ex) {
resource = null;
} finally {
rr_indexer.unlock();
}
}
}
return resource;
}
public synchronized ResourceReference createDefaultResource(String name) {
return createDefaultResource(name, null);
}
@param name@param req@return
protected synchronized
ResourceReference createDefaultResource(String name,
RequestInterface req)
{
if (name.equals("..") || name.equals("."))
return null ;
Hashtable defs = new Hashtable(10) ;
Resource resource = index(name, defs, req);
ResourceReference rr = null;
if ( resource != null ) {
rr = addResource(resource, defs) ;
markModified() ;
}
return rr ;
}
@param resource
protected ResourceContext updateDefaultChildAttributes(Hashtable attrs) {
ResourceContext context = null;
context = super.updateDefaultChildAttributes(attrs);
String name = (String) attrs.get("identifier");
if (( name != null ) && (getDirectory() != null)) {
attrs.put("directory", new File(getDirectory(), name));
return context;
} else {
return null;
}
}
public synchronized void reindex() {
if (getExtensibleFlag()) {
Enumeration e = enumerateAllResourceIdentifiers();
String name = null;
ResourceReference rr = null;
Resource r = null;
while (e.hasMoreElements()) {
name = (String) e.nextElement();
rr = lookup(name);
if (rr != null) {
try {
r = rr.lock();
if (r == this)
continue;
if (r instanceof DirectoryResource) {
DirectoryResource dir = (DirectoryResource) r;
Hashtable defs = new Hashtable(10);
defs.put("context", dir.getContext());
Resource newdir = index(name, defs);
if (newdir == null) {
dir.reindex();
} else {
if (! (newdir instanceof DirectoryResource)) {
throw new RuntimeException(
"Reindex Error : "+
name+" can't be reindexed. "+
"The reindexed resource is "+
"no more a DirectoryResource.");
}
DirectoryResource reindexed =
(DirectoryResource) newdir;
String indexer =
reindexed.getString(ATTR_INDEXER, "");
if (indexer.equals("")) {
dir.reindex();
indexer =
dir.getString(ATTR_INDEXER, null);
reindexed.setValue(ATTR_INDEXER, indexer);
} else {
dir.setValue(ATTR_INDEXER, indexer);
dir.reindex();
}
reindexed.setValue(ATTR_KEY, dir.getKey());
dir.setValue(ATTR_IDENTIFIER,
name+"-bakindex");
addResource(reindexed, defs);
try {
dir.replace(reindexed);
} catch (MultipleLockException ex) {
throw new RuntimeException(
"Reindex Error : "+
ex.getMessage());
}
}
} else if (! (r instanceof AbstractContainer)) {
Hashtable resdefs = new Hashtable(10);
Resource resource = index(name, resdefs);
if (resource != null) {
try {
r.delete();
} catch (MultipleLockException ex) {
throw new RuntimeException(
"Reindex Error : "+
ex.getMessage());
}
addResource(resource, resdefs);
}
}
} catch (InvalidResourceException ex) {
System.out.println(ex.getMessage());
} finally {
rr.unlock();
}
}
}
markModified();
}
}
@return
protected synchronized Enumeration enumerateAllResourceIdentifiers() {
File directory = getDirectory() ;
if ( directory != null ) {
synchronized(this) {
String lst[] = directory.list() ;
if ( lst != null ) {
for (int i = 0 ; i < lst.length ; i++) {
if (lst[i].equals(".") || lst[i].equals(".."))
continue ;
if (lookup(lst[i]) == null)
createDefaultResource(lst[i]) ;
}
}
}
}
return super.enumerateResourceIdentifiers(true);
}
@return
public synchronized Enumeration enumerateResourceIdentifiers(boolean all) {
if (all && getExtensibleFlag() ) {
File directory = getDirectory() ;
if ( directory != null ) {
synchronized(this) {
long dirstamp = directory.lastModified() ;
if ( dirstamp > getDirStamp() ) {
String lst[] = directory.list() ;
if ( lst != null ) {
for (int i = 0 ; i < lst.length ; i++) {
if (lst[i].equals(".") || lst[i].equals(".."))
continue ;
if (lookup(lst[i]) == null)
createDefaultResource(lst[i]) ;
}
}
setLong(ATTR_DIRSTAMP, dirstamp) ;
}
}
}
}
return super.enumerateResourceIdentifiers(all);
}
@param name@return
public ResourceReference lookup(String name)
{
ResourceReference rr = null;
rr = super.lookup(name);
if (rr != null)
return rr;
return getExtensibleFlag() ? createDefaultResource(name) : null ;
}
public synchronized void delete()
throws MultipleLockException
{
disableEvent();
setBoolean(ATTR_EXTENSIBLE, false);
super.delete();
}
public synchronized boolean verify() {
return getDirectory().exists();
}
@param values
public void initialize(Object values[]) {
super.initialize(values) ;
disableEvent();
File dir = null ;
if ( ! definesAttribute(ATTR_DIRECTORY) ) {
ResourceReference rr = getParent();
if (rr != null) {
try {
Resource parent = rr.lock();
if (parent.definesAttribute("directory")) {
File pdir = (File) parent.getValue("directory", null);
if ( pdir != null ) {
dir = new File(pdir, getIdentifier()) ;
setValue(ATTR_DIRECTORY, dir) ;
}
}
} catch (InvalidResourceException ex) {
} finally {
rr.unlock();
}
}
} else {
dir = getDirectory();
}
ResourceContext c = getContext();
String indexer = getString(ATTR_INDEXER, null);
if (( indexer != null ) && (!indexer.equals(""))) {
IndexerModule m = (IndexerModule)c.getModule(IndexerModule.NAME);
m.registerIndexer(c, indexer);
}
enableEvent();
}
}