/*
* Copyright 2016 DiffPlug
*
* 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.diffplug.spotless;
import java.io.File;
import java.io.Serializable;
import java.util.Objects;
import java.util.Random;
import com.diffplug.spotless.FormatterStep.Strict;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* Standard implementation of FormatExtension which cleanly enforces
* separation of serializable configuration and a pure format function.
*
* Not an inner-class of FormatterStep so that it can stay entirely private
* from the API.
*/
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
abstract class FormatterStepImpl<State extends Serializable> extends Strict<State> {
private static final long serialVersionUID = 1L;
/** Transient because only the state matters. */
final transient String name;
/** Transient because only the state matters. */
final transient ThrowingEx.Supplier<State> stateSupplier;
FormatterStepImpl(String name, ThrowingEx.Supplier<State> stateSupplier) {
this.name = Objects.requireNonNull(name);
this.stateSupplier = Objects.requireNonNull(stateSupplier);
}
@Override
public String getName() {
return name;
}
@Override
protected State calculateState() throws Exception {
return stateSupplier.get();
}
static final class Standard<State extends Serializable> extends FormatterStepImpl<State> {
private static final long serialVersionUID = 1L;
final transient ThrowingEx.Function<State, FormatterFunc> stateToFormatter;
transient FormatterFunc formatter; // initialized lazily
Standard(String name, ThrowingEx.Supplier<State> stateSupplier, ThrowingEx.Function<State, FormatterFunc> stateToFormatter) {
super(name, stateSupplier);
this.stateToFormatter = Objects.requireNonNull(stateToFormatter);
}
@Override
protected String format(State state, String rawUnix, File file) throws Exception {
Objects.requireNonNull(state, "state");
Objects.requireNonNull(rawUnix, "rawUnix");
Objects.requireNonNull(file, "file");
if (formatter == null) {
formatter = stateToFormatter.apply(state());
}
return formatter.apply(rawUnix);
}
}
/** Formatter which is equal to itself, but not to any other Formatter. */
static class NeverUpToDate extends FormatterStepImpl<Integer> {
private static final long serialVersionUID = 1L;
private static final Random RANDOM = new Random();
final transient ThrowingEx.Supplier<FormatterFunc> formatterSupplier;
transient FormatterFunc formatter; // initialized lazily
NeverUpToDate(String name, ThrowingEx.Supplier<FormatterFunc> formatterSupplier) {
super(name, RANDOM::nextInt);
this.formatterSupplier = Objects.requireNonNull(formatterSupplier, "formatterSupplier");
}
@Override
protected String format(Integer state, String rawUnix, File file) throws Exception {
if (formatter == null) {
formatter = formatterSupplier.get();
}
return formatter.apply(rawUnix);
}
}
}