com.getperka.flatpack.Visitors Maven / Gradle / Ivy
package com.getperka.flatpack;
/*
* #%L
* FlatPack serialization code
* %%
* Copyright (C) 2012 - 2013 Perka 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.
* #L%
*/
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.getperka.flatpack.ext.Codex;
import com.getperka.flatpack.ext.TypeContext;
import com.getperka.flatpack.ext.VisitorContext;
import com.getperka.flatpack.ext.Walker;
import com.getperka.flatpack.ext.Walkers;
/**
* A utility class that allows visitors to be written to traverse a FlatPack object graph.
*/
@Singleton
public class Visitors {
class FlatPackEntityWalker implements Walker> {
@Override
public void walk(FlatPackVisitor visitor, FlatPackEntity entity,
VisitorContext> context) {
@SuppressWarnings("unchecked")
Codex codex = (Codex) typeContext.getCodex(entity.getType());
if (visitor.visit(entity, codex, context)) {
entity.withValue(context.walkSingleton(codex).accept(visitor, entity.getValue()));
// Traverse the extra entities as a list, to allow insertion
Codex extraCodex = typeContext.getCodex(HasUuid.class);
List mutable = new ArrayList(entity.getExtraEntities());
context.walkList(extraCodex).accept(visitor, mutable);
entity.setExtraEntities(new HashSet(mutable));
}
visitor.endVisit(entity, codex, context);
}
}
@Inject
TypeContext typeContext;
@Inject
Walkers walkers;
protected Visitors() {}
/**
* Returns a {@link VisitorContext} for performing ad-hoc traversals.
*/
public Walkers getWalkers() {
return walkers;
}
/**
* Visit a {@link FlatPackEntity}, including its {@link FlatPackEntity#getValue() value} and
* {@link FlatPackEntity#getExtraEntities() extra entities};
*
* @param visitor the visitor to receive the object graph
* @param entity the FlatPackEntity to traverse
* @return {@code entity} or its replacement
*/
public FlatPackEntity visit(FlatPackVisitor visitor, FlatPackEntity entity) {
return getWalkers().walkSingleton(new FlatPackEntityWalker()).accept(visitor, entity);
}
/**
* Visit an entity.
*
* @param visitor the visitor to receive the object graph
* @param entity the entity to traverse
* @return {@code entity} or its replacement
*/
public T visit(FlatPackVisitor visitor, T entity) {
@SuppressWarnings("unchecked")
Class clazz = (Class) entity.getClass();
Codex codex = typeContext.getCodex(clazz);
return getWalkers().walkSingleton(codex).accept(visitor, entity);
}
}