001/**
002 * Copyright 2010-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community 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 * http://www.opensource.org/licenses/ecl2.php
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 */
016package org.kuali.common.util.property.processor;
017
018import java.util.Collections;
019import java.util.List;
020import java.util.Properties;
021
022import org.kuali.common.util.Mode;
023import org.kuali.common.util.PropertyUtils;
024import org.kuali.common.util.property.ImmutableProperties;
025
026import com.google.common.base.Preconditions;
027import com.google.common.collect.ImmutableList;
028
029public final class OverridingProcessor implements PropertyProcessor {
030
031        public static final int DEFAULT_INDENT = 2;
032        public static final Mode DEFAULT_OVERRIDE_MODE = Mode.INFORM;
033        public static final List<String> DEFAULT_INCLUDES = Collections.<String> emptyList();
034        public static final List<String> DEFAULT_EXCLUDES = Collections.<String> emptyList();
035
036        private final Mode overrideMode;
037        private final Properties overrides;
038        private final List<String> includes;
039        private final List<String> excludes;
040        private final int indent;
041
042        public OverridingProcessor(Properties overrides) {
043                this(overrides, DEFAULT_OVERRIDE_MODE, DEFAULT_INCLUDES, DEFAULT_EXCLUDES, DEFAULT_INDENT);
044        }
045
046        public OverridingProcessor(Properties overrides, List<String> includes) {
047                this(overrides, DEFAULT_OVERRIDE_MODE, includes, DEFAULT_EXCLUDES, DEFAULT_INDENT);
048        }
049
050        public OverridingProcessor(Properties overrides, List<String> includes, List<String> excludes) {
051                this(overrides, DEFAULT_OVERRIDE_MODE, includes, excludes, DEFAULT_INDENT);
052        }
053
054        public OverridingProcessor(Properties overrides, Mode overrideMode, List<String> includes, List<String> excludes, int indent) {
055                this.overrides = PropertyUtils.toImmutable(overrides);
056                this.overrideMode = overrideMode;
057                this.includes = ImmutableList.copyOf(includes);
058                this.excludes = ImmutableList.copyOf(excludes);
059                this.indent = indent;
060                Builder.validate(this);
061        }
062
063        @Override
064        public void process(Properties properties) {
065                List<String> keys = PropertyUtils.getSortedKeys(overrides, includes, excludes);
066                for (String key : keys) {
067                        String newValue = overrides.getProperty(key);
068                        PropertyUtils.addOrOverrideProperty(properties, key, newValue, overrideMode, indent);
069                }
070        }
071
072        public Mode getOverrideMode() {
073                return overrideMode;
074        }
075
076        public Properties getOverrides() {
077                return overrides;
078        }
079
080        public List<String> getIncludes() {
081                return includes;
082        }
083
084        public List<String> getExcludes() {
085                return excludes;
086        }
087
088        public int getIndent() {
089                return indent;
090        }
091
092        private OverridingProcessor(Builder builder) {
093                this.overrideMode = builder.overrideMode;
094                this.overrides = builder.overrides;
095                this.includes = builder.includes;
096                this.excludes = builder.excludes;
097                this.indent = builder.indent;
098        }
099
100        public static Builder builder(Properties overrides) {
101                return new Builder(overrides);
102        }
103
104        public static class Builder {
105
106                private final Properties overrides;
107                private Mode overrideMode = DEFAULT_OVERRIDE_MODE;
108                private List<String> includes = ImmutableList.of();
109                private List<String> excludes = ImmutableList.of();
110                private int indent = DEFAULT_INDENT;
111
112                public Builder(Properties overrides) {
113                        this.overrides = ImmutableProperties.copyOf(overrides);
114                }
115
116                public Builder overrideMode(Mode overrideMode) {
117                        this.overrideMode = overrideMode;
118                        return this;
119                }
120
121                public Builder includes(List<String> includes) {
122                        this.includes = includes;
123                        return this;
124                }
125
126                public Builder excludes(List<String> excludes) {
127                        this.excludes = excludes;
128                        return this;
129                }
130
131                public Builder indent(int indent) {
132                        this.indent = indent;
133                        return this;
134                }
135
136                public OverridingProcessor build() {
137                        OverridingProcessor instance = new OverridingProcessor(this);
138                        validate(instance);
139                        return instance;
140                }
141
142                private static void validate(OverridingProcessor instance) {
143                        Preconditions.checkNotNull(instance.overrides, "overrides cannot be null");
144                        Preconditions.checkArgument(instance.indent >= 0, "indent cannot be negative");
145                        Preconditions.checkNotNull(instance.includes, "includes cannot be null");
146                        Preconditions.checkNotNull(instance.excludes, "excludes cannot be null");
147                        Preconditions.checkNotNull(instance.overrideMode, "overrideMode cannot be null");
148                }
149        }
150}