由于项目需要做了一个从pdm中读取表/字段的代码,为以后使用方便记在此处

public class PDMHandler extends DefaultHandler2
{
private static final String DBMS = "/" + Target.dbms.id;

private static final String DBMS_NAME = DBMS + "/" + Target.dbmsName.id;

private static final String DBMS_CODE = DBMS + "/" + Target.dbmsCode.id;

private static final String TABLES = "/" + Target.tables.id;

private static final String TABLES_TABLE = TABLES + "/" + Target.table.id;

private static final String TABLES_TABLE_NAME = TABLES_TABLE + "/" + Target.tableName.id;

private static final String TABLES_TABLE_CODE = TABLES_TABLE + "/" + Target.tableCode.id;

private static final String TABLES_TABLE_COLUMNS = TABLES_TABLE + "/" + Target.columns.id;

private static final String TABLES_TABLE_COLUMNS_COLUMN = TABLES_TABLE_COLUMNS + "/" + Target.column.id;

private static Log log = LogFactory.getLog(PDMHandler.class);

// 是否正在处理
private boolean doing;

// 结果对象
private Tables tables = new Tables();

// 上一次的表对象
private Table lastTable;

// 上一次的列对象
private Column lastColumn;

// 上一次处理的对象
private Target lastObject;

// 上一次路径,元素之间用/进行分隔,属性则采用@来标识,这是借用了XPath的规范
private String lastPath = "";


/** *//**
* 开始文档解析
*
* @see org.xml.sax.helpers.DefaultHandler#startDocument()
*/
@Override

public void startDocument() throws SAXException
{
log.debug("powerdesigner pdm document parse start.");
}


/** *//**
* 结束文档解析
*
* @see org.xml.sax.helpers.DefaultHandler#endDocument()
*/
@Override

public void endDocument() throws SAXException
{
log.debug("powerdesigner pdm document parse finish.");
}


/** *//**
* 启动元素解析
*
* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
* java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
@Override

public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException
{
// 首先处理dbms的解释
if (Target.dbms.id.equals(name) || Target.tables.id.equals(name))
doing = true;

// 如果没有开始,则直接退出
if (!doing)
return;

// 设置路径
String tempPath = lastPath + "/" + name;

log.debug("开始解析:" + name);
// DBMS

if (lastPath.equals(DBMS))
{

if (tempPath.equals(DBMS_NAME))
{
lastObject = Target.dbmsName;

} else if (tempPath.equals(DBMS_CODE))
{
lastObject = Target.dbmsCode;
}
// TABLE

} else if (lastPath.equals(TABLES))
{

if (tempPath.equals(TABLES_TABLE))
{
// 新建一个表
lastTable = new Table();
tables.add(lastTable);
}
// TABLE的属性

} else if (lastPath.equals(TABLES_TABLE))
{

if (tempPath.equals(TABLES_TABLE_NAME))
{
lastObject = Target.tableName;

} else if (tempPath.equals(TABLES_TABLE_CODE))
{
lastObject = Target.tableCode;
}
// 列

} else if (lastPath.equals(TABLES_TABLE_COLUMNS))
{

if (tempPath.equals(TABLES_TABLE_COLUMNS_COLUMN))
{
// 新建列
lastColumn = new Column();
lastTable.add(lastColumn);
}

} else if (lastPath.equals(TABLES_TABLE_COLUMNS_COLUMN))
{
// 只处理列的属性
lastObject = findTarget(Group.column, name);
}
lastPath = tempPath;
}


/** *//**
* 结束元素解析
*
* @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
* java.lang.String, java.lang.String)
*/
@Override

public void endElement(String uri, String localName, String name) throws SAXException
{
// 管理是否结束schema的解析
if (!doing)
return;

log.debug("完成解析:" + name);
if (Target.dbms.id.equals(name) || Target.tables.id.equals(name))
doing = false;

// 恢复路径状态
lastPath = StringUtils.substringBeforeLast(lastPath, "/" + name);
}

@Override

public void characters(char[] ch, int start, int length) throws SAXException
{

if (lastObject != null && lastObject.ob != null)
{
Object dest = Group.table.equals(lastObject.og) ? lastTable : Group.column.equals(lastObject.og) ? lastColumn : tables;

try
{
BeanUtils.setProperty(dest, lastObject.ob, new String(ch, start, length));
lastObject = null;

} catch (Exception e)
{
throw new SAXException(e);
}
}
}


/** *//**
* 取得解析成功的Table定义信息
*
* @return
*/

public Tables getTables()
{
return tables;
}


/** *//**
* 根据标识找符合标识的东西
*
* @param group
* @param id
* @return
*/

private static Target findTarget(Group group, String id)
{

for (Target item : Target.class.getEnumConstants())
{
if (group == item.og && item.id.equals(id))
return item;
}
return null;
}


/** *//**
* 操作的组分类
*
* @author wilesun
* @create 2007-11-3
*/

private enum Group
{
dbms, table, column
}


/** *//**
* 解析操作码
*
* @author wilesun
* @create 2007-11-3
*/

private enum Target
{

/** *//**
* dbms
*/
dbms("o:DBMS"),

/** *//**
* dbms名称
*/
dbmsName("a:Name", "dbmsName", Group.dbms),

/** *//**
* dbms编码
*/
dbmsCode("a:Code", "dbmsCode", Group.dbms),

/** *//**
* 表集合
*/
tables("c:Tables"),

/** *//**
* 表
*/
table("o:Table"),

/** *//**
* 表名称
*/
tableName("a:Name", "name", Group.table),

/** *//**
* 表编码
*/
tableCode("a:Code", "code", Group.table),

/** *//**
* 列集合
*/
columns("c:Columns"),

/** *//**
* 列
*/
column("o:Column"),

/** *//**
* 列名称
*/
columnName("a:Name", "name", Group.column),

/** *//**
* 列编号
*/
columnCode("a:Code", "code", Group.column),

/** *//**
* 列格式
*/
columnFormat("a:Format", "format", Group.column),

/** *//**
* 列下拉
*/
columnList("a:ListOfValues", "list", Group.column),

/** *//**
* 列类型
*/
columnDataType("a:DataType", "dataType", Group.column),

/** *//**
* 列长度
*/
columnLength("a:Length", "length", Group.column),

/** *//**
* 列强制
*/
columnMandatory("a:Mandatory", "mandatory", Group.column);

// 操作码标识
private String id;

private String ob;

private Group og;


/** *//**
* 只根据标识,无组和操作构造
*
* @param id
*/

Target(String id)
{
this.id = id;
}


/** *//**
* 根据标识和操作做内部构造
*
* @param id
*/

Target(String id, String ob, Group og)
{
this.id = id;
this.ob = ob;
this.og = og;
}
}
}