그동안 이거저거하냐고 정리를 못했다
생각하다 보니 가장 좋은 방법은 Filter 구조를 취하는것 같았다.
private final List<NotionFilter> filterList = new ArrayList<>();
public NotionBlockConverter() {
filterList.add(new ParagraphFilter());
filterList.add(new HeadingOneFilter());
filterList.add(new HeadingTwoFilter());
filterList.add(new HeadingThreeFilter());
filterList.add(new BulletedListItemFilter());
filterList.add(new NumberedListItemFilter());
filterList.add(new QuoteFilter());
filterList.add(new TableFilter());
filterList.add(new ToDoFilter());
filterList.add(new ToggleBlockFilter());
filterList.add(new BookmarkFilter());
filterList.add(new CodeBlockFilter());
filterList.add(new DivideFilter());
filterList.add(new CallOutBlockFilter());
filterList.add(new ChildPageFilter());
filterList.add(new ImageFilter());
filterList.add(new FileFilter());
filterList.add(new LinkPreviewFilter());
filterList.add(new PdfFilter());
filterList.add(new SyncedBlockFilter());
}
이렇게 블록들을 등록했다.
필터는
public interface NotionFilter {
boolean isAcceptable(Block block);
String doFilter(Block block, NotionClient client);
}
두가지 매서드를 기본적으로 가지고 있고
isAcceptable에서 해결 가능한지 확인하고 Filter 처리를 하였다.
또한 무조건 child를 조회해야 하는 경우에는
@Override
public String doFilter(Block block, NotionClient client) {
int tableWidth = block.asTable().getTable().getTableWidth();
String id = block.getId();
return internalFunction(id, tableWidth, client) + "\n";
}
private String internalFunction(String id, int width, NotionClient notionClient) {
List<Block> results = reRequestTable(id, notionClient);
int row = results.get(0).asTableRow().getTableRow().getCells().size();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < width + 1; i++) {
stringBuilder.append("|");
if (i == 1) {
stringBuilder.append("--|".repeat(row));
stringBuilder.append("\n|");
}
Block selectBlock = results.get(i);
List<List<PageProperty.RichText>> cells = selectBlock.asTableRow().getTableRow().getCells();
for (List<PageProperty.RichText> cell : cells) {
for (PageProperty.RichText richText : cell) {
CheckAnnotations letterShape = new CheckAnnotations(richText);
stringBuilder.append(letterShape.applyAnnotations(richText));
}
stringBuilder.append("|");
}
stringBuilder.append("\n");
}
return stringBuilder.toString();
}
위처럼 안에서 한번 더 조회를 하였다. 문제는 들여쓰기였다.
Notion에서 들여쓰기를 하면 child로 잡는다.
이런식이다. child 1,2 조회를 위해선 무조건 Parent의 아이디로 자식들을 조회해야 한다.
따라서 Converter에 새로운 생성자를 만들었다.
public NotionBlockConverter(Integer deep) {
filterList.add(new ParagraphFilter(deep));
filterList.add(new HeadingOneFilter());
filterList.add(new HeadingTwoFilter());
filterList.add(new HeadingThreeFilter());
filterList.add(new BulletedListItemFilter(deep));
filterList.add(new NumberedListItemFilter(deep));
filterList.add(new QuoteFilter());
filterList.add(new TableFilter());
filterList.add(new ToDoFilter(deep));
filterList.add(new ToggleBlockFilter());
filterList.add(new BookmarkFilter());
filterList.add(new CodeBlockFilter());
filterList.add(new DivideFilter());
filterList.add(new CallOutBlockFilter());
filterList.add(new ChildPageFilter());
filterList.add(new ImageFilter());
filterList.add(new FileFilter());
filterList.add(new LinkPreviewFilter());
filterList.add(new PdfFilter());
filterList.add(new SyncedBlockFilter());
}
들여쓰기가 필요한 블록들은 deep 을 이용해 들여쓰기를 실행하였다.
필요한 데이터를 가져온 후 ChildConverter에 보내 들여쓰기를 해주었다.
필터 형태를 이용하면 자주 이용하는 블록들을 앞에 배치하여 빠르게 해결할 수 있고.
무엇보다 if-else문을 제거하여 가독성이 매우 높아졌다.
필터가 늘어날 때 마다 else문을 추가하는것 보다. Filter에 추가하는것이 좀 더 나아보인다.
이후 필요한 글자 색 등을 추가하여 현재 Notion 페이지를 옮기는것은 완성하였다.
현재 OAuth2.0을 적용중인데. 이도 적어보도록 하겠다.
좋은 정보 감사합니다