001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.core.style;
018
019import org.springframework.lang.Nullable;
020import org.springframework.util.Assert;
021
022/**
023 * Utility class that builds pretty-printing {@code toString()} methods
024 * with pluggable styling conventions. By default, ToStringCreator adheres
025 * to Spring's {@code toString()} styling conventions.
026 *
027 * @author Keith Donald
028 * @author Juergen Hoeller
029 * @since 1.2.2
030 */
031public class ToStringCreator {
032
033        /**
034         * Default ToStringStyler instance used by this ToStringCreator.
035         */
036        private static final ToStringStyler DEFAULT_TO_STRING_STYLER =
037                        new DefaultToStringStyler(StylerUtils.DEFAULT_VALUE_STYLER);
038
039
040        private final StringBuilder buffer = new StringBuilder(256);
041
042        private final ToStringStyler styler;
043
044        private final Object object;
045
046        private boolean styledFirstField;
047
048
049        /**
050         * Create a ToStringCreator for the given object.
051         * @param obj the object to be stringified
052         */
053        public ToStringCreator(Object obj) {
054                this(obj, (ToStringStyler) null);
055        }
056
057        /**
058         * Create a ToStringCreator for the given object, using the provided style.
059         * @param obj the object to be stringified
060         * @param styler the ValueStyler encapsulating pretty-print instructions
061         */
062        public ToStringCreator(Object obj, @Nullable ValueStyler styler) {
063                this(obj, new DefaultToStringStyler(styler != null ? styler : StylerUtils.DEFAULT_VALUE_STYLER));
064        }
065
066        /**
067         * Create a ToStringCreator for the given object, using the provided style.
068         * @param obj the object to be stringified
069         * @param styler the ToStringStyler encapsulating pretty-print instructions
070         */
071        public ToStringCreator(Object obj, @Nullable ToStringStyler styler) {
072                Assert.notNull(obj, "The object to be styled must not be null");
073                this.object = obj;
074                this.styler = (styler != null ? styler : DEFAULT_TO_STRING_STYLER);
075                this.styler.styleStart(this.buffer, this.object);
076        }
077
078
079        /**
080         * Append a byte field value.
081         * @param fieldName the name of the field, usually the member variable name
082         * @param value the field value
083         * @return this, to support call-chaining
084         */
085        public ToStringCreator append(String fieldName, byte value) {
086                return append(fieldName, Byte.valueOf(value));
087        }
088
089        /**
090         * Append a short field value.
091         * @param fieldName the name of the field, usually the member variable name
092         * @param value the field value
093         * @return this, to support call-chaining
094         */
095        public ToStringCreator append(String fieldName, short value) {
096                return append(fieldName, Short.valueOf(value));
097        }
098
099        /**
100         * Append a integer field value.
101         * @param fieldName the name of the field, usually the member variable name
102         * @param value the field value
103         * @return this, to support call-chaining
104         */
105        public ToStringCreator append(String fieldName, int value) {
106                return append(fieldName, Integer.valueOf(value));
107        }
108
109        /**
110         * Append a long field value.
111         * @param fieldName the name of the field, usually the member variable name
112         * @param value the field value
113         * @return this, to support call-chaining
114         */
115        public ToStringCreator append(String fieldName, long value) {
116                return append(fieldName, Long.valueOf(value));
117        }
118
119        /**
120         * Append a float field value.
121         * @param fieldName the name of the field, usually the member variable name
122         * @param value the field value
123         * @return this, to support call-chaining
124         */
125        public ToStringCreator append(String fieldName, float value) {
126                return append(fieldName, Float.valueOf(value));
127        }
128
129        /**
130         * Append a double field value.
131         * @param fieldName the name of the field, usually the member variable name
132         * @param value the field value
133         * @return this, to support call-chaining
134         */
135        public ToStringCreator append(String fieldName, double value) {
136                return append(fieldName, Double.valueOf(value));
137        }
138
139        /**
140         * Append a boolean field value.
141         * @param fieldName the name of the field, usually the member variable name
142         * @param value the field value
143         * @return this, to support call-chaining
144         */
145        public ToStringCreator append(String fieldName, boolean value) {
146                return append(fieldName, Boolean.valueOf(value));
147        }
148
149        /**
150         * Append a field value.
151         * @param fieldName the name of the field, usually the member variable name
152         * @param value the field value
153         * @return this, to support call-chaining
154         */
155        public ToStringCreator append(String fieldName, @Nullable Object value) {
156                printFieldSeparatorIfNecessary();
157                this.styler.styleField(this.buffer, fieldName, value);
158                return this;
159        }
160
161        private void printFieldSeparatorIfNecessary() {
162                if (this.styledFirstField) {
163                        this.styler.styleFieldSeparator(this.buffer);
164                }
165                else {
166                        this.styledFirstField = true;
167                }
168        }
169
170        /**
171         * Append the provided value.
172         * @param value the value to append
173         * @return this, to support call-chaining.
174         */
175        public ToStringCreator append(Object value) {
176                this.styler.styleValue(this.buffer, value);
177                return this;
178        }
179
180
181        /**
182         * Return the String representation that this ToStringCreator built.
183         */
184        @Override
185        public String toString() {
186                this.styler.styleEnd(this.buffer, this.object);
187                return this.buffer.toString();
188        }
189
190}