001 /**
002 * $RCSfile: MCRStartClassEditorServlet.java,v $
003 * $Revision: 15225 $ $Date: 2009-05-19 15:33:02 +0200 (Tue, 19 May 2009) $
004 *
005 * This file is part of ** M y C o R e **
006 * Visit our homepage at 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, normally in the file 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
025 package org.mycore.frontend.servlets;
026
027 import static org.jdom.Namespace.XML_NAMESPACE;
028
029 import java.io.IOException;
030 import java.util.Properties;
031
032 import org.apache.commons.fileupload.FileItem;
033 import org.apache.log4j.Logger;
034 import org.jdom.Element;
035 import org.jdom.output.Format;
036 import org.jdom.output.XMLOutputter;
037
038 import org.mycore.access.MCRAccessManager;
039 import org.mycore.common.MCRConfiguration;
040 import org.mycore.common.MCRSessionMgr;
041 import org.mycore.common.xml.MCRURIResolver;
042 import org.mycore.datamodel.classifications.MCRClassificationBrowserData;
043 import org.mycore.datamodel.classifications.MCRClassificationEditor;
044 import org.mycore.datamodel.classifications2.MCRCategory;
045 import org.mycore.datamodel.classifications2.MCRCategoryID;
046 import org.mycore.datamodel.classifications2.MCRLabel;
047 import org.mycore.datamodel.classifications2.utils.MCRCategoryTransformer;
048 import org.mycore.datamodel.metadata.MCRObjectID;
049 import org.mycore.frontend.editor.MCREditorSubmission;
050 import org.mycore.frontend.editor.MCRRequestParameters;
051
052 /**
053 * The servlet start the MyCoRe class editor session with some parameters from a
054 * HTML form. The parameters are:<br />
055 * <li> name="todo" values like 'create-classification, modify-classification,
056 * delete-classification, up and down' </li>
057 * <li> name="path" uri to page after editactions </li>
058 * <li> name="clid" classification id </li>
059 * <li> name="categid" category id </li>
060 *
061 * @author Anja Schaar
062 * @author Jens Kupferschmidt
063 * @version $Revision: 15225 $ $Date: 2009-05-19 15:33:02 +0200 (Tue, 19 May 2009) $
064 */
065
066 public class MCRStartClassEditorServlet extends MCRServlet {
067
068 private static final long serialVersionUID = 1L;
069
070 private static Logger LOGGER = Logger.getLogger(MCRStartClassEditorServlet.class);
071
072 private String todo = "";
073
074 private String todo2 = "";
075
076 private String clid = "";
077
078 private String categid = "";
079
080 private String path = "";
081
082 private static MCRClassificationEditor clE = new MCRClassificationEditor();
083
084 private static enum ReturnStatus {
085 success, fail
086 }
087
088 /**
089 * Replace the doGetPost method of MCRServlet. This method will be called
090 * two times when using the classification editor. Firtst time it prepare
091 * date for the editor and second time it execute the operation.
092 */
093 public void think(MCRServletJob job) throws Exception {
094
095 // read the XML data if given from Editorsession
096 MCREditorSubmission sub = (MCREditorSubmission) (job.getRequest().getAttribute("MCREditorSubmission"));
097
098 // read the parameter
099 MCRRequestParameters parms;
100 if (sub == null)
101 parms = new MCRRequestParameters(job.getRequest());
102 else {
103 parms = sub.getParameters();
104 }
105
106 // read the parameter
107 todo = parms.getParameter("todo");
108 todo2 = parms.getParameter("todo2");
109 path = parms.getParameter("path");
110
111 // get the Classification
112 clid = parms.getParameter("clid");
113
114 categid = parms.getParameter("categid");
115
116 if (todo == null)
117 todo = "";
118 if (todo2 == null)
119 todo2 = "";
120
121 LOGGER.debug("MCRStartClassEditorServlet TODO: " + todo);
122 LOGGER.debug("MCRStartClassEditorServlet TODO2: " + todo2);
123 LOGGER.debug("MCRStartClassEditorServlet CLID: " + clid);
124 LOGGER.debug("MCRStartClassEditorServlet CATEGID: " + categid);
125
126 String pagedir = MCRConfiguration.instance().getString("MCR.classeditor_page_dir", "");
127 String myfile = "editor_form_" + todo + ".xml";
128
129 String usererrorpage = pagedir + MCRConfiguration.instance().getString("MCR.classeditor_page_error_user", "editor_error_user.xml");
130 String cancelpage = pagedir + MCRConfiguration.instance().getString("MCR.classeditor_page_cancel", "classeditor_cancel.xml");
131 String icerrorpage = pagedir + MCRConfiguration.instance().getString("MCR.classeditor_page_error_id", "classeditor_error_clid.xml");
132 String iderrorpage = pagedir
133 + MCRConfiguration.instance().getString("MCR.classeditor_page_error_delete", "editor_error_delete.xml");
134 String imerrorpage = pagedir
135 + MCRConfiguration.instance().getString("MCR.classeditor_page_error_move", "classeditor_error_move.xml");
136 String imperrorpage = pagedir
137 + MCRConfiguration.instance().getString("MCR.classeditor_page_error_import", "classeditor_error_import.xml");
138 String isaveerrorpage = pagedir
139 + MCRConfiguration.instance().getString("MCR.classeditor_page_error_save", "classeditor_error_save.xml");
140 String ipurgeerrorpage = pagedir
141 + MCRConfiguration.instance().getString("MCR.classeditor_page_error_purge", "classeditor_error_purge.xml");
142
143 String referrer = job.getRequest().getHeader("Referer");
144 if (referrer == null || referrer.equals("")) {
145 referrer = getBaseURL() + cancelpage;
146 }
147
148 if (needsCreatePrivilege(todo, todo2)) {
149 if (!(MCRAccessManager.checkPermission("create-classification"))) {
150 setResponsePage(job, ReturnStatus.fail, getBaseURL() + usererrorpage);
151 return;
152 }
153 } else if (needsDeleteRight(todo, todo2)) {
154 if (!(MCRAccessManager.checkPermission(clid, "deletedb"))) {
155 setResponsePage(job, ReturnStatus.fail, getBaseURL() + usererrorpage);
156 return;
157 }
158 } else {
159 if (!(MCRAccessManager.checkPermission(clid, "writedb"))) {
160 setResponsePage(job, ReturnStatus.fail, getBaseURL() + usererrorpage);
161 return;
162 }
163 }
164
165 // nach Editoraufruf von new/modify auf commit
166 if ("commit-classification".equals(todo)) {
167 org.jdom.Document indoc = sub.getXML();
168 boolean bret = false;
169
170 // for debug
171 if (LOGGER.isDebugEnabled()) {
172 XMLOutputter outputter = new XMLOutputter();
173 LOGGER.debug(outputter.outputString(indoc));
174 }
175
176 if ("create-category".equals(todo2) || "modify-category".equals(todo2)) {
177 if ("create-category".equals(todo2)) {
178 // create
179 if (!clE.isLocked(clid)) {
180 MCRCategoryID id = new MCRCategoryID(clid, categid);
181 bret = clE.createCategoryInClassification(indoc, id);
182 }
183 } else {
184 // modify
185 if (!clE.isLocked(clid)) {
186 MCRCategoryID id = new MCRCategoryID(clid, categid);
187 bret = clE.modifyCategoryInClassification(indoc, id);
188 }
189 }
190 if (bret)
191 setResponsePage(job, ReturnStatus.success, path + "&categid=" + categid + "&clid=" + clid);
192 } else {
193 if (path.indexOf("&clid") > 0) {
194 // Classification abschneiden um wieder auf der
195 // Classifikationsstartseite zu landen
196 path = path.substring(0, path.indexOf("&clid"));
197 }
198 if ("create-classification".equals(todo2)) {
199 bret = clE.createNewClassification(indoc);
200 } else if ("modify-classification".equals(todo2)) {
201 if (!clE.isLocked(clid)) {
202 bret = clE.modifyClassificationDescription(indoc, clid);
203 }
204 } else if ("import-classification".equals(todo2)) {
205 String fname = parms.getParameter("/mycoreclass/pathes/path").trim();
206 fname = clE.setTempFile(fname, (FileItem) sub.getFiles().get(0));
207 String sUpdate = parms.getParameter("/mycoreclass/update");
208 boolean update = sUpdate == null ? true : "true".equals(sUpdate);
209 bret = clE.importClassification(update, fname);
210 clE.deleteTempFile();
211 if (!bret) {
212 setResponsePage(job, ReturnStatus.fail, getBaseURL() + imperrorpage);
213 return;
214 }
215 }
216 if (bret)
217 setResponsePage(job, ReturnStatus.success, path);
218 }
219 setResponsePage(job, ReturnStatus.fail, getBaseURL() + icerrorpage);
220 return;
221 }
222
223 if ("up-category".equals(todo) || "down-category".equals(todo) || "left-category".equals(todo) || "right-category".equals(todo)) {
224 boolean bret = false;
225 if (!clE.isLocked(clid)) {
226 bret = clE.moveCategoryInClassification(categid, clid, todo.substring(0, todo.indexOf("-")));
227 }
228 if (bret) {
229 setResponsePage(job, ReturnStatus.success, path + "&categid=" + categid + "&clid=" + clid);
230 }
231 setResponsePage(job, ReturnStatus.fail, getBaseURL() + imerrorpage);
232 return;
233 }
234
235 // first call, direct without editor
236 else if ("delete-category".equals(todo)) {
237 // l?schen
238 if (!clE.isLocked(clid)) {
239 int cnt = clE.deleteCategoryInClassification(clid, categid);
240
241 if (cnt == 0) { // deleted, no more references
242 setResponsePage(job, ReturnStatus.success, path + "&clid=" + clid);
243 }
244 // not delete cause references exist
245 setResponsePage(job, ReturnStatus.fail, getBaseURL() + iderrorpage);
246 }
247 return;
248 }
249
250 // first call, direct without editor
251 else if ("delete-classification".equals(todo)) {
252 if (!clE.isLocked(clid)) {
253 boolean cnt = clE.deleteClassification(clid);
254 if (cnt) { // deleted, no more references
255 path = getBaseURL() + "browse?mode=edit";
256 setResponsePage(job, ReturnStatus.success, path);
257 }
258 // not delete cause references exist
259 setResponsePage(job, ReturnStatus.fail, getBaseURL() + iderrorpage);
260 }
261 return;
262 }
263
264 // first call of editor, build the import dialogue
265 else if ("import-classification".equals(todo)) {
266 String base = getBaseURL() + myfile;
267 Properties params = new Properties();
268 params.put("cancelUrl", referrer);
269 params.put("clid", clid);
270 params.put("path", path);
271 params.put("todo2", todo);
272 params.put("todo", "commit-classification");
273 setResponsePage(job, ReturnStatus.success, buildRedirectURL(base, params));
274 return;
275 }
276
277 else if ("save-all".equals(todo)) {
278 if (clE.saveAll()) {
279 setResponsePage(job, ReturnStatus.success, path + "&clid=" + clid);
280 }
281 setResponsePage(job, ReturnStatus.fail, getBaseURL() + isaveerrorpage);
282 return;
283 } else if ("purge-all".equals(todo)) {
284 if (clE.purgeAll()) {
285 setResponsePage(job, ReturnStatus.success, path + "&clid=" + clid);
286 }
287 setResponsePage(job, ReturnStatus.fail, getBaseURL() + ipurgeerrorpage);
288 return;
289 }
290 // first call of editor, build the editor dialogue
291 if ("create-category".equals(todo) || "modify-category".equals(todo) || "create-classification".equals(todo)
292 || "modify-classification".equals(todo)) {
293
294 String base = getBaseURL() + myfile;
295 final String sessionObjectID = "classificationEditor";
296 Properties params = new Properties();
297 StringBuffer sb = new StringBuffer();
298 boolean isEdited = MCRClassificationBrowserData.getClassificationPool().isEdited(MCRCategoryID.rootID(clid));
299 MCRCategory classif = null;
300 if (isEdited) {
301 classif = MCRClassificationBrowserData.getClassificationPool().getClassificationAsPojo(MCRCategoryID.rootID(clid), false);
302 LOGGER.info("CLASSIF: " + classif.getId());
303 }
304
305 if ("modify-classification".equals(todo)) {
306 if (isEdited) {
307 sb.append("session:").append(sessionObjectID);
308 MCRSessionMgr.getCurrentSession().put(sessionObjectID,
309 MCRCategoryTransformer.getMetaDataDocument(classif, true).getRootElement());
310 } else {
311 sb.append("classification:metadata:0:children:").append(clid);
312 }
313 params.put("sourceUri", sb.toString());
314
315 }
316 if ("create-classification".equals(todo)) {
317 MCRObjectID cli = new MCRObjectID();
318 String idBase = MCRConfiguration.instance().getString("MCR.SWF.Project.ID", "DocPortal") + "_class";
319 cli.setNextFreeId(idBase);
320
321 if (!cli.isValid()) {
322 LOGGER.error("Create an unique CLID failed. " + cli.toString());
323 }
324 Element classRoot = new Element("mycoreclass").setAttribute("ID", cli.getId());
325 params.put("sourceUri", "session:" + sessionObjectID);
326 MCRSessionMgr.getCurrentSession().put(sessionObjectID, classRoot);
327 }
328 if ("modify-category".equals(todo)) {
329 if (isEdited) {
330 sb.append("session:").append(sessionObjectID);
331 Element classRoot = new Element("mycoreclass").setAttribute("ID", classif.getId().getRootID());
332 MCRLabel label = classif.getCurrentLabel();
333 Element le = new Element("label");
334 le.setAttribute("lang", label.getLang(), XML_NAMESPACE);
335 if (label.getText() != null) {
336 le.setAttribute("text", label.getText());
337 }
338 if (label.getDescription() != null) {
339 le.setAttribute("description", label.getDescription());
340 }
341 classRoot.addContent(le);
342
343 Element categs = new Element("categories");
344 MCRCategoryID id = new MCRCategoryID(classif.getId().getRootID(), categid);
345 MCRCategory cat = clE.findCategory(classif, id);
346 categs.addContent(MCRCategoryTransformer.getMetaDataElement(cat, true));
347 classRoot.addContent(categs);
348 MCRSessionMgr.getCurrentSession().put(sessionObjectID, classRoot);
349 } else {
350 sb.append("classification:metadata:0:children:").append(clid).append(':').append(categid);
351 }
352 params.put("sourceUri", sb.toString());
353 params.put("categid", categid);
354 }
355 if ("create-category".equals(todo)) {
356 if (isEdited) {
357 sb.append("session:").append(sessionObjectID);
358 MCRSessionMgr.getCurrentSession().put(sessionObjectID,
359 MCRCategoryTransformer.getMetaDataDocument(classif, true).getRootElement());
360 } else {
361 sb.append("classification:metadata:0:children:").append(clid);
362 }
363 params.put("sourceUri", sb.toString());
364 params.put("categid", categid);
365 }
366 params.put("cancelUrl", referrer);
367 params.put("clid", clid);
368 params.put("path", path);
369 params.put("todo2", todo);
370 params.put("todo", "commit-classification");
371 setResponsePage(job, ReturnStatus.success, buildRedirectURL(base, params));
372 return;
373 }
374 /* Wrong input data, write warning log */
375 LOGGER.warn("MCRStartClassEditorServlet default Case - Nothing to do ? " + todo);
376 setResponsePage(job, ReturnStatus.success, path);
377 }
378
379 public void setResponsePage(MCRServletJob job, ReturnStatus status, String url) {
380 String key = MCRStartClassEditorServlet.class.toString();
381 String value = job.getResponse().encodeRedirectURL(url);
382 key += "." + status;
383 job.getRequest().setAttribute(key, value);
384 }
385
386 public String getResponsePage(MCRServletJob job, ReturnStatus status) {
387 String key = MCRStartClassEditorServlet.class.toString() + "." + status;
388 return (String) job.getRequest().getAttribute(key);
389 }
390
391 public void render(MCRServletJob job, Exception thinkException) throws IOException {
392 String successURL = getResponsePage(job, ReturnStatus.success);
393 String failURL = getResponsePage(job, ReturnStatus.fail);
394
395 if (thinkException == null && successURL != null) {
396 job.getResponse().sendRedirect(successURL);
397 } else {
398 if (failURL != null)
399 job.getResponse().sendRedirect(failURL);
400 else
401 generateErrorPage(job.getRequest(), job.getResponse(), 500, thinkException.getMessage(), thinkException, false);
402 }
403 }
404
405 private boolean needsCreatePrivilege(String todo, String todo2) {
406 if (todo.equals("commit-classification")) {
407 if (todo2.equals("create-classification") || todo2.equals("import-classification"))
408 return true;
409 }
410 return false;
411 }
412
413 private boolean needsDeleteRight(String todo, String todo2) {
414 if (todo.equals("delete-classification")) {
415 return true;
416 }
417 return false;
418 }
419
420 }