/* * Copyright 2016-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.json; import com.facebook.buck.io.ProjectFilesystem; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSortedSet; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.file.Path; import java.util.Optional; @VisibleForTesting class JsonConcatenator { private final ProjectFilesystem filesystem; private ImmutableSortedSet<Path> inputs; private BufferedWriter destinationBufferedWriter; private boolean stillEmpty; @VisibleForTesting static final String JSON_ENCODING = "UTF-8"; public JsonConcatenator( ImmutableSortedSet<Path> inputs, Path destination, ProjectFilesystem filesystem) throws IOException { this.inputs = inputs; this.stillEmpty = true; try { this.destinationBufferedWriter = new BufferedWriter( new OutputStreamWriter(filesystem.newFileOutputStream(destination), JSON_ENCODING)); } catch (IOException e) { closeAll(); throw e; } this.filesystem = filesystem; } public void closeAll() throws IOException { if (destinationBufferedWriter != null) { destinationBufferedWriter.close(); } } public void concatenate() throws IOException { try { initializeArray(); for (Path input : inputs) { appendArray(loadJsonArrayFromFile(input)); } } finally { finalizeArray(); } } @VisibleForTesting void initializeArray() throws IOException { destinationBufferedWriter.write("["); } @VisibleForTesting void appendArray(String array) throws IOException { if (isArrayEmpty(array)) { return; } if (!stillEmpty) { destinationBufferedWriter.write(","); } destinationBufferedWriter.write(stripArrayTokens(array)); stillEmpty = false; } @VisibleForTesting void finalizeArray() throws IOException { try { destinationBufferedWriter.write("]"); } finally { closeAll(); } } private String loadJsonArrayFromFile(Path input) throws IOException { Optional<String> result = filesystem.readFileIfItExists(input); if (result.isPresent()) { return result.get(); } else { throw new IOException("Error loading " + input.toString()); } } @VisibleForTesting boolean isArrayEmpty(String array) { return array.matches("(\\s)*\\[(\\s)*\\](\\s)*"); } @VisibleForTesting String stripArrayTokens(String array) { return array.replaceAll("^(\\s)*\\[", "").replaceAll("\\](\\s)*$", ""); } }