package org.yaac.client.activity;
import static com.google.common.base.Strings.isNullOrEmpty;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;
import javax.inject.Inject;
import org.yaac.client.place.StatisticsPlace;
import org.yaac.client.service.StatisticsServiceAsync;
import org.yaac.client.ui.StatisticsView;
import org.yaac.client.ui.StatisticsView.KindBreakdown;
import org.yaac.client.ui.StatisticsView.NamespaceBreakdown;
import org.yaac.client.ui.StatisticsView.PropertyTypeBreakdown;
import org.yaac.client.ui.StatisticsView.Summary;
import org.yaac.client.util.ExceptionManager;
import org.yaac.shared.stat.StatDTO;
import org.yaac.shared.stat.StatDTO.KindWrapper;
import org.yaac.shared.stat.models.PropertyTypePropertyNameKind;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
/**
* @author Max Zhu (thebbsky@gmail.com)
*
*/
public class StatisticsActivity extends SinglePlaceActivity<StatisticsPlace> implements StatisticsView.Presenter {
private final StatisticsView view;
private final StatisticsServiceAsync statisticsService;
private final ExceptionManager exceptionManager;
@Inject
StatisticsActivity(
StatisticsView view,
StatisticsServiceAsync statisticsService,
ExceptionManager exceptionManager) {
super();
this.view = view;
this.statisticsService = statisticsService;
this.exceptionManager = exceptionManager;
}
@Override
public StatisticsActivity withPlace(StatisticsPlace place) {
return this;
}
/**
* stat DTO returned from server side
*
* will be parsed into easy-to-display format for view
*/
private StatDTO stat;
/**
* Invoked by the ActivityManager to start a new Activity
*/
@Override
public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
statisticsService.loadStat(new AsyncCallback<StatDTO>() {
@Override
public void onSuccess(StatDTO result) {
stat = result;
initFilters();
initSummary();
onFilterChange(null, null); // init tables and charts
}
@Override
public void onFailure(Throwable caught) {
exceptionManager.handle(caught);
}
});
view.setPresenter(this);
containerWidget.setWidget(view.asWidget());
}
/**
*
*/
private void initFilters() {
// init kind names
TreeSet<String> kindNames = new TreeSet<String>();
for (Iterable<KindWrapper> kinds : stat.getNsKindsMap().values()) {
for (KindWrapper kind : kinds) {
kindNames.add(kind.getKind().getKind_name());
}
}
view.initKindNames(kindNames);
// init namespaces
view.initNamespaceNames(stat.getNsKindsMap().keySet());
}
/**
*
*/
private void initSummary() {
view.updateSummary(new Summary(
stat.getTotal().getTimestamp(), stat.getTotal().getCount(), stat.getTotal().getBytes()));
}
@Override
public void onFilterChange(String selectedNamespace, String selectedKind) {
// namespace and kind breakdown
{
Map<String, NamespaceBreakdown> namespaceBreakdownMap = new HashMap<String, NamespaceBreakdown>();
Map<String, KindBreakdown> kindBreakdownMap = new HashMap<String, KindBreakdown>();
for (String namespace : stat.getNsKindsMap().keySet()) {
// filter out namespace
// shouldn't use Strings.isNullOrEmpty as there is an empty namespace
if (selectedNamespace != null && !namespace.equals(selectedNamespace)) {
continue;
}
NamespaceBreakdown namespaceBreakdown = namespaceBreakdownMap.get(namespace);
if (namespaceBreakdown == null) {
namespaceBreakdown = new NamespaceBreakdown(namespace);
namespaceBreakdownMap.put(namespace, namespaceBreakdown);
}
for (KindWrapper kindWrapper : stat.getNsKindsMap().get(namespace)) {
String kindName = kindWrapper.getKind().getKind_name();
// filter out kind
if (!isNullOrEmpty(selectedKind) && !selectedKind.equals(kindName)) {
continue;
}
KindBreakdown kindBreakdown = kindBreakdownMap.get(kindName);
if (kindBreakdown == null) {
kindBreakdown = new KindBreakdown(kindName);
kindBreakdownMap.put(kindName, kindBreakdown);
}
kindBreakdown.addCount(kindWrapper.getKind().getCount());
kindBreakdown.addSize(kindWrapper.getKind().getBytes());
kindBreakdown.addRootCount(
kindWrapper.getRootKind() == null ? 0l : kindWrapper.getRootKind().getCount());
kindBreakdown.addRootSize(
kindWrapper.getRootKind() == null ? 0l : kindWrapper.getRootKind().getBytes());
kindBreakdown.addNonRootCount(
kindWrapper.getNonRootKind() == null ? 0l : kindWrapper.getNonRootKind().getCount());
kindBreakdown.addNonRootSize(
kindWrapper.getNonRootKind() == null ? 0l : kindWrapper.getNonRootKind().getBytes());
// all aggregate to the same namespace
namespaceBreakdown.addBytes(kindWrapper.getKind().getBytes());
namespaceBreakdown.addCount(kindWrapper.getKind().getCount());
}
}
view.updateNamespaceBreakdown(new ArrayList<NamespaceBreakdown>(namespaceBreakdownMap.values()));
view.updateKindBreakdown(new ArrayList<KindBreakdown>(kindBreakdownMap.values()));
}
// property type breakdown
{
Map<String, PropertyTypeBreakdown> breakdownMap = new HashMap<String, PropertyTypeBreakdown>();
for (String namespace : stat.getNsPropertyMap().keySet()) {
// shouldn't use Strings.isNullOrEmpty as there is an empty namespace
if (selectedNamespace != null && !namespace.equals(selectedNamespace)) {
continue;
}
for (PropertyTypePropertyNameKind prop : stat.getNsPropertyMap().get(namespace)) {
// filter out kind
if (!isNullOrEmpty(selectedKind) && !selectedKind.equals(prop.getKind_name())) {
continue;
}
PropertyTypeBreakdown breakdown = breakdownMap.get(prop.getProperty_type());
if (breakdown == null) {
breakdown = new PropertyTypeBreakdown(prop.getProperty_type());
breakdownMap.put(prop.getProperty_type(), breakdown);
}
breakdown.addCount(prop.getCount());
breakdown.addBytes(prop.getBytes());
}
}
view.updatePropertyTypeBreakdown(new ArrayList<PropertyTypeBreakdown>(breakdownMap.values()));
}
}
}