%@page import="org.unicode.cldr.web.DataPage.DataRow.CandidateItem"%> <%@ page language="java" contentType="text/html; charset=UTF-8" import='java.sql.*,org.unicode.cldr.util.*,java.util.*' pageEncoding="UTF-8"%><%@ include file="/WEB-INF/jspf/session.jspf" %> <% if(cs.user.userlevel > UserRegistry.ADMIN) { response.sendRedirect(surveyUrl); return; } boolean reallymove = request.getParameter("reallymove")!=null; %>
<% Map<% } %> Moved <%= moveDataTotal %> data items, <%= moveVoteTotal %> votes, and deleted <%= nukeTotal %> bad (unreferenced) data items.> toFix = new TreeMap >(); // fix votes first. if(thisVotes!=null) { for(int xpath : thisVotes) { String badString = cs.sm.xpt.getById(xpath); int base_xpath = fixXpath(xpath, badString, cs.sm); // todo: optimize * Map possData[] = cs.sm.dbUtils.sqlQueryArrayAssoc(conn, "select cldr_data.id,cldr_data.base_xpath,cldr_data.xpath,cldr_data.value,cldr_data.origxpath from cldr_data where cldr_data.locale=? and ( cldr_data.base_xpath=? or cldr_data.base_xpath=?)", l, xpath, base_xpath); Map theseVotes[] = cs.sm.dbUtils.sqlQueryArrayAssoc(conn, "select cldr_vet.submitter,cldr_vet.id,cldr_vet.vote_xpath,cldr_vet.modtime,cldr_vet.base_xpath from cldr_vet where cldr_vet.locale=? and cldr_vet.base_xpath=? or cldr_vet.base_xpath=?", l, xpath, base_xpath); if(theseVotes==null||theseVotes.length==0) { throw new InternalError("Couldn't load votes for " + l + " : " + xpath); } Set goodSubmit = new TreeSet (); Map badSubmit = new HashMap (); Map valToData = new HashMap (); for(Map d : possData) { int aBase = (Integer)d.get("base_xpath"); if(aBase!=base_xpath) continue; // BAD data, skip int aXpath = (Integer)d.get("xpath"); String aVal = (String)d.get("value"); valToData.put(aVal,aXpath); } Map > submitterToGoodVote = new TreeMap >(); // collect 'good' votes for(Map m : theseVotes) { int aVoteBaseXpath = (Integer)m.get("base_xpath"); int aSubmitter = (Integer)m.get("submitter"); if(aVoteBaseXpath == base_xpath) { // already fixed submitterToGoodVote.put(aSubmitter,m); } } for(Map m : theseVotes) { int aId = (Integer)m.get("id"); int aVoteXpath = (Integer)m.get("vote_xpath"); int aFixVoteXpath = fixXpath(aVoteXpath); int aSubmitter = (Integer)m.get("submitter"); int aVoteBaseXpath = (Integer)m.get("base_xpath"); if(aVoteBaseXpath == base_xpath) { // already collected continue; } int nukeVoteId = -1; // vote to remove? int moveTo = XPathTable.NO_XPATH; // target XPATH of vote move Map goodm = submitterToGoodVote.get(aSubmitter); // row of VOTE row for this summitter, for good data Map dataToMove = null; // map of data row that must move if(goodm != null) { Timestamp badTimestamp = (Timestamp)m.get("modtime"); Timestamp goodTimestamp = (Timestamp)goodm.get("modtime"); int goodId = (Integer)goodm.get("id"); if(goodTimestamp.after(badTimestamp)) { nukeVoteId = aId; } else { nukeVoteId = goodId; addTo(toFix, base_xpath, "Note: Newer BAD vote by " + aSubmitter + " - nuke GOOD vote " + goodId); } } if(nukeVoteId==aId) { addTo(toFix, base_xpath, "Note: Newer vote by " + aSubmitter + " - nuke bad vote " + aId); goodSubmit.add(aSubmitter); // don't analyze further. } else if(aVoteXpath==XPathTable.NO_XPATH) { addTo(toFix, base_xpath, "GOOD abstention by " + aSubmitter + " " + xp(xpath) + " for " + xp(aVoteXpath) ); goodSubmit.add(aSubmitter); } else { // first, look in the good data for(Map d : possData) { int aBase = (Integer)d.get("base_xpath"); int aXpath = (Integer)d.get("xpath"); String aVal = (String)d.get("value"); Integer gooDataXpath = null; if(aVal!=null) gooDataXpath = valToData.get(aVal); if(aBase==base_xpath) { // GOOD path // good if(aXpath==aVoteXpath) { // addTo(toFix, base_xpath, "BAD vote by " + aSubmitter + " " + xp(xpath) + " for GOOD DATA " + xp(aVoteXpath) ); moveTo = aVoteXpath; // Just need to move the base path, no need to change values. } else if(aXpath==aFixVoteXpath) { addTo(toFix, base_xpath, "BAD vote by " + aSubmitter + " " + xp(xpath) + " for GOOD fixable (a) " + xp(aFixVoteXpath) ); moveTo = aFixVoteXpath; // move base and vote xpath, all OK } else { //addTo(toFix, base_xpath, "(nonex (a) " + xp(aBase)); } } else if(aXpath==aVoteXpath) { if(gooDataXpath!=null) { moveTo=gooDataXpath; addTo(toFix, base_xpath, "BAD vote by " + aSubmitter + " " + xp(xpath) + " for " + xp(aVoteXpath) + " REDIR
" + xp(moveTo) ); } else { // base needs to move, and data needs to move.. dataToMove=d; addTo(toFix, base_xpath, "BAD vote by " + aSubmitter + " " + xp(xpath) + " for found but BAD data " + xp(aVoteXpath) + " - NEED DATA MOVE"); } goodSubmit.add(aSubmitter); } else if(aXpath==aFixVoteXpath) { if(true) throw new InternalError("Doesn't occur. not imp."); if(gooDataXpath!=null) { moveTo=gooDataXpath; addTo(toFix, base_xpath, "BAD vote by " + aSubmitter + " " + xp(xpath) + " for fixable " + xp(aVoteXpath) + " REDIR
" + xp(moveTo) ); } else { addTo(toFix, base_xpath, "BAD vote by " + aSubmitter + " " + xp(xpath) + " for fixable " + xp(aFixVoteXpath) + " - NEED DATA MOVE"); // Data has a bad base path, but a good final path. // Data needs to move. dataToMove=d; moveTo = aFixVoteXpath; } } else { //addTo(toFix, base_xpath, "(nonex (b) " + xp(aBase)); } } if(moveTo==XPathTable.NO_XPATH) { badSubmit.put(aSubmitter,aFixVoteXpath); } else { goodSubmit.add(aSubmitter); } } // Now, do the moves if(reallymove) { if(dataToMove != null) { int adBase = (Integer)dataToMove.get("base_xpath"); int adXpath = (Integer)dataToMove.get("xpath"); int adId = (Integer)dataToMove.get("id"); int adoXpath = (Integer)dataToMove.get("origxpath"); String adVal = (String)dataToMove.get("value"); if(moveTo==-1) { // we don't know the right vxpath. Make up something. moveTo=fixXpath(adXpath); valToData.put(adVal,moveTo); // for other votes, don't move the data again! moveData.setInt(1,moveTo); moveData.setInt(2,fixXpath(adoXpath)); moveData.setInt(3,base_xpath); moveData.setInt(4,adId); int rw = moveData.executeUpdate(); moveDataTotal+=rw; addTo(toFix, base_xpath, "Moved data in id " + adId + " == " + rw); } else { throw new InternalError("not imp."); } } if(nukeVoteId>=0) { nukeVote.setInt(1, nukeVoteId); int rw = nukeVote.executeUpdate(); addTo(toFix, base_xpath, "Deleted vote id " + nukeVoteId+ " of " + aSubmitter + " == " + rw); moveVoteTotal+=rw; } // now, move the vote //moveVote = cs.sm.dbUtils.prepareForwardReadOnly(conn, "update cldr_vet set base_xpath=?,vote_xpath=? where id=?"); { moveVote.setInt(1, base_xpath); // rebase moveVote.setInt(2, moveTo); moveVote.setInt(3, aId); int rw = moveVote.executeUpdate(); addTo(toFix, base_xpath, "Moved vote in id " + aId+ " of " + xp(xpath) + " == " + rw); moveVoteTotal+=rw; } } } for(int good : goodSubmit) { badSubmit.remove(good); } for(Map.Entrybad : badSubmit.entrySet()) { addTo(toFix, base_xpath, "Unfound vote by " + bad.getKey() + " " + xp(xpath) + " for NO DATA @ "+ xp(bad.getValue())); } } } if(thisData!=null) for(int xpath : thisData) { String badString = cs.sm.xpt.getById(xpath); int base_xpath = fixXpath(xpath, badString, cs.sm); Map badData[] = cs.sm.dbUtils.sqlQueryArrayAssoc(conn, "select * from cldr_data where cldr_data.locale=? and ( cldr_data.base_xpath=? or cldr_data.base_xpath=?)", l, xpath, base_xpath); if(badData==null || badData.length==0) { addTo(toFix, base_xpath, "data: " + badString + " #"+xpath + " - query failed" ); continue; } for(Map m : badData) { int aXpath = (Integer)m.get("xpath"); int aId = (Integer)m.get("id"); int aOxpath = (Integer)m.get("origxpath"); int aBaseXpath = (Integer)m.get("base_xpath"); if(aBaseXpath==base_xpath) { addTo(toFix, base_xpath, "EXIST GOOD: " + xp(aOxpath)); } else { int fixOpath = fixXpath(aOxpath,null,cs.sm); int fixXpath = fixXpath(aXpath,null,cs.sm); addTo(toFix, base_xpath, "EXIST BAD : xp:"+xp(aXpath)+">>"+xp(fixXpath)+",
ox:"+xp(aOxpath)+">>"+xp(fixOpath)); } } if(reallymove) { nukeData.setString(1,l.toString()); nukeData.setInt(2,xpath); int rw = nukeData.executeUpdate(); addTo(toFix, base_xpath, "Removed " + rw + " data rows from " + xp(xpath)); nukeTotal+=rw; } } for(Map.Entry> e : toFix.entrySet()) { %>
<%= cs.sm.xpt.getPrettyPath(e.getKey()) %>
<%= cs.sm.xpt.getById(e.getKey()) %> - #<%= e.getKey() %><% for(String s : e.getValue()) { %>
<% } %>- <%= s %>
<% } %>