/*
* Copyright (c) 2014.
*
* BaasBox - info-at-baasbox.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baasbox.service.query;
import com.baasbox.service.storage.BaasBoxPrivateFields;
import com.google.code.regexp.Matcher;
import com.google.code.regexp.Pattern;
public class PartsLexer {
public Part parse(String part,int position){
return PartFactory.parse(part,position);
}
public static abstract class Part {
String source;
int position;
public abstract String getName();
public Part(String part){
this.source = part;
this.position = 1;
}
public Part(String part,int position){
this.source = part;
this.position = position;
}
protected static String getGroupName(String input,String groupName,Pattern pattern){
Matcher m = pattern.matcher(input);
if(m.matches()){
return m.group(groupName);
}
return null;
}
public abstract String validate() throws PartValidationException;
}
public static class PartValidationException extends RuntimeException {
public PartValidationException(String source,int position,String reason){
super(String.format("Part %s at position %d is not valid:%s",source,position,reason));
}
}
public static class Field extends Part{
static final Pattern p = Pattern.compile("^(?<name>(\\w)+)(\\[(?<arrayIndex>[0-9]+)\\])?$");
public String fieldName;
protected Field(String source,int position){
super(source,position);
this.fieldName = getFieldName();
}
@Override
public String getName() {
return this.fieldName;
}
private String getFieldName(){
return getGroupName(this.source.substring(1), "name",p);
}
@Override
public String validate() throws PartValidationException {
boolean result = this.source.startsWith(".");
String error = null;
if(!result){
error = "Field should starts with a .";
}
if(this.fieldName==null){
error = "Field name is not compliant.It could only contain lowercase/uppercase letters and/or digits";
}else{
for (BaasBoxPrivateFields r : BaasBoxPrivateFields.values()){
if(r.toString().equals(this.fieldName)){
error = "This field is private and can't be modified";
break;
}
}
}
return error;
}
}
public static class ArrayField extends Field{
private int getArrayIndex(){
int result = -1;
String index;
if((index = getGroupName(this.source.substring(1), "arrayIndex", p))!=null){
result = Integer.parseInt(index);
}
return result;
}
public int arrayIndex;
protected ArrayField(String source,int position){
super(source,position);
arrayIndex = getArrayIndex();
}
@Override
public String validate() throws PartValidationException {
String error = super.validate();
if(error==null){
int index = getArrayIndex();
if(index<0){
error = "The index provided for the array should be >= 0";
}
}
return error;
}
}
}