net.sf.jabb.util.stat.AggregationPeriodHierarchy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jabb-core-java8 Show documentation
Show all versions of jabb-core-java8 Show documentation
Additions to jabb-core that require Java 8
The newest version!
/**
*
*/
package net.sf.jabb.util.stat;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collectors;
/**
* The forest structure of AggregationPeriod nodes.
* Each node can have an attachment object.
* @author James Hu
*
* @param type of attachments
*/
public class AggregationPeriodHierarchy implements Serializable{
private static final long serialVersionUID = 8664232464718744888L;
protected Map> codeMapping = new HashMap<>();
protected SortedMap> roots = new TreeMap<>();
static class AggregationPeriodNode implements Serializable{
private static final long serialVersionUID = 4925692035577355240L;
AggregationPeriodAndAttachment aggregationPeriodAndAttachment;
AggregationPeriodNode lowerLevelNode;
Set> upperLevelNodes;
SortedMap> upperLevels;
AggregationPeriodNode(AggregationPeriodAndAttachment aggregationPeriodAndAttachment){
this.aggregationPeriodAndAttachment = aggregationPeriodAndAttachment;
}
AggregationPeriodNode(AggregationPeriod aggregationPeriod, NT attachment){
this.aggregationPeriodAndAttachment = new AggregationPeriodAndAttachment(aggregationPeriod, attachment);
}
void addUpperLevel(AggregationPeriodNode upperLevel){
if (upperLevelNodes == null){
upperLevelNodes = new HashSet<>();
upperLevels = new TreeMap<>();
}
upperLevelNodes.add(upperLevel);
upperLevels.put(upperLevel.aggregationPeriodAndAttachment.getAggregationPeriod(), upperLevel.aggregationPeriodAndAttachment);
upperLevel.lowerLevelNode = this;
}
}
/**
* Add a root which represents the lowest level aggregation period in the aggregation hierarchy
* @param aggregationPeriod the root - lowest level in the aggregation hierarchy
* @return true if successfully added, false if such a root already exists
*/
public boolean add(AggregationPeriod aggregationPeriod){
return add(aggregationPeriod, (T)null);
}
/**
* Add a root which represents the lowest level aggregation period in the aggregation hierarchy
* @param aggregationPeriod the root - lowest level in the aggregation hierarchy
* @param attachment the attachment object
* @return true if successfully added, false if such a root already exists
*/
public boolean add(AggregationPeriod aggregationPeriod, T attachment){
AggregationPeriodNode root = new AggregationPeriodNode(aggregationPeriod, attachment);
String code = root.aggregationPeriodAndAttachment.getAggregationPeriod().getCodeName();
if (codeMapping.putIfAbsent(code, root) == null){
roots.put(aggregationPeriod, new AggregationPeriodAndAttachment(aggregationPeriod, attachment));
return true;
}else{
return false;
}
}
/**
* Add a root which represents the lowest level aggregation period in the aggregation hierarchy
* @param codeName code name of the root - lowest level in the aggregation hierarchy
* @return true if successfully added, false if such a root already exists
*/
public boolean add(String codeName){
return add(codeName, (T)null);
}
/**
* Add a root which represents the lowest level aggregation period in the aggregation hierarchy
* @param codeName code name of the root - lowest level in the aggregation hierarchy
* @param attachment the attachment object
* @return true if successfully added, false if such a root already exists
*/
public boolean add(String codeName, T attachment){
return add(AggregationPeriod.parse(codeName), attachment);
}
/**
* Add a root which represents the lowest level aggregation period in the aggregation hierarchy
* @param amount amount of the aggregation period
* @param unit unit of the aggregation period
* @return true if successfully added, false if such a root already exists
*/
public boolean add(int amount, AggregationPeriodUnit unit){
return add(amount, unit, (T)null);
}
/**
* Add a root which represents the lowest level aggregation period in the aggregation hierarchy
* @param amount amount of the aggregation period
* @param unit unit of the aggregation period
* @param attachment the attachment object
* @return true if successfully added, false if such a root already exists
*/
public boolean add(int amount, AggregationPeriodUnit unit, T attachment){
return add(new AggregationPeriod(amount, unit), attachment);
}
/**
* Add a non-root aggregation period
* @param base the lower level aggregation period that the upper level one one is based on.
* It must already exist in the hierarchy
* @param upperLevel the aggregation period that will be added
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(AggregationPeriod base, AggregationPeriod upperLevel){
return add(base, upperLevel, (T)null);
}
/**
* Add a non-root aggregation period
* @param base the lower level aggregation period that the upper level one one is based on.
* It must already exist in the hierarchy
* @param upperLevel the aggregation period that will be added
* @param attachment the attachment object
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(AggregationPeriod base, AggregationPeriod upperLevel, T attachment){
return add(base.getCodeName(), upperLevel, attachment);
}
/**
* Add a non-root aggregation period
* @param baseCodeName the code name of the lower level aggregation period that the upper level one one is based on.
* It must already exist in the hierarchy
* @param upperLevel the aggregation period that will be added
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(String baseCodeName, AggregationPeriod upperLevel){
return add(baseCodeName, upperLevel, (T)null);
}
/**
* Add a non-root aggregation period
* @param baseCodeName the code name of the lower level aggregation period that the upper level one one is based on.
* It must already exist in the hierarchy
* @param upperLevel the aggregation period that will be added
* @param attachment the attachment object
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(String baseCodeName, AggregationPeriod upperLevel, T attachment){
AggregationPeriodNode parent = codeMapping.get(baseCodeName);
if (parent == null){
return false;
}
if (!parent.aggregationPeriodAndAttachment.aggregationPeriod.canBeAggregatedTo(upperLevel)){
throw new IllegalArgumentException("Aggregation period [" + parent.aggregationPeriodAndAttachment.aggregationPeriod + "] cannot be aggregated to ["
+ upperLevel + "]");
}
AggregationPeriodNode child = new AggregationPeriodNode(upperLevel, attachment);
String code = upperLevel.getCodeName();
if (codeMapping.putIfAbsent(code, child) == null){
parent.addUpperLevel(child);
return true;
}else{
return false;
}
}
/**
* Add a non-root aggregation period
* @param baseCodeName the code name of the lower level aggregation period that the upper level one one is based on.
* It must already exist in the hierarchy
* @param amount amount of the aggregation period
* @param unit unit of the aggregation period
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(String baseCodeName, int amount, AggregationPeriodUnit unit){
return add(baseCodeName, amount, unit, (T)null);
}
/**
* Add a non-root aggregation period
* @param baseCodeName the code name of the lower level aggregation period that the upper level one one is based on.
* It must already exist in the hierarchy
* @param amount amount of the aggregation period
* @param unit unit of the aggregation period
* @param attachment the attachment object
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(String baseCodeName, int amount, AggregationPeriodUnit unit, T attachment){
return add(baseCodeName, new AggregationPeriod(amount, unit), attachment);
}
/**
* Add a non-root aggregation period
* @param baseCodeName the code name of the lower level aggregation period that the upper level one one is based on.
* It must already exist in the hierarchy
* @param codeName code name of the aggregation period that will be added
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(String baseCodeName, String codeName){
return add(baseCodeName, codeName, (T)null);
}
/**
* Add a non-root aggregation period
* @param baseCodeName the code name of the lower level aggregation period that the upper level one one is based on.
* It must already exist in the hierarchy
* @param codeName code name of the aggregation period that will be added
* @param attachment the attachment object
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(String baseCodeName, String codeName, T attachment){
return add(baseCodeName, AggregationPeriod.parse(codeName), attachment);
}
/**
* Add a non-root aggregation period
* @param baseAmount amount of the lower level aggregation period that the upper level one one is based on.
* @param baseUnit unit of the lower level aggregation period that the upper level one one is based on.
* @param amount amount of the aggregation period that will be added
* @param unit unit of the aggregation period that will be added
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(int baseAmount, AggregationPeriodUnit baseUnit, int amount, AggregationPeriodUnit unit){
return add(baseAmount, baseUnit, amount, unit, (T)null);
}
/**
* Add a non-root aggregation period
* @param baseAmount amount of the lower level aggregation period that the upper level one one is based on.
* @param baseUnit unit of the lower level aggregation period that the upper level one one is based on.
* @param amount amount of the aggregation period that will be added
* @param unit unit of the aggregation period that will be added
* @param attachment the attachment object
* @return true if successfully added, false if the upper level aggregation period already exists or if the base does not exist
* @throws IllegalArgumentException if the base aggregation period cannot be aggregated to the upper level aggregation period
*/
public boolean add(int baseAmount, AggregationPeriodUnit baseUnit, int amount, AggregationPeriodUnit unit, T attachment){
return add(AggregationPeriod.getCodeName(baseAmount, baseUnit), new AggregationPeriod(amount, unit), attachment);
}
/**
* Get all roots - aggregation periods that are of the lowest level.
* The result is sorted.
* @return the roots
*/
public Set getRoots(){
return roots.keySet();
}
/**
* Get all roots with attachments - aggregation periods that are of the lowest level.
* The result is sorted.
* @return the roots
*/
public Collection> getRootsWithAttachments(){
return roots.values();
}
/**
* Get all aggregation periods across all levels.
* The result is not sorted.
* @return all aggregation periods
*/
public Set getAll(){
return codeMapping.values().stream()
.map(node->node.aggregationPeriodAndAttachment.getAggregationPeriod())
.collect(Collectors.toSet());
}
/**
* Get all aggregation periods with attachments across all levels.
* The result is not sorted.
* @return all aggregation periods with attachments
*/
public Collection> getAllWithAttachments(){
return codeMapping.values().stream()
.map(node->node.aggregationPeriodAndAttachment)
.collect(Collectors.toSet());
}
/**
* Get the number of aggregation periods contained in the hierarchy
* @return number of aggregation periods
*/
public int size(){
return codeMapping.size();
}
/**
* Get the aggregation period in the hierarchy with the specified code name
* @param code the code name
* @return the matching AggregationPeriod found in the hierarchy, or null if not found
*/
public AggregationPeriod get(String code){
AggregationPeriodNode node = codeMapping.get(code);
return node == null ? null : node.aggregationPeriodAndAttachment.getAggregationPeriod();
}
/**
* Get the aggregation period in the hierarchy with the specified code name, with attachment
* @param code the code name
* @return the matching AggregationPeriod found in the hierarchy including attachment, or null if not found
*/
public AggregationPeriodAndAttachment getWithAttachment(String code){
AggregationPeriodNode node = codeMapping.get(code);
return node == null ? null : node.aggregationPeriodAndAttachment;
}
/**
* Get the lower level aggregation period of an aggregation period in the hierarchy
* @param code the code name of the aggregation period for which the lower level aggregation period needs to be returned
* @return the lower level aggregation period, or null if there is no aggregation period matching the code name or if the one matching the code name is a root
*/
public AggregationPeriod getLowerLevelAggregationPeriod(String code){
AggregationPeriodNode node = codeMapping.get(code);
return node == null ? null :
(node.lowerLevelNode == null ? null : node.lowerLevelNode.aggregationPeriodAndAttachment.getAggregationPeriod());
}
/**
* Get the lower level aggregation period of an aggregation period in the hierarchy, with attachment
* @param code the code name of the aggregation period for which the lower level aggregation period needs to be returned
* @return the lower level aggregation period, or null if there is no aggregation period matching the code name or if the one matching the code name is a root
*/
public AggregationPeriodAndAttachment getLowerLevelAggregationPeriodWithAttachment(String code){
AggregationPeriodNode node = codeMapping.get(code);
return node == null ? null :
(node.lowerLevelNode == null ? null : node.lowerLevelNode.aggregationPeriodAndAttachment);
}
/**
* Get the upper level aggregation periods of an aggregation period in the hierarchy
* @param code the code name of the aggregation period for which the upper level aggregation periods need to be returned
* @return the upper level aggregation periods, it will not be null but may be empty.
*/
public Set getUpperLevelAggregationPeriods(String code){
AggregationPeriodNode node = codeMapping.get(code);
Set result = node == null ? null :
(node.upperLevels == null ? null : node.upperLevels.keySet());
return result == null ? Collections.emptySortedSet() : result;
}
/**
* Get the upper level aggregation periods of an aggregation period in the hierarchy, with attachments
* @param code the code name of the aggregation period for which the upper level aggregation periods need to be returned
* @return the sorted upper level aggregation periods with attachments, it will not be null but may be empty.
*/
public Collection> getUpperLevelAggregationPeriodsWithAttachments(String code){
AggregationPeriodNode node = codeMapping.get(code);
Collection> result = node == null ? null :
(node.upperLevels == null ? null : node.upperLevels.values());
return result == null ? Collections.emptySortedSet() : result;
}
/**
* Get the lower level aggregation period of an aggregation period in the hierarchy
* @param aggregationPeriod the aggregation period for which the lower level aggregation period needs to be returned
* @return the lower level aggregation period, or null if the specified aggregation period is a root
*/
public AggregationPeriod getLowerLevelAggregationPeriod(AggregationPeriod aggregationPeriod){
return getLowerLevelAggregationPeriod(aggregationPeriod.getCodeName());
}
/**
* Get the lower level aggregation period of an aggregation period in the hierarchy, with attachments
* @param aggregationPeriod the aggregation period for which the lower level aggregation period needs to be returned
* @return the lower level aggregation period with attachment, or null if the specified aggregation period is a root
*/
public AggregationPeriodAndAttachment getLowerLevelAggregationPeriodWithAttachment(AggregationPeriod aggregationPeriod){
return getLowerLevelAggregationPeriodWithAttachment(aggregationPeriod.getCodeName());
}
/**
* Get the upper level aggregation periods of an aggregation period in the hierarchy
* @param aggregationPeriod the aggregation period for which the upper level aggregation periods need to be returned
* @return the upper level aggregation periods, it will not be null but may be empty.
*/
public Set getUpperLevelAggregationPeriods(AggregationPeriod aggregationPeriod){
return getUpperLevelAggregationPeriods(aggregationPeriod.getCodeName());
}
/**
* Get the upper level aggregation periods of an aggregation period in the hierarchy, with attachments
* @param aggregationPeriod the aggregation period for which the upper level aggregation periods need to be returned
* @return the sorted upper level aggregation periods with attachments, it will not be null but may be empty.
*/
public Collection> getUpperLevelAggregationPeriodsWithAttachments(AggregationPeriod aggregationPeriod){
return getUpperLevelAggregationPeriodsWithAttachments(aggregationPeriod.getCodeName());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy