Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2014 - 2018 by haui - all rights reserved
*/
package com.github.uscexp.dotnotation;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.parboiled.Parboiled;
import com.github.uscexp.dotnotation.exception.AttributeAccessExeption;
import com.github.uscexp.dotnotation.parser.attributedetail.AttributeDetailInterpreterResult;
import com.github.uscexp.dotnotation.parser.attributedetail.AttributeDetailParser;
import com.github.uscexp.dotnotation.parser.attributepath.AttributePathInterpreterResult;
import com.github.uscexp.dotnotation.parser.attributepath.AttributePathParser;
import com.github.uscexp.parboiled.extension.exception.AstInterpreterException;
import com.github.uscexp.parboiled.extension.interpreter.AstInterpreter;
import com.github.uscexp.parboiled.extension.interpreter.ProcessStore;
import com.github.uscexp.parboiled.extension.nodes.AstTreeNode;
import com.github.uscexp.parboiled.extension.parser.Parser;
//@formatter:off
/**
* With this class one can access values of attributes via a defined path from a
* root element.
*
* To access an attrubute value use the dot notation:
*
*
level1.level2.text
*
accesses attrbute level1 in root class, than accesses attribute level2 in
* level1 class and than accesses attrbute text in level2 class.
*
levels1.text
*
accesses all text attributes in collection or array levels1 (returns an
* array).
*
levels1[0].text
*
accesses attribute text in first (index 0) collection or array element of
* levels1
*
level1.texts[0]
*
accessses first (index 0) element of collection or array attribute texts
*
*
* Attention!
*
* Accessing collections e.g. HashSets via index doesn't make alway sense,
* because the order of the set isn't fix. So if you set a value at index 0 and
* later you want to access it, it is very probable that you won't find it at
* index 0 anymore.
*
* @author haui
*
*/
public class DotNotationAccessor {
//@formatter:on
private boolean resolveAttributesViaAccessorsOnly = true;
private boolean accessPrivateAttributes = false;
private boolean throwExceptionOnNullValueInAttributePath = true;
/**
* Creates an {@link DotNotationAccessor} instance with default
* configuration:
* only resolves attributes via getters and setters, does not access private
* attributes and throws exeptions on null values in attribute path.
*/
public DotNotationAccessor() {
this(false, true, true);
}
/**
* Creates an {@link DotNotationAccessor} instance with given configuration.
*
* @param resolveAttributesViaAccessorsOnly
* if true, attributes will only be resolved via accessors
* (gertters/setters), else attributes will also be accessed via
* reflection.
* @param accessPrivateAttributes
* if true, private attributes can be accessed, too.
* @param throwExceptionOnNullValueInAttributePath
* if true, exceptions will be thrown if there are null values
* within the attribute path.
*/
public DotNotationAccessor(boolean resolveAttributesViaAccessorsOnly, boolean accessPrivateAttributes,
boolean throwExceptionOnNullValueInAttributePath) {
super();
this.resolveAttributesViaAccessorsOnly = resolveAttributesViaAccessorsOnly;
this.accessPrivateAttributes = accessPrivateAttributes;
this.throwExceptionOnNullValueInAttributePath = throwExceptionOnNullValueInAttributePath;
}
/**
* get the value/values of an attibute, defined via dot notation.
*
* @param rootElement
* root class instance to start the attribute path resolvation.
* @param attributePath
* the attribute path (dot notation).
* @return the value/values of the final attribute in attribute path.
* @throws AttributeAccessExeption
* on error
*/
public Object getAttribute(Object rootElement, String attributePath)
throws AttributeAccessExeption {
Object result = accessAttribute(rootElement, attributePath, null, AccessorType.GETTER);
return result;
}
/**
* set the value of an attibute, defined via dot notation.
*
* @param rootElement
* root class instance to start the attribute path resolvation.
* @param attributePath
* the attribute path (dot notation).
* @param value
* to set in the final attribute/attributes.
* @throws AttributeAccessExeption
* on error
*/
public void setAttribute(Object rootElement, String attributePath, Object value)
throws AttributeAccessExeption {
accessAttribute(rootElement, attributePath, value, AccessorType.SETTER);
}
protected Object accessAttribute(Object rootElement, String attributePath, Object value, AccessorType accessorType)
throws AttributeAccessExeption {
Object result = null;
AttributeDetail[] attributes = null;
int i = 0;
try {
AttributePathInterpreterResult attributePathInterpreterResult = runInterpreter(attributePath);
attributes = new AttributeDetail[attributePathInterpreterResult.getAttributeDetailInterpreterResults().size()];
for (AttributeDetailInterpreterResult attributeDetailInterpreterResult : attributePathInterpreterResult.getAttributeDetailInterpreterResults()) {
attributes[i++] = new AttributeDetail(attributeDetailInterpreterResult);
}
result = accessAttribute(rootElement, attributes, 0, value, accessorType);
} catch (AstInterpreterException | ReflectiveOperationException | IllegalArgumentException | IntrospectionException e) {
throw new AttributeAccessExeption(String.format("Error accessing attribute %s", attributes[i - 1]), e);
}
return result;
}
public static AttributePathInterpreterResult runInterpreter(String attributePath)
throws AttributeAccessExeption, AstInterpreterException {
AttributePathParser attributePathParser = Parboiled.createParser(AttributePathParser.class);
AstTreeNode rootNode = Parser.parseInput(AttributePathParser.class, attributePathParser.attributePath(), attributePath, true);
AstInterpreter attributePathInterpreter = new AstInterpreter<>();
Long id = new Date().getTime() + UUID.randomUUID().hashCode();
ProcessStore processStore = prepareProcessStore(id);
attributePathInterpreter.interpretBackwardOrder(AttributePathParser.class, rootNode, id);
AttributePathInterpreterResult attributePathInterpreterResult = (AttributePathInterpreterResult) processStore.getVariable(AttributePathParser.ATTRIBUTE_PATH_INTERPRETER_RESULT);
attributePathInterpreter.cleanUp(id);
return attributePathInterpreterResult;
}
private static ProcessStore prepareProcessStore(Long id) {
ProcessStore processStore = ProcessStore.getInstance(id);
// set the result object
processStore.setNewVariable(AttributePathParser.ATTRIBUTE_PATH_INTERPRETER_RESULT, new AttributePathInterpreterResult());
processStore.setNewVariable(AttributeDetailParser.ATTRIBUTE_DETAIL_INTERPRETER_RESULT, new AttributeDetailInterpreterResult());
return processStore;
}
protected Object accessAttribute(Object element, AttributeDetail[] attributes, int attributeIndex, Object value,
AccessorType accessorType)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException, InstantiationException {
Object result = null;
ArrayType arrayType = getArrayType(element);
if (!arrayType.isArrayType()) {
result = accessNonArrayTypeAttribute(element, attributes, attributeIndex, value, accessorType);
} else {
result = accessArrayTypeAttribute(element, attributes, attributeIndex, value, accessorType, arrayType);
}
return result;
}
private Object accessArrayTypeAttribute(Object element, AttributeDetail[] attributes, int attributeIndex, Object value,
AccessorType accessorType, ArrayType arrayType)
throws IllegalAccessException, InvocationTargetException, IntrospectionException, IllegalArgumentException, InstantiationException {
Object result = null;
Object[] array = arrayType.getArray(element);
List