001    /*
002     * $RCSfile$
003     * $Revision: 817 $ $Date: 2009-04-21 13:22:33 +0200 (Di, 21 Apr 2009) $
004     *
005     * This file is part of ***  M y C o R e  ***
006     * See http://www.mycore.de/ for details.
007     *
008     * This program is free software; you can use it, redistribute it
009     * and / or modify it under the terms of the GNU General Public License
010     * (GPL) as published by the Free Software Foundation; either version 2
011     * of the License or (at your option) any later version.
012     *
013     * This program is distributed in the hope that it will be useful, but
014     * WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program, in a file called gpl.txt or license.txt.
020     * If not, write to the Free Software Foundation Inc.,
021     * 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
022     */
023    
024    package org.mycore.frontend.redundancy.servlets;
025    
026    import java.io.File;
027    import java.io.FileOutputStream;
028    import java.io.IOException;
029    
030    import javax.servlet.ServletException;
031    
032    import org.apache.log4j.Logger;
033    import org.jdom.Document;
034    import org.jdom.Element;
035    import org.jdom.JDOMException;
036    import org.jdom.filter.ElementFilter;
037    import org.jdom.filter.Filter;
038    import org.jdom.input.SAXBuilder;
039    import org.jdom.output.Format;
040    import org.jdom.output.XMLOutputter;
041    import org.mycore.common.MCRConfiguration;
042    import org.mycore.common.MCRSession;
043    import org.mycore.common.MCRSessionMgr;
044    import org.mycore.frontend.redundancy.MCRRedundancyUtil;
045    import org.mycore.frontend.servlets.MCRServlet;
046    import org.mycore.frontend.servlets.MCRServletJob;
047    import org.mycore.user.MCRUserMgr;
048    
049    /**
050     * @author Matthias Eichner
051     */
052    public class MCRRedundancyMapServlet extends MCRServlet {
053    
054        private static final long serialVersionUID = 1L;
055    
056        private static Logger LOGGER = Logger.getLogger(MCRRedundancyMapServlet.class);;
057    
058        private int nonDoubletCount;
059    
060        private int doubletCount;
061    
062        private int notWorkedCount;
063    
064        private int errorCount;
065    
066        public void init() throws ServletException {
067            super.init();
068        }
069    
070        public synchronized void doGetPost(MCRServletJob job) throws JDOMException, IOException {
071            // init params
072            MCRSession session = MCRSessionMgr.getCurrentSession();
073            String redMap = job.getRequest().getParameter("redunMap");
074            String filename = redMap.substring(redMap.indexOf("/") + 1);
075            String redMapPath = MCRRedundancyUtil.DIR + filename;
076    
077            // get redun list
078            SAXBuilder builder = new SAXBuilder();
079            Document redunMap = builder.build(redMapPath);
080            LOGGER.debug("read duplicate list from file=" + redMapPath);
081    
082            // get duplicate entry
083            String redunObject = job.getRequest().getParameter("redunObject").trim();
084    
085            String xPathExpr = "//redundancyObjects[@id=" + redunObject + "]";
086            org.jdom.xpath.XPath xp = org.jdom.xpath.XPath.newInstance(xPathExpr);
087            Element redundancyObjectsElement = (Element) xp.selectSingleNode(redunMap);
088    
089            initCounter(job, redundancyObjectsElement);
090            // check if some inputs are invalid
091            int errorId = validateInput();
092            if (errorId != -1) {
093                forwardExceptionToClient(job, errorId);
094                return;
095            }
096    
097            // update the xml structure
098            updateXML(job, session, redundancyObjectsElement);
099    
100            // save redun list
101            Format format = Format.getPrettyFormat();
102            FileOutputStream fos = new FileOutputStream(new File(redMapPath));
103            XMLOutputter xo = new XMLOutputter(format);
104            xo.output(redunMap, fos);
105            fos.flush();
106            fos.close();
107            LOGGER.debug("saved changed  dublicate list to file=" + redMapPath);
108    
109            int maxObjects = redunMap.getRootElement().getContent(new ElementFilter()).size();
110            // send to client
111            forwardToClient(job, maxObjects);
112        }
113    
114        /**
115         * Inits counters for the group.
116         */
117        private void initCounter(MCRServletJob job, Element redObjectsElement) {
118            nonDoubletCount = 0;
119            doubletCount = 0;
120            notWorkedCount = 0;
121            errorCount = 0;
122            Filter elementAndObjectFilter = new ElementFilter("object");
123            for (int i = 1; i <= redObjectsElement.getContent(elementAndObjectFilter).size(); i++) {
124                String status = job.getRequest().getParameter("selection_" + i);
125                if (status == null || status.equals("")) {
126                    notWorkedCount++;
127                } else if (status.equals("doublet")) {
128                    doubletCount++;
129                } else if (status.equals("nonDoublet")) {
130                    nonDoubletCount++;
131                } else if (status.equals("error")) {
132                    errorCount++;
133                }
134            }
135        }
136    
137        /**
138         * Validates the input of the given combobox values. 
139         * @return the error code
140         */
141        private int validateInput() {
142            if (nonDoubletCount > 1 && doubletCount > 0)
143                return 1;
144            if (doubletCount > 0 && nonDoubletCount == 0)
145                return 2;
146            return -1;
147        }
148    
149        /**
150         * Updates the redundancy-{type}.xml files with the given combobox values.
151         */
152        private void updateXML(MCRServletJob job, MCRSession session, Element redObjectsElement) {
153            boolean closed = true;
154            int count = 1;
155            Filter elementAndObjectFilter = new ElementFilter("object");
156            for (Object o : redObjectsElement.getContent(elementAndObjectFilter)) {
157                Element objectElement = (Element) o;
158                String objectId = "object-id_" + count;
159                String selection = job.getRequest().getParameter("selection_" + count);
160    
161                if (selection == null || selection.equals("")) {
162                    closed = false;
163                }
164                // edit doublet entry
165                objectElement.setAttribute("status", selection);
166                
167                count++;
168            }
169            // add some general infos to the redObjectsElements
170            String user = session.getCurrentUserID();
171            String userRealName = MCRUserMgr.instance().retrieveUser(user).getUserContact().getFirstName() + " "
172                    + MCRUserMgr.instance().retrieveUser(user).getUserContact().getLastName();
173            long time = System.currentTimeMillis();
174            java.util.Date date = new java.util.Date(time);
175            redObjectsElement.setAttribute("user", user);
176            redObjectsElement.setAttribute("userRealName", userRealName);
177            redObjectsElement.setAttribute("time", Long.toString(time));
178            redObjectsElement.setAttribute("timePretty", date.toGMTString());
179            if (closed)
180                redObjectsElement.setAttribute("status", "closed");
181            else
182                redObjectsElement.removeAttribute("status");
183    
184            if (errorCount > 0)
185                redObjectsElement.setAttribute("hasErrors", "true");
186            else
187                redObjectsElement.removeAttribute("hasErrors");
188        }
189    
190        private synchronized void forwardToClient(MCRServletJob job, int maxObjects) throws IOException {
191            String redunObject = job.getRequest().getParameter("redunObject").trim();
192            String returnURL = getBaseURL(job);
193            int nextNum = Integer.valueOf(redunObject) + 1;
194            if (!(nextNum > maxObjects)) {
195                // show next Element
196                returnURL += "&XSL.redunObject=" + (Integer.valueOf(redunObject) + 1);
197            }
198            job.getResponse().sendRedirect(returnURL);
199        }
200    
201        private synchronized void forwardExceptionToClient(MCRServletJob job, int id) throws IOException {
202            String redunObject = job.getRequest().getParameter("redunObject").trim();
203            String returnURL = getBaseURL(job);
204            returnURL += "&XSL.redunObject=" + redunObject + "&XSL.exceptionId=" + id;
205            job.getResponse().sendRedirect(returnURL);
206        }
207    
208        private String getBaseURL(MCRServletJob job) {
209            String redunMapURL = job.getRequest().getParameter("redunMap");
210            String redunModeValue = job.getRequest().getParameter("redunMode");
211            String redunMode = "XSL.redunMode.SESSION=" + redunModeValue;
212            return MCRConfiguration.instance().getString("MCR.baseurl") + redunMapURL + "?" + redunMode;
213        }
214    }