📄 typeparser.java
字号:
package org.jawin.browser.typelib;
import org.jawin.browser.data.*;
import java.io.File;
import org.jawin.COMException;
import org.jawin.HRESULT;
import org.jawin.Variant;
import org.jawin.win32.*;
import org.jawin.constants.VarTypes;
import org.jawin.code.TypeLibWrapper;
import org.jawin.browser.project.ProjectItem;
import org.jawin.browser.log.Log;
import org.jawin.browser.codegen.TypeConversionManager;
import org.jawin.browser.codegen.TypeConversionConfig;
/**
* Parses type info from a type library.
*
* The structure of this parser is similar to a SAX parser, in that data structures
* are stored locally on the class and it is not thread safe.
*
* This is to simplify the logic of parsing the libary and adding structures to
* their correct parents without much parameter passing.
*
* <p>Title: Jawin Code Generation GUI</p>
* <p>Description: GUI for exploring type libraries and generating Java code</p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: Open Source Incentive</p>
*
* @author Josh Passenger
* @version 1.0
*/
public class TypeParser
{
/**
* The basic tree created up front to simply parsing logic
*/
private BaseData libraryNode = null;
private BaseData enumCollection = null;
private BaseData recordCollection = null;
private BaseData moduleCollection = null;
private BaseData interfaceCollection = null;
private BaseData dispatchCollection = null;
private BaseData coClassCollection = null;
private BaseData aliasCollection = null;
private BaseData unionCollection = null;
/**
* The file to be parsed
*/
private File libraryFile = null;
/**
* The project configuration for this item
*/
private ProjectItem projectItem = null;
public TypeParser()
{
}
private void initializeTree()
{
libraryNode = new LibraryNode(libraryFile.getAbsolutePath(), libraryFile.getName(),
projectItem.getName(), projectItem.getSaveDirectory(), projectItem.getJavaEncoding(),
projectItem.getPackageName(), projectItem);
recordCollection = new DataCollection("Records", "records", "images/record.png", projectItem);
libraryNode.addChild(recordCollection);
enumCollection = new DataCollection("Enums", "enums", "images/enum.png", projectItem);
libraryNode.addChild(enumCollection);
interfaceCollection = new DataCollection("Interfaces", "interfaces", "images/interface.png", projectItem);
libraryNode.addChild(interfaceCollection);
moduleCollection = new DataCollection("Modules", "modules", "images/module.png", projectItem);
libraryNode.addChild(moduleCollection);
dispatchCollection = new DataCollection("Dispatches", "dispatches", "images/dispatch.png", projectItem);
libraryNode.addChild(dispatchCollection);
coClassCollection = new DataCollection("CoClasses", "coclasses", "images/coclass.png", projectItem);
libraryNode.addChild(coClassCollection);
aliasCollection = new DataCollection("Aliases", "aliases", "images/alias.png", projectItem);
libraryNode.addChild(aliasCollection);
unionCollection = new DataCollection("Unions", "unions", "images/union.png", projectItem);
libraryNode.addChild(unionCollection);
}
/**
* Parses the type info from the requested library file
* and returns a BaseData tree node that contains the parsed data
*
* @param newLibraryFile the type library to parse
* @param newProjectItem the project configuration for this library
* @return the new tree root containing the parsed type info
*/
public BaseData parseTypeInfo(File newLibraryFile, ProjectItem newProjectItem)
{
libraryFile = newLibraryFile;
projectItem = newProjectItem;
initializeTree();
String libaryName = libraryFile.getName();
/* parseCxxHeader */
TypeLibWrapper typeLibWrapper = new TypeLibWrapper();
ITypeLib iTypeLib = new ITypeLib();
if(typeLibWrapper.loadTypeLib(libraryFile.getAbsolutePath()) == 0)
{
/**
* Get a TLIBATTR array for this type library
*/
TLIBATTR [] typeLibAttributeArray = new TLIBATTR[1];
iTypeLib.getLibAttr(typeLibAttributeArray);
/**
* Display info about this type library
*/
debugTypeLibraryAttribute(typeLibAttributeArray[0]);
for (int i = 0; i < iTypeLib.getTypeInfoCount(); i++)
{
/**
* Get a TYPEATTR array for each type library info
*/
ITypeInfo[] iTypeInfo = new ITypeInfo[1];
iTypeLib.getTypeInfo(i, iTypeInfo);
TYPEATTR [] typeAttributeArray = new TYPEATTR[1];
int err = iTypeInfo[0].getTypeAttr(typeAttributeArray);
if (HRESULT.FAILED(err)) {
throw new RuntimeException(new COMException(err).toString());
}
BaseData node =
createTypeInfoNode(
typeLibWrapper,
iTypeLib,
i,
iTypeInfo,
typeAttributeArray);
/**
* Parse the variables and data members in this type library
*/
for (int j = 0; j < typeAttributeArray[0].cVars; j++)
{
parseVarDesc(iTypeInfo, node, j);
}
/**
* Parse the functions on this node
*/
for(int j = 0; j < typeAttributeArray [0].cFuncs; j++)
{
parseFuncDesc(iTypeInfo, node, j);
}
}
}
else
{
libraryNode = new LibraryNode(libraryFile.getAbsolutePath(),
libaryName + " did not contain type info",
projectItem.getName(), projectItem.getSaveDirectory(), projectItem.getJavaEncoding(),
projectItem.getPackageName(), projectItem);
}
return libraryNode;
}
private void parseFuncDesc(ITypeInfo[] iTypeInfo, BaseData node, int j) {
int err;
FUNCDESC [] funcDesc = new FUNCDESC [1];
iTypeInfo [0].getFuncDesc(j, funcDesc);
String [] functionName = new String [1];
String [] functionDocString = new String [1];
String [] functionHelpFile = new String [1];
int [] functionHelpContext = new int [1];
err = iTypeInfo[0].getDocumentation(funcDesc[0].memid, functionName,
functionDocString, functionHelpContext, functionHelpFile);
FunctionNode functionNode = new FunctionNode(functionName[0], functionDocString[0],
functionHelpFile[0], functionHelpContext[0]);
functionNode.setVTableOffset(funcDesc[0].oVft);
functionNode.setParamCount(funcDesc[0].cParams);
functionNode.setOptionalParamCount(funcDesc[0].cParamsOpt);
node.addChild(functionNode);
/**
* Extract the return parameter info
*/
TypeConversionConfig functionReturnType = TypeConversionManager.getInstance().getConfig(funcDesc[0].elemdescFunc.tdesc.vt);
if (functionReturnType != null)
{
FunctionReturnNode returnNode = new FunctionReturnNode(functionReturnType);
if(funcDesc[0].elemdescFunc.tdesc!=null)
{
buildTypeDescription(iTypeInfo[0], returnNode, funcDesc[0].elemdescFunc.tdesc, functionReturnType);
if(funcDesc[0].elemdescFunc.idldesc != null)
{
buildIDLDesc(iTypeInfo[0], returnNode, funcDesc[0].elemdescFunc.idldesc, functionReturnType);
}
}
functionNode.addChild(returnNode);
}
/**
* Fetch the invoke kind
*/
String [] parameterNames = null;
int [] pcNames = new int [1];
switch (funcDesc[0].invkind)
{
case 1:
functionNode.setInvokeKind("DISPATCH_METHOD");
parameterNames = new String [funcDesc[0].cParams + 1];
iTypeInfo[0].getNames(funcDesc[0].memid, parameterNames, funcDesc[0].cParams + 1, pcNames);
break;
case 2:
functionNode.setInvokeKind("DISPATCH_PROPERTYGET");
parameterNames = new String [funcDesc[0].cParams + 1];
iTypeInfo[0].getNames(funcDesc[0].memid, parameterNames, funcDesc[0].cParams + 1, pcNames);
//if(functionName[0].compareToIgnoreCase("Item")==0)
{
//System.out.println((funcDesc[0].cParams + 1)+" "+parameterNames[0]+" "+parameterNames[1]+" "+parameterNames[2]);
}
if(parameterNames!=null && parameterNames.length>1 && parameterNames[1]==null)
{
parameterNames[1]=parameterNames[0];
//System.out.println(parameterNames[1]+" : "+pcNames[0]);
}
break;
case 4:
functionNode.setInvokeKind("DISPATCH_PROPERTYPUT");
//parameterNames = new String[1];
//parameterNames[0] = functionName[0];
parameterNames = new String [funcDesc[0].cParams + 1];
iTypeInfo[0].getNames(funcDesc[0].memid, parameterNames, funcDesc[0].cParams + 1, pcNames);
//if(functionName[0].compareToIgnoreCase("Item")==0)
{
//System.out.println((funcDesc[0].cParams + 1)+" "+parameterNames[0]+" "+parameterNames[1]+" "+parameterNames[2]);
}
if(parameterNames.length>0 && parameterNames[1]==null)
{
parameterNames[1]=parameterNames[0];
//System.out.println(parameterNames[1]+" : "+pcNames[0]);
}
break;
case 8:
functionNode.setInvokeKind("DISPATCH_PROPERTYPUTREF");
break;
default:
functionNode.setInvokeKind("NOT IMPLEMENTED");
break;
}
/**
* Distinguish the function kind
*/
switch (funcDesc[0].funckind)
{
case 0:
functionNode.setFunctionKind("FUNC_VIRTUAL");
break;
case 1:
functionNode.setFunctionKind("FUNC_PUREVIRTUAL");
break;
case 2:
functionNode.setFunctionKind("FUNC_NONVIRTUAL");
break;
case 3:
functionNode.setFunctionKind("FUNC_STATIC");
break;
default:
functionNode.setFunctionKind("FUNC_DISPATCH");
break;
}
if(funcDesc[0].elemdescFunc.tdesc.vt==VarTypes.VT_PTR)
{
parameterNames = new String[funcDesc[0].cParams + 1];
iTypeInfo[0].getNames(funcDesc[0].memid, parameterNames, funcDesc[0].cParams + 1, pcNames);
}
if (parameterNames != null && pcNames[0] > 0)
{
for(int k = 1; k <= funcDesc[0].cParams; k++)
{
if (funcDesc[0].lprgelemdescParam.length > k-1)
{
if (funcDesc[0].lprgelemdescParam[k-1].tdesc != null)
{
int paramTypeId = funcDesc[0].lprgelemdescParam[k-1].tdesc.vt;
TypeConversionConfig paramType = TypeConversionManager.getInstance().getConfig(paramTypeId);
String parameterName=parameterNames[k];
if(parameterName==null)
{
parameterName="newValue"+k;
}
ParameterNode parameterNode = new ParameterNode(parameterName, paramTypeId);
if (paramType != null)
{
parameterNode.setTypeConfig(paramType);
buildTypeDescription(iTypeInfo[0], parameterNode, funcDesc[0].lprgelemdescParam[k-1].tdesc, paramType);
if (funcDesc[0].lprgelemdescParam[k-1].paramdesc != null)
{
buildPARAMDesc(iTypeInfo[0], parameterNode, funcDesc[0].lprgelemdescParam[k-1].paramdesc, paramType);
}
if (funcDesc[0].lprgelemdescParam[k-1].idldesc!=null)
{
buildIDLDesc(iTypeInfo[0], parameterNode, funcDesc[0].lprgelemdescParam[k-1].idldesc, paramType);
}
functionNode.addChild(parameterNode);
}
else
{
System.out.println(functionName[0] + " - unknown VT-type (" + paramTypeId + ") at " +
parameterNames[k] + " " + k + "th parameter");
}
}
else
{
System.out.println(functionName[0] + " - null at " +
parameterNames[k] + " " + k + "th parameter");
}
}
else
{
System.out.println(functionName[0] + " - Error typing " +
parameterNames[k] + " " + k + "th parameter " +
funcDesc[0].cParams + " " + funcDesc[0].cParamsOpt + " " +
funcDesc[0].lprgelemdescParam.length);
}
}
}
}
private void parseVarDesc(ITypeInfo[] iTypeInfo, BaseData node, int j) {
int err;
VARDESC[] varDesc = new VARDESC[1];
iTypeInfo[0].getVarDesc(j, varDesc);
String[] propertyName = new String [1];
String[] propertyDocString = new String [1];
String[] propertyHelpFile = new String [1];
int [] propertyHelpContext = new int [1];
err = iTypeInfo[0].getDocumentation(varDesc[0].memid, propertyName, propertyDocString, propertyHelpContext, propertyHelpFile);
int paramType = varDesc[0].elemdescVar.tdesc.vt;
PropertyNode propertyNode = new PropertyNode(propertyName[0],
propertyDocString[0], paramType);
node.addChild(propertyNode);
TypeConversionConfig config = TypeConversionManager.getInstance().getConfig(paramType);
propertyNode.setTypeConfig(config);
buildTypeDescription(iTypeInfo[0], propertyNode, varDesc[0].elemdescVar.tdesc, config);
/**
* Added 16 Feb 2003 JP as updated by Roger
* This handles default values for enums
* and typing of properties on type info nodes
*/
/**
* Extract out any constant values
*/
switch (varDesc[0].varkind)
{
case VARKIND.VAR_PERINSTANCE:
{
propertyNode.setPropertyKind("VAR_PERINSTANCE");
break;
}
case VARKIND.VAR_STATIC:
{
propertyNode.setPropertyKind("VAR_STATIC");
break;
}
case VARKIND.VAR_CONST:
{
propertyNode.setPropertyKind("VAR_CONST");
VariantNode variantNode = new VariantNode();
buildVariant(variantNode, varDesc[0].lpvarValue[0]);
propertyNode.addChild(variantNode);
break;
}
case VARKIND.VAR_DISPATCH:
{
propertyNode.setPropertyKind("VAR_DISPATCH");
break;
}
default:
{
propertyNode.setPropertyKind("NOT IMPLEMENTED");
break;
}
}
if(varDesc[0].elemdescVar.paramdesc != null)
{
buildPARAMDesc(iTypeInfo[0], propertyNode, varDesc[0].elemdescVar.paramdesc, config);
}
if(varDesc[0].elemdescVar.idldesc != null)
{
buildIDLDesc(iTypeInfo[0], propertyNode, varDesc[0].elemdescVar.idldesc, config);
}
/**
* End code added 16 Feb 2003, JP
*/
}
/* parseCxxHeader()
if(libaryName.endsWith(".h"))
{
String line=null, newline = null;
java.io.LineNumberReader reader =null;
try
{
// Create logger
org.apache.avalon.framework.logger.Logger logger = new org.apache.avalon.framework.logger.ConsoleLogger(org.apache.avalon.framework.logger.ConsoleLogger.LEVEL_DEBUG);
// Create factory for SAX parser
javax.xml.parsers.SAXParserFactory parserFactoryImpl = javax.xml.parsers.SAXParserFactory.newInstance();
parserFactoryImpl.setNamespaceAware(true);
// Get a SAX parser
org.xml.sax.XMLReader xmlparser = parserFactoryImpl.newSAXParser().getXMLReader();
// Create a lexicon model for a given lexicon file
org.apache.avalon.framework.configuration.NamespacedSAXConfigurationHandler handler = new org.apache.avalon.framework.configuration.NamespacedSAXConfigurationHandler();
xmlparser.setContentHandler(handler);
xmlparser.parse("./chaperon/header.xlex");
org.apache.avalon.framework.configuration.Configuration lexiconconfig = handler.getConfiguration();
net.sourceforge.chaperon.model.lexicon.Lexicon lexicon = net.sourceforge.chaperon.adapter.avalon.LexiconFactory.createLexicon(lexiconconfig);
// Build a automaton from the lexicon model
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -