DirectoryXmlContainer.java
package emissary.directory;
import emissary.util.xml.SaferJDOMUtil;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
/**
* This class acts as a container and producer for turning a directory entry list into a full xml document
*/
public class DirectoryXmlContainer {
private static final Logger logger = LoggerFactory.getLogger(DirectoryXmlContainer.class);
public static final String DIRECTORY = "directory";
public static final String LOC_ATTR = "location";
public static final String DATAID_ATTR = "dataid";
/**
* Build an xml document from the contents of a directory place
*/
public static Document buildDocument(final IDirectoryPlace dir) {
final Element root = new Element(DIRECTORY);
root.setAttribute(LOC_ATTR, dir.getKey());
// Each directory entry
for (final String dataId : dir.getEntryKeys()) {
final DirectoryEntryList list = dir.getEntryList(dataId);
if (list != null) {
final Element listEl = list.getXml();
listEl.setAttribute(DATAID_ATTR, dataId);
root.addContent(listEl);
}
}
return new Document(root);
}
/**
* Build an xml document from the map.
*
* @param map the map of entries
* @param loc directory location key
*/
public static Document buildDocument(final DirectoryEntryMap map, final String loc) {
final Element root = new Element(DIRECTORY);
root.setAttribute(LOC_ATTR, loc);
// Each directory entry
for (final Map.Entry<String, DirectoryEntryList> entry : map.entrySet()) {
final String dataId = entry.getKey();
final DirectoryEntryList list = entry.getValue();
if (list != null) {
final Element listEl = list.getXml();
listEl.setAttribute(DATAID_ATTR, dataId);
root.addContent(listEl);
}
}
return new Document(root);
}
/**
* Build an xml document from the contents of the directory as if proxied through the place itself. Except when the
* entries actually belong to the requester.
*
* @param dir the directory that will act as a proxy
* @param requester the directory doing the requesting
*/
public static Document buildProxyDocument(final IRemoteDirectory dir, final String requester) {
final String proxyKey = dir.getKey();
final Element root = new Element(DIRECTORY);
root.setAttribute(LOC_ATTR, proxyKey);
logger.debug("Building proxy view of dir contents for {}", requester);
// Each directory entry
for (final String dataId : dir.getEntryKeys()) {
final DirectoryEntryList list = dir.getEntryList(dataId);
logger.debug("List of {} for {} has {} entries", dataId, requester, list.size());
// set up proxy for each entry
for (final DirectoryEntry e : list) {
e.proxyFor(proxyKey);
}
// Add them to the xml
if (!list.isEmpty()) {
final Element listEl = list.getXml();
listEl.setAttribute(DATAID_ATTR, dataId);
root.addContent(listEl);
}
}
return new Document(root);
}
/**
* Build an xml string from the contents of a directory place This method pulls the main entryMap of the directory.
*
* @param dir the directory to pull the entryMap contents from
* @return xml string representing the keys
*/
public static String toXmlString(final IDirectoryPlace dir) {
final Document jdom = buildDocument(dir);
return SaferJDOMUtil.toString(jdom);
}
/**
* Build an xml string from the contents of a directory place making it appear that the place represented by proxyKey
* acts as a proxy for all or the keys in the directory map
*
* @param dir the directory to pull the entryMap contents from
* @param proxyKey place to appear as the proxy
* @param requester the key of the remote directory that is requesting the local directory contents
* @return xml string representing the proxied keys
*/
public static String toXmlString(final IDirectoryPlace dir, @Nullable final String proxyKey, final String requester) {
logger.debug("Building xml string for {}", requester);
final String xml;
if ((proxyKey == null) || !(dir instanceof IRemoteDirectory)) {
xml = toXmlString(dir);
} else {
final Document jdom = buildProxyDocument((IRemoteDirectory) dir, requester);
xml = SaferJDOMUtil.toString(jdom);
}
return xml;
}
/**
* Build a DirectoryEntryList map from string xml
*/
public static DirectoryEntryMap buildEntryListMap(final String xml) throws JDOMException {
final Document jdom = SaferJDOMUtil.createDocument(xml);
return buildEntryListMap(jdom);
}
/**
* Build a DirectoryEntryList map from a JDOM document
*/
public static DirectoryEntryMap buildEntryListMap(final Document jdom) {
final Element el = jdom.getRootElement();
return buildEntryListMap(el);
}
/**
* Build a DirectoryEntryMap from a JDOM Element
*/
public static DirectoryEntryMap buildEntryListMap(final Element el) {
final DirectoryEntryMap map = new DirectoryEntryMap();
final List<Element> entryLists = el.getChildren(DirectoryEntryList.ENTRYLIST);
for (final Element listElement : entryLists) {
final DirectoryEntryList d = DirectoryEntryList.fromXml(listElement);
final String dataId = listElement.getAttributeValue(DATAID_ATTR);
map.put(dataId, d);
}
logger.debug("Constructed map of {} directory entry lists from xml", map.size());
return map;
}
/** This class is not meant to be instantiated. */
private DirectoryXmlContainer() {}
}