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 }