/*******************************************************************************
* Copyright (c) 2004, 2010 BREDEX GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BREDEX GmbH - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.jubula.client.core.utils;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jubula.client.core.gen.parser.parameter.analysis.DepthFirstAdapter;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.AAlphanumericFunctionArgToken;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.AAlphanumericParamToken;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.AAnySequenceParamToken;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.AEscapeSequenceFunctionArgToken;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.AEscapeSequenceParamToken;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.AFunction;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.ALiteral;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.AReference;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.AVariable;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.PFunctionArgList;
import org.eclipse.jubula.client.core.gen.parser.parameter.node.TComma;
import org.eclipse.jubula.client.core.model.IParamDescriptionPO;
import org.eclipse.jubula.client.core.model.IParameterInterfacePO;
import org.eclipse.jubula.tools.internal.messagehandling.MessageIDs;
/**
* Contains information gathered from parsing a Parameter string. The class
* is designed to be instantiated, used in a call to
* {@link Start#apply(org.eclipse.jubula.client.core.parser.parameter.node.Switch)},
* and then queried for tokens via {@link #getTokens()}.
* @author BREDEX GmbH
* @created 12.01.2011
*/
public class ParsedParameter extends DepthFirstAdapter {
/** parsed value tokens */
private List<IParamValueToken> m_paramValueTokens;
/** whether the parsed value comes from user input */
private boolean m_isGuiSource;
/** the parameter node to which the parsed parameter belongs */
private IParameterInterfacePO m_paramNode;
/** the parameter description to which the parsed parameter belongs */
private IParamDescriptionPO m_paramDesc;
/**
* Constructor
*
* @param isGuiSource Whether the parsed value comes from user input.
* @param paramNode The parameter node to which the parsed parameter belongs.
* Can be null in the GUI context!
* @param desc The parameter description to which the
* parsed parameter belongs.
*/
public ParsedParameter(boolean isGuiSource,
IParameterInterfacePO paramNode, IParamDescriptionPO desc) {
m_paramValueTokens = new ArrayList<IParamValueToken>();
m_isGuiSource = isGuiSource;
m_paramNode = paramNode;
m_paramDesc = desc;
}
@Override
public void caseALiteral(ALiteral literal) {
super.caseALiteral(literal);
StringBuilder literalBuilder = new StringBuilder();
literalBuilder.append(literal.getOpenLiteral().getText());
if (literal.getLiteralBody() != null) {
literalBuilder.append(literal.getLiteralBody().getText());
}
literalBuilder.append(literal.getCloseLiteral().getText());
m_paramValueTokens.add(new LiteralToken(
literalBuilder.toString(), literal.getOpenLiteral().getPos()));
}
@Override
public void caseAEscapeSequenceParamToken(
AEscapeSequenceParamToken escSeq) {
super.caseAEscapeSequenceParamToken(escSeq);
m_paramValueTokens.add(new SimpleValueToken(
escSeq.getEscapedSymbol().getText(),
escSeq.getEscapedSymbol().getPos(), m_paramDesc));
}
@Override
public void caseAReference(AReference ref) {
super.caseAReference(ref);
boolean containsBraces = ref.getOpenBrace() != null;
StringBuilder refBuilder =
new StringBuilder(ref.getReferenceToken().getText());
if (containsBraces) {
refBuilder.append(ref.getOpenBrace().getText());
}
if (ref.getReferenceBody() != null) {
refBuilder.append(ref.getReferenceBody().getText());
} else {
if (containsBraces && ref.getCloseBrace() != null) {
throw new SemanticParsingException(
MessageIDs.getMessage(
MessageIDs.E_MISSING_CONTENT),
MessageIDs.E_MISSING_CONTENT,
ref.getReferenceToken().getPos());
}
throw new SemanticParsingException(
MessageIDs.getMessage(
MessageIDs.E_ONE_CHAR_PARSE_ERROR),
MessageIDs.E_ONE_CHAR_PARSE_ERROR,
ref.getReferenceToken().getPos());
}
if (ref.getCloseBrace() != null) {
if (!containsBraces) {
throw new SemanticParsingException(
MessageIDs.getMessage(
MessageIDs.E_GENERAL_PARSE_ERROR),
MessageIDs.E_GENERAL_PARSE_ERROR,
ref.getCloseBrace().getPos());
}
refBuilder.append(ref.getCloseBrace().getText());
} else if (containsBraces) {
throw new SemanticParsingException(
MessageIDs.getMessage(
MessageIDs.E_MISSING_CLOSING_BRACE),
MessageIDs.E_MISSING_CLOSING_BRACE,
ref.getOpenBrace().getPos());
}
m_paramValueTokens.add(new RefToken(refBuilder.toString(),
m_isGuiSource, ref.getReferenceToken().getPos(), m_paramNode,
m_paramDesc));
}
@Override
public void caseAVariable(AVariable var) {
super.caseAVariable(var);
boolean containsBraces = var.getOpenBrace() != null;
String variableBody = var.getVariableBody() != null
? var.getVariableBody().getText() : StringUtils.EMPTY;
StringBuilder varBuilder =
new StringBuilder(var.getVariableToken().getText());
if (containsBraces) {
varBuilder.append(var.getOpenBrace().getText());
}
if (!StringUtils.isEmpty(variableBody)) {
varBuilder.append(variableBody);
} else {
if (containsBraces && var.getCloseBrace() != null) {
throw new SemanticParsingException(
MessageIDs.getMessage(
MessageIDs.E_MISSING_CONTENT),
MessageIDs.E_MISSING_CONTENT,
var.getVariableToken().getPos());
}
throw new SemanticParsingException(
MessageIDs.getMessage(
MessageIDs.E_ONE_CHAR_PARSE_ERROR),
MessageIDs.E_ONE_CHAR_PARSE_ERROR,
var.getVariableToken().getPos());
}
if (var.getCloseBrace() != null) {
if (!containsBraces) {
throw new SemanticParsingException(
MessageIDs.getMessage(
MessageIDs.E_GENERAL_PARSE_ERROR),
MessageIDs.E_GENERAL_PARSE_ERROR,
var.getCloseBrace().getPos());
}
varBuilder.append(var.getCloseBrace().getText());
} else if (containsBraces) {
throw new SemanticParsingException(
MessageIDs.getMessage(
MessageIDs.E_MISSING_CLOSING_BRACE),
MessageIDs.E_MISSING_CLOSING_BRACE,
var.getOpenBrace().getPos());
}
m_paramValueTokens.add(new VariableToken(
varBuilder.toString(), var.getVariableToken().getPos(),
variableBody, m_paramDesc));
}
@Override
public void caseAAlphanumericParamToken(
AAlphanumericParamToken alphanumeric) {
super.caseAAlphanumericParamToken(alphanumeric);
m_paramValueTokens.add(new SimpleValueToken(
alphanumeric.getAlphanumeric().getText(),
alphanumeric.getAlphanumeric().getPos(), m_paramDesc));
}
@Override
public void caseAAnySequenceParamToken(AAnySequenceParamToken anySeq) {
super.caseAAnySequenceParamToken(anySeq);
m_paramValueTokens.add(new SimpleValueToken(
anySeq.getChar().getText(),
anySeq.getChar().getPos(), m_paramDesc));
}
@Override
public void caseAFunction(AFunction function) {
// No call to super() here because we want to traverse the argument list
// separately. We do not want the argument list productions to appear
// aside from the function.
if (function.getFunctionName() == null
|| StringUtils.isEmpty(function.getFunctionName().getText())) {
throw new SemanticParsingException(
MessageIDs.getMessage(
MessageIDs.E_MISSING_FUNCTION_NAME),
MessageIDs.E_MISSING_FUNCTION_NAME,
function.getFunctionToken().getPos());
}
// collect argument list
ParsedParameter argumentParser = new ParsedParameter(
m_isGuiSource, m_paramNode, m_paramDesc);
PFunctionArgList functionArgList = function.getFunctionArgList();
if (functionArgList != null) {
functionArgList.apply(argumentParser);
}
IParamValueToken[] argumentTokens = argumentParser.getTokens().toArray(
new IParamValueToken[argumentParser.getTokens().size()]);
StringBuilder functionTextBuilder = new StringBuilder();
functionTextBuilder.append(function.getFunctionToken().getText())
.append(function.getFunctionName().getText())
.append(function.getBeginFunctionArgsToken().getText());
String functionPrefix = functionTextBuilder.toString();
for (IParamValueToken token : argumentTokens) {
if (m_isGuiSource) {
functionTextBuilder.append(token.getGuiString());
} else {
functionTextBuilder.append(token.getModelString());
}
}
String functionSuffix = function.getEndFunctionArgsToken().getText();
functionTextBuilder.append(functionSuffix);
m_paramValueTokens.add(new FunctionToken(
functionTextBuilder.toString(),
functionPrefix, functionSuffix,
function.getFunctionToken().getPos(), m_paramDesc,
function.getFunctionName().getText(),
argumentTokens));
}
@Override
public void caseTComma(TComma node) {
super.caseTComma(node);
m_paramValueTokens.add(new FunctionArgumentSeparatorToken(
node.getText(), node.getPos(), m_paramDesc));
}
@Override
public void caseAEscapeSequenceFunctionArgToken(
AEscapeSequenceFunctionArgToken escapeSequence) {
super.caseAEscapeSequenceFunctionArgToken(escapeSequence);
m_paramValueTokens.add(new SimpleValueToken(
escapeSequence.getEscapedSymbolInFunction().getText(),
escapeSequence.getEscapedSymbolInFunction().getPos(),
m_paramDesc));
}
@Override
public void caseAAlphanumericFunctionArgToken(
AAlphanumericFunctionArgToken node) {
super.caseAAlphanumericFunctionArgToken(node);
m_paramValueTokens.add(new SimpleValueToken(
node.getFunctionAlphanumeric().getText(),
node.getFunctionAlphanumeric().getPos(),
m_paramDesc));
}
/**
*
* @return the tokens parsed from the AST.
*/
public List<IParamValueToken> getTokens() {
return m_paramValueTokens;
}
}