/*
* JBoss, Home of Professional Open Source.
* Copyright 2016, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* 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 org.jboss.as.cli.parsing.operation.header;
import org.jboss.as.cli.CommandFormatException;
import org.jboss.as.cli.operation.impl.DefaultCallbackHandler;
import org.jboss.as.cli.operation.impl.ParsedRolloutPlanHeader;
import org.jboss.as.cli.operation.impl.SingleRolloutPlanGroup;
import org.jboss.as.cli.parsing.ParsingContext;
import org.jboss.as.cli.parsing.ParsingStateCallbackHandler;
import org.jboss.as.cli.parsing.operation.HeaderValueState;
import org.jboss.as.cli.parsing.operation.PropertyListState;
import org.jboss.as.cli.parsing.operation.PropertyState;
import org.jboss.as.cli.parsing.operation.PropertyValueState;
/**
*
* @author Alexey Loubyansky
*/
public class RolloutPlanHeaderCallbackHandler implements ParsingStateCallbackHandler {
private final ParsedRolloutPlanHeader header = new ParsedRolloutPlanHeader();
private final DefaultCallbackHandler handler;
final StringBuilder buffer = new StringBuilder();
private String name;
private SingleRolloutPlanGroup group;
private boolean concurrent;
private int lastChunkIndex;
public RolloutPlanHeaderCallbackHandler(DefaultCallbackHandler handler) {
this.handler = handler;
}
@Override
public void enteredState(ParsingContext ctx) throws CommandFormatException {
final String id = ctx.getState().getId();
//System.out.println("rollout.entered " + id + " '" + ctx.getCharacter() + "'");
if(HeaderValueState.ID.equals(id)) {
ctx.enterState(RolloutPlanState.INSTANCE);
} else if(ServerGroupState.ID.equals(id)) {
group = new SingleRolloutPlanGroup();
} else if(ConcurrentSignState.ID.equals(id)) {
concurrent = true;
header.groupConcurrentSeparator(ctx.getLocation());
} else if ("NAME_VALUE_SEPARATOR".equals(id)) {
name = buffer.length() == 0 ? null : buffer.toString().trim();
if(name == null || name.isEmpty()) {
throw new CommandFormatException("Property is missing name at index " + ctx.getLocation());
}
if(group != null) {
group.addProperty(name, lastChunkIndex);
group.propertyValueSeparator(ctx.getLocation());
} else {
header.planIdValueSeparator(ctx.getLocation());
}
} else if(ServerGroupSeparatorState.ID.equals(id)) {
header.groupSequenceSeparator(ctx.getLocation());
} else if(PropertyListState.ID.equals(id)) {
if(group != null) {
group.propertyListStart(ctx.getLocation());
} else {
header.propertyListStart(ctx.getLocation());
}
}
buffer.setLength(0);
lastChunkIndex = ctx.getLocation();
}
@Override
public void leavingState(ParsingContext ctx) throws CommandFormatException {
final String id = ctx.getState().getId();
//System.out.println("rollout.leaving " + id + " '" + ctx.getCharacter() + "'");
if(id.equals(HeaderValueState.ID)) {
handler.header(header);
} else if(PropertyValueState.ID.equals(id)) {
final String value = buffer.length() == 0 ? null : buffer.toString().trim();
if(value == null || value.isEmpty()) {
throw new CommandFormatException("Property '" + name + "' is missing value at index " + ctx.getLocation());
}
if(group == null) {
if("id".equals(name) || "name".equals(name)) {
header.setPlanRef(lastChunkIndex, value);
} else {
header.addProperty(name, value, lastChunkIndex);
}
} else {
group.addProperty(name, value, lastChunkIndex);
if(!ctx.isEndOfContent()) {
group.propertySeparator(ctx.getLocation());
}
}
} else if(PropertyState.ID.equals(id)) {
if(name == null && buffer.length() > 0) {
if(group != null) {
group.addProperty(buffer.toString().trim(), lastChunkIndex);
if (!ctx.isEndOfContent() && ctx.getCharacter() == ',') {
group.propertySeparator(ctx.getLocation());
}
} else {
header.addProperty(buffer.toString().trim(), lastChunkIndex);
}
buffer.setLength(0);
} else {
name = null;
buffer.setLength(0);
}
} else if(ServerGroupNameState.ID.equals(id)) {
final String groupName = buffer.toString().trim();
if(groupName.isEmpty()) {
throw new CommandFormatException("Empty group name at index " + ctx.getLocation());
}
group.setGroupName(groupName, lastChunkIndex);
} else if(ServerGroupState.ID.equals(id)) {
if(concurrent) {
header.addConcurrentGroup(group);
concurrent = false;
} else {
header.addGroup(group);
}
group = null;
} else if(!ctx.isEndOfContent() && PropertyListState.ID.equals(id)) {
if(group != null) {
group.propertyListEnd(ctx.getLocation());
} else {
header.propertyListEnd(ctx.getLocation());
}
}
}
@Override
public void character(ParsingContext ctx) throws CommandFormatException {
//System.out.println("rollout.content " + ctx.getState().getId() + " '" + ctx.getCharacter() + "'");
buffer.append(ctx.getCharacter());
}
}