001 /*
002 *
003 * $Revision: 15272 $ $Date: 2009-05-26 12:37:41 +0200 (Tue, 26 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.File;
027 import java.io.FileOutputStream;
028 import java.io.IOException;
029 import java.io.InputStream;
030 import java.io.PrintWriter;
031 import java.io.StringWriter;
032 import java.net.URL;
033 import java.util.ArrayList;
034 import java.util.List;
035
036 import javax.servlet.http.HttpSession;
037
038 import org.apache.log4j.Level;
039 import org.apache.log4j.Logger;
040 import org.jdom.Document;
041 import org.jdom.Element;
042 import org.mycore.common.MCRConfiguration;
043 import org.mycore.common.MCRConfigurationException;
044 import org.mycore.common.MCRException;
045 import org.mycore.common.MCRSession;
046 import org.mycore.common.MCRSessionMgr;
047 import org.mycore.common.MCRUtils;
048 import org.mycore.datamodel.metadata.MCRObjectID;
049 import org.mycore.datamodel.metadata.validator.MCREditorOutValidator;
050 import org.mycore.frontend.editor.MCREditorSubmission;
051 import org.mycore.frontend.editor.MCRRequestParameters;
052 import org.mycore.frontend.workflow.MCRSimpleWorkflowManager;
053
054 /**
055 * This class is the superclass of servlets which checks the MCREditorServlet
056 * output XML and store the XML in a file or if an error was occured start the
057 * editor again.
058 *
059 * @author Jens Kupferschmidt
060 * @author Thomas Scheffler (yagee)
061 * @version $Revision: 15272 $ $Date: 2009-05-26 12:37:41 +0200 (Tue, 26 May 2009) $
062 */
063 abstract public class MCRCheckDataBase extends MCRCheckBase {
064 private static final long serialVersionUID = 8744330302159842747L;
065
066 private static Logger LOGGER = Logger.getLogger(MCRCheckDataBase.class);
067
068 /**
069 * This method overrides doGetPost of MCRServlet. <br />
070 */
071 public void doGetPost(MCRServletJob job) throws Exception {
072 // read the XML data
073 MCREditorSubmission sub = (MCREditorSubmission) (job.getRequest().getAttribute("MCREditorSubmission"));
074 org.jdom.Document indoc = sub.getXML();
075
076 // read the parameter
077 MCRRequestParameters parms;
078
079 if (sub == null) {
080 parms = new MCRRequestParameters(job.getRequest());
081 } else {
082 parms = sub.getParameters();
083 }
084
085 String oldmcrid = parms.getParameter("mcrid");
086 String oldtype = parms.getParameter("type");
087 String oldstep = parms.getParameter("step");
088 LOGGER.debug("XSL.target.param.0 = " + oldmcrid);
089 LOGGER.debug("XSL.target.param.1 = " + oldtype);
090 LOGGER.debug("XSL.target.param.2 = " + oldstep);
091
092 // get the MCRSession object for the current thread from the session
093 // manager.
094 MCRSession mcrSession = MCRSessionMgr.getCurrentSession();
095 String lang = mcrSession.getCurrentLanguage();
096 LOGGER.info("LANG = " + lang);
097
098 // prepare the MCRObjectID's for the Metadata
099 String mmcrid = "";
100 boolean hasid = false;
101
102 try {
103 mmcrid = indoc.getRootElement().getAttributeValue("ID");
104
105 if (mmcrid == null) {
106 mmcrid = oldmcrid;
107 } else {
108 hasid = true;
109 }
110 } catch (Exception e) {
111 mmcrid = oldmcrid;
112 }
113
114 MCRObjectID ID = new MCRObjectID(mmcrid);
115
116 if (!ID.getTypeId().equals(oldtype)) {
117 ID = new MCRObjectID(oldmcrid);
118 hasid = false;
119 }
120
121 if (!hasid) {
122 indoc.getRootElement().setAttribute("ID", ID.getId());
123 }
124
125 // check access
126 if (!checkAccess(ID)) {
127 job.getResponse().sendRedirect(getBaseURL() + usererrorpage);
128 return;
129 }
130
131 // Save the incoming to a file
132 byte[] outxml = MCRUtils.getByteArray(indoc);
133 File savedir = MCRSimpleWorkflowManager.instance().getDirectoryPath(ID.getBase());
134 File fullname = new File(savedir, ID.getId() + ".xml");
135 storeMetadata(outxml, job, ID, fullname.getAbsolutePath());
136
137 // create a metadata object and prepare it
138 org.jdom.Document outdoc = prepareMetadata((org.jdom.Document) indoc.clone(), ID, job, lang);
139 if (outdoc == null)
140 return;
141 outxml = MCRUtils.getByteArray(outdoc);
142
143 // Save the prepared metadata object
144 boolean okay = storeMetadata(outxml, job, ID, fullname.getAbsolutePath());
145
146 // call the getNextURL and sendMail methods
147 String url = getNextURL(ID, okay);
148 sendMail(ID);
149 if (!job.getResponse().isCommitted())
150 job.getResponse().sendRedirect(job.getResponse().encodeRedirectURL(getBaseURL() + url));
151 }
152
153 /**
154 * The method stores the data in a working directory dependenced of the
155 * type.
156 *
157 * @param outxml
158 * the prepared JDOM object
159 * @param job
160 * the MCRServletJob
161 * @param ID
162 * MCRObjectID of the MCRObject/MCRDerivate
163 * @param fullname
164 * the file name where the JDOM was stored.
165 */
166 public final boolean storeMetadata(byte[] outxml, MCRServletJob job, MCRObjectID ID, String fullname) throws Exception {
167 if (outxml == null) {
168 return false;
169 }
170
171 // Save the prepared MCRObject/MCRDerivate to a file
172 FileOutputStream out = new FileOutputStream(fullname);
173 try {
174 out.write(outxml);
175 out.flush();
176 } catch (IOException ex) {
177 LOGGER.error(ex.getMessage());
178 LOGGER.error("Exception while store to file " + fullname);
179 errorHandlerIO(job);
180
181 return false;
182 } finally {
183 out.close();
184 }
185
186 LOGGER.info("Object " + ID.getId() + " stored under " + fullname + ".");
187 return true;
188 }
189
190 /**
191 * The method read the incoming JDOM tree in a MCRObject and prepare this by
192 * the following rules. After them it return a JDOM as result of
193 * MCRObject.createXML(). <br/>
194 * <li>remove all target of MCRMetaClassification they have not a categid
195 * attribute.</li>
196 * <br/>
197 * <li>remove all target of MCRMetaLangText they have an empty text</li>
198 * <br/>
199 *
200 * @param jdom_in
201 * the JDOM tree from the editor
202 * @param ID
203 * the MCRObjectID of the MCRObject
204 * @param job
205 * the MCRServletJob data
206 * @param lang
207 * the current language
208 * @throws IOException
209 */
210 protected org.jdom.Document prepareMetadata(org.jdom.Document jdom_in, MCRObjectID ID, MCRServletJob job, String lang)
211 throws IOException {
212 MCREditorOutValidator ev = null;
213 try {
214 ev = new MCREditorOutValidator(jdom_in, ID);
215 Document jdom_out = ev.generateValidMyCoReObject();
216 if (LOGGER.getEffectiveLevel().isGreaterOrEqual(Level.INFO))
217 for (String logMsg : ev.getErrorLog()) {
218 LOGGER.info(logMsg);
219 }
220 return jdom_out;
221 } catch (Exception e) {
222 List<String> errorLog = ev != null ? ev.getErrorLog() : new ArrayList<String>();
223 StringWriter sw = new StringWriter();
224 PrintWriter pw = new PrintWriter(sw);
225 e.printStackTrace(pw);
226 errorLog.add(sw.toString());
227 pw.close();
228 errorHandlerValid(job, errorLog, ID, lang);
229 return null;
230 }
231 }
232
233 /**
234 * A method to handle valid errors.
235 * @throws IOException
236 */
237 private final void errorHandlerValid(MCRServletJob job, List<String> logtext, MCRObjectID ID, String lang) throws IOException {
238 // handle HttpSession
239 String sessionID = "";
240 HttpSession session = job.getRequest().getSession(false);
241 if (session != null) {
242 String jSessionID = MCRConfiguration.instance().getString("MCR.Session.Param", ";jsessionid=");
243 sessionID = jSessionID + session.getId();
244 }
245
246 // write to the log file
247 for (int i = 0; i < logtext.size(); i++) {
248 LOGGER.error(logtext.get(i));
249 }
250
251 // prepare editor with error messages
252 String pagedir = MCRConfiguration.instance().getString("MCR.SWF.PageDir", "");
253 String myfile = pagedir + MCRConfiguration.instance().getString("MCR.SWF.PageErrorFormular", "editor_error_formular.xml");
254 org.jdom.Document jdom = null;
255
256 try {
257 //TODO: Access File directly
258 InputStream in = new URL(getBaseURL() + myfile + sessionID + "?XSL.Style=xml").openStream();
259
260 if (in == null) {
261 throw new MCRConfigurationException("Can't read editor file " + myfile);
262 }
263
264 jdom = new org.jdom.input.SAXBuilder().build(in);
265
266 Element root = jdom.getRootElement();
267 @SuppressWarnings("unchecked")
268 List<Element> sectionlist = root.getChildren("section");
269
270 for (int i = 0; i < sectionlist.size(); i++) {
271 Element section = sectionlist.get(i);
272
273 final String sectLang = section.getAttributeValue("lang", org.jdom.Namespace.XML_NAMESPACE);
274 if (!sectLang.equals(lang) && !sectLang.equals("all")) {
275 continue;
276 }
277
278 Element p = new Element("p");
279 section.addContent(0, p);
280
281 Element center = new Element("center");
282
283 // the error message
284 Element table = new Element("table");
285 table.setAttribute("width", "80%");
286
287 for (String logMsg : logtext) {
288 Element tr = new Element("tr");
289 Element td = new Element("td");
290 Element el = new Element("pre");
291 el.setAttribute("style", "color:red;");
292 el.addContent(logMsg);
293 td.addContent(el);
294 tr.addContent(td);
295 table.addContent(tr);
296 }
297
298 center.addContent(table);
299 section.addContent(1, center);
300 p = new Element("p");
301 section.addContent(2, p);
302 break;
303 }
304 } catch (org.jdom.JDOMException e) {
305 throw new MCRException("Can't read editor file " + myfile + " or it has a parse error.", e);
306 }
307
308 // restart editor
309 getLayoutService().doLayout(job.getRequest(), job.getResponse(), jdom);
310 }
311
312 }