public Object getAttribute(String name,
Configuration modeConf,
Map objectModel) throws ConfigurationException {
if (!this.initialized) {
this.lazy_initialize();
}
if (this.defaultInput == null) {
if (getLogger().isWarnEnabled())
getLogger().warn("No input module given. FAILING");
return null;
}
// obtain correct configuration objects
// default vs dynamic
Configuration inputConfig = null;
String inputName=null;
String rootName = this.rootName;
String ignore = this.ignore;
String use = this.use;
String strip = this.strip;
if (modeConf!=null) {
inputName = modeConf.getChild("input-module").getAttribute("name",null);
rootName = modeConf.getAttribute("root",this.rootName);
ignore = modeConf.getAttribute("ignore" ,this.ignore );
use = modeConf.getAttribute("use" ,this.use );
strip = modeConf.getAttribute("strip" ,this.strip );
// preferred
rootName = modeConf.getChild("root").getValue(rootName);
ignore = modeConf.getChild("ignore").getValue(ignore );
use = modeConf.getChild("use").getValue(use );
strip = modeConf.getChild("strip").getValue(strip );
if (inputName != null) {
inputConfig = modeConf.getChild("input-module");
}
}
// see whether the Document is already stored as request
// attribute and return that
Request request = ObjectModelHelper.getRequest(objectModel);
Map cache = (Map) request.getAttribute(CACHE_OBJECT_NAME);
Object key = (modeConf != null ? modeConf : this.config);
Document doc = null;
if (cache != null && cache.containsKey(key)) {
doc = (Document) cache.get(key);
if (getLogger().isDebugEnabled())
getLogger().debug("using cached copy "+doc);
return doc;
}
if (getLogger().isDebugEnabled())
getLogger().debug("no cached copy "+cache+" / "+key);
// get InputModule and all attribute names
InputModule input = null;
if (inputName != null) input = obtainModule(inputName);
Iterator names = getNames(objectModel,
this.input, this.defaultInput, this.inputConf,
input, inputName, inputConfig);
// first, sort all attribute names that the DOM can be created in one go
// while doing so, remove unwanted attributes
SortedSet set = new TreeSet();
String aName = null;
while (names.hasNext()){
aName = (String) names.next();
if ((use == null || aName.startsWith(use)) &&
(ignore == null || !aName.startsWith(ignore))) {
set.add(aName);
}
}
try {
names = set.iterator();
// create new document and append root node
doc = DOMUtil.createDocument();
Element elem = doc.createElement(rootName);
doc.appendChild(elem);
while (names.hasNext()){
aName = (String) names.next();
// obtain values from input module
Object[] value = getValues(aName, objectModel,
this.input, this.defaultInput, this.inputConf,
input, inputName, inputConfig);
// strip unwanted prefix from attribute name if present
if (strip != null && aName.startsWith(strip))
aName = aName.substring(strip.length());
if (value.length > 0) {
// add new node from xpath
// (since the names are in a set, the node cannot exist already)
Node node = DOMUtil.selectSingleNode(doc.getDocumentElement(), aName, this.xpathProcessor);
node.appendChild( node.getOwnerDocument().createTextNode(value[0].toString()));
if (value.length > 1) {
// if more than one value was obtained, append
// further nodes (same name)
// isolate node name, selection expressions
// "[...]" may not be part of it
int endPos = aName.length() - (aName.endsWith("/") ? 1 : 0);
int startPos = aName.lastIndexOf("/", endPos) +1;
String nodeName = aName.substring(startPos, endPos);
if (nodeName.indexOf("[") != -1) {
endPos = nodeName.lastIndexOf("]");
startPos = nodeName.indexOf("[") +1;
nodeName = nodeName.substring(startPos, endPos);
}
// append more nodes
Node parent = node.getParentNode();
for (int i = 1; i < value.length; i++) {
Node newNode = parent.getOwnerDocument().createElementNS(null, nodeName);
parent.appendChild( newNode );
newNode.appendChild( newNode.getOwnerDocument().createTextNode(value[i].toString()));
}
}
}
}
} catch (Exception e) {
throw new ConfigurationException(e.getMessage());
}
if (input != null) releaseModule(input);
// create a wrapped instance that is XMLizable
doc = new DocumentWrapper(doc);
// store Document as request attribute
if (cache == null)
cache = new HashMap();
if (getLogger().isDebugEnabled())
getLogger().debug("no cached copy "+cache+" / "+key);
cache.put(key, doc);
request.setAttribute(CACHE_OBJECT_NAME,cache);
if (getLogger().isDebugEnabled())
getLogger().debug("returning "+doc.toString());
return doc;
}
|