001package org.kuali.common.util.properties;
002
003import static com.google.common.base.Preconditions.checkArgument;
004import static com.google.common.base.Preconditions.checkNotNull;
005
006import java.nio.charset.Charset;
007
008import org.apache.commons.lang3.StringUtils;
009import org.kuali.common.util.Mode;
010import org.kuali.common.util.property.PropertyFormat;
011
012public final class Location {
013
014        public static final Mode DEFAULT_MISSING_MODE = Mode.ERROR;
015        public static final boolean DEFAULT_CACHEABLE = false;
016        public static final PropertyFormat DEFAULT_PROPERTY_FORMAT = PropertyFormat.NORMAL;
017        public static final String DEFAULT_ENCODING = Charset.defaultCharset().toString();
018
019        private final Mode missingMode;
020        private final String encoding;
021        private final PropertyFormat format;
022        private final String value;
023        private final boolean cacheable;
024
025        public Location(String value) {
026                this(value, DEFAULT_ENCODING, DEFAULT_MISSING_MODE, DEFAULT_PROPERTY_FORMAT);
027        }
028
029        public Location(String value, String encoding) {
030                this(value, encoding, DEFAULT_MISSING_MODE, DEFAULT_PROPERTY_FORMAT);
031        }
032
033        public Location(String value, String encoding, boolean cacheable) {
034                this(value, encoding, DEFAULT_MISSING_MODE, DEFAULT_PROPERTY_FORMAT, cacheable);
035        }
036
037        public Location(String value, String encoding, Mode missingMode, PropertyFormat format) {
038                this(value, encoding, DEFAULT_MISSING_MODE, DEFAULT_PROPERTY_FORMAT, DEFAULT_CACHEABLE);
039        }
040
041        public Location(String value, String encoding, Mode missingMode, PropertyFormat format, boolean cacheable) {
042                this.value = value;
043                this.encoding = encoding;
044                this.missingMode = missingMode;
045                this.format = format;
046                this.cacheable = cacheable;
047                Builder.validate(this);
048        }
049
050        public Mode getMissingMode() {
051                return missingMode;
052        }
053
054        public String getEncoding() {
055                return encoding;
056        }
057
058        public PropertyFormat getFormat() {
059                return format;
060        }
061
062        public String getValue() {
063                return value;
064        }
065
066        public boolean isCacheable() {
067                return cacheable;
068        }
069
070        private Location(Builder builder) {
071                this.missingMode = builder.missingMode;
072                this.encoding = builder.encoding;
073                this.format = builder.format;
074                this.value = builder.value;
075                this.cacheable = builder.cacheable;
076        }
077
078        public static Builder builder(String value) {
079                return new Builder(value);
080        }
081
082        /**
083         * Create a new {@code Location} identical to an existing location but with {@code newValue} for its value
084         */
085        public static Builder builder(Location existing, String newValue) {
086                return new Builder(newValue).cacheable(existing.isCacheable()).encoding(existing.getEncoding()).format(existing.getFormat()).missingMode(existing.getMissingMode());
087        }
088
089        public static class Builder {
090
091                private final String value;
092                private Mode missingMode = DEFAULT_MISSING_MODE;
093                private String encoding = DEFAULT_ENCODING;
094                private PropertyFormat format = DEFAULT_PROPERTY_FORMAT;
095                private boolean cacheable = DEFAULT_CACHEABLE;
096
097                public Builder(String value) {
098                        this.value = value;
099                }
100
101                public Builder missingMode(Mode missingMode) {
102                        this.missingMode = missingMode;
103                        return this;
104                }
105
106                public Builder encoding(String encoding) {
107                        this.encoding = encoding;
108                        return this;
109                }
110
111                public Builder format(PropertyFormat format) {
112                        this.format = format;
113                        return this;
114                }
115
116                public Builder cacheable(boolean cacheable) {
117                        this.cacheable = cacheable;
118                        return this;
119                }
120
121                public Location build() {
122                        Location instance = new Location(this);
123                        validate(instance);
124                        return instance;
125                }
126
127                private static void validate(Location instance) {
128                        checkArgument(!StringUtils.isBlank(instance.value), "value cannot be blank");
129                        checkArgument(!StringUtils.isBlank(instance.encoding), "encoding cannot be blank");
130                        checkNotNull(instance.format, "format cannot be null");
131                        checkNotNull(instance.missingMode, "missingMode cannot be null");
132                }
133
134                public Mode getMissingMode() {
135                        return missingMode;
136                }
137
138                public void setMissingMode(Mode missingMode) {
139                        this.missingMode = missingMode;
140                }
141
142                public String getEncoding() {
143                        return encoding;
144                }
145
146                public void setEncoding(String encoding) {
147                        this.encoding = encoding;
148                }
149
150                public PropertyFormat getFormat() {
151                        return format;
152                }
153
154                public void setFormat(PropertyFormat format) {
155                        this.format = format;
156                }
157
158                public boolean isCacheable() {
159                        return cacheable;
160                }
161
162                public void setCacheable(boolean cacheable) {
163                        this.cacheable = cacheable;
164                }
165
166                public String getValue() {
167                        return value;
168                }
169        }
170
171}