From 1c900609d64445040e8c5bdbfa01ae1a0f563f43 Mon Sep 17 00:00:00 2001 From: gregor Date: Wed, 28 Feb 2007 13:17:57 +0000 Subject: Initial commit git-svn-id: https://joinup.ec.europa.eu/svn/moa-idspss/trunk@806 d688527b-c9ab-4aba-bd8d-4036d912da1d --- .../moa/ss/erechtclient/servlets/Dispatcher.java | 428 +++++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/servlets/Dispatcher.java (limited to 'erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/servlets/Dispatcher.java') diff --git a/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/servlets/Dispatcher.java b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/servlets/Dispatcher.java new file mode 100644 index 000000000..23c4dbb53 --- /dev/null +++ b/erecht.client.ss/src/at/gv/egovernment/moa/ss/erechtclient/servlets/Dispatcher.java @@ -0,0 +1,428 @@ +/* + * Created on 25.11.2003 + * + * (c) Stabsstelle IKT-Strategie des Bundes + */ +package at.gv.egovernment.moa.ss.erechtclient.servlets; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.log4j.Logger; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.ss.erechtclient.ERechtClientException; +import at.gv.egovernment.moa.ss.erechtclient.init.Constants; +import at.gv.egovernment.moa.ss.erechtclient.moainvoker.MOAInvoker; +import at.gv.egovernment.moa.ss.erechtclient.moainvoker.RequestBuilder; +import at.gv.egovernment.moa.ss.erechtclient.util.DOMUtils; +import at.gv.egovernment.moa.ss.erechtclient.util.Utils; +import at.gv.egovernment.moa.ss.erechtclient.util.XPathUtils; + +/** + * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at) + */ +public class Dispatcher extends HttpServlet +{ + private static Logger logger_ = Logger.getLogger(Constants.LH_SERVLETS_); + + private static final String XPATH_ALL_IMGS_ = "//" + Constants.NSPRE_XMLBGBL_ + ":" + Constants.XML_LN_XMLBGBL_IMG_; + + private static final String FN_XMLBGBL_ = "xMLBGBl"; + private static final String FN_STYLESHEET_ = "stylesheet"; + private static final String FN_IMAGE_ = "image."; + private static final String FN_XMLSIG_ = "signature"; + + private static final String TS_XMLBGBL_ = "xml"; + private static final String TS_STYLESHEET_ = "xsl"; + private static final String TS_IMAGE_ = "img"; + private static final String TS_XMLSIG_ = "xml"; + + private static final String LN_XMLSIG_ = "Signature"; + private static final String LN_SIGENV_ = "SignatureEnvironment"; + + public Dispatcher() + { + super(); + } + + /* ---------------------------------------------------------------------------------------------------- */ + + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException + { + try { + String screenName = request.getServletPath(); + if (Constants.SRVN_UPLOAD_XML_.equals(screenName)) + { + // Invalidate session if one exist from a previous use of the web application + HttpSession session = ((HttpServletRequest) request).getSession(false); + if (session != null) session.invalidate(); + + RequestDispatcher dispatcher = request.getRequestDispatcher(Constants.JSPPN_UPLOAD_XML_); + dispatcher.forward(request, response); + } + else + { + String message = "Unproper use of servlet \"" + screenName + "\". Please start with servlet \"" + + Constants.SRVN_UPLOAD_XML_ + "\"."; + throw new ERechtClientException(message); + } + } + catch (Exception e) + { + Utils.returnErrorPage(request, response, e); + } + + } + /* ---------------------------------------------------------------------------------------------------- */ + + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException + { + try + { + String screenName = request.getServletPath(); + if (Constants.SRVN_UPLOAD_XML_.equals(screenName)) + { + // Evaluate uploaded XML BGBl + HttpSession session = request.getSession(true); + + // Read BGBl XML upload from POST request + List params = parseParameters(request); + FileItem xMLBGBlFI = getFileItem(Constants.FPN_UPLOAD_XML_XMLBGBL_, params); + String xMLBGBlFileName = saveFileItem(xMLBGBlFI, FN_XMLBGBL_, TS_XMLBGBL_, session.getId(), this.getServletContext()); + session.setAttribute(Constants.SCP_XMLBGBL_FNAME_, xMLBGBlFileName); + + // Read stylesheet upload from POST request + FileItem stylesheetFI = getFileItem(Constants.FPN_UPLOAD_STYLESHEET_, params); + if (stylesheetFI.getName() != null && !"".equals(stylesheetFI.getName().trim())) + { + // Stylesheet has been uploaded + String stylesheetFileName = saveFileItem(stylesheetFI, FN_STYLESHEET_, TS_STYLESHEET_, session.getId(), this.getServletContext()); + session.setAttribute(Constants.SCP_STYLESHEET_FNAME_, stylesheetFileName); + } + + // Scan BGBl XML for potential images + Document xMLBGBlDoc = parseXMLBGBlDocument(xMLBGBlFileName, this.getServletContext()); + ArrayList imageNames = scanXMLBGBlForImages(xMLBGBlDoc); + + if (!imageNames.isEmpty()) + { + // Images exist in the BGBl XML, therefore continue with image upload + session.setAttribute(Constants.SCP_IMAGE_NAMES_LIST_, imageNames); + RequestDispatcher dispatcher = request.getRequestDispatcher(Constants.JSPPN_UPLOAD_IMG_); + dispatcher.forward(request, response); + return; + } + else + { + // Indicate with empty List in session that there are no images available + session.setAttribute(Constants.SCP_IMAGES_LIST_, new ArrayList(0)); + } + } + else if (Constants.SRVN_UPLOAD_IMG_.equals(screenName)) + { + HttpSession session = ((HttpServletRequest) request).getSession(false); + if (session == null) + { + String message = "Could not read session object."; + throw new ERechtClientException(message); + } + + List images = parseImageParameters(request, this.getServletContext()); + session.setAttribute(Constants.SCP_IMAGES_LIST_, images); + } + else + { + String message = "Unproper use of servlet \"" + screenName + "\". Please start with servlet \"" + + Constants.SRVN_UPLOAD_XML_ + "\"."; + logger_.error(message); + throw new ERechtClientException(message); + } + + // Create and store signature + HttpSession session = request.getSession(false); + Document signatureResponse = createXMLSignature(request, session); + String signatureFileName = saveXMLSignature(signatureResponse, session.getId(), this.getServletContext()); + Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_); + String webAppHostPortFromMOASS = Utils.readInitProperty(initProps, Constants.IP_WEBAPP_HOST_PORT_FROM_MOA_SS_, logger_); + session.setAttribute(Constants.SCP_SIGNATURE_URL_, webAppHostPortFromMOASS + request.getContextPath() + signatureFileName); + + // Dispatch Download JSP page + RequestDispatcher dispatcher = request.getRequestDispatcher(Constants.JSPPN_DOWNLOAD_SIG_); + dispatcher.forward(request, response); + } + catch (Exception e) + { + Utils.returnErrorPage(request, response, e); + } + } + + private Document createXMLSignature(HttpServletRequest request, HttpSession session) throws ERechtClientException + { + RequestBuilder requestBuilder = new RequestBuilder(this.getServletContext(), request.getContextPath()); + String xMLBGBlFileName = (String) session.getAttribute(Constants.SCP_XMLBGBL_FNAME_); + if (xMLBGBlFileName == null) + { + String message = "Could not read XML BGBl file name from session."; + logger_.error(message); + throw new ERechtClientException(message); + } + requestBuilder.setXMLDocument(xMLBGBlFileName); + + String stylesheetFileName = (String) session.getAttribute(Constants.SCP_STYLESHEET_FNAME_); + if (stylesheetFileName != null) + { + requestBuilder.setStylesheet(stylesheetFileName); + } + else + { + requestBuilder.useDefaultStylesheet(); + } + + List images = (List) session.getAttribute(Constants.SCP_IMAGES_LIST_); + if (images == null) + { + String message = "Could not read images from session."; + logger_.error(message); + throw new ERechtClientException(message); + } + Iterator imagesIt = images.iterator(); + while (imagesIt.hasNext()) + { + Image currImg = (Image) imagesIt.next(); + requestBuilder.addImage(currImg.name_, currImg.fileLocation_); + } + Document signatureRequest = requestBuilder.getRequest(); + Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_); + String serviceEndpoint = Utils.readInitProperty(initProps, Constants.IP_SS_ENDPOINT_, logger_); + String mOASchemaLoc = Utils.readInitProperty(initProps, Constants.IP_MOA_SCHEMA_, logger_); + String webAppHostPort = Utils.readInitProperty(initProps, Constants.IP_WEBAPP_HOST_PORT_, logger_); + Document signatureResponse = MOAInvoker.invokeSS(signatureRequest, serviceEndpoint, + "file:" + this.getServletContext().getRealPath(mOASchemaLoc)); + return signatureResponse; + } + + private List parseImageParameters(HttpServletRequest request, ServletContext context) throws ERechtClientException + { + HttpSession session = request.getSession(false); + if (session == null) + { + String message = "Could not read session object."; + throw new ERechtClientException(message); + } + + ArrayList imageNames = (ArrayList) session.getAttribute(Constants.SCP_IMAGE_NAMES_LIST_); + List params = parseParameters(request); + ArrayList images = new ArrayList(imageNames.size()); + for (int i = 0; i < params.size(); i++) + { + FileItem currItem = (FileItem) params.get(i); + if (currItem.getFieldName().startsWith(Constants.FPN_UPLOAD_IMG_IMG_)) + { + if (currItem.getSize() <= 0) + { + String message = "No content received for image \"" + currItem.getFieldName() + "\"."; + logger_.error(message); + throw new ERechtClientException(message); + } + String imgFileName = saveFileItem(currItem, FN_IMAGE_ + images.size(), TS_IMAGE_, session.getId(), context); + images.add(new Image(currItem.getFieldName().substring(Constants.FPN_UPLOAD_IMG_IMG_.length()), imgFileName)); + } + } + + // Check if there is a file item for each image name + if (imageNames.size() != images.size()) + { + String message = "No correct number of immages has been uploaded (Expected " + + imageNames.size() + ", actually received " + images.size() + ")."; + logger_.error(message); + throw new ERechtClientException(message); + } + + return images; + } + + private Document parseXMLBGBlDocument(String docFileName, ServletContext context) throws ERechtClientException + { + // TODO Change to validating parsing? + // DOMParser xmlParser = (DOMParser) context.getAttribute(Constants.WSCP_XMLPARSER_); + // InputSource docInputSource = new InputSource(docIS); + Document parsedDoc = null; + try + { + // xmlParser.parse(docInputSource); + FileInputStream docIS = new FileInputStream(context.getRealPath(docFileName)); + parsedDoc = DOMUtils.parseWellFormed(docIS); + + } + catch (Exception e) + { + String message = "Parsing XML BGBl document failed."; + logger_.error(message, e); + throw new ERechtClientException(message, e); + } + + Element docElem = parsedDoc.getDocumentElement(); + if (docElem.getNamespaceURI() != Constants.NSURI_XMLBGBL_ || docElem.getLocalName() != Constants.XML_LN_XMLBGBL_ROOT_) + { + String message = "XML BGBl has wrong root element (Local name equals \"" + docElem.getLocalName() + "\", NS-URI equals \"" + docElem.getNamespaceURI() + "\")."; + logger_.error(message); + throw new ERechtClientException(message); + } + + return parsedDoc; + } + + private ArrayList scanXMLBGBlForImages(Document xMLBGBlDoc) throws ERechtClientException + { + // Get all bka:binary elements in XML BGBl document + NodeList imgElems; + try { + XPathUtils xpUtils = new XPathUtils(); + String additionalNSPrefixes = Constants.NSPRE_XMLBGBL_ + " " + Constants.NSURI_XMLBGBL_; + xpUtils.setupContext(XPATH_ALL_IMGS_, xMLBGBlDoc.getDocumentElement(), additionalNSPrefixes); + imgElems = xpUtils.selectNodeSet(xMLBGBlDoc); + } + catch (Exception e) + { + String message = "Scanning for image elements in XML BGBl failed."; + logger_.error(message, e); + throw new ERechtClientException(message, e); + } + + // Collect the file refs of all bka:binary elements (either in bka:binary/@ref or in bka:binary/bka:src) + ArrayList list = new ArrayList(imgElems.getLength()); + for (int i = 0; i < imgElems.getLength(); i++) + { + Element currElem = (Element) imgElems.item(i); + Attr refAttr = currElem.getAttributeNodeNS(null, Constants.XML_LN_XMLBGBL_IMG_REF_); + if (refAttr != null) + { + list.add(i, refAttr.getValue()); + } + else + { + list.add(DOMUtils.getChildText(currElem, Constants.NSURI_XMLBGBL_, Constants.XML_LN_XMLBGBL_IMG_SRC_)); + } + } + return list; + } + + private List parseParameters(HttpServletRequest request) throws ERechtClientException + { + + if (ServletFileUpload.isMultipartContent(request)) + { + // Request is encoded as multipart/form-data + List items; + try + { + FileItemFactory factory = new DiskFileItemFactory(); + ServletFileUpload upload = null;; + upload = new ServletFileUpload(factory); + items = upload.parseRequest(request); + return items; + } + catch (FileUploadException e) + { + String message = "Parsing HTML form parameter failed."; + logger_.error(message, e); + throw new ERechtClientException(message, e); + } + } + else + { + // Request must be encoded als multipart/form-data + throw new ERechtClientException("HTML form encoding is not mulitpart/form-data."); + } + } + + private FileItem getFileItem(String fileItemName, List fileItemParams) + { + Iterator iter = fileItemParams.iterator(); + while (iter.hasNext()) + { + FileItem currentFI = (FileItem) iter.next(); + if (currentFI.getFieldName().equals(fileItemName)) return currentFI; + } + return null; + } + + private String saveFileItem(FileItem fileItem, String name, String typeSuffix, String sessionId, + ServletContext context) throws ERechtClientException + { + Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_); + String tempDir = Utils.readInitProperty(initProps, Constants.IP_TEMP_DIR_, logger_); + String fileName = tempDir + sessionId + "." + name + "." + typeSuffix; + String realFileName = context.getRealPath(fileName); + try { + fileItem.write(new File(realFileName)); + } catch (Exception e) + { + String message = "Writing item \"" + name + "\" to file system failed."; + logger_.error(message, e); + throw new ERechtClientException(message, e); + } + return fileName; + } + + private String saveXMLSignature(Document mOAResponse, String sessionId, ServletContext context) + throws ERechtClientException + { + Element sigEnvElem = DOMUtils.getChildElem(mOAResponse.getDocumentElement(), Constants.NSURI_MOA_13_, LN_SIGENV_); + Element signatureElem = DOMUtils.getChildElem(sigEnvElem, Constants.NSURI_DSIG_, LN_XMLSIG_); + + Properties initProps = (Properties) this.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_); + String tempDir = Utils.readInitProperty(initProps, Constants.IP_TEMP_DIR_, logger_); + String fileName = tempDir + sessionId + "." + FN_XMLSIG_ + "." + TS_XMLSIG_; + String realFileName = context.getRealPath(fileName); + try { + FileOutputStream fileOS = new FileOutputStream(realFileName); + MOAInvoker.serializeElement(signatureElem, fileOS); + fileOS.close(); + } catch (Exception e) + { + String message = "Writing xml signature to file system failed."; + logger_.error(message, e); + throw new ERechtClientException(message, e); + } + return fileName; + } + + class Image + { + public String name_; + public String fileLocation_; + + public Image(String name, String fileLocation) + { + name_ = name; + fileLocation_ = fileLocation; + } + } +} -- cgit v1.2.3