Fields Summary |
---|
private org.apache.avalon.framework.context.Context | contextThe context employed by this repository |
private org.apache.avalon.framework.configuration.Configuration | configurationThe configuration employed by this repository |
private boolean | readOnlyWhether the repository is read only |
private File | rootPathThe groups are located under this path. |
private File | tempPathArticles are temporarily written here and then sent to the spooler. |
private NNTPSpooler | spoolThe spooler for this repository. |
private ArticleIDRepository | articleIDRepoThe article ID repository associated with this NNTP repository. |
private HashMap | groupNameMapA map to allow lookup of valid newsgroup names |
private boolean | definedGroupsOnlyRestrict use to newsgroups specified in config only |
private String | rootPathStringThe root path as a String. |
private String | tempPathStringThe temp path as a String. |
private String | articleIdPathStringThe article ID path as a String. |
private String | articleIDDomainSuffixThe domain suffix used for files in the article ID repository. |
private String[] | overviewFormatThe ordered list of fields returned in the overview format for
articles stored in this repository. |
private HashMap | repositoryGroupsThis is a mapping of group names to NNTP group objects.
TODO: This needs to be addressed so it scales better |
Methods Summary |
---|
public void | configure(org.apache.avalon.framework.configuration.Configuration aConfiguration)
configuration = aConfiguration;
readOnly = configuration.getChild("readOnly").getValueAsBoolean(false);
articleIDDomainSuffix = configuration.getChild("articleIDDomainSuffix")
.getValue("foo.bar.sho.boo");
rootPathString = configuration.getChild("rootPath").getValue(null);
if (rootPathString == null) {
throw new ConfigurationException("Root path URL is required.");
}
tempPathString = configuration.getChild("tempPath").getValue(null);
if (tempPathString == null) {
throw new ConfigurationException("Temp path URL is required.");
}
articleIdPathString = configuration.getChild("articleIDPath").getValue(null);
if (articleIdPathString == null) {
throw new ConfigurationException("Article ID path URL is required.");
}
if (getLogger().isDebugEnabled()) {
if (readOnly) {
getLogger().debug("NNTP repository is read only.");
} else {
getLogger().debug("NNTP repository is writeable.");
}
getLogger().debug("NNTP repository root path URL is " + rootPathString);
getLogger().debug("NNTP repository temp path URL is " + tempPathString);
getLogger().debug("NNTP repository article ID path URL is " + articleIdPathString);
}
Configuration newsgroupConfiguration = configuration.getChild("newsgroups");
definedGroupsOnly = newsgroupConfiguration.getAttributeAsBoolean("only", false);
groupNameMap = new HashMap();
if ( newsgroupConfiguration != null ) {
Configuration[] children = newsgroupConfiguration.getChildren("newsgroup");
if ( children != null ) {
for ( int i = 0 ; i < children.length ; i++ ) {
String groupName = children[i].getValue();
groupNameMap.put(groupName, groupName);
}
}
}
getLogger().debug("Repository configuration done");
|
public void | contextualize(org.apache.avalon.framework.context.Context context)
this.context = context;
|
public void | createArticle(java.io.InputStream in)
StringBuffer fileBuffer =
new StringBuffer(32)
.append(System.currentTimeMillis())
.append(".")
.append(Math.random());
File f = new File(tempPath, fileBuffer.toString());
FileOutputStream fout = null;
try {
fout = new FileOutputStream(f);
byte[] readBuffer = new byte[1024];
int bytesRead = 0;
while ( ( bytesRead = in.read(readBuffer, 0, 1024) ) > 0 ) {
fout.write(readBuffer, 0, bytesRead);
}
fout.flush();
fout.close();
fout = null;
boolean renamed = f.renameTo(new File(spool.getSpoolPath(),f.getName()));
if (!renamed) {
throw new IOException("Could not create article on the spool.");
}
} catch(IOException ex) {
throw new NNTPException("create article failed",ex);
} finally {
if (fout != null) {
try {
fout.close();
} catch (IOException ioe) {
// Ignored
}
}
}
|
private NNTPSpooler | createSpooler()Creates an instance of the spooler class.
TODO: This method doesn't properly implement the Avalon lifecycle.
String className = "org.apache.james.nntpserver.repository.NNTPSpooler";
Configuration spoolerConfiguration = configuration.getChild("spool");
try {
// Must be a subclass of org.apache.james.nntpserver.repository.NNTPSpooler
className = spoolerConfiguration.getAttribute("class");
} catch(ConfigurationException ce) {
// Use the default class.
}
try {
Object obj = getClass().getClassLoader().loadClass(className).newInstance();
// TODO: Need to support service
ContainerUtil.enableLogging(obj, getLogger());
ContainerUtil.contextualize(obj, context);
ContainerUtil.configure(obj, spoolerConfiguration.getChild("configuration"));
ContainerUtil.initialize(obj);
return (NNTPSpooler)obj;
} catch(ClassCastException cce) {
StringBuffer errorBuffer =
new StringBuffer(128)
.append("Spooler initialization failed because the spooler class ")
.append(className)
.append(" was not a subclass of org.apache.james.nntpserver.repository.NNTPSpooler");
String errorString = errorBuffer.toString();
getLogger().error(errorString, cce);
throw new ConfigurationException(errorString, cce);
} catch(Exception ex) {
getLogger().error("Spooler initialization failed",ex);
throw new ConfigurationException("Spooler initialization failed",ex);
}
|
public NNTPArticle | getArticleFromID(java.lang.String id)
try {
return articleIDRepo.getArticle(this,id);
} catch(Exception ex) {
getLogger().error("Couldn't get article " + id + ": ", ex);
return null;
}
|
public java.util.Iterator | getArticlesSince(java.util.Date dt)
final Iterator giter = getGroupsSince(dt);
return new Iterator() {
private Iterator iter = null;
public boolean hasNext() {
if ( iter == null ) {
if ( giter.hasNext() ) {
NNTPGroup group = (NNTPGroup)giter.next();
iter = group.getArticlesSince(dt);
}
else {
return false;
}
}
if ( iter.hasNext() ) {
return true;
} else {
iter = null;
return hasNext();
}
}
public Object next() {
return iter.next();
}
public void remove() {
throw new UnsupportedOperationException("remove not supported");
}
};
|
public NNTPGroup | getGroup(java.lang.String groupName)
if (definedGroupsOnly && groupNameMap.get(groupName) == null) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(groupName + " is not a newsgroup hosted on this server.");
}
return null;
}
File groupFile = new File(rootPath,groupName);
NNTPGroup groupToReturn = null;
synchronized(this) {
groupToReturn = (NNTPGroup)repositoryGroups.get(groupName);
if ((groupToReturn == null) && groupFile.exists() && groupFile.isDirectory() ) {
try {
groupToReturn = new NNTPGroupImpl(groupFile);
ContainerUtil.enableLogging(groupToReturn, getLogger());
ContainerUtil.contextualize(groupToReturn, context);
ContainerUtil.initialize(groupToReturn);
repositoryGroups.put(groupName, groupToReturn);
} catch (Exception e) {
getLogger().error("Couldn't create group object.", e);
groupToReturn = null;
}
}
}
return groupToReturn;
|
private java.util.Iterator | getGroups(java.io.File[] f)Gets an iterator of all news groups represented by the files
in the parameter array.
List list = new ArrayList();
for ( int i = 0 ; i < f.length ; i++ ) {
if (f[i] != null) {
list.add(getGroup(f[i].getName()));
}
}
return list.iterator();
|
public java.util.Iterator | getGroupsSince(java.util.Date dt)
File[] f = rootPath.listFiles(new AndFileFilter(new GroupFilter(), new AndFileFilter
(new DirectoryFileFilter(),new DateSinceFileFilter(dt.getTime()))));
return getGroups(f);
|
public java.util.Iterator | getMatchedGroups(java.lang.String wildmat)
File[] f = rootPath.listFiles(new AndFileFilter(new GroupFilter(), new AndFileFilter
(new DirectoryFileFilter(),new GlobFilenameFilter(wildmat))));
return getGroups(f);
|
public java.lang.String[] | getOverviewFormat()
return overviewFormat;
|
public void | initialize()
getLogger().debug("Starting initialize");
File articleIDPath = null;
try {
rootPath = AvalonContextUtilities.getFile(context, rootPathString);
tempPath = AvalonContextUtilities.getFile(context, tempPathString);
articleIDPath = AvalonContextUtilities.getFile(context, articleIdPathString);
} catch (Exception e) {
getLogger().fatalError(e.getMessage(), e);
throw e;
}
if ( articleIDPath.exists() == false ) {
articleIDPath.mkdirs();
}
articleIDRepo = new ArticleIDRepository(articleIDPath, articleIDDomainSuffix);
spool = (NNTPSpooler)createSpooler();
spool.setRepository(this);
spool.setArticleIDRepository(articleIDRepo);
if (getLogger().isDebugEnabled()) {
getLogger().debug("repository:readOnly=" + readOnly);
getLogger().debug("repository:rootPath=" + rootPath.getAbsolutePath());
getLogger().debug("repository:tempPath=" + tempPath.getAbsolutePath());
}
if ( rootPath.exists() == false ) {
rootPath.mkdirs();
} else if (!(rootPath.isDirectory())) {
StringBuffer errorBuffer =
new StringBuffer(128)
.append("NNTP repository root directory is improperly configured. The specified path ")
.append(rootPathString)
.append(" is not a directory.");
throw new ConfigurationException(errorBuffer.toString());
}
Set groups = groupNameMap.keySet();
Iterator groupIterator = groups.iterator();
while( groupIterator.hasNext() ) {
String groupName = (String)groupIterator.next();
File groupFile = new File(rootPath,groupName);
if ( groupFile.exists() == false ) {
groupFile.mkdirs();
} else if (!(groupFile.isDirectory())) {
StringBuffer errorBuffer =
new StringBuffer(128)
.append("A file exists in the NNTP root directory with the same name as a newsgroup. File ")
.append(groupName)
.append("in directory ")
.append(rootPathString)
.append(" is not a directory.");
throw new ConfigurationException(errorBuffer.toString());
}
}
if ( tempPath.exists() == false ) {
tempPath.mkdirs();
} else if (!(tempPath.isDirectory())) {
StringBuffer errorBuffer =
new StringBuffer(128)
.append("NNTP repository temp directory is improperly configured. The specified path ")
.append(tempPathString)
.append(" is not a directory.");
throw new ConfigurationException(errorBuffer.toString());
}
getLogger().debug("repository initialization done");
|
public boolean | isReadOnly()
return readOnly;
|