📄 xmlconfigutils.java
字号:
package MyNa.xml;
import MyNa.utils.Env;
import MyNa.utils.Logger;
import java.util.Enumeration;
import java.net.URL;
import java.io.IOException;
import java.io.File;
import java.lang.Class;
import java.lang.reflect.Constructor;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Attr;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.sun.xml.parser.Resolver;
import com.sun.xml.tree.XmlDocument;
import com.sun.xml.tree.TreeWalker;
import org.w3c.dom.Element;
public class XmlConfigUtils {
/* not for instantiation; these are simple ways to provide the functionality
of interface XmlConfig. Note that if a bean uses these, then each of the
subbeans will also use initFromEnv with an appropriately defined environment,
and that bean's initFromEnv(Env E) should call on whatever setters are needed
to extract information from the environment, _after_ calling on this
static method. For instance, the XmlConfig might say
public String initFromEnv(Env E){
String S=XmlConfigUtils.initFromEnv(E);
if(S.length()>0)return S; // something wrong;
useEnv(E);
return "";
}
public void useEnv(Env E){ // pull properties from Env, call setters.
setInitDefs(E);
setDbUser(E.getStr("dbUser");
setDbPwd(E.getStr("dbPwd");
...
}
and less directly,
public String initFromTopEnv(Env E){
String S=XmlConfigUtils.initFromTopEnv(E);
if(S.length()>0)return S; // something wrong
initFromEnv(E);
}
in this case, the XmlConfig.initFromTopEnv function
first calls on the XmlConfigUtils.initFromTopEnv static function
which gives recursive structure to the Env; the
XmlConfig.initFromTopEnv function then calls on its
own initFromEnv function which uses the recursive Env
via the XmlConfigUtils recursive initFromEnv, which calls
each subbean's XmlConfig.initFromEnv function for each
point on the tree. the XmlConfig initFromEnv function
can therefore be extremely simple, as above.
*/
public static String initFromTopEnv(Env E){
Enumeration keys=E.keys();
while(keys.hasMoreElements()){
String key=(String)keys.nextElement();
if(key.indexOf('_')<0)continue;
E.putSplit(key,E.get(key));
E.remove(key);
}
return ""; // no errors reported in this version.
}
public static String initFromXmlFile(String fileName,boolean validate,Env E){
InputSource input;
XmlDocument doc;
if(null==fileName)return "null fileName for xml initialization";
try {
if(fileName.startsWith("http:"))
input=Resolver.createInputSource(new URL(fileName),true);
else input=Resolver.createInputSource(new File(fileName));
doc = XmlDocument.createXmlDocument (input, validate);
return initFromTopDomTree(doc,E);
} catch (SAXParseException err) {
return "** Parsing error: line " + err.getLineNumber()+err;
} catch (SAXException e) {
return ""+e;
} catch (IOException t) {
return ""+t;
}
}
public static String initBean(Env beanE,String beanClass){
try{
Class C=Class.forName(beanClass);
Class[]paramTypes={};
Object[]paramVals={};
Constructor cons=C.getConstructor(paramTypes);
Object theBean=cons.newInstance(paramVals);
if(!(theBean instanceof XmlConfig))
return "class "+beanClass+" is not an XmlConfig";
beanE.put("theBeanItself",theBean);
}catch(Exception E){return ""+E;}
System.out.println("initBean: created bean "+beanClass);
return "";
}
public static String initFromEnv(Env E){
// recursively constructs beans, calls their initFromEnv methods
String msg="";
try{
Enumeration keys=E.keys();
while(keys.hasMoreElements() && msg.length()==0){
String key=(String)keys.nextElement();
if(key.equals("theBeanParentEnv"))continue;
Object ob=E.get(key);
if(!(ob instanceof Env))continue;
Env beanE=(Env)ob;
String beanName=beanE.getStr("beanName");
String beanClass=beanE.getStr("class");
if(null==beanName || null==beanClass) continue;
System.out.println("iFE: beanName="+beanName+", beanClass="+beanClass);
beanE.put("theBeanParentEnv",E);
if(null==beanE.get("theBeanItself"))
if((msg=initBean(beanE,beanClass)).length()>0)
return msg;
XmlConfig xc=(XmlConfig)beanE.get("theBeanItself");
msg=xc.initFromEnv(beanE);
}
}catch(Exception e){msg+=e;}
return msg;
}
public static void setNodeNameVal(Env E, Node N){
if(null==N)return;
String name=N.getNodeName();
N=N.getFirstChild(); // nodeName=#text, nodeValue=text
if(null==N)return;
String val=N.getNodeValue();
if(null!=val)E.put(name,val);
}
public static String initFromTopDomTree(Node theNode,Env E){ // E is output.
if(null==theNode)return "no tree for initialization";
theNode=(new TreeWalker(theNode)).getNextElement("topbean");
if(null==theNode)return "no topbean node in initialization tree";
theNode=theNode.getFirstChild();
return initFromDomTree(theNode,E);
}
/* normally XmlConfig should depend on DTDs. In case it doesn't, we
use nextSib and firstKid instead of getNextSibling() and getFirstChild()
these simply skip over text nodes, assuming that they are going to be
the whitespace nodes introduced by dtd-lessness.
*/
public static Node nextSib(Node theNode){
if(null==theNode)return null;
Node nxt=theNode.getNextSibling();
while(null!=nxt && nxt.getNodeType()==Node.TEXT_NODE)
nxt=nxt.getNextSibling();
return nxt;
}
public static Node firstKid(Node theNode){
if(null==theNode)return null;
Node nxt=theNode.getFirstChild();
while(null!=nxt && nxt.getNodeType()==Node.TEXT_NODE)
nxt=nxt.getNextSibling();
return nxt;
}
public static String initFromDomTree(Node theNode, Env E){ // E is output
// from here on, we depend on your DTD for correctness...or on your care
if(null==theNode)return "null node at start of initFromDomTree";
String beanName=theNode.getNodeName();
E.put("beanName",beanName);
theNode=firstKid(theNode); // has to be <class>xxx.yyy.zzz</class>
if(null==theNode || !"class".equals(theNode.getNodeName()))
return "no class specified under "+beanName;
setNodeNameVal(E,theNode);
theNode=nextSib(theNode);
if(null==theNode)
return "bean def ends with class node for "+beanName;
if("useclass".equals(theNode.getNodeName())){
setNodeNameVal(E,theNode);
theNode=nextSib(theNode);
if(null==theNode)
return "bean def ends with useclass node for "+beanName;
}
String S="";
if("subbeans".equals(theNode.getNodeName())){
Node sub=firstKid(theNode);
while(null!=sub && S.length()==0){
String subName=sub.getNodeName();
Env subEnv=new Env();
E.put(subName,subEnv);
S=initFromDomTree(sub,subEnv);
sub=nextSib(sub);
}
theNode=nextSib(theNode); // now just properties...
}
while(null!=theNode){
setNodeNameVal(E,theNode);
theNode=nextSib(theNode);
}
return S; // return empty if no error message.
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -