Java tutorial
/** * @filename TvRedirectionAction.java * @version * @author Administrator * @since * * Copyright (c) 2006-2010 Aerohive Co., Ltd. * All right reserved. */ package com.ah.ui.actions.teacherView; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.ah.be.app.HmBeActivationUtil; import com.ah.be.app.HmBeCommunicationUtil; import com.ah.be.app.HmBeMiscUtil; import com.ah.be.app.HmBeOsUtil; import com.ah.be.common.DBOperationUtil; import com.ah.be.common.NmsUtil; import com.ah.be.common.cache.CacheMgmt; import com.ah.be.common.cache.SimpleHiveAp; import com.ah.be.communication.BeCommunicationConstant; import com.ah.be.communication.BeCommunicationEncodeException; import com.ah.be.communication.event.BeCliEvent; import com.ah.be.misc.teacherview.ClearClassRequest; import com.ah.be.misc.teacherview.TeacherViewException; import com.ah.be.parameter.constant.util.AhConstantUtil; import com.ah.bo.HmBo; import com.ah.bo.admin.HMServicesSettings; import com.ah.bo.admin.HmAuditLog; import com.ah.bo.admin.HmUser; import com.ah.bo.admin.HmUserGroup; import com.ah.bo.hiveap.HiveAp; import com.ah.bo.mgmt.FilterParams; import com.ah.bo.mgmt.QueryBo; import com.ah.bo.mgmt.QueryUtil; import com.ah.bo.mgmt.SortParams; import com.ah.bo.teacherView.TvClass; import com.ah.bo.teacherView.TvClassSchedule; import com.ah.bo.teacherView.TvResourceMap; import com.ah.bo.teacherView.ViewingClass; import com.ah.ha.HAUtil; import com.ah.ui.actions.LoginAction; import com.ah.util.CheckItem; import com.ah.util.HmProxyUtil; import com.ah.util.MgrUtil; import com.ah.util.Tracer; import com.ah.util.datetime.AhDateTimeUtil; public class TvRedirectionAction extends LoginAction implements QueryBo { private static final long serialVersionUID = 1L; private static final Tracer log = new Tracer(TvRedirectionAction.class.getSimpleName()); private static final String REDIRECT_ACTION_UPDATE = "update"; //private static final String REDIRECT_ACTION_APPEND = "append"; /** * The replacement of AP address if students cannot find their host AP */ public static final String NONE_AP_IP = "0.0.0.0"; public static String NONE_AP_IP_MAC = NONE_AP_IP + "/" + "00:00:00:00:00:00"; /** * The maximum count of classes could be viewed by one designated AP */ private static final int MAX_VIEW_COUNT = 8; private static final String CLASS_TIME_SEPERATOR = ":"; private static final int MAX_ADMIN_USER = 32; @Override public String execute() throws Exception { try { if (null == userContext) { return "redirectLogin"; } if ("classInfo".equals(operation)) { getClassDetail(); return "json"; } else if ("teacherList".equals(operation)) { getTeacherList(); return "json"; } else if ("refreshClassList".equals(operation)) { refreshClassList(); return "json"; } else if ("redirect".equals(operation)) { if (executeRedirection()) { /* * redirect user to HiveUI */ return "redirect"; } else { /* * redirection failed, error message will be added into * the page. */ return SUCCESS; } } return SUCCESS; } catch (Exception e) { return prepareActionError(e); } } public void prepare() throws Exception { userContext = getSessionUserContext(); licTile = MgrUtil.getUserMessage("teacherView.title"); // hm version information versionInfo = getSessionVersionInfo(); if (null == versionInfo) { versionInfo = NmsUtil.getVersionInfo(); if (null != versionInfo) { setSessionVersionInfo(versionInfo); } } if (null == userContext) { authTeacher(); } domainId = QueryUtil.getDependentDomainFilter(userContext); setDataSource(TvClass.class); } /** * Teacher view user has authentication by cas * * @throws Exception - */ public void authTeacher() throws Exception { // HA status if (HAUtil.isSlave()) { redirectUrl = getMasterURL() + "/teacherView.action"; return; } redirectUrl = NmsUtil.getAuthServiceURL() + "/logout"; if (!NmsUtil.isHTTPEnable() && !"https".equals(request.getScheme())) { // SSL redirect (check this only in case of HTTP not enabled) } else { // get user from cas server String user = request.getRemoteUser(); if (null != user) { // the HiveManager is in maintenance mode if (HmBeOsUtil.getMaintenanceModeFromDb()) { redirectUrl += "?url=error.authentication.credentials.bad.maintenance"; return; } // select by user name List<HmUser> allUsers = QueryUtil.executeQuery(HmUser.class, new SortParams("id"), new FilterParams("lower(userName) = :s1 AND userGroup.groupName = :s2", new Object[] { user.toLowerCase(), HmUserGroup.TEACHER }), null, this); if (allUsers.size() != 1) { // select by email address allUsers = QueryUtil.executeQuery(HmUser.class, new SortParams("id"), new FilterParams("lower(emailAddress) = :s1 AND userGroup.groupName = :s2", new Object[] { user.toLowerCase(), HmUserGroup.TEACHER }), null, this); } if (allUsers.size() == 1) { userContext = allUsers.get(0); } } if (null != userContext) { try { setSessionUserContext(userContext); userContext.setUserIpAddress(HmProxyUtil.getClientIp(request)); initLicenseAndActKeyInfo(); // check license and activation key if (null == licenseInfo || !getLicenseValidFlag() || !HmBeActivationUtil.ACTIVATION_KEY_VALID) { userContext = null; return; } refreshNavigationTree(); generateAuditLog(HmAuditLog.STATUS_SUCCESS, MgrUtil.getUserMessage( "info.teacherView.teacher.login", new String[] { userContext.getUserName() })); } catch (Exception e) { userContext = null; } } } } /** * This method is just to eliminate some javascript for feature 'hm search' in topPane.jsp. * Because feature 'hm search' is not permitted in Teacher View * * @return - */ public boolean getTopoSearch() { return true; } /** * Get classes which are taught by the current teacher user. * * @return a <code>List</code> of <code>CheckItem</code> objects, <code>id</code> is the index ID of class * in database table, <code>value</code> is spelled by CLASS_NAME + (SUBJECT). * @author Joseph Chen */ public List<CheckItem> getTeacherClassList() { List<CheckItem> items = new ArrayList<CheckItem>(); /* * find classes from database */ List<TvClass> bos = QueryUtil.executeQuery(TvClass.class, null, // new FilterParams("teacherId", this.getUserContext().getUserName()), new FilterParams("lower(teacherId)", StringUtils.lowerCase(this.getUserContext().getEmailAddress())), // fix bug 23956 in Geneva,make VHM with IDM can create teacher this.getDomainId(), this); if (bos.isEmpty()) { items.add(new CheckItem((long) CHECK_ITEM_ID_NONE, MgrUtil.getUserMessage("config.optionsTransfer.none"))); return items; } /* * put the most wanted class at the first place */ List<TvClass> orderedClass; if (bos.size() > 1) { orderedClass = moveTopClass(bos); } else { orderedClass = bos; } /* * set initial subject and teacher */ TvClass currentClass = orderedClass.get(0); this.subject = currentClass.getSubject(); this.teacher = currentClass.getTeacherId(); /* * add class info to CheckItem list */ for (TvClass tvClass : orderedClass) { String itemValue = new StringBuffer(tvClass.getClassName()).append("(").append(tvClass.getSubject()) .append(")").toString(); items.add(new CheckItem(tvClass.getId(), itemValue)); } return items; } /** * Get all subjects of class in a school * * @return a <code>List</code> of <code>String</code> objects, element is subject name * @author Joseph Chen */ public List<String> getSubjectList() { List<String> subjects = new ArrayList<String>(); /* * find subjects from database */ StringBuilder sql = new StringBuilder("SELECT DISTINCT subject FROM tv_class ").append("WHERE owner=") .append(this.getDomainId()); List<?> objs = QueryUtil.executeNativeQuery(sql.toString()); if (objs.isEmpty()) { subjects.add(MgrUtil.getUserMessage("config.optionsTransfer.none")); return subjects; } /* * add subjects to list */ for (Object obj : objs) { subjects.add((String) obj); } return subjects; } private List<TvClass> moveTopClass(List<TvClass> classes) { /* * check if there is class at today(weekday) */ // String currentWeekDay = AhDateTimeUtil.getCurrentWeekDay(getUserTimeZone()); TvClass topClass = null; for (TvClass tvClass : classes) { List<TvClassSchedule> periods = tvClass.getItems(); if (periods.size() == 0) { continue; } for (TvClassSchedule period : periods) { if (period == null) { continue; } if (hasClassToday(period)) { if (isClassExpired(period)) { continue; } if (topClass == null) { topClass = tvClass; } else { if (moreClose(topClass, tvClass)) { topClass = tvClass; } } break; } } } /* * if no class is at today, exit */ if (topClass == null) { return classes; } List<TvClass> newList = new ArrayList<TvClass>(); newList.add(topClass); /* * put classes into a linked list */ for (TvClass tvClass : classes) { if (!tvClass.getId().equals(topClass.getId())) { newList.add(tvClass); } } return newList; } private boolean moreClose(TvClass topClass, TvClass newClass) { return getTimeDistance(newClass) < getTimeDistance(topClass); } private long getTimeDistance(TvClass tvClass) { Calendar calClass = Calendar.getInstance(getUserTimeZone()); calClass.setTimeInMillis(System.currentTimeMillis()); /* * set the start time of class to calClass */ for (TvClassSchedule period : tvClass.getItems()) { if (hasClassToday(period)) { /* * set the HH and MM to calClass */ setClassTime(calClass, period.getStartTime()); break; } } /* * return the absolute value of subtraction */ return Math.abs(calClass.getTimeInMillis() - System.currentTimeMillis()); } private void setClassTime(Calendar calendar, String time) { if (time == null) { return; } String[] segments = time.split(CLASS_TIME_SEPERATOR); calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(segments[0])); calendar.set(Calendar.MINUTE, Integer.parseInt(segments[1])); } private boolean isClassExpired(TvClassSchedule period) { if (period == null) { return true; } /* * set HH and MM to a calendar of now */ Calendar calNow = Calendar.getInstance(getUserTimeZone()); calNow.setTimeInMillis(System.currentTimeMillis()); setClassTime(calNow, period.getEndTime()); return System.currentTimeMillis() - calNow.getTimeInMillis() >= 0; } private void getClassDetail() throws JSONException { if (getClassId() == null || getClassId() == -1) { return; } /* * get class object from database */ TvClass aClass = QueryUtil.findBoById(TvClass.class, getClassId(), this); if (aClass == null) { return; } List<TvClassSchedule> schedule = aClass.getItems(); if (schedule == null) { return; } /* * add class info to JSON array */ jsonArray = new JSONArray(); for (TvClassSchedule period : schedule) { JSONObject jsonObject = new JSONObject(); jsonObject.put("selected", isClassToday(period)); jsonObject.put("day", period.getWeekdaySecString()); jsonObject.put("start", period.getStartTime()); jsonObject.put("end", period.getEndTime()); jsonObject.put("room", period.getRoom()); jsonArray.put(jsonObject); } } private boolean isClassToday(TvClassSchedule period) { return period != null && hasClassToday(period) && !isClassExpired(period); } private void getTeacherList() throws JSONException { if (getSubject() == null) { return; } /* * get teachers of a subject from database */ StringBuilder sql = new StringBuilder(); sql.append("SELECT DISTINCT teacherid FROM tv_class "); sql.append("WHERE subject=\'").append(NmsUtil.convertSqlStr(getSubject())).append("\'"); sql.append("AND owner=").append(this.getDomainId()); List<?> list = QueryUtil.executeNativeQuery(sql.toString()); if (list.isEmpty()) { return; } List<String> teachers = new ArrayList<String>(); if (getClassId() != null) { TvClass theClass = QueryUtil.findBoById(TvClass.class, getClassId(), this); teachers.add(theClass.getTeacherId()); } for (Object obj : list) { if (!teachers.contains(obj.toString())) { teachers.add((String) obj); } } /* * add class info to JSON array */ jsonArray = new JSONArray(); for (Object obj : teachers) { JSONObject jsonObject = new JSONObject(); jsonObject.put("teacher", obj); jsonArray.put(jsonObject); } } private void refreshClassList() throws JSONException { if (getTeacher() == null) { return; } /* * find classes from database */ List<TvClass> bos = QueryUtil.executeQuery(TvClass.class, null, new FilterParams("subject = :s1 AND teacherId = :s2", new String[] { getSubject(), getTeacher() }), this.getDomainId(), this); if (bos.isEmpty()) { return; } /* * put the most wanted class at the first place */ List<TvClass> orderedClass; if (bos.size() > 1) { orderedClass = moveTopClass(bos); } else { orderedClass = bos; } /* * add class info to JSON array */ jsonArray = new JSONArray(); for (TvClass tvClass : orderedClass) { String className = new StringBuffer(tvClass.getClassName()).append(" (").append(tvClass.getSubject()) .append(")").toString(); JSONObject jsonObject = new JSONObject(); jsonObject.put("id", tvClass.getId()); jsonObject.put("name", className); jsonArray.put(jsonObject); } } private boolean executeRedirection() { /* * get class name by class id */ TvClass tvClass = QueryUtil.findBoById(TvClass.class, getClassId(), this); if (tvClass == null) { this.addActionError(MgrUtil.getUserMessage("error.teacherView.class.notFound")); return false; } /* * search for existing record in table viewing_class */ ViewingClass viewingClass = QueryUtil.findBoByAttribute(ViewingClass.class, "className", tvClass.getClassName(), this.getDomainId()); if (viewingClass != null) { // class is being viewing String apAddress = viewingClass.getApIpAddress(); String apMacAddress = viewingClass.getApMacAddress(); ClassAP classAP = getClassAPStatus(apMacAddress); boolean isAPConnected = classAP == null ? false : classAP.isConnected(); boolean isSptHttps = classAP == null ? false : classAP.isSptHttps(); if (isAPConnected) { /* * redirect to the AP */ return redirect(tvClass, apAddress, apMacAddress, isSptHttps); } else { /* * an CAPWAP event should be send to tell the AP * to clear old student list */ try { log.info(MgrUtil.getUserMessage("info.teacherView.redirect.clear.event", new String[] { apAddress, tvClass.getClassName() })); HmBeMiscUtil.addClearClassRequest(new ClearClassRequest(apAddress, tvClass.getClassName())); } catch (Exception e) { log.error(MgrUtil.getUserMessage("error.teacherView.redirect.clear.event", new String[] { apAddress, tvClass.getClassName() })); } } } ApConnectedStudents designatedAP = null; try { designatedAP = getDesignatedAP(tvClass); if (designatedAP == null) throw new TeacherViewException( MgrUtil.getUserMessage("error.teacherView.redirect.no.online.student")); } catch (TeacherViewException e) { this.addActionError(e.getMessage()); log.error(e.getMessage(), e); return false; } catch (Exception e) { this.addActionError(MgrUtil.getUserMessage("error.teacherView.redirect.unknown")); log.error(e.getMessage(), e); return false; } if (redirect(tvClass, designatedAP.getApAddress(), designatedAP.getMacAddress(), designatedAP.isSptHttps())) { addViewingClass(tvClass, designatedAP); return true; } else { return false; } } //We just can use macAddress to query the HiveAp information, if use IP, sometimes will get duplicate info. private ClassAP getClassAPStatus(String macAddress) { if (macAddress == null) { return null; } ClassAP classAP = new ClassAP(); List<HiveAp> hiveAps = QueryUtil.executeQuery(HiveAp.class, null, new FilterParams("macAddress = :s1 and simulated = :s2 and hiveApModel in (:s3)", new Object[] { macAddress, false, AhConstantUtil.getTeacherViewSupportDevices() }), this.getDomainId()); if (hiveAps == null || hiveAps.size() == 0) { return classAP; } else { classAP.setConnected(hiveAps.get(0) != null && hiveAps.get(0).isConnected()); boolean after_Guadalupe = hiveAps.get(0) == null ? false : hiveAps.get(0).getSoftVer() != null && (NmsUtil.compareSoftwareVersion("6.1.6.0", hiveAps.get(0).getSoftVer()) <= 0); classAP.setSptHttps(after_Guadalupe); } return classAP; } private boolean redirect(TvClass tvClass, String apAddress, String apMacAddress, boolean isSptHttps) { /* * download CAS and resource map to AP */ boolean downloadSucc = downloadTeacherViewSettings(apMacAddress); if (!downloadSucc) { this.addActionError(MgrUtil.getUserMessage("error.teacherView.redirect.download.settings", apAddress)); return false; } this.setRedirectURL(getRedirectRequestURL(apAddress, isSptHttps)); this.setClassName(tvClass.getClassName()); this.setRosterType(tvClass.getRosterType()); HMServicesSettings hmService = QueryUtil.findBoByAttribute(HMServicesSettings.class, "owner", getDomain()); if (hmService.isEnableTVProxy()) { try { this.setProxyServer(encodeProxyServer(hmService.getTvProxyIP(), hmService.getTvProxyPort(), hmService.getTvAutoProxyFile())); } catch (TeacherViewException e) { addActionError(e.getMessage()); return false; } catch (Exception e) { log.error(MgrUtil.getUserMessage("error.teacherView.redirect.encoding", "proxy server"), e); } } this.caseInsensitive = hmService.getEnableCaseSensitive(); /* * AP and Student list */ String apStudents = null; try { apStudents = encodeAPStudents(tvClass); } catch (Exception e) { log.error(MgrUtil.getUserMessage("error.teacherView.redirect.encoding"), e); } if (apStudents == null) { this.addActionError(MgrUtil.getUserMessage("error.teacherView.redirect.encoding")); return false; } else { this.setApStudents(apStudents); } try { this.setAdminUserName(encodeAdminUsers()); } catch (TeacherViewException e) { addActionError(e.getMessage()); return false; } catch (Exception e) { log.error(MgrUtil.getUserMessage("error.teacherView.redirect.encoding", "error to get the admin user name list"), e); } /* * Expired Time of class */ String strExpiredTime = null; try { strExpiredTime = getClassExpiredTime(tvClass); if (strExpiredTime == null) { this.addActionError(MgrUtil.getUserMessage("error.teacherView.redirect.class.expired", new String[] { AhDateTimeUtil.getCurrentDate("HH:mm", getUserTimeZone()), getClassTime(tvClass) })); return false; } strExpiredTime = String .valueOf((getExpiredTimeMillis(strExpiredTime) - System.currentTimeMillis()) / 1000); } catch (TeacherViewException e) { this.addActionError(e.getMessage()); return false; } catch (Exception e) { log.error(MgrUtil.getUserMessage("error.teacherView.redirect.expiredTime", tvClass.getClassName()), e); } if (strExpiredTime == null) { this.addActionError(MgrUtil.getUserMessage("error.teacherView.redirect.class.expired", new String[] { AhDateTimeUtil.getCurrentDate("HH:mm", getUserTimeZone()), getClassTime(tvClass) })); return false; } else { this.setExpiredTime(strExpiredTime); } this.setRedirectAction(REDIRECT_ACTION_UPDATE); return true; } private String getClassTime(TvClass tvClass) { List<TvClassSchedule> schedule = tvClass.getItems(); if (schedule == null || schedule.size() == 0) { return "Not Available"; } TvClassSchedule lastPeriod = schedule.get(schedule.size() - 1); return lastPeriod.getStartTime() + " - " + lastPeriod.getEndTime(); } private String getRedirectRequestURL(String apAddress, boolean isSptHttps) { StringBuilder url = new StringBuilder(); if (isSptHttps) { url.append("https://"); } else { url.append("http://"); } url.append(apAddress); url.append("/cmn/teacherView.php5"); return url.toString(); } private String encodeAPStudents(TvClass tvClass) throws Exception { Map<String, Map<String, String>> apStudents; if (tvClass.getApStudents() != null) { apStudents = tvClass.getApStudents(); } else { apStudents = getAPStudents(tvClass); tvClass.setApStudents(apStudents); } String apStudentString; try { apStudentString = transformString(apStudents); } catch (Exception e) { log.error(MgrUtil.getUserMessage("error.teacherView.redirect.encode.json", tvClass.getClassName()), e); throw new TeacherViewException( MgrUtil.getUserMessage("error.teacherView.redirect.encode.json", tvClass.getClassName())); } return apStudentString; } private String encodeAdminUsers() throws Exception { StringBuilder hql = new StringBuilder(); hql.append("SELECT distinct userName FROM HmUser "); hql.append("WHERE owner = ").append(this.getDomainId()); List<?> adminUsers = QueryUtil.executeQuery(hql.toString(), MAX_ADMIN_USER); List<String> adminUserNames = new ArrayList<String>(adminUsers.size()); for (Object adminUser : adminUsers) { adminUserNames.add((String) adminUser); } String adminUserEncodeStr; try { adminUserEncodeStr = transformAdminUserStr(adminUserNames); } catch (Exception e) { log.error(MgrUtil.getUserMessage("error.teacherView.redirect.encode.adminuser.json"), e); throw new TeacherViewException( MgrUtil.getUserMessage("error.teacherView.redirect.encode.adminuser.json")); } adminUserEncodeStr = adminUserEncodeStr.replace("\\", "\\\\").replace("'", "\\'"); return adminUserEncodeStr; } private String transformAdminUserStr(List<String> adminUsers) throws Exception { JSONObject adminUsersEle = new JSONObject(); JSONArray adminUserArray = new JSONArray(); for (String adminUser : adminUsers) { JSONObject nameElement = new JSONObject(); nameElement.put("name", adminUser); adminUserArray.put(nameElement); } adminUsersEle.put("adminUserName", adminUserArray); String adminUserEncodeStr = adminUsersEle.toString().replace("\\", "\\\\").replace("'", "\\'"); return adminUserEncodeStr; } private String getClassExpiredTime(final TvClass tvClass) throws Exception { List<TvClassSchedule> schedule = tvClass.getItems(); if (schedule == null) { throw new TeacherViewException( MgrUtil.getUserMessage("error.teacherView.class.no.schedule", tvClass.getClassName())); } String expiredTime = null; boolean hasClassToday = false; Map<Long, TvClassSchedule> timeMinusMap = new HashMap<Long, TvClassSchedule>(); Long timeMinus; for (TvClassSchedule period : schedule) { if (period == null) { continue; } if (hasClassToday(period)) { hasClassToday = true; timeMinus = getExpiredTimeMillis(period.getEndTime()) - System.currentTimeMillis(); if (timeMinus < 0) { /* * the period is expired */ continue; } else { timeMinusMap.put(timeMinus, period); } } } if (timeMinusMap.size() > 0) { Long minus = System.currentTimeMillis(); for (Long timeMillis : timeMinusMap.keySet()) { if (timeMillis < minus) { minus = timeMillis; } } expiredTime = timeMinusMap.get(minus).getEndTime(); } if (!hasClassToday) { throw new TeacherViewException(MgrUtil.getUserMessage("error.teacherView.redirect.today.no")); } return expiredTime; } private boolean hasClassToday(final TvClassSchedule period) { String periodWeekday = period.getWeekdaySecString(); String currentWeekday = AhDateTimeUtil.getCurrentWeekDay(getUserTimeZone()); if (TvClassSchedule.MONDAY_TO_FRIDAY.equals(period.getWeekdaySec())) { int day = AhDateTimeUtil.getDatePart(new Date(), "w", getUserTimeZone()); if (day > Calendar.SUNDAY && day < Calendar.SATURDAY) { return true; } } else { if (periodWeekday.toLowerCase().contains(currentWeekday.toLowerCase().substring(0, 3))) { return true; } } return false; } private long getExpiredTimeMillis(String endTime) { if (endTime == null) { return 0; } Calendar calendar = Calendar.getInstance(getUserTimeZone()); calendar.setTimeInMillis(System.currentTimeMillis()); setClassTime(calendar, endTime); return calendar.getTimeInMillis(); } private void addToMap(Map<String, Map<String, String>> map, Object studentId, Object studentName, Object ap) { String key; if (ap == null) { key = NONE_AP_IP_MAC; } else { SimpleHiveAp hiveAp = CacheMgmt.getInstance().getSimpleHiveAp(ap.toString()); if (hiveAp != null) { short hiveapModel = hiveAp.getHiveApModel(); if (hiveapModel == HiveAp.HIVEAP_MODEL_BR100 || HiveAp.isCVGAppliance(hiveapModel)) { key = NONE_AP_IP_MAC; } else { key = hiveAp.getIpAddress() + "/" + hiveAp.getMacAddress(); } } else { key = NONE_AP_IP_MAC; } } if (map.containsKey(key)) { Map<String, String> values = map.get(key); values.put(studentId.toString(), studentName.toString()); } else { Map<String, String> values = new HashMap<String, String>(); values.put(studentId.toString(), studentName.toString()); map.put(key, values); } } private String transformString(Map<String, Map<String, String>> apStudents) throws Exception { JSONArray apArray = new JSONArray(); for (String key : apStudents.keySet()) { if (key == null) { continue; } JSONObject apElement = new JSONObject(); apElement.put("ap", key); JSONArray studentArray = new JSONArray(); Map<String, String> students = apStudents.get(key); for (String student : students.keySet()) { if (student == null) { continue; } JSONObject studentItem = new JSONObject(); studentItem.put("id", student); studentItem.put("name", students.get(student)); studentArray.put(studentItem); } apElement.put("students", studentArray); apArray.put(apElement); } String apArrayStr = apArray.toString(); //To fix the bug 23065 apArrayStr = apArrayStr.replace("\\", "\\\\"); apArrayStr = apArrayStr.replace("'", "\\'"); return apArrayStr; } private Map<String, Map<String, String>> getAPStudents(final TvClass tvClass) throws Exception { /* * get student - mac mapping * 1. get student from HM database */ StringBuilder sql = new StringBuilder(); int rosterType = tvClass.getRosterType(); if (rosterType == TvClass.TV_ROSTER_TYPE_STUDENT) { // student roster sql.append("SELECT studentid,studentname "); sql.append("FROM tv_student_roster "); sql.append("WHERE class_id = ").append(tvClass.getId()).append(" "); sql.append("AND owner = ").append(this.getDomainId()); } else if (rosterType == TvClass.TV_ROSTER_TYPE_COMPUTERCART) { // computer cart sql.append("SELECT stumac,stuname "); sql.append("FROM tv_computer_cart_mac "); sql.append("WHERE tv_cart_id = ").append(tvClass.getComputerCart().getId()); } else { throw new TeacherViewException( MgrUtil.getUserMessage("error.teacherView.class.no.student", tvClass.getClassName())); } List<?> studentResults = QueryUtil.executeNativeQuery(sql.toString()); if (studentResults.isEmpty()) { throw new TeacherViewException( MgrUtil.getUserMessage("error.teacherView.class.no.student", tvClass.getClassName())); } /* * get student - mac mapping * 2. get mac from memory database */ StringBuilder sqlActiveClient = new StringBuilder(); if (rosterType == TvClass.TV_ROSTER_TYPE_STUDENT) { // student roster sqlActiveClient.append("SELECT clientusername,apmac FROM ah_clientsession "); sqlActiveClient.append("WHERE lower(clientusername) IN ("); } else if (rosterType == TvClass.TV_ROSTER_TYPE_COMPUTERCART) { // computer cart sqlActiveClient.append("SELECT clientmac,apmac FROM ah_clientsession "); sqlActiveClient.append("WHERE lower(clientmac) IN ("); } int counter = 0; for (Object obj : studentResults) { Object[] columns = (Object[]) obj; if (counter++ == studentResults.size() - 1) { sqlActiveClient.append("\'").append(columns[0].toString().toLowerCase()).append("\'"); } else { sqlActiveClient.append("\'").append(columns[0].toString().toLowerCase()).append("\',"); } } sqlActiveClient.append(")"); List<?> clientResults = DBOperationUtil.executeQuery(sqlActiveClient.toString()); if (clientResults == null) { throw new TeacherViewException(MgrUtil.getUserMessage("error.teacherView.redirect.no.online.student")); } /* * get student - mac mapping * 3. build student-mac mapping */ List<Object[]> studentMac = new ArrayList<Object[]>(); for (Object obj : studentResults) { Object[] studentInfo = (Object[]) obj; Object[] studentMacInfo = new Object[3]; System.arraycopy(studentInfo, 0, studentMacInfo, 0, studentInfo.length); studentMacInfo[2] = getMacFromClientResult(studentInfo[0], clientResults); studentMac.add(studentMacInfo); } /* * put data into a map<ap, List<student>> */ Map<String, Map<String, String>> apStudents = new HashMap<String, Map<String, String>>(); for (Object obj : studentMac) { Object[] columns = (Object[]) obj; /* * find ap ip by ap mac */ addToMap(apStudents, columns[0], columns[1], columns[2]); } return apStudents; } private Object getMacFromClientResult(Object student, List<?> clientList) { Object mac = null; for (Object obj : clientList) { Object[] columns = (Object[]) obj; if (student.toString().equalsIgnoreCase(columns[0].toString())) { mac = columns[1]; break; } } return mac; } private ApConnectedStudents getDesignatedAP(TvClass tvClass) throws Exception { /* * get AP and students */ Map<String, Map<String, String>> apStudents; if (tvClass.getApStudents() == null) { apStudents = getAPStudents(tvClass); tvClass.setApStudents(apStudents); } else { apStudents = tvClass.getApStudents(); } /* * sort APs by student count */ List<ApConnectedStudents> apList = new ArrayList<ApConnectedStudents>(); for (String key : apStudents.keySet()) { String[] ipAndMAC = key.split("/"); if (ipAndMAC.length != 2) { throw new TeacherViewException( MgrUtil.getUserMessage("error.teacherView.redirect.ap.disconnected")); } String ipAddress = ipAndMAC[0]; String macAddress = ipAndMAC[1]; ClassAP classAP = getClassAPStatus(macAddress); boolean isSptHttps = classAP == null ? false : classAP.isSptHttps(); ApConnectedStudents counter = new ApConnectedStudents(); counter.setApAddress(ipAddress); counter.setMacAddress(macAddress); counter.setSptHttps(isSptHttps); if (apStudents.get(key) != null) { counter.setStudentCount(apStudents.get(key).size()); } else { counter.setStudentCount(0); } apList.add(counter); } Collections.sort(apList); int maxCounter = 0; // an counter of AP which hosts 2 or more classes int disconnectCounter = 0; // an counter of AP which is disconnected int noApCounter = 0; // an counter of AP whose address is "0.0.0.0" /* * test each AP to find a designated one */ for (ApConnectedStudents sc : apList) { String apAddress = sc.getApAddress(); String macAddress = sc.getMacAddress(); if ("0.0.0.0".equals(apAddress)) { noApCounter++; } else if (getViewedCount(apAddress) >= MAX_VIEW_COUNT) { maxCounter++; } else { ClassAP classAP = getClassAPStatus(macAddress); boolean isAPConnected = classAP == null ? false : classAP.isConnected(); if (isAPConnected) { return sc; } else { disconnectCounter++; } } } /* * no designated AP is found, give reasons */ if (noApCounter == apList.size()) { throw new TeacherViewException(MgrUtil.getUserMessage("error.teacherView.redirect.no.online.student")); } if (maxCounter == apList.size()) { throw new TeacherViewException(MgrUtil.getUserMessage("error.teacherView.redirect.exceed.max", String.valueOf(MAX_VIEW_COUNT))); } if (disconnectCounter == apList.size()) { throw new TeacherViewException(MgrUtil.getUserMessage("error.teacherView.redirect.ap.disconnected")); } return null; } private long getViewedCount(String apAddress) { String where = "apIpAddress = :s1 AND owner.id = :s2"; Object[] values = new Object[2]; values[0] = apAddress; values[1] = this.getDomainId(); return QueryUtil.findRowCount(ViewingClass.class, new FilterParams(where, values)); } private void addViewingClass(final TvClass tvClass, ApConnectedStudents designatedAP) { ViewingClass viewingClass = new ViewingClass(); viewingClass.setClassName(tvClass.getClassName()); viewingClass.setApIpAddress(designatedAP.getApAddress()); viewingClass.setApMacAddress(designatedAP.getMacAddress()); viewingClass.setSelectedTime(System.currentTimeMillis()); try { viewingClass.setEndTime(getExpiredTimeMillis(getClassExpiredTime(tvClass))); } catch (Exception e) { log.error(MgrUtil.getUserMessage("error.teacherView.class.endTime", tvClass.getClassName()), e); } viewingClass.setOwner(getDomain()); try { QueryUtil.createBo(viewingClass); } catch (Exception e) { log.error(MgrUtil.getUserMessage("error.teacherView.class.record", tvClass.getClassName()), e); } } private boolean downloadTeacherViewSettings(String apMacAddress) { List<String> clis = new ArrayList<String>(); /* * CAS */ clis.addAll(getCASCLIs()); /* * resource map */ clis.addAll(getResourceMapCLIs()); /* * save configuration */ clis.add("save config\n"); HiveAp hiveAp = QueryUtil.findBoByAttribute(HiveAp.class, "macAddress", apMacAddress, this.getDomainId()); /* * send event to AP */ BeCliEvent cliEvent = new BeCliEvent(); cliEvent.setAp(hiveAp); String[] cliArray = new String[clis.size()]; for (int i = 0; i < clis.size(); i++) { cliArray[i] = clis.get(i); } cliEvent.setClis(cliArray); cliEvent.setSequenceNum(HmBeCommunicationUtil.getSequenceNumber()); try { cliEvent.buildPacket(); } catch (BeCommunicationEncodeException e) { log.error(MgrUtil.getUserMessage("error.teacherView.redirect.cli.build"), e); return false; } int serialNum = HmBeCommunicationUtil.sendRequest(cliEvent); return serialNum != BeCommunicationConstant.SERIALNUM_SENDREQUESTFAILED; } private String[] getCASServer() { /* * like "https://myhive-auth.aerohive.com:443/cas" */ String casAddress = NmsUtil.getAuthServiceURL(); if (casAddress == null) { log.error(MgrUtil.getUserMessage("error.teacherView.redirect.no.cas")); return null; } String[] casSettings = new String[2]; casSettings[0] = casAddress.substring(8, casAddress.indexOf(":", 8)); casSettings[1] = casAddress.substring(casAddress.indexOf(":", casAddress.indexOf(casSettings[0])) + 1, casAddress.indexOf("/cas")); return casSettings; } private List<String> getResourceMapCLIs() { StringBuilder cli = new StringBuilder(); List<String> clis = new ArrayList<String>(); clis.add("no teacher-view resource-map\n"); List<TvResourceMap> maps = QueryUtil.executeQuery(TvResourceMap.class, null, null, this.getDomainId()); for (TvResourceMap map : maps) { cli.append("teacher-view resource-map name ").append("\"" + map.getResource() + "\"").append(" ip ") .append(map.getAlias()).append(" port ").append(map.getPort()).append("\n"); clis.add(cli.toString()); cli.delete(0, cli.length()); } return clis; } private List<String> getCASCLIs() { List<String> clis = new ArrayList<String>(); /* * CLI for CAS settings */ String[] casServer = getCASServer(); if (casServer == null) { return clis; } /* * cas address */ StringBuilder cli = new StringBuilder(); cli.append("hiveui cas client server name ").append(casServer[0]).append("\n"); clis.add(cli.toString()); cli.delete(0, cli.length()); /* * port */ cli.append("hiveui cas client server port ").append(casServer[1]).append("\n"); clis.add(cli.toString()); cli.delete(0, cli.length()); return clis; } private class ApConnectedStudents implements Comparable<Object> { private String apAddress; private String macAddress; private int studentCount; private boolean sptHttps = false; public ApConnectedStudents() { } /** * getter of apAddress * @return the apAddress */ public String getApAddress() { return apAddress; } /** * setter of apAddress * @param apAddress the apAddress to set */ public void setApAddress(String apAddress) { this.apAddress = apAddress; } /** * getter of studentCount * @return the studentCount */ public int getStudentCount() { return studentCount; } /** * setter of studentCount * @param studentCount the studentCount to set */ public void setStudentCount(int studentCount) { this.studentCount = studentCount; } public String getMacAddress() { return macAddress; } public void setMacAddress(String macAddress) { this.macAddress = macAddress; } public boolean isSptHttps() { return sptHttps; } public void setSptHttps(boolean sptHttps) { this.sptHttps = sptHttps; } @Override public int compareTo(Object obj) { if (obj == null) { return -1; } if (!(obj instanceof ApConnectedStudents)) { return -1; } ApConnectedStudents sc = (ApConnectedStudents) obj; if (sc.getStudentCount() > this.getStudentCount()) { return 1; } else if (sc.getStudentCount() == this.getStudentCount()) { return 0; } else { return -1; } } } private Long classId; /** * getter of classId * @return the classId */ public Long getClassId() { return classId; } /** * setter of classId * @param classId the classId to set */ public void setClassId(Long classId) { this.classId = classId; } private String subject; /** * getter of subject * @return the subject */ public String getSubject() { return subject; } /** * setter of subject * @param subject the subject to set */ public void setSubject(String subject) { this.subject = subject; } private String teacher; /** * getter of teacher * @return the teacher */ public String getTeacher() { return teacher; } /** * setter of teacher * @param teacher the teacher to set */ public void setTeacher(String teacher) { this.teacher = teacher; } private String className; /** * getter of className * @return the className */ public String getClassName() { return className; } /** * setter of className * @param className the className to set */ public void setClassName(String className) { this.className = className; } private int rosterType; /** * getter of rosterType * @return the rosterType */ public int getRosterType() { return rosterType; } /** * setter of rosterType * @param rosterType the rosterType to set */ public void setRosterType(int rosterType) { this.rosterType = rosterType; } private String apStudents; /** * getter of apStudents * @return the apStudents */ public String getApStudents() { return apStudents; } /** * setter of apStudents * @param apStudents the apStudents to set */ public void setApStudents(String apStudents) { this.apStudents = apStudents; } private String expiredTime; /** * getter of expiredTime * @return the expiredTime */ public String getExpiredTime() { return expiredTime; } /** * setter of expiredTime * @param expiredTime the expiredTime to set */ public void setExpiredTime(String expiredTime) { this.expiredTime = expiredTime; } private String redirectAction; private String redirectURL; /** * getter of redirectURL * @return the redirectURL */ public String getRedirectURL() { return redirectURL; } /** * setter of redirectURL * @param redirectURL the redirectURL to set */ public void setRedirectURL(String redirectURL) { this.redirectURL = redirectURL; } /** * getter of redirectAction * @return the redirectAction */ public String getRedirectAction() { return redirectAction; } /** * setter of redirectAction * @param redirectAction the redirectAction to set */ public void setRedirectAction(String redirectAction) { this.redirectAction = redirectAction; } public String getHMTVURL() { StringBuilder url = new StringBuilder(); String casClient = NmsUtil.getCasClient(); if (null != casClient) { url.append(casClient); if (casClient.endsWith("/")) { url.append("hm/teacherView.action"); } else { url.append("/hm/teacherView.action"); } } else { url.append("https://"); url.append(HmBeOsUtil.getHiveManagerIPAddr()); url.append("/hm/teacherView.action"); } return url.toString(); } @Override public Collection<HmBo> load(HmBo bo) { if (bo instanceof TvClass) { TvClass tvClass = (TvClass) bo; if (tvClass.getItems() != null) { tvClass.getItems().size(); } } if (bo instanceof HmUser) { HmUser user = (HmUser) bo; HmUserGroup group = user.getUserGroup(); if (group.getFeaturePermissions() != null) { group.getFeaturePermissions().size(); } } return null; } private String proxyServer; public void setProxyServer(String proxyServer) { this.proxyServer = proxyServer; } public String getProxyServer() { return proxyServer; } /** * Convert Proxy server information to JSON * @author huihe * @param proxyIP, proxyPort * @return * @throws Exception */ private String encodeProxyServer(String proxyIP, int proxyPort, String autoProxyFile) throws Exception { JSONObject proxyElement = new JSONObject(); JSONObject subElement = new JSONObject(); subElement.put("ip", proxyIP); subElement.put("port", proxyPort); subElement.put("autoProxyFile", autoProxyFile); proxyElement.put("proxyServer", subElement); return proxyElement.toString(); } //Case Sensitive with LDAP private short caseInsensitive; public short getCaseInsensitive() { return caseInsensitive; } public void setCaseInsensitive(short caseInsensitive) { this.caseInsensitive = caseInsensitive; } //This admin user name will send to Device, to help them exclude the admin name from the student list. private String adminUserName; public String getAdminUserName() { return adminUserName; } public void setAdminUserName(String adminUserName) { this.adminUserName = adminUserName; } private class ClassAP { private boolean isConnected = false; private boolean isSptHttps = false; public boolean isConnected() { return isConnected; } public void setConnected(boolean isConnected) { this.isConnected = isConnected; } public boolean isSptHttps() { return isSptHttps; } public void setSptHttps(boolean isSptHttps) { this.isSptHttps = isSptHttps; } } }