文章标题:基于xml文件实现系统属性配置管理 .
文章地址: http://blog.csdn.net/5iasp/article/details/11774501
作者: javaboy2012
Email:yanek@163.com
qq: 1046011462
项目截图;
主要有如下几个类和配置文件实现:
1. SystemProperties
package com.yanek.cfg; import java.util.Collection;
import java.util.Map; public interface SystemProperties
extends Map
{ public abstract Collection getChildrenNames(String s); public abstract Collection getPropertyNames(); public void init();
}
2. XMLSystemProperties类
package com.yanek.cfg; import java.io.*;
import java.util.*;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.*;
import org.apache.log4j.Logger; public class XMLSystemProperties
implements SystemProperties
{
static Logger logger = Logger.getLogger(XMLSystemProperties.class.getName()); private File file;
private Document doc;
private Map propertyCache;
private Object propLock; public XMLSystemProperties(InputStream in)
throws Exception
{
propertyCache = new HashMap();
propLock = new Object();
Reader reader = new BufferedReader(new InputStreamReader(in));
buildDoc(reader);
} public XMLSystemProperties(String fileName)
throws IOException
{
File tempFile;
boolean error=false;
Reader reader;
propertyCache = new HashMap();
propLock = new Object();
file = new File(fileName);
if(!file.exists())
{
tempFile = new File(file.getParentFile(), file.getName() + ".tmp");
if(tempFile.exists())
{
logger.error("WARNING: " + fileName + " was not found, but temp file from " + "previous write operation was. Attempting automatic recovery. Please " + "check file for data consistency.");
tempFile.renameTo(file);
} else
{
throw new FileNotFoundException("XML properties file does not exist: " + fileName);
}
}
tempFile = new File(file.getParentFile(), file.getName() + ".tmp");
if(tempFile.exists())
{
logger.error("WARNING: found a temp file: " + tempFile.getName() +
". This may " +
"indicate that a previous write operation failed. Attempting automatic " +
"recovery. Please check file " + fileName +
" for data consistency.");
if (tempFile.lastModified() > file.lastModified())
{
error = false;
reader = null;
try{
reader = new InputStreamReader(new FileInputStream(tempFile),
"UTF-8");
SAXReader xmlReader = new SAXReader();
xmlReader.read(reader);
}catch(Exception e){
try
{
reader.close();
}
catch (Exception ex)
{}
error = true;
}
}
}
if(error)
{
String bakFile = tempFile.getName() + "-" + System.currentTimeMillis() + ".bak";
tempFile.renameTo(new File(tempFile.getParentFile(), bakFile));
} else
{
/*String bakFile = file.getName() + "-" + System.currentTimeMillis() + ".bak";
file.renameTo(new File(file.getParentFile(), bakFile));
try
{
Thread.sleep(100L);
}
catch(Exception e) { }
tempFile.renameTo(file);*/
}
error = false;
reader = null;
try{
reader = new InputStreamReader(new FileInputStream(file), "UTF-8");
SAXReader xmlReader = new SAXReader();
xmlReader.read(reader);
try
{
reader.close();
}
catch (Exception e)
{}
}catch(Exception e){
error = true;
}
if(error)
{
String bakFileName = file.getName() + "-" + System.currentTimeMillis() + ".bak";
File bakFile = new File(file.getParentFile(), bakFileName);
file.renameTo(bakFile);
try
{
Thread.sleep(100L);
}
catch(Exception e) { }
tempFile.renameTo(file);
} /*else
{
String bakFile = tempFile.getName() + "-" + System.currentTimeMillis() + ".bak";
tempFile.renameTo(new File(tempFile.getParentFile(), bakFile));
}*/
if(!file.canRead())
throw new IOException("XML properties file must be readable: " + fileName);
if(!file.canWrite())
throw new IOException("XML properties file must be writable: " + fileName);
reader = null;
try
{
reader = new InputStreamReader(new FileInputStream(file), "UTF-8");
buildDoc(reader);
}
catch(Exception e)
{
logger.error("Error creating XML properties file " + fileName + ": " + e.getMessage());
throw new IOException(e.getMessage());
}
finally { }
try
{
reader.close();
}
catch(Exception e)
{
e.printStackTrace();
}
} public Object get(Object o)
{
String name;
String value;
Element element;
name = (String)o;
value = (String)propertyCache.get(name);
if(value != null)
return value;
String propName[] = parsePropertyName(name);
element = doc.getRootElement();
for(int i = 0; i < propName.length; i++)
{
element = element.element(propName[i]);
if(element == null)
return null;
} synchronized(propLock){
value = element.getText();
if ("".equals(value))
return null;
value = value.trim();
propertyCache.put(name, value);
return value;
}
} public Collection getChildrenNames(String parent)
{
String propName[] = parsePropertyName(parent);
Element element = doc.getRootElement();
for(int i = 0; i < propName.length; i++)
{
element = element.element(propName[i]);
if(element == null)
return Collections.EMPTY_LIST;
} List children = element.elements();
int childCount = children.size();
List childrenNames = new ArrayList(childCount);
for(Iterator i = children.iterator(); i.hasNext(); childrenNames.add(((Element)i.next()).getName()));
return childrenNames;
} public Collection getPropertyNames()
{
List propNames = new java.util.LinkedList();
List elements = doc.getRootElement().elements();
if(elements.size() == 0)
return Collections.EMPTY_LIST;
for(int i = 0; i < elements.size(); i++)
{
Element element = (Element)elements.get(i);
getElementNames(propNames, element, element.getName());
} return propNames;
} public String getAttribute(String name, String attribute)
{
if(name == null || attribute == null)
return null;
String propName[] = parsePropertyName(name);
Element element = doc.getRootElement();
int i = 0;
do
{
if(i >= propName.length)
break;
String child = propName[i];
element = element.element(child);
if(element == null)
break;
i++;
} while(true);
if(element != null)
return element.attributeValue(attribute);
else
return null;
} private void getElementNames(List list, Element e, String name)
{
if(e.elements().isEmpty())
{
list.add(name);
} else
{
List children = e.elements();
for(int i = 0; i < children.size(); i++)
{
Element child = (Element)children.get(i);
getElementNames(list, child, name + '.' + child.getName());
} }
} public synchronized Object put(Object k, Object v)
{
String name = (String)k;
String value = (String)v;
propertyCache.put(name, value);
String propName[] = parsePropertyName(name);
Element element = doc.getRootElement();
for(int i = 0; i < propName.length; i++)
{
if(element.element(propName[i]) == null)
element.addElement(propName[i]);
element = element.element(propName[i]);
} element.setText(value);
saveProperties();
return null;
} public synchronized void putAll(Map propertyMap)
{
String propertyName;
String propertyValue;
for(Iterator iter = propertyMap.keySet().iterator(); iter.hasNext(); propertyCache.put(propertyName, propertyValue))
{
propertyName = (String)iter.next();
propertyValue = (String)propertyMap.get(propertyName);
String propName[] = parsePropertyName(propertyName);
Element element = doc.getRootElement();
for(int i = 0; i < propName.length; i++)
{
if(element.element(propName[i]) == null)
element.addElement(propName[i]);
element = element.element(propName[i]);
} if(propertyValue != null)
element.setText(propertyValue);
} saveProperties();
} public synchronized Object remove(Object n)
{
String name = (String)n;
propertyCache.remove(name);
String propName[] = parsePropertyName(name);
Element element = doc.getRootElement();
for(int i = 0; i < propName.length - 1; i++)
{
element = element.element(propName[i]);
if(element == null)
return null;
} String value = element.getText();
element.remove(element.element(propName[propName.length - 1]));
saveProperties();
return value;
} public String getProperty(String name)
{
return (String)get(name);
} public boolean containsKey(Object object)
{
return get(object) != null;
} public boolean containsValue(Object object)
{
throw new UnsupportedOperationException("Not implemented in xml version");
} public Collection values()
{
throw new UnsupportedOperationException("Not implemented in xml version");
} public boolean isEmpty()
{
return false;
} public int size()
{
throw new UnsupportedOperationException("Not implemented in xml version");
} public Set entrySet()
{
throw new UnsupportedOperationException("Not implemented in xml version");
} public void clear()
{
throw new UnsupportedOperationException("Not implemented in xml version");
} public Set keySet()
{
throw new UnsupportedOperationException("Not implemented in xml version");
} private void buildDoc(Reader in)
throws Exception
{
SAXReader xmlReader = new SAXReader();
doc = xmlReader.read(in);
} private synchronized void saveProperties()
{
Writer writer;
boolean error;
File tempFile;
writer = null;
error = false;
tempFile = null;
try{
tempFile = new File(file.getParentFile(), file.getName() + ".tmp");
writer = new OutputStreamWriter(new FileOutputStream(tempFile),
"UTF-8");
XMLWriter xmlWriter = new XMLWriter(writer,
OutputFormat.createPrettyPrint());
xmlWriter.write(doc);
try
{
writer.close();
}
catch (Exception ex)
{
logger.error(ex);
error = true;
}
}catch(Exception ex){
logger.error("Unable to write to file " + file.getName() + ".tmp" +
": " + ex.getMessage());
error = true;
}finally{
try
{
writer.close();
}
catch (Exception e)
{
logger.error(e);
error = true;
}
}
if(error)
return;
error = false;
if(file.exists() && !file.delete())
{
logger.error("Error deleting property file: " + file.getAbsolutePath());
return;
}
try{
writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
XMLWriter xmlWriter = new XMLWriter(writer,
OutputFormat.createPrettyPrint());
xmlWriter.write(doc);
try
{
writer.close();
}
catch (Exception e)
{
logger.error(e);
error = true;
}
}catch(Exception e){
logger.error("Unable to write to file '" + file.getName() + "': " +
e.getMessage());
error = true;
try
{
file.delete();
}
catch(Exception fe) { }
try
{
writer.close();
}
catch(Exception ex)
{
logger.error(ex);
error = true;
}
}
if(!error)
tempFile.delete();
} private String[] parsePropertyName(String name)
{
List propName = new ArrayList(5);
for(StringTokenizer tokenizer = new StringTokenizer(name, "."); tokenizer.hasMoreTokens(); propName.add(tokenizer.nextToken()));
return (String[])(String[])propName.toArray(new String[propName.size()]);
}
public void init() {
}
}
3. SystemGlobals
package com.yanek.cfg; import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger; import javax.naming.InitialContext; import org.dom4j.Document;
import org.dom4j.io.SAXReader; public class SystemGlobals
{
static class InitPropLoader
{ public String getSystemHome()
{
String systemHome;
InputStream in;
systemHome = null;
in = null;
if(systemHome == null)
{
try
{
in = getClass().getResourceAsStream("/sys_init.xml");
if (in != null)
{
Document doc = (new SAXReader()).read(in);
systemHome = doc.getRootElement().getText();
}
}
catch (Exception e)
{
SystemGlobals.log.log(Level.SEVERE,
"Error loading sys_init.xml to find systemHome -> " +
e.getMessage(), e);
}
finally
{
try
{
if (in != null)
in.close();
}
catch (Exception e)
{}
}
}
if(systemHome != null)
for(systemHome = systemHome.trim(); systemHome.endsWith("/") || systemHome.endsWith("\\"); systemHome = systemHome.substring(0, systemHome.length() - 1));
if("".equals(systemHome))
systemHome = null;
return systemHome;
} InitPropLoader()
{
}
} private static final Logger log;
private static String SYS_CONFIG_FILENAME = "system_config.xml"; public static String systemHome = null;
public static boolean failedLoading = false;
private static SystemProperties setupProperties = null; private static Date startupDate = new Date(); private SystemGlobals()
{
} public static Date getStartupDate()
{
return startupDate;
} public static String getSystemHome()
{
if(systemHome == null)
loadSetupProperties();
return systemHome;
} public static synchronized void setSystemHome(String sysHome)
{ setupProperties = null;
failedLoading = false;
systemHome = sysHome; loadSetupProperties();
System.err.println("Warning - sysHome is being reset to " + sysHome + "! Resetting the baduHome is a normal part of the setup process, " + "however it should not occur during the normal operations of System.");
} public static void setConfigName(String configName)
{
SYS_CONFIG_FILENAME = configName;
} public static boolean isSetup()
{
return "true".equals(getLocalProperty("setup"));
} public static String getLocalProperty(String name)
{
if(setupProperties == null)
loadSetupProperties();
if(setupProperties == null)
return null;
else
return (String)setupProperties.get(name);
} public static int getLocalProperty(String name, int defaultValue)
{
String value;
value = getLocalProperty(name);
if(value != null)
{
try{
return Integer.parseInt(value);
}catch(NumberFormatException nfe){}
}
return defaultValue;
} public static List getLocalProperties(String parent)
{
if(setupProperties == null)
loadSetupProperties();
if(setupProperties == null)
return Collections.EMPTY_LIST;
Collection propNames = setupProperties.getChildrenNames(parent);
List values = new ArrayList();
Iterator i = propNames.iterator();
do
{
if(!i.hasNext())
break;
String propName = (String)i.next();
String value = getLocalProperty(parent + "." + propName);
if(value != null)
values.add(value);
} while(true);
return values;
} public static void setLocalProperty(String name, String value)
{
if(setupProperties == null)
loadSetupProperties();
if(setupProperties != null)
setupProperties.put(name, value);
} public static void setLocalProperties(Map propertyMap)
{
if(setupProperties == null)
loadSetupProperties();
if(setupProperties != null)
setupProperties.putAll(propertyMap);
} public static void deleteLocalProperty(String name)
{
if(setupProperties == null)
loadSetupProperties();
setupProperties.remove(name);
} public static boolean isWhiteLabel(){
return true;
} private static synchronized void loadSetupProperties()
{
if(failedLoading)
return;
if(setupProperties == null)
{
if(systemHome == null)
systemHome = (new InitPropLoader()).getSystemHome();
if(systemHome == null)
try
{
InitialContext context = new InitialContext();
systemHome = (String)context.lookup("java:comp/env/baduHome");
}
catch(Exception e) { }
if(systemHome == null)
systemHome = System.getProperty("systemHome");
if(systemHome == null)
{
failedLoading = true;
StringBuffer msg = new StringBuffer();
msg.append("Critical Error! The systemHome directory could not be loaded, \n");
msg.append("which will prevent the application from working correctly.\n\n");
msg.append("You must set systemHome in one of three ways:\n");
msg.append(" 1) Add a sys_init.xml file to your classpath, which points \n ");
msg.append(" to sysHome. Normally, this file will be in WEB-INF/classes.\n");
msg.append(" 2) Set the JNDI value \"java:comp/env/systemHome\" with a String \n");
msg.append(" that points to your systemHome directory. \n");
msg.append(" 3) Set the Java system property \"systemHome\".\n\n");
msg.append("Further instructions for setting systemHome can be found in the \n");
msg.append("installation documentation.");
System.err.println(msg.toString());
return;
}
try
{
File jh = new File(systemHome);
if(!jh.exists())
log.severe("Error - the specified systemHome directory does not exist (" + systemHome + ")");
else
if(!jh.canRead() || !jh.canWrite())
log.severe("Error - the user running this System application can not read and write to the specified systemHome directory (" + systemHome + "). Please grant the executing user " + "read and write perms.");
setupProperties = new XMLSystemProperties(systemHome + File.separator + SYS_CONFIG_FILENAME);
}
catch(IOException ioe)
{
log.log(Level.SEVERE, ioe.getMessage(), ioe);
failedLoading = true;
}
}
} static
{
log = Logger.getLogger((com.yanek.cfg.SystemGlobals.class).getName());
} }
4. 配置文件 sys_init.xml ,
定义xml 配置文件的目录
<?xml version="1.0"?>
<systemHome>E:\work\XmlProp\conf</systemHome>
5. xml 配置文件:
<?xml version="1.0" encoding="UTF-8"?> <config>
<setup>true</setup>
<upload>
<file>
<imgFilePath>f:\img\</imgFilePath>
<maxSize>1024</maxSize>
<allowFileType>gif,bmp,png,jpg</allowFileType>
</file>
</upload>
<prop>
<connection>
<pool>
<name>proxool.test.prop</name>
</pool>
<jndi>
<name>test/test</name>
</jndi>
</connection>
</prop>
<log4j>
<filePath>WEB-INF/classes/log4j.properties</filePath>
</log4j>
<taskEngine>
<status>false</status>
</taskEngine>
<list>
<x>aaaa</x>
<y>222</y>
<z>333</z>
</list>
<dbname>testdb</dbname>
<db>
<username>test</username>
<password>test</password>
</db>
</config>
6. 测试类:
package com.yanek.cfg; import java.util.List; public class Test { /**
* @param args
*/
public static void main(String[] args) { System.out.println("setup:"+SystemGlobals.getLocalProperty("setup"));
System.out.println("taskEngine.status:"+SystemGlobals.getLocalProperty("taskEngine.status"));
System.out.println("prop.connection.pool.name:"+SystemGlobals.getLocalProperty("prop.connection.pool.name")); List list=SystemGlobals.getLocalProperties("upload.file");
System.out.println(list);
for(int i=0;i<list.size();i++)
{
System.out.println((String)list.get(i));
} SystemGlobals.setLocalProperty("db.username", "test");
SystemGlobals.setLocalProperty("db.password", "test"); } }