📄 iclmappingparser.java
字号:
// $CALOLSI$
/*
* #=========================================================================
* # Copyright 2004 SRI International. All rights reserved.
* #
* # The material contained in this file is confidential and proprietary to SRI
* # International and may not be reproduced, published, or disclosed to others
* # without authorization from SRI International.
* #
* # DISCLAIMER OF WARRANTIES
* #
* # SRI International MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
* # SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
* # LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* # PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SRI International SHALL NOT BE
* # LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* # OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
* #=========================================================================
* Author : evans
* Date: May 6, 2004
* Time: 2:34:38 PM
*/
package com.sri.oaa2.mapper;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import com.sri.oaa2.icl.IclTerm;
import antlr_oaa.RecognitionException;
import antlr_oaa.TokenStreamException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.InputSource;
/**
* Parses an XML mapping descriptor for mapping ICL solvables to Java function calls.
*/
public class IclMappingParser
{
private SAXReader saxReader = new SAXReader();
public IclMapping parse(InputStream in) throws MappingException
{
return parse(new InputSource(in));
}
public IclMapping parse(Reader in) throws MappingException
{
return parse(new InputSource(in));
}
public IclMapping parse(InputSource in) throws MappingException
{
try
{
Document document = saxReader.read(in);
IclMapping iclMapping = new IclMapping();
parseMappings(document, iclMapping);
validateMapping(iclMapping);
return iclMapping;
}
catch(DocumentException de)
{
throw new MappingException("Invalid XML: " + de, de);
}
}
private void parseMappings(Document document, IclMapping iclMapping) throws MappingException
{
try
{
// parse functions
List functionNodes = document.selectNodes("/icl-mapping/function");
iclMapping.setFunctionMappings(new FunctionMapping[functionNodes.size()]);
int functionIndex = 0;
for(Iterator iterator = functionNodes.iterator(); iterator.hasNext();)
{
Element functionElement = (Element)iterator.next();
iclMapping.getFunctionMappings()[functionIndex++] = parseFunctionMapping(functionElement);
}
// parse classes:
List classNodes = document.selectNodes("/icl-mapping/class");
iclMapping.setClassMappings(new ClassMapping[classNodes.size()]);
int classIndex = 0;
for(Iterator iterator = classNodes.iterator(); iterator.hasNext();)
{
Element classElement = (Element)iterator.next();
iclMapping.getClassMappings()[classIndex++] = parseClassMapping(classElement);
}
}
catch(MappingException me)
{
throw me;
}
catch(Exception e)
{
throw new MappingException("Mapping exception: " + e.toString(), e);
}
}
private ClassMapping parseClassMapping(Element classElement)
throws ClassNotFoundException, TokenStreamException, RecognitionException, MappingException, IntrospectionException, IllegalAccessException, InstantiationException
{
ClassMapping classMapping = new ClassMapping();
Class mappingClass = getClass(classElement.attributeValue("type"));
classMapping.setMappingClass(mappingClass);
classMapping.setMapper(getMapper(classElement));
if(classMapping.getMapper() == null)
{
IclTerm icl = IclTerm.fromString(classElement.selectSingleNode("./icl").getText());
classMapping.setIcl(icl);
BeanInfo beanInfo = Introspector.getBeanInfo(mappingClass);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
// run through icl tree and locate all IclVars and map to properties:
List varNames = getVarNames(icl);
PropertyMapping[] properties = new PropertyMapping[varNames.size()];
classMapping.setProperties(properties);
int index = 0;
for(Iterator iterator = varNames.iterator(); iterator.hasNext();)
{
PropertyMapping propertyMapping = new PropertyMapping();
properties[index++] = propertyMapping;
String propertyName = fixPropertyName((String)iterator.next());
for(int i = 0; i < propertyDescriptors.length && propertyMapping.getProperty() == null; i++)
{
if(propertyDescriptors[i].getName().equals(propertyName))
{
propertyMapping.setProperty(propertyDescriptors[i]);
propertyMapping.setType(propertyDescriptors[i].getPropertyType());
}
}
if(propertyMapping.getProperty() == null || propertyMapping.getProperty().getReadMethod() == null || propertyMapping.getProperty().getWriteMethod() == null)
{
throw new MappingException("No matching property " + propertyName + " found in class " + classMapping.getMappingClass().getName() + " with correct read and write methods");
}
}
// see if any property types have been overridden by XML:
List varElements = classElement.selectNodes("./var");
for(Iterator iterator = varElements.iterator(); iterator.hasNext();)
{
Element varElement = (Element)iterator.next();
String name = fixPropertyName(varElement.attributeValue("name"));
Class varType = getClass(varElement.attributeValue("type"));
IclMapper iclMapper = getMapper(varElement);
for(int i = 0; i < properties.length; i++)
{
PropertyMapping property = properties[i];
if(property.getProperty().getName().equals(name))
{
if(varType != null) property.setType(varType);
property.setMapper(iclMapper);
}
}
}
}
return classMapping;
}
private FunctionMapping parseFunctionMapping(Element functionElement)
throws MappingException, ClassNotFoundException, TokenStreamException, RecognitionException, IllegalAccessException, InstantiationException
{
FunctionMapping functionMapping = new FunctionMapping();
functionMapping.setFunctionClass(getClass(functionElement.attributeValue("type")));
String functionName = functionElement.attributeValue("name");
String ownThreadStr = functionElement.attributeValue("ownThread");
functionMapping.setOwnThread((ownThreadStr != null) && ownThreadStr.equals("true"));
IclTerm icl = IclTerm.fromString(functionElement.selectSingleNode("./icl").getText());
functionMapping.setIcl(icl);
// run through icl tree and locate all IclVars:
List varNames = getVarNames(icl);
for(Iterator iterator = varNames.iterator(); iterator.hasNext();)
{
String varName = (String)iterator.next();
if(varName.equals("Result"))
{
functionMapping.setReturnsResult(true);
iterator.remove();
}
else if(!varName.startsWith("Arg"))
{
throw new MappingException("ICL mapping for function " + functionName +
" has malformed argument " + varName);
}
}
// validate the args:
ParameterMapping[] varMappings = new ParameterMapping[varNames.size()];
functionMapping.setParameters(varMappings);
for(Iterator iterator = varNames.iterator(); iterator.hasNext();)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -