001    /*
002     * 
003     * $Revision: 15202 $ $Date: 2009-05-15 17:00:44 +0200 (Fri, 15 May 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.servlets;
025    
026    import java.io.InputStream;
027    import java.net.URL;
028    import java.util.ArrayList;
029    import java.util.List;
030    
031    import org.apache.log4j.Logger;
032    import org.jdom.Document;
033    import org.jdom.Element;
034    import org.mycore.common.MCRConfiguration;
035    import org.mycore.common.MCRConfigurationException;
036    import org.mycore.common.MCRException;
037    import org.mycore.common.MCRSession;
038    import org.mycore.common.MCRSessionMgr;
039    import org.mycore.common.MCRUtils;
040    import org.mycore.datamodel.metadata.MCRObjectID;
041    import org.mycore.frontend.editor.MCREditorSubmission;
042    import org.mycore.frontend.editor.MCRRequestParameters;
043    
044    /**
045     * This class is a special to work wit the interactive input from the dialog of
046     * ACL (Access Control List) changes.
047     * 
048     * @author Jens Kupferschmidt
049     * @author Thomas Scheffler (yagee)
050     * @version $Revision: 15202 $ $Date: 2009-05-15 17:00:44 +0200 (Fri, 15 May 2009) $
051     */
052    abstract public class MCRCheckACLBase extends MCRCheckBase {
053    
054        private static final long serialVersionUID = 1L;
055        private static Logger LOGGER = Logger.getLogger(MCRCheckACLBase.class);
056    
057        /**
058         * This method overrides doGetPost of MCRServlet and handels all actions
059         * against the ACL data.
060         * 
061         * @param job
062         *            the MCRServlet job instance
063         */
064        public void doGetPost(MCRServletJob job) throws Exception {
065            // read the XML data
066            MCREditorSubmission sub = (MCREditorSubmission) (job.getRequest().getAttribute("MCREditorSubmission"));
067            Document indoc = sub.getXML();
068    
069            // read the parameter
070            MCRRequestParameters parms;
071    
072            if (sub == null) {
073                parms = new MCRRequestParameters(job.getRequest());
074            } else {
075                parms = sub.getParameters();
076            }
077    
078            String oldmcrid = parms.getParameter("mcrid");
079            String oldtype = parms.getParameter("type");
080            String oldstep = parms.getParameter("step");
081            LOGGER.debug("XSL.target.param.0 = " + oldmcrid);
082            LOGGER.debug("XSL.target.param.1 = " + oldtype);
083            LOGGER.debug("XSL.target.param.2 = " + oldstep);
084    
085            // get the MCRSession object for the current thread from the session
086            // manager.
087            MCRSession mcrSession = MCRSessionMgr.getCurrentSession();
088            String lang = mcrSession.getCurrentLanguage();
089            LOGGER.info("LANG = " + lang);
090    
091            // prepare the MCRObjectID's for the Metadata
092            String mmcrid = oldmcrid;
093            MCRObjectID ID = new MCRObjectID(mmcrid);
094    
095            if (!ID.getTypeId().equals(oldtype)) {
096                ID = new MCRObjectID(oldmcrid);
097            }
098    
099            // check access
100            if (!checkAccess(ID)) {
101                job.getResponse().sendRedirect(getBaseURL() + usererrorpage);
102                return;
103            }
104    
105            // create a service object and prepare it
106            Element outelm = prepareService((Document) indoc.clone(), ID, job, lang);
107    
108            // Save the prepared metadata object
109            boolean okay = storeService(outelm, job, ID);
110    
111            // call the getNextURL and sendMail methods
112            String url = getNextURL(ID, okay);
113            sendMail(ID);
114    
115            job.getResponse().sendRedirect(job.getResponse().encodeRedirectURL(getBaseURL() + url));
116        }
117    
118        /**
119         * The method store the incoming service data from the ACL editor to the
120         * workflow.
121         * 
122         * @param outelm
123         *            the service subelement of an MCRObject
124         * @param job
125         *            the MCRServletJob instance
126         * @param ID
127         *            the MCRObjectID
128         */
129        abstract public boolean storeService(Element outelm, MCRServletJob job, MCRObjectID ID);
130    
131        /**
132         * The method read the incoming servacls JDOM tree in a MCRService and
133         * prepare this by the following rules. After them it return a JDOM Element
134         * of servacls as clone of the prepared data.
135         * 
136         * @param jdom_in
137         *            the JDOM tree from the editor
138         * @param ID
139         *            the MCRObjectID of the MCRObject
140         * @param job
141         *            the MCRServletJob data
142         * @param lang
143         *            the current language
144         */
145        protected Element prepareService(Document jdom_in, MCRObjectID ID, MCRServletJob job, String lang) throws Exception {
146            Element elm_out = null;
147            ArrayList<String> logtext = new ArrayList<String>();
148            Element root = jdom_in.getRootElement();
149            if (root != null) {
150                Element servacls = root.getChild("servacls");
151                if (servacls != null) {
152                    @SuppressWarnings("unchecked")
153                    List<Element> servacllist = servacls.getChildren("servacl");
154                    if (servacllist.size() != 0) {
155                        for (int i = 0; i < servacllist.size(); i++) {
156                            Element servacl = servacllist.get(i);
157                            Element outcond = servacl.getChild("condition");
158                            if (outcond != null) {
159                                Element outbool = outcond.getChild("boolean");
160                                if (outbool != null) {
161                                    @SuppressWarnings("unchecked")
162                                    List<Element> inbool = outbool.getChildren("boolean");
163                                    String outoper = outbool.getAttributeValue("operator");
164                                    if (inbool.size() != 0 && outoper != null && !outoper.equals("true")) {
165                                        for (int j = 0; j < inbool.size(); j++) {
166                                            @SuppressWarnings("unchecked")
167                                            List<Element> incondlist = inbool.get(j).getChildren("condition");
168                                            int k = incondlist.size();
169                                            if (k != 0) {
170                                                for (int l = 0; l < k; l++) {
171                                                    Element incond = incondlist.get(l);
172                                                    String condvalue = incond.getAttributeValue("value");
173                                                    if (condvalue == null || (condvalue = condvalue.trim()).length() == 0) {
174                                                        ((Element) inbool.get(j)).removeContent(incond);
175                                                        k--;
176                                                        l--;
177                                                        continue;
178                                                    }
179                                                    String condfield = incond.getAttributeValue("field");
180                                                    if (condfield.equals("user")) {
181                                                        if (!UM.existUser(condvalue)) {
182                                                            inbool.get(j).removeContent(incond);
183                                                            k--;
184                                                            l--;
185                                                            continue;
186                                                        }
187                                                    }
188                                                    if (condfield.equals("group")) {
189                                                        if (!UM.existGroup(condvalue)) {
190                                                            inbool.get(j).removeContent(incond);
191                                                            k--;
192                                                            l--;
193                                                            continue;
194                                                        }
195                                                    }
196                                                    if (condfield.equals("date")) {
197                                                        if (MCRUtils.covertDateToISO(condvalue) == null) {
198                                                            inbool.get(j).removeContent(incond);
199                                                            k--;
200                                                            l--;
201                                                            continue;
202                                                        }
203                                                    }
204                                                }
205                                                if (k == 1) {
206                                                    String inbooloper = inbool.get(j).getAttributeValue("operator");
207                                                    if ((inbooloper != null) && inbooloper.toLowerCase().equals("and")) {
208                                                        Element newtrue = new Element("boolean");
209                                                        newtrue.setAttribute("operator", "true");
210                                                        inbool.get(j).addContent(newtrue);
211                                                    } else {
212                                                        Element newfalse = new Element("boolean");
213                                                        newfalse.setAttribute("operator", "false");
214                                                        inbool.get(j).addContent(newfalse);
215                                                    }
216                                                }
217                                            } else {
218                                                logtext.add("Can't find an inner condition element.");
219                                            }
220                                        }
221                                    } else {
222                                        if (outoper == null || !outoper.equals("true")) {
223                                            logtext.add("Wrong structure of MyCoRe ACL JDOM in boolean.");
224                                        }
225                                    }
226                                } else {
227                                    outbool = new Element("boolean");
228                                    outbool.setAttribute("operator", "true");
229                                    outcond.addContent(outbool);
230                                }
231                            } else {
232                                logtext.add("Can't find a condition element.");
233                            }
234                        }
235                    } else {
236                        logtext.add("Can't find a servacl element.");
237                    }
238                } else {
239                    logtext.add("Can't find the servacls element.");
240                }
241            } else {
242                logtext.add("The service part is null.");
243            }
244            elm_out = (Element) root.clone();
245            errorHandlerValid(job, logtext, ID, lang);
246            return elm_out;
247        }
248    
249        /**
250         * An internal method to handle validation errors.
251         * 
252         * @param job
253         *            the MCRServletJob instance
254         * @param logtext
255         *            a list of log texts as strings
256         * @param ID
257         *            the current MCRObjectID
258         * @param lang
259         *            the current language
260         */
261        private final void errorHandlerValid(MCRServletJob job, List<String> logtext, MCRObjectID ID, String lang) throws Exception {
262            if (logtext.size() == 0) {
263                return;
264            }
265    
266            // write to the log file
267            for (int i = 0; i < logtext.size(); i++) {
268                LOGGER.error(logtext.get(i));
269            }
270    
271            // prepare editor with error messages
272            String pagedir = MCRConfiguration.instance().getString("MCR.SWF.PageDir", "");
273            String myfile = pagedir + MCRConfiguration.instance().getString("MCR.SWF.PageErrorFormular", "editor_error_formular.xml");
274            Document jdom = null;
275    
276            try {
277                InputStream in = (new URL(getBaseURL() + myfile + "?XSL.Style=xml")).openStream();
278    
279                if (in == null) {
280                    throw new MCRConfigurationException("Can't read editor file " + myfile);
281                }
282    
283                jdom = new org.jdom.input.SAXBuilder().build(in);
284    
285                Element root = jdom.getRootElement();
286                @SuppressWarnings("unchecked")
287                List<Element> sectionlist = root.getChildren("section");
288    
289                for (int i = 0; i < sectionlist.size(); i++) {
290                    Element section = sectionlist.get(i);
291    
292                    if (!section.getAttributeValue("lang", org.jdom.Namespace.XML_NAMESPACE).equals(lang.toLowerCase())) {
293                        continue;
294                    }
295    
296                    Element p = new Element("p");
297                    section.addContent(0, p);
298    
299                    Element center = new Element("center");
300    
301                    // the error message
302                    Element table = new Element("table");
303                    table.setAttribute("width", "80%");
304    
305                    for (int j = 0; j < logtext.size(); j++) {
306                        Element tr = new Element("tr");
307                        Element td = new Element("td");
308                        Element el = new Element("font");
309                        el.setAttribute("color", "red");
310                        el.addContent(logtext.get(j));
311                        td.addContent(el);
312                        tr.addContent(td);
313                        table.addContent(tr);
314                    }
315    
316                    center.addContent(table);
317                    section.addContent(1, center);
318                    p = new Element("p");
319                    section.addContent(2, p);
320    
321                    // the edit button
322                    Element form = section.getChild("form");
323                    form.setAttribute("action", job.getResponse().encodeRedirectURL(getBaseURL() + "servlets/MCRStartEditorServlet"));
324    
325                    Element input1 = new Element("input");
326                    input1.setAttribute("name", "lang");
327                    input1.setAttribute("type", "hidden");
328                    input1.setAttribute("value", lang);
329                    form.addContent(input1);
330    
331                    Element input2 = new Element("input");
332                    input2.setAttribute("name", "se_mcrid");
333                    input2.setAttribute("type", "hidden");
334                    input2.setAttribute("value", ID.getId());
335                    form.addContent(input2);
336    
337                    Element input3 = new Element("input");
338                    input3.setAttribute("name", "type");
339                    input3.setAttribute("type", "hidden");
340                    input3.setAttribute("value", ID.getTypeId());
341                    form.addContent(input3);
342                }
343            } catch (org.jdom.JDOMException e) {
344                throw new MCRException("Can't read editor file " + myfile + " or it has a parse error.", e);
345            }
346    
347            // restart editor
348            job.getRequest().setAttribute("XSL.Style", lang);
349            getLayoutService().doLayout(job.getRequest(), job.getResponse(), jdom);
350        }
351        
352    }