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