package fr.openwide.core.basicapp.web.application.history.component.factory;
import java.util.Map;
import org.apache.wicket.Component;
import org.apache.wicket.model.IModel;
import org.bindgen.BindingRoot;
import com.google.common.collect.Maps;
import fr.openwide.core.basicapp.core.business.history.model.HistoryDifference;
import fr.openwide.core.basicapp.web.application.history.component.CompositeHistoryDifferencePanel;
import fr.openwide.core.basicapp.web.application.history.component.DefaultHistoryDifferencePanel;
import fr.openwide.core.commons.util.fieldpath.FieldPath;
import fr.openwide.core.wicket.more.util.model.Detachables;
/**
* A {@link IHistoryComponentFactory} allowing the caller to customize the way some particular fields are displayed.
* <p>The customization is done through the <code>customXXX()</code> methods.
*/
public class CustomizableHistoryComponentFactory implements IHistoryComponentFactory {
private static final long serialVersionUID = 7490592521281331323L;
private final IHistoryComponentFactory defaultFactory;
private final Map<FieldPath, IHistoryComponentFactory> specificComponentFactories = Maps.newHashMap();
private final IHistoryComponentFactory compositeBlockFactory;
private final IHistoryComponentFactory compositeInlineFactory;
private transient boolean detaching = false;
public CustomizableHistoryComponentFactory() {
this(DefaultHistoryDifferencePanel.factory());
}
public CustomizableHistoryComponentFactory(IHistoryComponentFactory defaultFactory) {
super();
this.defaultFactory = defaultFactory;
this.compositeBlockFactory = CompositeHistoryDifferencePanel.block(this);
this.compositeInlineFactory = CompositeHistoryDifferencePanel.inline(this);
}
@Override
public Component create(String wicketId, IModel<HistoryDifference> parameter) {
IHistoryComponentFactory factory = getFactory(parameter.getObject());
return factory.create(wicketId, parameter);
}
private IHistoryComponentFactory getFactory(HistoryDifference difference) {
FieldPath path = difference.getPath().getPath();
IHistoryComponentFactory result = specificComponentFactories.get(path);
if (result != null) {
return result;
} else {
return defaultFactory;
}
}
/**
* Use a custom {@link IHistoryComponentFactory} for the given field.
*/
public CustomizableHistoryComponentFactory customForPath(FieldPath path, IHistoryComponentFactory factory) {
specificComponentFactories.put(path, factory);
return this;
}
/**
* Use a custom {@link IHistoryComponentFactory} for the given field.
*/
public CustomizableHistoryComponentFactory customForBinding(BindingRoot<?, ?> binding, IHistoryComponentFactory factory) {
return customForPath(FieldPath.fromBinding(binding), factory);
}
/**
* Use a custom {@link IHistoryComponentFactory} for the given field's items.
*/
public CustomizableHistoryComponentFactory customForBindingItem(BindingRoot<?, ?> binding, IHistoryComponentFactory factory) {
return customForPath(FieldPath.fromBinding(binding).item(), factory);
}
/**
* Use the {@link CompositeHistoryDifferencePanel#block(IHistoryComponentFactory) block composite}
* layout for the given field.
*/
public CustomizableHistoryComponentFactory compositeBlockForPath(FieldPath path) {
return customForPath(path, compositeBlockFactory);
}
/**
* Use the {@link CompositeHistoryDifferencePanel#block(IHistoryComponentFactory) block composite}
* layout for the given field.
*/
public CustomizableHistoryComponentFactory compositeBlockForBinding(BindingRoot<?, ?> binding) {
return customForBinding(binding, compositeBlockFactory);
}
/**
* Use the {@link CompositeHistoryDifferencePanel#block(IHistoryComponentFactory) block composite}
* layout for the given field's items.
*/
public CustomizableHistoryComponentFactory compositeBlockForBindingItem(BindingRoot<?, ?> binding) {
return customForBindingItem(binding, compositeBlockFactory);
}
/**
* Use the {@link CompositeHistoryDifferencePanel#inline(IHistoryComponentFactory) inline composite}
* layout for the given field.
*/
public CustomizableHistoryComponentFactory compositeInlineForPath(FieldPath path) {
return customForPath(path, compositeInlineFactory);
}
/**
* Use the {@link CompositeHistoryDifferencePanel#inline(IHistoryComponentFactory) inline composite}
* layout for the given field.
*/
public CustomizableHistoryComponentFactory compositeInlineForBinding(BindingRoot<?, ?> binding) {
return customForBinding(binding, compositeInlineFactory);
}
/**
* Use the {@link CompositeHistoryDifferencePanel#inline(IHistoryComponentFactory) inline composite}
* layout for the given field's items.
*/
public CustomizableHistoryComponentFactory compositeInlineForBindingItem(BindingRoot<?, ?> binding) {
return customForBindingItem(binding, compositeInlineFactory);
}
@Override
public void detach() {
if (!detaching) {
try {
this.detaching = true;
Detachables.detach(specificComponentFactories.values());
} finally {
this.detaching = false;
}
}
}
}