/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.celements.sajson;
import static org.easymock.EasyMock.*;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
public class LexicalParserTest {
private IEventHandler<IGenericLiteral> mockEventHandler;
private LexicalParser<IGenericLiteral> lexicalParser;
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
mockEventHandler = createStrictMock(IEventHandler.class);
lexicalParser = new LexicalParser<IGenericLiteral>(ERulesLiteral.RULES_ARRAY, mockEventHandler);
}
@Test
public void testBooleanEvent_true() {
mockEventHandler.openEvent(ERulesLiteral.RULES_ARRAY);
mockEventHandler.openEvent(ERulesLiteral.RULE_DICT);
mockEventHandler.openEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.readPropertyKey("isDeleted");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.booleanEvent(true);
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_DICT);
mockEventHandler.closeEvent(ERulesLiteral.RULES_ARRAY);
replayAll();
lexicalParser.initEvent();
lexicalParser.openArrayEvent();
// rule
lexicalParser.openDictionaryEvent();
// isDeleted
lexicalParser.openPropertyEvent("isDeleted");
lexicalParser.booleanEvent(true);
lexicalParser.closePropertyEvent();
// end rule
lexicalParser.closeDictionaryEvent();
// end rules
lexicalParser.closeArrayEvent();
lexicalParser.finishEvent();
verifyAll();
}
@Test
public void testBooleanEvent_false() {
mockEventHandler.openEvent(ERulesLiteral.RULES_ARRAY);
mockEventHandler.openEvent(ERulesLiteral.RULE_DICT);
mockEventHandler.openEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.readPropertyKey("isDeleted");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.booleanEvent(false);
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_DICT);
mockEventHandler.closeEvent(ERulesLiteral.RULES_ARRAY);
replayAll();
lexicalParser.initEvent();
lexicalParser.openArrayEvent();
// rule
lexicalParser.openDictionaryEvent();
// isDeleted
lexicalParser.openPropertyEvent("isDeleted");
lexicalParser.booleanEvent(false);
lexicalParser.closePropertyEvent();
// end rule
lexicalParser.closeDictionaryEvent();
// end rules
lexicalParser.closeArrayEvent();
lexicalParser.finishEvent();
verifyAll();
}
@Test
public void testComplicatedRulesJSON_firstDictionaryOrder() {
mockEventHandler.openEvent(ERulesLiteral.RULES_ARRAY);
mockEventHandler.openEvent(ERulesLiteral.RULE_DICT);
mockEventHandler.openEvent(ERulesLiteral.CONDITION_OR_ACTION_PROPERTY);
mockEventHandler.readPropertyKey("actions");
mockEventHandler.openEvent(ERulesLiteral.CONDITIONS_OR_ACTIONS_ARRAY);
mockEventHandler.openEvent(ERulesLiteral.CONDITION_OR_ACTION_DICT);
mockEventHandler.openEvent(ERulesLiteral.CON_OR_ACT_ATTRIBUTE);
mockEventHandler.readPropertyKey("type");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.stringEvent("addTo");
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.CON_OR_ACT_ATTRIBUTE);
mockEventHandler.closeEvent(ERulesLiteral.CONDITION_OR_ACTION_DICT);
mockEventHandler.closeEvent(ERulesLiteral.CONDITIONS_OR_ACTIONS_ARRAY);
mockEventHandler.closeEvent(ERulesLiteral.CONDITION_OR_ACTION_PROPERTY);
mockEventHandler.openEvent(ERulesLiteral.CONDITION_OR_ACTION_PROPERTY);
mockEventHandler.readPropertyKey("conditions");
mockEventHandler.openEvent(ERulesLiteral.CONDITIONS_OR_ACTIONS_ARRAY);
mockEventHandler.openEvent(ERulesLiteral.CONDITION_OR_ACTION_DICT);
mockEventHandler.openEvent(ERulesLiteral.CON_OR_ACT_ATTRIBUTE);
mockEventHandler.readPropertyKey("type");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.stringEvent("titleCondition");
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.CON_OR_ACT_ATTRIBUTE);
mockEventHandler.closeEvent(ERulesLiteral.CONDITION_OR_ACTION_DICT);
mockEventHandler.closeEvent(ERulesLiteral.CONDITIONS_OR_ACTIONS_ARRAY);
mockEventHandler.closeEvent(ERulesLiteral.CONDITION_OR_ACTION_PROPERTY);
mockEventHandler.openEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.readPropertyKey("name");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.stringEvent("Rule1");
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.openEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.readPropertyKey("type");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.stringEvent("any");
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_DICT);
mockEventHandler.closeEvent(ERulesLiteral.RULES_ARRAY);
replayAll();
lexicalParser.initEvent();
lexicalParser.openArrayEvent();
// rule
lexicalParser.openDictionaryEvent();
// actions
lexicalParser.openPropertyEvent("actions");
lexicalParser.openArrayEvent();
// action
lexicalParser.openDictionaryEvent();
lexicalParser.openPropertyEvent("type");
lexicalParser.stringEvent("addTo");
lexicalParser.closePropertyEvent();
lexicalParser.closeDictionaryEvent();
// end action
lexicalParser.closeArrayEvent();
// end actions
lexicalParser.closePropertyEvent();
// conditions
lexicalParser.openPropertyEvent("conditions");
lexicalParser.openArrayEvent();
// condition
lexicalParser.openDictionaryEvent();
lexicalParser.openPropertyEvent("type");
lexicalParser.stringEvent("titleCondition");
lexicalParser.closePropertyEvent();
lexicalParser.closeDictionaryEvent();
// end condition
lexicalParser.closeArrayEvent();
// end conditions
lexicalParser.closePropertyEvent();
// rulesname
lexicalParser.openPropertyEvent("name");
lexicalParser.stringEvent("Rule1");
lexicalParser.closePropertyEvent();
// rule type
lexicalParser.openPropertyEvent("type");
lexicalParser.stringEvent("any");
lexicalParser.closePropertyEvent();
// end rule
lexicalParser.closeDictionaryEvent();
// end rules
lexicalParser.closeArrayEvent();
lexicalParser.finishEvent();
verifyAll();
}
@Test
public void testComplicatedRulesJSON_secondDictionaryOrder() {
mockEventHandler.openEvent(ERulesLiteral.RULES_ARRAY);
mockEventHandler.openEvent(ERulesLiteral.RULE_DICT);
mockEventHandler.openEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.readPropertyKey("type");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.stringEvent("any");
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.openEvent(ERulesLiteral.CONDITION_OR_ACTION_PROPERTY);
mockEventHandler.readPropertyKey("conditions");
mockEventHandler.openEvent(ERulesLiteral.CONDITIONS_OR_ACTIONS_ARRAY);
mockEventHandler.openEvent(ERulesLiteral.CONDITION_OR_ACTION_DICT);
mockEventHandler.openEvent(ERulesLiteral.CON_OR_ACT_ATTRIBUTE);
mockEventHandler.readPropertyKey("type");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.stringEvent("titleCondition");
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.CON_OR_ACT_ATTRIBUTE);
mockEventHandler.closeEvent(ERulesLiteral.CONDITION_OR_ACTION_DICT);
mockEventHandler.closeEvent(ERulesLiteral.CONDITIONS_OR_ACTIONS_ARRAY);
mockEventHandler.closeEvent(ERulesLiteral.CONDITION_OR_ACTION_PROPERTY);
mockEventHandler.openEvent(ERulesLiteral.CONDITION_OR_ACTION_PROPERTY);
mockEventHandler.readPropertyKey("actions");
mockEventHandler.openEvent(ERulesLiteral.CONDITIONS_OR_ACTIONS_ARRAY);
mockEventHandler.openEvent(ERulesLiteral.CONDITION_OR_ACTION_DICT);
mockEventHandler.openEvent(ERulesLiteral.CON_OR_ACT_ATTRIBUTE);
mockEventHandler.readPropertyKey("type");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.stringEvent("addTo");
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.CON_OR_ACT_ATTRIBUTE);
mockEventHandler.closeEvent(ERulesLiteral.CONDITION_OR_ACTION_DICT);
mockEventHandler.closeEvent(ERulesLiteral.CONDITIONS_OR_ACTIONS_ARRAY);
mockEventHandler.closeEvent(ERulesLiteral.CONDITION_OR_ACTION_PROPERTY);
mockEventHandler.openEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.readPropertyKey("name");
mockEventHandler.openEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.stringEvent("Rule1");
mockEventHandler.closeEvent(ERulesLiteral.OBJECT_VALUE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_ATTRIBUTE);
mockEventHandler.closeEvent(ERulesLiteral.RULE_DICT);
mockEventHandler.closeEvent(ERulesLiteral.RULES_ARRAY);
replayAll();
lexicalParser.initEvent();
lexicalParser.openArrayEvent();
// rule
lexicalParser.openDictionaryEvent();
// rule type
lexicalParser.openPropertyEvent("type");
lexicalParser.stringEvent("any");
lexicalParser.closePropertyEvent();
// conditions
lexicalParser.openPropertyEvent("conditions");
lexicalParser.openArrayEvent();
// condition
lexicalParser.openDictionaryEvent();
lexicalParser.openPropertyEvent("type");
lexicalParser.stringEvent("titleCondition");
lexicalParser.closePropertyEvent();
lexicalParser.closeDictionaryEvent();
// end condition
lexicalParser.closeArrayEvent();
// end conditions
lexicalParser.closePropertyEvent();
// actions
lexicalParser.openPropertyEvent("actions");
lexicalParser.openArrayEvent();
// action
lexicalParser.openDictionaryEvent();
lexicalParser.openPropertyEvent("type");
lexicalParser.stringEvent("addTo");
lexicalParser.closePropertyEvent();
lexicalParser.closeDictionaryEvent();
// end action
lexicalParser.closeArrayEvent();
// end actions
lexicalParser.closePropertyEvent();
// rulesname
lexicalParser.openPropertyEvent("name");
lexicalParser.stringEvent("Rule1");
lexicalParser.closePropertyEvent();
// end rule
lexicalParser.closeDictionaryEvent();
// end rules
lexicalParser.closeArrayEvent();
lexicalParser.finishEvent();
verifyAll();
}
private void replayAll(Object... mocks) {
replay(mockEventHandler);
replay(mocks);
}
private void verifyAll(Object... mocks) {
verify(mockEventHandler);
verify(mocks);
}
private enum ERulesLiteral implements IGenericLiteral {
OBJECT_VALUE(ECommand.VALUE_COMMAND), RULE_ATTRIBUTE(OBJECT_VALUE, "name",
"*"), CON_OR_ACT_ATTRIBUTE(OBJECT_VALUE, "type"), CONDITION_OR_ACTION_DICT(
ECommand.DICTIONARY_COMMAND, CON_OR_ACT_ATTRIBUTE), CONDITIONS_OR_ACTIONS_ARRAY(
ECommand.ARRAY_COMMAND, CONDITION_OR_ACTION_DICT), CONDITION_OR_ACTION_PROPERTY(
CONDITIONS_OR_ACTIONS_ARRAY, "conditions", "actions"), RULE_DICT(
ECommand.DICTIONARY_COMMAND, CONDITION_OR_ACTION_PROPERTY,
RULE_ATTRIBUTE), RULES_ARRAY(ECommand.ARRAY_COMMAND, RULE_DICT);
private ERulesLiteral[] literals;
private ECommand command;
private int nextLiteral = 0;
private Map<String, ERulesLiteral> propertyNameMap;
private String[] names;
private ERulesLiteral(ECommand command, ERulesLiteral... literals) {
this.literals = literals;
this.command = command;
}
private ERulesLiteral(ERulesLiteral literal, String... names) {
this.command = ECommand.PROPERTY_COMMAND;
this.literals = new ERulesLiteral[] { literal };
this.names = names;
}
public ECommand getCommand() {
return command;
}
public String[] getNames() {
return names;
}
public IGenericLiteral getNextLiteral() {
nextLiteral = nextLiteral + 1;
if (nextLiteral > literals.length) {
return null;
}
return literals[nextLiteral - 1];
}
public IGenericLiteral getFirstLiteral() {
nextLiteral = 1;
return literals[0];
}
public IGenericLiteral getPropertyLiteralForKey(String key, IGenericLiteral placeholder) {
nextLiteral = 0; // properties in dictionary may occur multiple times
// (once for each name) and are optional
ERulesLiteral propertyLiteral = getPropertyNameMap().get(key);
if (propertyLiteral == null) {
propertyLiteral = getPropertyNameMap().get("*");
}
return propertyLiteral;
}
private Map<String, ERulesLiteral> getPropertyNameMap() {
if (propertyNameMap == null) {
propertyNameMap = new HashMap<String, ERulesLiteral>();
for (ERulesLiteral literal : literals) {
checkPropertyLiteral(literal);
for (String key : literal.getNames()) {
if (!propertyNameMap.containsKey(key)) {
propertyNameMap.put(key, literal);
} else {
throw new IllegalStateException("duplicate property literal for name [" + key
+ "] in dictionary [" + this + "].");
}
}
}
}
return propertyNameMap;
}
private void checkPropertyLiteral(ERulesLiteral literal) {
if (literal.getCommand() != ECommand.PROPERTY_COMMAND) {
throw new IllegalStateException("expecting only property literal inside"
+ " dictionary but found [" + literal + "].");
}
if (literal.getNames() == null) {
throw new IllegalStateException("missing property names for property literal [" + literal
+ "]");
}
}
}
}