📄 resourcestatement.java
字号:
{
Element entry = new Element("entry");
String expression = currentNode.getText();
Object value = evaluate(expression, currentNode.getLine(), currentNode.getColumn());
entry.setAttribute("value", convertToString(value));
resourceElement.addContent(entry);
currentNode = currentNode.getNextSibling();
}
}
//------------------------------------------------------------------------------------------------
/**
* Converts a "toolbar" entry to XML.
*
* @param sourceNode The node containing the AST data to convert.
* @param resourceElement The entry to which the new nodes must be added.
*/
private void convertToolbarEntry(AST sourceNode, Element resourceElement)
{
resourceElement.setAttribute("type", "toolbar");
AST currentNode = sourceNode.getFirstChild();
if (currentNode != null)
{
if (currentNode.getType() == RCParserTokenTypes.RESOURCE_ATTRIBUTES)
{
convertResourceAttributes(resourceElement, currentNode);
currentNode = currentNode.getNextSibling();
}
// The next two entries are button width and height.
processEntryWithEvaluation(currentNode, "button-width", resourceElement);
currentNode = currentNode.getNextSibling();
processEntryWithEvaluation(currentNode, "button-height", resourceElement);
currentNode = currentNode.getNextSibling();
// After the button sizes follows the list of toolbar buttons.
while (currentNode != null)
{
switch (currentNode.getType())
{
case RCParserTokenTypes.LITERAL_button:
{
AST idNode = currentNode.getFirstChild();
processEntryWithEvaluation(idNode, "button", resourceElement);
break;
}
case RCParserTokenTypes.LITERAL_separator:
{
Element separatorElement = new Element("Separator");
resourceElement.addContent(separatorElement);
break;
}
default:
// Actually this should never happen as the parser already takes care to find the
// correct syntax.
reportError("Invalid toolbar content definition.");
}
currentNode = currentNode.getNextSibling();
}
}
}
//------------------------------------------------------------------------------------------------
/**
* Converts the given symbol value into a string that can be placed into a DOM element.
* If the object is a string literal then it gets unquoted first.
*
* @param value The value to convert.
* @return The converted value as string.
*/
private String convertToString(Object value)
{
if (value instanceof AST)
{
value = evaluate((AST) value);
}
else
if (value instanceof String)
{
String string = (String) value;
if (string.startsWith("\""))
return string.substring(1, string.length() - 1);
else
return string;
}
return value.toString();
}
//------------------------------------------------------------------------------------------------
/**
* Converts a user defined entry to XML.
*
* @param sourceNode The node containing the AST data to convert.
* @param resourceElement The entry to which the new nodes must be added.
*/
private void convertUserDefinedEntry(AST sourceNode, Element resourceElement)
{
resourceElement.setAttribute("type", "user-defined");
AST currentNode = sourceNode.getFirstChild();
resourceElement.setAttribute("resource-type", currentNode.getText());
currentNode = currentNode.getNextSibling();
if (currentNode != null)
{
if (currentNode.getType() == RCParserTokenTypes.RESOURCE_ATTRIBUTES)
{
convertResourceAttributes(resourceElement, currentNode);
currentNode = currentNode.getNextSibling();
}
// Optional common resource info part.
if (currentNode != null)
{
while (currentNode.getType() == RCParserTokenTypes.COMMON_RESOURCE_INFO)
{
convertCommonResourceInfo(currentNode, resourceElement);
currentNode = currentNode.getNextSibling();
}
}
if (currentNode != null)
{
if (currentNode.getType() == RCParserTokenTypes.FILE_NAME)
{
Element fileNameElement = new Element("data");
resourceElement.addContent(fileNameElement);
String filename = currentNode.getFirstChild().getText();
if (filename.startsWith("\""))
filename = filename.substring(1, filename.length());
fileNameElement.setAttribute("file-name", filename);
}
else
{
// Must be raw data, e.g. single literals (string, character, integer etc.) or
// a collection of hex numbers enclosed by single quotes.
convertRawDataToXML(currentNode, resourceElement);
}
}
}
}
//------------------------------------------------------------------------------------------------
/**
* Converts a "versioninfo" entry to XML.
*
* @param sourceNode The node containing the AST data to convert.
* @param resourceElement The entry to which the new nodes must be added.
*/
private void convertVersionInfoEntry(AST sourceNode, Element resourceElement)
{
resourceElement.setAttribute("type", "version-info");
AST currentNode = sourceNode.getFirstChild();
// Optional fixed version info part.
if (currentNode != null)
{
while (currentNode.getType() == RCParserTokenTypes.VERSION_FIXED_INFO)
{
AST infoNode = currentNode.getFirstChild();
Element infoElement = new Element("info-detail");
infoElement.setAttribute("name", infoNode.getText());
resourceElement.addContent(infoElement);
convertExpressionList(infoNode.getFirstChild(), infoElement);
currentNode = currentNode.getNextSibling();
}
}
// Optional common resource info part.
if (currentNode != null)
{
while (currentNode.getType() == RCParserTokenTypes.COMMON_RESOURCE_INFO)
{
convertCommonResourceInfo(currentNode, resourceElement);
currentNode = currentNode.getNextSibling();
}
}
// Finally the main content.
while (currentNode != null)
{
switch (currentNode.getType())
{
case RCParserTokenTypes.STRING_FILE_INFO:
{
Element infoElement = new Element("string-file-info");
resourceElement.addContent(infoElement);
AST blockNode = currentNode.getFirstChild();
while (blockNode != null)
{
Element blockElement = new Element("block");
infoElement.addContent(blockElement);
AST entryNode = blockNode.getFirstChild();
processEntryWithEvaluationAsAttribute(entryNode, "charset", blockElement);
entryNode = entryNode.getNextSibling();
while (entryNode != null)
{
Element valueElement = new Element("value");
blockElement.addContent(valueElement);
AST valueNode = entryNode.getFirstChild();
valueElement.setAttribute("name", convertToString(valueNode));
valueNode = valueNode.getNextSibling();
valueElement.setAttribute("value", convertToString(valueNode));
entryNode = entryNode.getNextSibling();
}
blockNode = blockNode.getNextSibling();
}
break;
}
case RCParserTokenTypes.VAR_FILE_INFO:
{
Element infoElement = new Element("var-file-info");
resourceElement.addContent(infoElement);
AST entryNode = currentNode.getFirstChild();
while (entryNode != null)
{
Element valueElement = new Element("value");
infoElement.addContent(valueElement);
AST valueNode = entryNode.getFirstChild();
valueElement.setAttribute("name", convertToString(valueNode.getText()));
convertExpressionList(valueNode.getNextSibling(), valueElement);
entryNode = entryNode.getNextSibling();
}
break;
}
}
currentNode = currentNode.getNextSibling();
}
}
//------------------------------------------------------------------------------------------------
/**
* Adds a new XML node with name <b>name</b> to target. The AST node's value is added as
* an attribute with name <b>symbol</b> and if that symbol can be evaluated to a single value
* then this value is also added as attribute with name <b>symbol-value</b>.
* If the current AST node does not represent a symbol then it is taken as expression, evaluated
* and added as single attribute <b>value</b>.
*
* @param node The AST node to parse.
* @param name The name for the new XML node to create.
* @param target The target XML node to which the new XML node must be added.
* @return The newly created child XML node.
*/
private Element processEntryWithEvaluation(AST node, String name, Element target)
{
String symbol = node.getText();
Element element = new Element(name);
target.addContent(element);
if (node != null)
{
if (node.getType() == RCParserTokenTypes.IDENTIFIER)
{
element.setAttribute("symbol", symbol);
Object symbolValue = evaluate(symbol, node.getLine(), node.getColumn());
if (symbolValue != null)
element.setAttribute("symbol-value", convertToString(symbolValue));
}
else
if (node.getType() == RCParserTokenTypes.EXPR)
{
Object value = evaluate(node);
if (value != null)
element.setAttribute("value", convertToString(value));
else
element.setAttribute("value", convertExpressionToText(node.getFirstChild()));
}
else
{
// There is only a scalar value or an expression. Try to evaluate it and add the result as
// attribute to the new XML node. If it cannot be evaluated then add the pure text data.
Object symbolValue = evaluate(symbol, node.getLine(), node.getColumn());
if (symbolValue == null)
element.setAttribute("value", symbol);
else
element.setAttribute("value", convertToString(symbolValue));
}
}
return element;
}
//------------------------------------------------------------------------------------------------
/**
* This method is very similar as {@see ResourceStatement#processEntryWithEvaluation}. What is
* different here is that the result is added as attribute to the target node.
*
* @param node The AST node to parse.
* @param name The name for the attribute to use.
* @param target The target XML node to which the attribute is to be attached.
*/
private void processEntryWithEvaluationAsAttribute(AST node, String name, Element target)
{
if (node != null)
{
if (node.getType() == RCParserTokenTypes.IDENTIFIER)
{
Object value = evaluate(node.getText(), node.getLine(), node.getColumn());
if (value != null)
target.setAttribute(name, convertToString(value));
else
target.setAttribute(name, convertExpressionToText(node.getFirstChild()));
}
else
if (node.getType() == RCParserTokenTypes.EXPR)
{
Object value = evaluate(node);
if (value != null)
target.setAttribute(name, convertToString(value));
else
target.setAttribute(name, convertExpressionToText(node.getFirstChild()));
}
else
{
// There is only a scalar value or an expression.
Object symbolValue = evaluate(node.getText(), node.getLine(), node.getColumn());
if (symbolValue == null)
target.setAttribute("value", node.getText());
else
target.setAttribute("value", convertToString(symbolValue));
}
}
}
//------------------------------------------------------------------------------------------------
/**
* Conversion routine to create an XML subtree from the current AST subtree.
*
* @param target The target node in the XML DOM where to add the converted data.
*/
public void convert(Element target)
{
switch (getAstNode().getType())
{
case RCParserTokenTypes.LITER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -