001/*
002 * Copyright 2017 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.batch.item.ldif.builder;
018
019import org.springframework.batch.item.ldif.LdifReader;
020import org.springframework.batch.item.ldif.RecordCallbackHandler;
021import org.springframework.core.io.Resource;
022import org.springframework.util.Assert;
023
024/**
025 * Creates a fully qualified LdifReader.
026 *
027 * @author Glenn Renfro
028 *
029 * @since 4.0
030 */
031public class LdifReaderBuilder  {
032        private Resource resource;
033
034        private int recordsToSkip = 0;
035
036        private boolean strict = true;
037
038        private RecordCallbackHandler skippedRecordsCallback;
039
040        private boolean saveState = true;
041
042        private String name;
043
044        private int maxItemCount = Integer.MAX_VALUE;
045
046        private int currentItemCount;
047
048        /**
049         * Configure if the state of the {@link org.springframework.batch.item.ItemStreamSupport}
050         * should be persisted within the {@link org.springframework.batch.item.ExecutionContext}
051         * for restart purposes.
052         *
053         * @param saveState defaults to true
054         * @return The current instance of the builder.
055         */
056        public LdifReaderBuilder saveState(boolean saveState) {
057                this.saveState = saveState;
058
059                return this;
060        }
061
062        /**
063         * The name used to calculate the key within the
064         * {@link org.springframework.batch.item.ExecutionContext}. Required if
065         * {@link #saveState(boolean)} is set to true.
066         *
067         * @param name name of the reader instance
068         * @return The current instance of the builder.
069         * @see org.springframework.batch.item.ItemStreamSupport#setName(String)
070         */
071        public LdifReaderBuilder name(String name) {
072                this.name = name;
073
074                return this;
075        }
076
077        /**
078         * Configure the max number of items to be read.
079         *
080         * @param maxItemCount the max items to be read
081         * @return The current instance of the builder.
082         * @see org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader#setMaxItemCount(int)
083         */
084        public LdifReaderBuilder maxItemCount(int maxItemCount) {
085                this.maxItemCount = maxItemCount;
086
087                return this;
088        }
089
090        /**
091         * Index for the current item. Used on restarts to indicate where to start from.
092         *
093         * @param currentItemCount current index
094         * @return this instance for method chaining
095         * @see org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader#setCurrentItemCount(int)
096         */
097        public LdifReaderBuilder currentItemCount(int currentItemCount) {
098                this.currentItemCount = currentItemCount;
099
100                return this;
101        }
102
103        /**
104         * In strict mode the reader will throw an exception on
105         * {@link LdifReader#open(org.springframework.batch.item.ExecutionContext)} if the
106         * input resource does not exist.
107         *
108         * @param strict true by default
109         * @return this instance for method chaining.
110         * @see LdifReader#setStrict(boolean)
111         */
112        public LdifReaderBuilder strict(boolean strict) {
113                this.strict = strict;
114
115                return this;
116        }
117
118        /**
119         * {@link RecordCallbackHandler RecordCallbackHandler} implementations can be used to
120         * take action on skipped records.
121         *
122         * @param skippedRecordsCallback will be called for each one of the initial skipped
123         * lines before any items are read.
124         * @return this instance for method chaining.
125         * @see LdifReader#setSkippedRecordsCallback(RecordCallbackHandler)
126         */
127        public LdifReaderBuilder skippedRecordsCallback(RecordCallbackHandler skippedRecordsCallback) {
128                this.skippedRecordsCallback = skippedRecordsCallback;
129
130                return this;
131        }
132
133        /**
134         * Public setter for the number of lines to skip at the start of a file. Can be used
135         * if the file contains a header without useful (column name) information, and without
136         * a comment delimiter at the beginning of the lines.
137         *
138         * @param recordsToSkip the number of lines to skip
139         * @return this instance for method chaining.
140         * @see LdifReader#setRecordsToSkip(int)
141         */
142        public LdifReaderBuilder recordsToSkip(int recordsToSkip) {
143                this.recordsToSkip = recordsToSkip;
144
145                return this;
146        }
147
148        /**
149         * Establishes the resource that will be used as the input for the LdifReader.
150         *
151         * @param resource the resource that will be read.
152         * @return this instance for method chaining.
153         * @see LdifReader#setResource(Resource)
154         */
155        public LdifReaderBuilder resource(Resource resource) {
156                this.resource = resource;
157
158                return this;
159        }
160
161        /**
162         * Returns a fully constructed {@link LdifReader}.
163         *
164         * @return a new {@link org.springframework.batch.item.ldif.LdifReader}
165         */
166        public LdifReader build() {
167                Assert.notNull(this.resource, "Resource is required.");
168                if (this.saveState) {
169                        Assert.hasText(this.name, "A name is required when saveState is set to true");
170                }
171                LdifReader reader = new LdifReader();
172                reader.setResource(this.resource);
173                reader.setRecordsToSkip(this.recordsToSkip);
174                reader.setSaveState(this.saveState);
175                reader.setName(this.name);
176                reader.setCurrentItemCount(this.currentItemCount);
177                reader.setMaxItemCount(this.maxItemCount);
178                if (this.skippedRecordsCallback != null) {
179                        reader.setSkippedRecordsCallback(this.skippedRecordsCallback);
180                }
181                reader.setStrict(this.strict);
182
183                return reader;
184        }
185
186}