/*
Copyright (C) 2009 Steffen Dienst
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package de.elatexam.editor.components.panels.tree;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import net.databinder.models.hib.HibernateObjectModel;
import org.apache.wicket.Component;
import org.apache.wicket.model.IComponentInheritedModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.IWrapModel;
import wickettree.ITreeProvider;
import com.google.common.collect.Iterators;
import de.elatexam.editor.user.BasicUser;
import de.elatexam.model.Category;
import de.elatexam.model.ComplexTaskDef;
import de.elatexam.model.Indexed;
import de.elatexam.model.SubTaskDef;
import de.elatexam.model.manual.HomogeneousTaskBlock;
/**
* Provide tree structure for rendering. Represents a {@link ComplexTaskDef} in
* a user comprehensible way. <br>
* TODO add taskdef choice blocks
*
* @author Steffen Dienst
*
*/
public class ComplexTaskdefTreeProvider<T extends Indexed> implements ITreeProvider<T> {
/**
* wrap each object in a HibernateObjectModel, implement equals/hashcode
* correctly (respecting the primary key only)
*
* @author Steffen Dienst
*
*/
private static class HackedHibernateObjectModel<T extends Indexed>
extends
HibernateObjectModel<T>
implements
IWrapModel<T>,
IComponentInheritedModel<T> {
private HackedHibernateObjectModel(Class<? extends Indexed> objectClass, Serializable entityId) {
super(objectClass, entityId);
}
@Override
public boolean equals(final Object obj) {
final T target = getObject();
if (target != null && obj instanceof HibernateObjectModel)
return equalId(target,((HibernateObjectModel<T>) obj).getObject());
return super.equals(obj);
}
private boolean equalId(final T o1, final T o2) {
return o2!=null
&& o1.getClass().equals(o2.getClass())
&& o1.getHjid().equals(o2.getHjid());
}
@Override
public int hashCode() {
final T target = getObject();
if (target == null)
return super.hashCode();
int hash = 1;
hash = hash * 31 + target.getClass().hashCode();
hash = hash * 31 + target.getHjid().hashCode();
return hash;
}
// HACK: the tree uses StyledLinks which itself contains an
// AjaxFallBackLink without any model
// This breaks the DND-feature somehow. Using these two methods we
// signal
// that children may inherit this model if they have none
@Override
public IWrapModel<T> wrapOnInheritance(Component component) {
return this;
}
@Override
public IModel<T> getWrappedModel() {
return this;
}
}
private final IModel<List<T>> model;
public ComplexTaskdefTreeProvider(final IModel<List<T>> model) {
this.model = model;
}
/*
* (non-Javadoc)
*
* @see org.apache.wicket.model.IDetachable#detach()
*/
public void detach() {
model.detach();
}
private Iterator<T> getChildren(final Category cat) {
return (Iterator<T>) cat.getTaskBlocks().iterator();
}
private Iterator<T> getChildren(final HomogeneousTaskBlock tb) {
List<? extends SubTaskDef> subtasks = tb.getSubtaskDefs();
return (Iterator<T>) subtasks.iterator();
}
private Iterator<T> getChildren(final ComplexTaskDef ctd) {
return (Iterator<T>) ctd.getCategory().iterator();
}
/*
* (non-Javadoc)
*
* @see wickettree.ITreeProvider#getChildren(java.lang.Object)
*/
public Iterator<T> getChildren(final Indexed object) {
if (object instanceof BasicUser)
return getChildren((BasicUser) object);
else if (object instanceof ComplexTaskDef)
return getChildren((ComplexTaskDef) object);
else if (object instanceof Category)
return getChildren((Category) object);
else if (object instanceof HomogeneousTaskBlock)
return getChildren((HomogeneousTaskBlock) object);
else
return Iterators.emptyIterator();
}
private Iterator<T> getChildren(final BasicUser user) {
return (Iterator<T>) user.getTaskdefs().iterator();
}
public Iterator<T> getRoots() {
return model.getObject().iterator();
}
public boolean hasChildren(final Indexed object) {
return Iterators.size(getChildren(object)) > 0;
}
/*
* (non-Javadoc)
*
* @see wickettree.ITreeProvider#model(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public IModel<T> model(final T object) {
try {
return new HackedHibernateObjectModel<T>(object.getClass(),object.getHjid());
} catch (final Exception e) {
e.printStackTrace();
return null;
}
}
}