Elements Class — spring-boot Architecture
Architecture documentation for the Elements class in ConfigurationPropertyName.java from the spring-boot codebase.
Entity Profile
Relationship Graph
Source Code
core/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertyName.java lines 796–978
private static class Elements {
private static final int[] NO_POSITION = {};
private static final ElementType[] NO_TYPE = {};
public static final Elements EMPTY = new Elements("", 0, NO_POSITION, NO_POSITION, NO_TYPE, null, null);
private final CharSequence source;
private final int size;
private final int[] start;
private final int[] end;
private final ElementType[] type;
private final int[] hashCode;
/**
* Contains any resolved elements or can be {@code null} if there aren't any.
* Resolved elements allow us to modify the element values in some way (or example
* when adapting with a mapping function, or when append has been called). Note
* that this array is not used as a cache, in fact, when it's not null then
* {@link #canShortcutWithSource} will always return false which may hurt
* performance.
*/
private final @Nullable CharSequence @Nullable [] resolved;
Elements(CharSequence source, int size, int[] start, int[] end, ElementType[] type, int @Nullable [] hashCode,
CharSequence @Nullable [] resolved) {
this.source = source;
this.size = size;
this.start = start;
this.end = end;
this.type = type;
this.hashCode = (hashCode != null) ? hashCode : new int[size];
this.resolved = resolved;
}
Elements append(Elements additional) {
int size = this.size + additional.size;
ElementType[] type = new ElementType[size];
int[] hashCode = new int[size];
System.arraycopy(this.type, 0, type, 0, this.size);
System.arraycopy(additional.type, 0, type, this.size, additional.size);
System.arraycopy(this.hashCode, 0, hashCode, 0, this.size);
System.arraycopy(additional.hashCode, 0, hashCode, this.size, additional.size);
CharSequence[] resolved = newResolved(0, size);
for (int i = 0; i < additional.size; i++) {
resolved[this.size + i] = additional.get(i);
}
return new Elements(this.source, size, this.start, this.end, type, hashCode, resolved);
}
Elements chop(int size) {
CharSequence[] resolved = newResolved(0, size);
return new Elements(this.source, size, this.start, this.end, this.type, this.hashCode, resolved);
}
Elements subElements(int offset) {
int size = this.size - offset;
CharSequence[] resolved = newResolved(offset, size);
int[] start = new int[size];
System.arraycopy(this.start, offset, start, 0, size);
int[] end = new int[size];
System.arraycopy(this.end, offset, end, 0, size);
ElementType[] type = new ElementType[size];
System.arraycopy(this.type, offset, type, 0, size);
int[] hashCode = new int[size];
System.arraycopy(this.hashCode, offset, hashCode, 0, size);
return new Elements(this.source, size, start, end, type, hashCode, resolved);
}
private CharSequence[] newResolved(int offset, int size) {
CharSequence[] resolved = new CharSequence[size];
if (this.resolved != null) {
System.arraycopy(this.resolved, offset, resolved, 0, Math.min(size, this.size));
}
return resolved;
}
int getSize() {
return this.size;
}
CharSequence get(int index) {
if (this.resolved != null) {
CharSequence element = this.resolved[index];
if (element != null) {
return element;
}
}
int start = this.start[index];
int end = this.end[index];
return this.source.subSequence(start, end);
}
int getLength(int index) {
if (this.resolved != null) {
CharSequence element = this.resolved[index];
if (element != null) {
return element.length();
}
}
int start = this.start[index];
int end = this.end[index];
return end - start;
}
char charAt(int index, int charIndex) {
if (this.resolved != null) {
CharSequence element = this.resolved[index];
if (element != null) {
return element.charAt(charIndex);
}
}
int start = this.start[index];
return this.source.charAt(start + charIndex);
}
ElementType getType(int index) {
return this.type[index];
}
int hashCode(int index) {
int hashCode = this.hashCode[index];
if (hashCode == 0) {
boolean indexed = getType(index).isIndexed();
int length = getLength(index);
for (int i = 0; i < length; i++) {
char ch = charAt(index, i);
if (!indexed) {
ch = Character.toLowerCase(ch);
}
if (ElementsParser.isAlphaNumeric(ch)) {
hashCode = 31 * hashCode + ch;
}
}
this.hashCode[index] = hashCode;
}
return hashCode;
}
CharSequence getSource() {
return this.source;
}
/**
* Returns if the element source can be used as a shortcut for an operation such
* as {@code equals} or {@code toString}.
* @param requiredType the required type
* @return {@code true} if all elements match at least one of the types
*/
boolean canShortcutWithSource(ElementType requiredType) {
return canShortcutWithSource(requiredType, requiredType);
}
/**
* Returns if the element source can be used as a shortcut for an operation such
* as {@code equals} or {@code toString}.
* @param requiredType the required type
* @param alternativeType and alternative required type
* @return {@code true} if all elements match at least one of the types
*/
boolean canShortcutWithSource(ElementType requiredType, ElementType alternativeType) {
if (this.resolved != null) {
return false;
}
for (int i = 0; i < this.size; i++) {
ElementType type = this.type[i];
if (type != requiredType && type != alternativeType) {
return false;
}
if (i > 0 && this.end[i - 1] + 1 != this.start[i]) {
return false;
}
}
return true;
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free