ChartView.java 7.84 KB
package fi.codecrew.moya.web.cdiview.user;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ejb.EJB;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.ChartSeries;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fi.codecrew.moya.beans.RoleBeanLocal;
import fi.codecrew.moya.beans.UserBeanLocal;
import fi.codecrew.moya.enums.apps.UserPermission;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.Role;
import fi.codecrew.moya.util.UserSearchQuery;
import fi.codecrew.moya.web.annotations.SelectedUser;
import fi.codecrew.moya.web.cdiview.GenericCDIView;
import fi.codecrew.moya.utilities.SearchResult;

@Named
@ConversationScoped
public class ChartView extends GenericCDIView {
	private class ChartThread implements Runnable {

		private List<ChartSeries> series;
		private Object[] sortedAges;
		private Object[] keys;
		private HashMap<Integer, Integer> ages;
		private Integer totalAmount;
		private Role role;
		
		
		private boolean running = true;
		
		public boolean getRunning() {
			return running;
		}
		
		public ChartThread(List<ChartSeries> series, Object[] sortedAges, Object[] keys, HashMap<Integer, Integer> ages, Role role, Integer totalAmount) {
			this.series = series;
			this.sortedAges = sortedAges;
			this.keys = keys;
			this.ages = ages;
			this.role = role;
			this.totalAmount = totalAmount;
		}

		@Override
		public void run() {
			System.out.println("Role: " + role.getName() + " keys length: " + keys.length + " ages.length: " + ages.values().size());

			int i = 0;
			for (Object obj : keys) {
				int age = (int) obj;
				int amount = ages.get(age);

				for (ChartSeries serie : series) {
					if (serie.getLabel() == role.getName()) {
						System.out.println("Int i: " + i + " sortedAges-length; " + sortedAges.length + " Age: " + age + ", amount: " + amount);
						if (i < sortedAges.length) {
							if (age > (int) sortedAges[i]) {
								while (age > (int) sortedAges[i]) {
									System.out.println("Age: " + age + ", amount: 0");
									serie.set(String.valueOf(sortedAges[i]), 0);
									if (i < sortedAges.length)
										i++;
								}
							}
							if (age == (int) sortedAges[i]) {
								if (i < sortedAges.length)
									i++;
								System.out.println("Age: " + age + ", amount: " + amount);
								if(totalAmount > 0) {
									double percentage = amount/totalAmount;
									serie.set(String.valueOf(age), percentage);
								} else
									serie.set(String.valueOf(age), amount);
							}
						}
						break;
					}
					Thread.yield();
				}

			}
			System.out.println("Running set in thread to false.");
			this.running = false;
		}
		
	}
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -2692873541096663937L;
	
	@EJB
	private transient UserBeanLocal userbean;
	
	@EJB
	private transient RoleBeanLocal rolebean;
	
	@Inject
	@SelectedUser
	private transient EventUser selectedUser;
	
	private List<Role> selectedRoles;
	
	private String type = "0";
	
	public ChartView() {
		createAgesChart();
	}
	
	public void initCreateView() {
		if (super.requirePermissions(UserPermission.VIEW_ALL))
		{
			createAgesChart();
			super.beginConversation();
		}
	}
	
	private CartesianChartModel agesChart = new CartesianChartModel();  
	
	public CartesianChartModel getAgesChart() {
		if(agesChart == null)
			agesChart = new CartesianChartModel();
        return agesChart;  
    }  
	
	public void updateAgesChart() {
		createAgesChart();
	}
	
	private void createAgesChart() {  
        
		if(selectedRoles != null) {
			//selectedRoles = new ArrayList<Role>();

			agesChart = new CartesianChartModel();  

			ArrayList<ChartSeries> series = new ArrayList<ChartSeries>();

			for (Role role : selectedRoles) {
				series.add(new ChartSeries(role.getName()));
			}

			HashMap<Role, HashMap<Integer, Integer>> hashMap = new HashMap<Role, HashMap<Integer, Integer>>(); 

			UserSearchQuery usersearch = new UserSearchQuery();
			usersearch.setPagesize(999999999);
			usersearch.setPage(0);
			//usersearch.setFilterRoles(selectedRoles);
			//usersearch.setOnlyThisEvent(true);

			ArrayList<Integer> ageList = new ArrayList<Integer>();

			HashMap<Role, Integer> totalAmounts = new HashMap<Role, Integer>();
			
			if(userbean != null) {
				//System.out.println("userbean not null");

				System.out.println("Looping eventUsers and roles for data\n\n");

				SearchResult<EventUser> users = userbean.getThisEventsUsers(usersearch);

				for (Role role : selectedRoles) {
					System.out.println("Role: " + role.getName());

					for (EventUser eventUser : users.getResults()) {
						//if(eventUser.getEvent() == selectedUser.getEvent()) {
						System.out.println("EventUser: " + eventUser.getLogin());

						List<Role> usersRoles = userbean.findUsersRoles(eventUser);
						if(usersRoles != null && !usersRoles.isEmpty() && usersRoles.contains(role)) {
							System.out.println("EventUser contains role: " + role.getName());
							int age = eventUser.getUser().getAge().intValue();
							System.out.println("Age: " + age);
							int amount = 0;

							HashMap<Integer, Integer> ages = new HashMap<Integer, Integer>();

							if(hashMap.containsKey(role)) {
								ages = hashMap.get(role);
							}
							if(ages.containsKey(age)) {
								amount = ages.get(age);
							}

							if(!ageList.contains(age))
								ageList.add(age);

							ages.put(age, amount + 1);
							hashMap.put(role, ages);
							int totalAmount = 0;
							if(totalAmounts.containsKey(role))
								totalAmount = totalAmounts.get(role);
							totalAmounts.put(role,  totalAmount+amount+1);
							System.out.println("Amount: " + amount);
							//}
						}
					}
				}

				Object[] sortedAges = ageList.toArray();
				Arrays.sort(sortedAges);

				System.out.println("Data looped. Starting adding data to series..\n\n");

				ArrayList<ChartThread> threads = new ArrayList<ChartThread>();
				
				Set set = hashMap.entrySet();
				Iterator iterator = set.iterator();
				//for (Role role : hashMap.keySet()) {
				while (iterator.hasNext()) {
					
					System.out.println("While for adding data to serieses parallel.");
					Map.Entry<Role, HashMap<Integer,Integer>> me = (Map.Entry<Role, HashMap<Integer,Integer>>) iterator.next();
					Role role = (Role) me.getKey();
					HashMap<Integer, Integer> ages = hashMap.get(role);
					Object[] keys = ages.keySet().toArray();
					Arrays.sort(keys);
					
					
					int totalAmount = 0;
					if(type.equals("1") && totalAmounts.containsKey(role))
						totalAmount = totalAmounts.get(role);
					
					ChartThread ch = new ChartThread(series, sortedAges, keys, ages, role, totalAmount);
					threads.add(ch);
					new Thread(ch).start();
				} 

				boolean done = false;
				while(!done) {
					boolean running = false;
					for(ChartThread thread : threads) {
						if(thread.getRunning()) {
							running = true;
							break;
						}
					}
					if(!running) {
						done = true;
						System.out.println("While finished. No thread is running.");
					} else {
						try {
							System.out.println("Thread is still running, waiting 10ms..");
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
				
				System.out.println("Data set to series. Adding serieses to chart.\n\n");

				for(ChartSeries serie : series) {
					if(serie.getData() != null && !serie.getData().isEmpty())
						agesChart.addSeries(serie);
				}
			} 
		}
    }  
	
	public void setFilterRoles(List<Role> roles) {
		this.selectedRoles = roles;
	}
	public List<Role> getFilterRoles() {
		return this.selectedRoles;
	}
	
	public void setType(String type) {
		this.type = type;
	}
	public String getType() {
		return this.type;
	}
}