com.google.common.css.compiler.passes.DelegatingVisitor Maven / Gradle / Ivy
Show all versions of closure-stylesheets Show documentation
/*
* Copyright 2009 Google 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.google.common.css.compiler.passes;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.css.compiler.ast.CssTreeVisitor;
import com.google.common.reflect.Reflection;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
/**
* Dispatches to multiple {@code CssTreeVisitor}s. All {@code enter*} methods are called in the
* order provided to the constructor and all {@code leave*} methods are called in the opposite
* order.
*
* Because {@code enter*} methods' return value changes the visitor behavior, the value returned
* by the last delegate is the one returned by the method.
*/
public class DelegatingVisitor {
private DelegatingVisitor() {
}
/**
* Creates a {@code DelegatingVisitor} from the given list of visitors. The list must have at
* least one element.
*/
public static CssTreeVisitor from(List originalVisitors) {
Preconditions.checkArgument(!originalVisitors.isEmpty());
if (originalVisitors.size() == 1) {
return originalVisitors.get(0);
}
final ImmutableList visitors = ImmutableList.copyOf(originalVisitors);
final ImmutableList reverseVisitors = visitors.reverse();
return Reflection.newProxy(
CssTreeVisitor.class,
(proxy, method, args) -> {
try {
Object returnValue = null;
Iterable visitorsInOrderForMethod;
if (method.getName().startsWith("enter")) {
visitorsInOrderForMethod = visitors;
} else { // assume it's a leave* method
visitorsInOrderForMethod = reverseVisitors;
}
for (CssTreeVisitor visitor : visitorsInOrderForMethod) {
returnValue = method.invoke(visitor, args);
}
return returnValue;
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
});
}
/**
* Creates a {@code DelegatingVisitor} from the given array of visitors. Changes to the array will
* not be reflected after construction.
*/
public static CssTreeVisitor from(CssTreeVisitor... visitors) {
return from(ImmutableList.copyOf(visitors));
}
}