001/* 002 * Copyright (c) 2023-2026, Agents-Flex (fuhai999@gmail.com). 003 * <p> 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 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 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 com.agentsflex.core.document.splitter; 017 018import com.agentsflex.core.document.Document; 019import com.agentsflex.core.document.DocumentSplitter; 020import com.agentsflex.core.document.id.DocumentIdGenerator; 021import com.agentsflex.core.util.StringUtil; 022 023import java.util.ArrayList; 024import java.util.Collections; 025import java.util.List; 026 027public class SimpleDocumentSplitter implements DocumentSplitter { 028 private int chunkSize; 029 private int overlapSize; 030 031 public SimpleDocumentSplitter(int chunkSize) { 032 this.chunkSize = chunkSize; 033 if (this.chunkSize <= 0) { 034 throw new IllegalArgumentException("chunkSize must be greater than 0, chunkSize: " + this.chunkSize); 035 } 036 } 037 038 public SimpleDocumentSplitter(int chunkSize, int overlapSize) { 039 this.chunkSize = chunkSize; 040 this.overlapSize = overlapSize; 041 042 if (this.chunkSize <= 0) { 043 throw new IllegalArgumentException("chunkSize must be greater than 0, chunkSize: " + this.chunkSize); 044 } 045 if (this.overlapSize >= this.chunkSize) { 046 throw new IllegalArgumentException("overlapSize must be less than chunkSize, overlapSize: " + this.overlapSize + ", chunkSize: " + this.chunkSize); 047 } 048 } 049 050 public int getChunkSize() { 051 return chunkSize; 052 } 053 054 public void setChunkSize(int chunkSize) { 055 this.chunkSize = chunkSize; 056 } 057 058 public int getOverlapSize() { 059 return overlapSize; 060 } 061 062 public void setOverlapSize(int overlapSize) { 063 this.overlapSize = overlapSize; 064 } 065 066 @Override 067 public List<Document> split(Document document, DocumentIdGenerator idGenerator) { 068 if (document == null || StringUtil.noText(document.getContent())) { 069 return Collections.emptyList(); 070 } 071 072 String content = document.getContent(); 073 int index = 0, currentIndex = index; 074 int maxIndex = content.length(); 075 076 List<Document> chunks = new ArrayList<>(); 077 while (currentIndex < maxIndex) { 078 int endIndex = Math.min(currentIndex + chunkSize, maxIndex); 079 String chunk = content.substring(currentIndex, endIndex).trim(); 080 currentIndex = currentIndex + chunkSize - overlapSize; 081 082 if (chunk.isEmpty()) { 083 continue; 084 } 085 086 Document newDocument = new Document(); 087 newDocument.addMetadata(document.getMetadataMap()); 088 newDocument.setContent(chunk); 089 090 //we should invoke setId after setContent 091 newDocument.setId(idGenerator == null ? null : idGenerator.generateId(newDocument)); 092 chunks.add(newDocument); 093 } 094 095 return chunks; 096 } 097}