0001: //$HeadURL: svn+ssh://mschneider@svn.wald.intevation.org/deegree/base/trunk/resources/eclipse/svn_classfile_header_template.xml $
0002: /*---------------- FILE HEADER ------------------------------------------
0003: This file is part of adv ebrim project.
0004: Copyright (C) 2007 by:
0005:
0006: Andreas Poth
0007: lat/lon GmbH
0008: Aennchenstr. 19
0009: 53177 Bonn
0010: Germany
0011: E-Mail: poth@lat-lon.de
0012:
0013: ---------------------------------------------------------------------------*/
0014:
0015: package de.latlon.adv;
0016:
0017: import java.io.BufferedReader;
0018: import java.io.ByteArrayOutputStream;
0019: import java.io.IOException;
0020: import java.io.InputStream;
0021: import java.io.InputStreamReader;
0022: import java.io.OutputStream;
0023: import java.io.OutputStreamWriter;
0024: import java.io.PrintWriter;
0025: import java.net.MalformedURLException;
0026: import java.net.URI;
0027: import java.net.URISyntaxException;
0028: import java.net.URL;
0029: import java.security.InvalidParameterException;
0030: import java.util.ArrayList;
0031: import java.util.HashMap;
0032: import java.util.List;
0033: import java.util.Map;
0034: import java.util.Set;
0035:
0036: import javax.mail.MessagingException;
0037: import javax.mail.internet.ContentDisposition;
0038: import javax.mail.internet.MimeBodyPart;
0039: import javax.mail.internet.MimeMultipart;
0040: import javax.mail.internet.MimeUtility;
0041: import javax.mail.util.ByteArrayDataSource;
0042: import javax.servlet.Filter;
0043: import javax.servlet.FilterChain;
0044: import javax.servlet.FilterConfig;
0045: import javax.servlet.ServletException;
0046: import javax.servlet.ServletRequest;
0047: import javax.servlet.ServletResponse;
0048: import javax.servlet.http.HttpServletRequest;
0049: import javax.servlet.http.HttpServletResponse;
0050:
0051: import org.deegree.enterprise.servlet.ServletRequestWrapper;
0052: import org.deegree.enterprise.servlet.ServletResponseWrapper;
0053: import org.deegree.framework.log.ILogger;
0054: import org.deegree.framework.log.LoggerFactory;
0055: import org.deegree.framework.util.CharsetUtils;
0056: import org.deegree.framework.util.IDGenerator;
0057: import org.deegree.framework.util.WebappResourceResolver;
0058: import org.deegree.framework.xml.InvalidConfigurationException;
0059: import org.deegree.framework.xml.XMLException;
0060: import org.deegree.framework.xml.XMLFragment;
0061: import org.deegree.framework.xml.XMLParsingException;
0062: import org.deegree.framework.xml.XMLTools;
0063: import org.deegree.ogcbase.CommonNamespaces;
0064: import org.deegree.ogcbase.ExceptionCode;
0065: import org.deegree.ogcwebservices.OGCWebServiceException;
0066: import org.deegree.ogcwebservices.OGCWebServiceRequest;
0067: import org.deegree.ogcwebservices.csw.CSWExceptionCode;
0068: import org.deegree.ogcwebservices.csw.CatalogueService;
0069: import org.deegree.ogcwebservices.csw.configuration.CatalogueConfiguration;
0070: import org.deegree.ogcwebservices.csw.manager.Insert;
0071: import org.deegree.ogcwebservices.csw.manager.InsertResults;
0072: import org.deegree.ogcwebservices.csw.manager.Manager;
0073: import org.deegree.ogcwebservices.csw.manager.Operation;
0074: import org.deegree.ogcwebservices.csw.manager.Transaction;
0075: import org.deegree.ogcwebservices.csw.manager.TransactionResult;
0076: import org.deegree.ogcwebservices.csw.manager.TransactionResultDocument;
0077: import org.deegree.ogcwebservices.csw.manager.XMLFactory;
0078: import org.deegree.security.GeneralSecurityException;
0079: import org.deegree.security.drm.model.User;
0080: import org.w3c.dom.CDATASection;
0081: import org.w3c.dom.Document;
0082: import org.w3c.dom.Element;
0083: import org.w3c.dom.Node;
0084: import org.xml.sax.SAXException;
0085:
0086: /**
0087: * The <code>CSWInsertFilter</code> class is able to handle an incoming csw/wrs ebrim Transaction.
0088: * This extra filter is necessary because the insertion of an ebrim object is handled different then
0089: * the original csw:Insert.
0090: * <p>
0091: * The first difference is the usage of the form/multipart header which allows for ExtrinsicObjects
0092: * to be defined outside the message Body and thus must be handled seperatly.
0093: * </p>
0094: * <p>
0095: * A second difference results after the insertion of an Object for every update and insertion leads
0096: * to the extra insertion of an auditableEvent. The AuditableEvents result in an audit-trail (a
0097: * version coontrol history ) for each inserted or updated app:RegistryObject.
0098: * </p>
0099: *
0100: * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
0101: *
0102: * @author last edited by: $Author: poth $
0103: *
0104: * @version $Revision: 1.13 $, $Date: 2007-11-27 12:50:25 $
0105: *
0106: */
0107:
0108: public class CSWInsertFilter implements Filter {
0109:
0110: private static ILogger LOG = LoggerFactory
0111: .getLogger(CSWInsertFilter.class);
0112:
0113: private Manager transactionManager = null;
0114:
0115: private URI appURI;
0116:
0117: private OWSProxyHandler proxyHandler = null;
0118:
0119: public void init(FilterConfig config) throws ServletException {
0120: String configLocation = config.getInitParameter("csw.config");
0121: try {
0122: URL configURL = WebappResourceResolver.resolveFileLocation(
0123: configLocation, config.getServletContext(), LOG);
0124: CatalogueConfiguration cswConfig = CatalogueConfiguration
0125: .createConfiguration(configURL);
0126: CatalogueService cswService = CatalogueService
0127: .create(cswConfig);
0128: transactionManager = cswService.getManager();
0129: if (transactionManager.getWfsService() == null) {
0130: LOG
0131: .logError("CSW (Ebrim) Insert-Filter: The InserFilter has no access to the localWFS");
0132: }
0133: } catch (MalformedURLException e) {
0134: LOG.logError("Could not initiate CSWInsertfilter: "
0135: + e.getMessage());
0136: } catch (IOException e) {
0137: LOG.logError("Could not initiate CSWInsertfilter: "
0138: + e.getMessage());
0139: } catch (SAXException e) {
0140: LOG.logError("Could not initiate CSWInsertfilter: "
0141: + e.getMessage());
0142: } catch (InvalidConfigurationException e) {
0143: LOG.logError("Could not initiate CSWInsertfilter: "
0144: + e.getMessage());
0145: } catch (OGCWebServiceException e) {
0146: LOG.logError("Could not initiate CSWInsertfilter: "
0147: + e.getMessage());
0148: }
0149: if (transactionManager != null) {
0150: try {
0151: appURI = new URI("http://www.deegree.org/app");
0152: proxyHandler = new OWSProxyHandler(config);
0153: } catch (URISyntaxException e) {
0154: // This never happens but whatever
0155: } catch (InvalidParameterException ipe) {
0156: LOG
0157: .logInfo("CSW (Ebrim) Insert-Filter: couldn't create an OWSProxyHandler, so no user authentification available, because: "
0158: + ipe.getMessage());
0159: }
0160: LOG
0161: .logInfo("CSW (Ebrim) Insert Servlet Filter successfully initialized");
0162: } else {
0163: LOG
0164: .logInfo("CSW (Ebrim) Insert Servlet Filter was not initialized");
0165: }
0166: }
0167:
0168: public void doFilter(ServletRequest request,
0169: ServletResponse response, FilterChain chain)
0170: throws IOException, ServletException {
0171: if (transactionManager == null) {
0172: LOG
0173: .logInfo("CSW (Ebrim) Insert-Filter: Local Catalogue service is not instantiated, therefore the CSW-Insert filter can not be used");
0174: sendException(response, new OGCWebServiceException(
0175: "The transactionManager is not configured "
0176: + "so not accepting any requests.",
0177: CSWExceptionCode.WRS_NOTIMPLEMENTED));
0178: // chain.doFilter( request, response );
0179: return;
0180: }
0181: response.setCharacterEncoding("UTF-8");
0182: Map<String, String[]> params = request.getParameterMap();
0183:
0184: if (params.size() != 0) {
0185: chain.doFilter(request, response);
0186: return;
0187: }
0188:
0189: // so no get request (or a get Request without parameters)
0190: ServletRequestWrapper requestWrapper = null;
0191: if (request instanceof ServletRequestWrapper) {
0192: LOG
0193: .logDebug("the incoming request is actually an org.deegree.enterprise.servlet.RequestWrapper, so not creating new instance.");
0194: requestWrapper = (ServletRequestWrapper) request;
0195: } else {
0196: requestWrapper = new ServletRequestWrapper(
0197: (HttpServletRequest) request);
0198: }
0199:
0200: Transaction transaction = null;
0201: BufferedReader reader = new BufferedReader(
0202: new InputStreamReader(requestWrapper.getInputStream()));
0203: String firstLine = reader.readLine();
0204: LOG.logDebug("first line of request: " + firstLine);
0205: if (firstLine == null) {
0206: LOG
0207: .logInfo("CSW (Ebrim) Insert-Filter: no request characters found, not handling request");
0208: // chain.doFilter( requestWrapper, response );
0209: sendException(
0210: response,
0211: new OGCWebServiceException(
0212: "no request characters found, not handling request",
0213: CSWExceptionCode.WRS_INVALIDREQUEST));
0214: return;
0215: }
0216: if (ILogger.LOG_DEBUG == LOG.getLevel()) {
0217: LOG.logDebug("OUTPUTING as Strings");
0218: LOG.logDebug(firstLine);
0219: while (reader.ready()) {
0220: LOG.logDebug(reader.readLine());
0221: }
0222: }
0223:
0224: LOG.logDebug("GetContentype(): "
0225: + requestWrapper.getContentType());
0226:
0227: // These variables will be set according to the request properties
0228: CSWSOAPHandler soapHandler = new CSWSOAPHandler();
0229: if (requestWrapper.getContentType() != null
0230: && requestWrapper.getContentType().contains(
0231: "multipart/form-data")) {
0232: try {
0233: // because we have some multiparts, the soap/owsproxy handling is done in the
0234: // #handleMultiparts method
0235: transaction = handleMultiparts(requestWrapper,
0236: soapHandler);
0237: if (transaction == null) {
0238: LOG
0239: .logDebug("could not generate a Transaction object out of the multiparts, giving request to the chain");
0240: sendException(
0241: response,
0242: new OGCWebServiceException(
0243: "Could not generate a Transaction object out of the multiparts",
0244: CSWExceptionCode.WRS_INVALIDREQUEST));
0245: // chain.doFilter( request, response );
0246: return;
0247: }
0248: } catch (OGCWebServiceException e) {
0249: sendException(response, e);
0250: return;
0251: }
0252: } else {
0253: XMLFragment doc = null;
0254: try {
0255: doc = new XMLFragment(new InputStreamReader(
0256: requestWrapper.getInputStream()),
0257: "http://some_server.org");
0258: } catch (SAXException e) {
0259: LOG
0260: .logDebug("couldn't create an xml Fragment of the incoming request, so not handling. "
0261: + e.getMessage());
0262: sendException(
0263: response,
0264: new OGCWebServiceException(
0265: "Couldn't create an xml Fragment of the incoming request",
0266: CSWExceptionCode.WRS_INVALIDREQUEST));
0267: // chain.doFilter( requestWrapper, response );
0268: return;
0269: }
0270: Element rootElement = doc.getRootElement();
0271: String ns = rootElement.getNamespaceURI();
0272: LOG.logDebug("Decoded request as xml:\n "
0273: + doc.getAsPrettyString());
0274:
0275: if (!CommonNamespaces.CSWNS.toASCIIString().equals(ns)
0276: && !CommonNamespaces.W3SOAP_ENVELOPE
0277: .toASCIIString().equals(ns)) {
0278: LOG.logDebug("The namespace of the root element (" + ns
0279: + ") is neither: "
0280: + CommonNamespaces.W3SOAP_ENVELOPE + " nor: "
0281: + CommonNamespaces.CSWNS.toASCIIString()
0282: + ", so not using the servlet filter ");
0283: sendException(response, new OGCWebServiceException(
0284: "Service not known",
0285: CSWExceptionCode.WRS_INVALIDREQUEST));
0286: // chain.doFilter( requestWrapper, response );
0287: return;
0288: }
0289: soapHandler.setIncomingRequest(doc);
0290: try {
0291: doc = soapHandler.createCSWRequestFromSOAP();
0292: if (doc == null) {
0293: LOG
0294: .logDebug("the soap handler returned a null valued XMLFragment, cannot be!");
0295: sendException(
0296: response,
0297: new OGCWebServiceException(
0298: "The body of your request could not be parsed.",
0299: CSWExceptionCode.WRS_INVALIDREQUEST));
0300: }
0301: rootElement = doc.getRootElement();
0302: LOG.logDebug("after soap: " + doc.getAsPrettyString());
0303:
0304: // reset the stream to handle the request without the soap
0305: if (soapHandler.isSOAPRequest()) {
0306: ByteArrayOutputStream bos = new ByteArrayOutputStream(
0307: 50000);
0308: OutputStreamWriter osw = new OutputStreamWriter(
0309: bos, CharsetUtils.getSystemCharset());
0310: doc.write(osw);
0311: requestWrapper.setInputStreamAsByteArray(bos
0312: .toByteArray());
0313: }
0314:
0315: // checking the authorization of the user.
0316: OGCWebServiceRequest owsProxyRequest = null;
0317: if (this .proxyHandler != null) {
0318: owsProxyRequest = proxyHandler
0319: .createOWSRequest(requestWrapper);
0320: authorizeRequest(soapHandler, owsProxyRequest,
0321: requestWrapper);
0322: } else {
0323: LOG
0324: .logDebug("the proxyHandler is not defined so no user Authentification.");
0325: sendException(
0326: response,
0327: new OGCWebServiceException(
0328: "The proxyHandler is not defined so not accepting any requests.",
0329: CSWExceptionCode.WRS_NOTIMPLEMENTED));
0330: return;
0331: }
0332:
0333: if (!"Transaction".equals(rootElement.getLocalName())) {
0334: LOG
0335: .logDebug("The localname of the root element is not: 'Transaction', so not using the servlet filter. ");
0336: // Try the user authorization of the response
0337: ServletResponseWrapper responseWrapper = new ServletResponseWrapper(
0338: (HttpServletResponse) response);
0339: responseWrapper.setCharacterEncoding("UTF-8");
0340: chain.doFilter(requestWrapper, responseWrapper);
0341: if (this .proxyHandler != null) {
0342: authorizeResponse(soapHandler, owsProxyRequest,
0343: responseWrapper);
0344: }
0345: LOG.logDebug("got following response: ");
0346: OutputStream os = responseWrapper.getOutputStream();
0347: String encoding = request.getCharacterEncoding();
0348: LOG
0349: .logDebug("the request uses following character encoding: "
0350: + encoding);
0351: if (!"UTF-8".equals(encoding)) {
0352: LOG
0353: .logDebug("the request uses following character encoding: "
0354: + encoding
0355: + " setting to UTF-8.");
0356: encoding = "UTF-8";
0357: }
0358:
0359: String responseString = ((ServletResponseWrapper.ProxyServletOutputStream) os)
0360: .toString(encoding);
0361: LOG.logDebug("got the string: " + responseString);
0362: // byte[] b = ( (ServletResponseWrapper.ProxyServletOutputStream) os
0363: // ).toByteArray();
0364: // LOG.logDebug( "got the array: " + b.length );
0365: // LOG.logDebug( "got the array: " );
0366:
0367: os.close();
0368: // ServletOutputStream so = response.getOutputStream();
0369: // so.write( b );
0370: // so.flush();
0371: // so.close();
0372: PrintWriter writer = response.getWriter();
0373: writer.write(responseString);
0374: writer.flush();
0375: writer.close();
0376: // responseWrapper.flushBuffer();
0377: return;
0378: }
0379:
0380: // create the transaction
0381: transaction = Transaction.create(Long
0382: .toString(IDGenerator.getInstance()
0383: .generateUniqueID()), rootElement);
0384:
0385: } catch (OGCWebServiceException e) {
0386: sendException(response, e);
0387: return;
0388: }
0389: }
0390:
0391: try {
0392: LOG
0393: .logDebug("The request is a csw:Transaction parsed and handled by the CSWInsertFilter");
0394: if (transaction == null) {
0395: LOG.logDebug("the transaction is null, this cannot be");
0396: sendException(
0397: response,
0398: new OGCWebServiceException(
0399: "Failed to handle your transaction, please check your request.",
0400: CSWExceptionCode.WRS_INVALIDREQUEST));
0401: }
0402: if (soapHandler == null) {
0403: LOG.logDebug("the soaphandler is null, this cannot be");
0404: sendException(
0405: response,
0406: new OGCWebServiceException(
0407: "Failed to handle your transaction, please check your request.",
0408: CSWExceptionCode.WRS_INVALIDREQUEST));
0409: }
0410: TransactionResult result = handleTransactions(transaction,
0411: soapHandler.getUserName());
0412: if (result != null) {
0413: LOG
0414: .logDebug("Creating xml representation of the csw-transaction ");
0415: TransactionResultDocument resultDoc = XMLFactory
0416: .export(result);
0417: String prettyString = resultDoc.getAsPrettyString();
0418: LOG
0419: .logDebug("The result of the csw-transaction was not null, it has following xml-structure: \n"
0420: + prettyString);
0421: response.setContentType("application/xml");
0422: ServletResponseWrapper responseWrapper = new ServletResponseWrapper(
0423: (HttpServletResponse) response);
0424:
0425: PrintWriter writer = new PrintWriter(
0426: new OutputStreamWriter(responseWrapper
0427: .getOutputStream()));
0428: writer.write(prettyString);
0429: writer.flush();
0430: if (this .proxyHandler != null && soapHandler != null) {
0431: authorizeResponse(soapHandler, transaction,
0432: responseWrapper);
0433: }
0434: writer.close();
0435: writer = response.getWriter();
0436: writer.write(prettyString);
0437: writer.flush();
0438: writer.close();
0439: return;
0440: }
0441: } catch (OGCWebServiceException e) {
0442: sendException(response, e);
0443: return;
0444: } catch (XMLParsingException e) {
0445: sendException(response, new OGCWebServiceException(e
0446: .getMessage(), CSWExceptionCode.WRS_INVALIDREQUEST));
0447: return;
0448: }
0449: if (response.isCommitted()) {
0450: return;
0451: }
0452: // chain.doFilter( requestWrapper, response );
0453:
0454: }
0455:
0456: private void authorizeRequest(CSWSOAPHandler soapHandler,
0457: OGCWebServiceRequest owsProxyRequest,
0458: ServletRequestWrapper requestWrapper)
0459: throws OGCWebServiceException {
0460: // checking the authorization of the user.
0461: if (this .proxyHandler != null) {
0462: try {
0463: User user = proxyHandler.authentificateFromUserPw(
0464: soapHandler.getUserName(), soapHandler
0465: .getPassword());
0466:
0467: // owsProxyRequest = proxyHandler.createOWSRequest( requestWrapper );
0468: proxyHandler.doRequestValidation(requestWrapper, user,
0469: owsProxyRequest);
0470: } catch (GeneralSecurityException e) {
0471: // e.printStackTrace( System.out );
0472: LOG.logDebug("User: " + soapHandler.getUserName()
0473: + " with password: "
0474: + soapHandler.getPassword()
0475: + " couldn't get authentification because: "
0476: + e.getMessage());
0477: throw new OGCWebServiceException(e.getMessage(),
0478: CSWExceptionCode.WRS_INVALIDREQUEST);
0479: }
0480: }
0481: }
0482:
0483: private void authorizeResponse(CSWSOAPHandler soapHandler,
0484: OGCWebServiceRequest owsProxyRequest,
0485: ServletResponseWrapper responseWrapper)
0486: throws OGCWebServiceException {
0487: // checking the authorization of the user.
0488: if (this .proxyHandler != null) {
0489: try {
0490: User user = proxyHandler.authentificateFromUserPw(
0491: soapHandler.getUserName(), soapHandler
0492: .getPassword());
0493: proxyHandler.doResponseValidation(responseWrapper,
0494: user, owsProxyRequest);
0495: } catch (GeneralSecurityException e) {
0496: LOG.logDebug("User: " + soapHandler.getUserName()
0497: + " with password: "
0498: + soapHandler.getPassword()
0499: + " couldn't get authentification because: "
0500: + e.getMessage());
0501: throw new OGCWebServiceException(e.getMessage(),
0502: CSWExceptionCode.WRS_INVALIDREQUEST);
0503: } catch (IOException e) {
0504: LOG
0505: .logDebug("couldn't get an outputstream for the repsponse because: "
0506: + e.getMessage());
0507: throw new OGCWebServiceException(e.getMessage(),
0508: CSWExceptionCode.WRS_INVALIDREQUEST);
0509: }
0510: }
0511: }
0512:
0513: public void destroy() {
0514: // implements nottin.
0515: }
0516:
0517: /**
0518: * Sends the passed <tt>OGCWebServiceException</tt> to the calling client and flushes/closes
0519: * the writer.
0520: *
0521: * @param responseWriter
0522: * to write the message of the exception to
0523: * @param e
0524: * the exception to 'send' e.g. write to the stream.
0525: * @throws IOException
0526: * if an error occurred while getting the writer of the response.
0527: */
0528: private void sendException(ServletResponse response,
0529: OGCWebServiceException e) throws IOException {
0530: if (LOG.getLevel() == ILogger.LOG_DEBUG) {
0531: Thread.dumpStack();
0532: }
0533: if (response instanceof ServletResponseWrapper) {
0534: ((ServletResponseWrapper) response).reset();
0535: }
0536: response.setContentType("application/xml");
0537: PrintWriter writer = response.getWriter();
0538: LOG
0539: .logInfo("CSW (Ebrim) Insert-Filter: Sending OGCWebServiceException to client with message: ."
0540: + e.getMessage());
0541: Document doc = XMLTools.create();
0542:
0543: XMLFragment frag = new XMLFragment(doc.createElementNS(
0544: CommonNamespaces.OWSNS.toASCIIString(),
0545: "ows:ExceptionReport"));
0546: ExceptionCode code = e.getCode();
0547: String exceptionCode = CSWExceptionCode.WRS_INVALIDREQUEST.value;
0548: if (code != null && code.value != null) {
0549: exceptionCode = code.value;
0550: }
0551: Element soapFailed = XMLTools.appendElement(frag
0552: .getRootElement(), CommonNamespaces.WRS_EBRIMNS,
0553: exceptionCode);
0554: XMLTools.setNodeValue(soapFailed, e.getMessage());
0555: writer.write(frag.getAsPrettyString());
0556: writer.flush();
0557: writer.close();
0558: }
0559:
0560: /**
0561: * This method handles the operations in the given Transaction that is, it splits the
0562: * Transaction into update/delete and insert operations. The update and delete operations are
0563: * gathered as long as there are no insert operations. If an Insert opertation is encountered
0564: * the pending delete/update operations are first send to the csw after which all records in the
0565: * insert operation are sequently inserted into the registry, using the
0566: * {@link InsertTransactionHandler}. Note this method guarantees the sequential processing of
0567: * the operations in their defined order.
0568: *
0569: * @param transaction
0570: * bean representation of the incoming request.
0571: * @param username
0572: * of the user which inserts the registryObjects.
0573: * @throws OGCWebServiceException
0574: * if an error occurred while hanlding an operations.
0575: */
0576: private TransactionResult handleTransactions(
0577: Transaction transaction, String username)
0578: throws OGCWebServiceException {
0579: List<Operation> ops = transaction.getOperations();
0580: // find all the ids which were referenced by the transaction.
0581: List<Operation> pendingOps = new ArrayList<Operation>();
0582: List<Node> briefInsertedRecords = new ArrayList<Node>();
0583: // 0 = insert
0584: // 1 = delete
0585: // 2 = update
0586: int[] resultValues = new int[3];
0587: for (Operation op : ops) {
0588: if ("Insert".equalsIgnoreCase(op.getName())) {
0589: // First do all transactions which were not insert(s)
0590: if (pendingOps.size() > 0) {
0591: TransactionResult tr = sendPendingOperations(
0592: transaction, pendingOps);
0593: resultValues[0] += tr.getTotalInserted();
0594: resultValues[1] += tr.getTotalDeleted();
0595: resultValues[2] += tr.getTotalUpdated();
0596: }
0597: // handle all records inside the insert operation, e.g. set the
0598: // app:RegistryObject/app:status to invalid
0599: // if the id of the object allready exists.
0600: InsertTransactionHandler handler = new InsertTransactionHandler(
0601: transaction, (Insert) op, appURI, username);
0602: briefInsertedRecords.addAll(handler
0603: .handleInsertTransaction(
0604: this .transactionManager, resultValues));
0605:
0606: } else {
0607: pendingOps.add(op);
0608: }
0609: }
0610: if (pendingOps.size() > 0) {
0611: TransactionResult tr = sendPendingOperations(transaction,
0612: pendingOps);
0613: resultValues[0] += tr.getTotalInserted();
0614: resultValues[1] += tr.getTotalDeleted();
0615: resultValues[2] += tr.getTotalUpdated();
0616: }
0617: LOG.logDebug("Number of brief inserted records: "
0618: + briefInsertedRecords.size());
0619: InsertResults iresults = new InsertResults(briefInsertedRecords);
0620: return new TransactionResult(transaction, resultValues[0],
0621: resultValues[1], resultValues[2], iresults);
0622: }
0623:
0624: /**
0625: * Sends all operations in the list to the csw.
0626: *
0627: * @param originalTransaction
0628: * used to get the version, id and vendorspecific params from.
0629: * @param pendingOps
0630: * the list of delete and update operations.
0631: * @return the Result of the csw.
0632: * @throws OGCWebServiceException
0633: */
0634: private TransactionResult sendPendingOperations(
0635: Transaction originalTransaction, List<Operation> pendingOps)
0636: throws OGCWebServiceException {
0637: Transaction transaction = new Transaction(originalTransaction
0638: .getVersion(), originalTransaction.getId(),
0639: originalTransaction.getVendorSpecificParameters(),
0640: pendingOps, false);
0641:
0642: return transactionManager.transaction(transaction);
0643: }
0644:
0645: /**
0646: * This method handles the multiparts of a ServletRequest. This method is called when the
0647: * content-type:form/multipart header is set. Inside the multiparts different extrinsice object
0648: * representations (as xml) may reside. They will be added inside the appropriate
0649: * InsertOperation (found by the extrinsicObject's/@id) and inserted in the xml representation
0650: * of the referenced (again while looking at the /@id attribute) extrinicObject. The definition
0651: * of the extrinsicObject (e.g. inside the multipart) will be put inside the following
0652: * xml-Element: 'deegreecsw:DescribedObject', at the end of the nodelist of the
0653: * 'rim:ExtrinsicOjbects'.
0654: *
0655: * @param request
0656: * the actual HttpServletRequest.
0657: * @param soapHandler
0658: * @return the Transaction Representation of the incoming request
0659: * @throws OGCWebServiceException
0660: * if an exception occurred while processing the mime parts.
0661: */
0662: private Transaction handleMultiparts(HttpServletRequest request,
0663: CSWSOAPHandler soapHandler) throws OGCWebServiceException {
0664: Transaction trans = null;
0665: // StreamDataSource sds = new StreamDataSource( request );
0666: try {
0667: ByteArrayDataSource bads = new ByteArrayDataSource(request
0668: .getInputStream(), "application/xml");
0669: LOG
0670: .logInfo("CSW (Ebrim) Insert-Filter: Setting the 'mail.mime.multipart.ignoremissingendboundary' System property to false.");
0671: System.setProperty(
0672: "mail.mime.multipart.ignoremissingendboundary",
0673: "false");
0674: MimeMultipart multi = new MimeMultipart(bads);
0675: Map<String, Insert> insertOpContainingExtObj = new HashMap<String, Insert>();
0676:
0677: for (int i = 0; i < multi.getCount(); i++) {
0678: MimeBodyPart content = (MimeBodyPart) multi
0679: .getBodyPart(i);
0680: LOG.logDebug("multipart (" + (i + 1) + " of "
0681: + multi.getCount() + ") content id: "
0682: + content.getContentID());
0683: LOG.logDebug("multipart (" + (i + 1) + " of "
0684: + multi.getCount() + ") content type: "
0685: + content.getContentType());
0686: String contentType = content.getContentType();
0687: if (!(contentType.contains("application/xml") || contentType
0688: .contains("text/xml"))) {
0689: throw new OGCWebServiceException(
0690: "Other than xml-encoded data can not be handled in the multiparts",
0691: CSWExceptionCode.WRS_INVALIDREQUEST);
0692: }
0693: String[] names = content
0694: .getHeader("Content-Disposition");
0695: String nameID = null;
0696: if (names != null) {
0697: for (String name : names) {
0698: ContentDisposition cd = new ContentDisposition(
0699: name);
0700: String nm = cd.getParameter("name");
0701: if (nm != null) {
0702: nameID = nm;
0703: break;
0704: }
0705: }
0706: }
0707:
0708: if (nameID == null) {
0709: nameID = content.getContentID();
0710: if (nameID == null) {
0711: throw new OGCWebServiceException(
0712: "Exactly one 'name' parameter must be set in the header.",
0713: CSWExceptionCode.WRS_INVALIDREQUEST);
0714: }
0715: }
0716: LOG.logDebug("Working with multipart (" + (i + 1)
0717: + " of " + multi.getCount() + ") content name:"
0718: + nameID);
0719: LOG.logDebug("multipart (" + (i + 1) + " of "
0720: + multi.getCount() + ") lineCount: "
0721: + content.getLineCount());
0722: LOG.logDebug("multipart (" + (i + 1) + " of "
0723: + multi.getCount() + ") encoding: "
0724: + content.getEncoding());
0725: if ("Transaction".equalsIgnoreCase(nameID)) {
0726: InputStream contentIS = null;
0727: if (!"UTF-8"
0728: .equalsIgnoreCase(content.getEncoding())) {
0729: contentIS = MimeUtility.decode(content
0730: .getInputStream(), content
0731: .getEncoding());
0732: } else {
0733: contentIS = content.getInputStream();
0734: }
0735:
0736: // first get an xml fragment of the request and check if it is a soap.
0737: XMLFragment doc = new XMLFragment(
0738: new InputStreamReader(contentIS),
0739: XMLFragment.DEFAULT_URL);
0740: LOG.logDebug("Decoded first multiPart:\n "
0741: + doc.getAsPrettyString());
0742: soapHandler.setIncomingRequest(doc);
0743:
0744: doc = soapHandler.createCSWRequestFromSOAP();
0745: Element rootElement = doc.getRootElement();
0746:
0747: String ns = rootElement.getNamespaceURI();
0748: if (!CommonNamespaces.CSWNS.toASCIIString().equals(
0749: ns)
0750: || !"Transaction".equals(rootElement
0751: .getLocalName())) {
0752: // create the transaction
0753: LOG
0754: .logDebug("The namespace of the root element ("
0755: + ns
0756: + ") is not"
0757: + CommonNamespaces.CSWNS
0758: .toASCIIString()
0759: + ", or the request isn't a Transaction so not creating a Transaction object. ");
0760: // set the first multipart to the multipart without the soap.
0761: content.setContent(doc.getAsPrettyString(),
0762: "application/xml");
0763: return null;
0764: }
0765: trans = Transaction.create("0", rootElement);
0766:
0767: if (this .proxyHandler != null) {
0768: ServletRequestWrapper wrapper = new ServletRequestWrapper(
0769: request);
0770: ByteArrayOutputStream bos = new ByteArrayOutputStream(
0771: 50000);
0772: OutputStreamWriter osw = new OutputStreamWriter(
0773: bos, CharsetUtils.getSystemCharset());
0774: doc.write(osw);
0775: wrapper.setInputStreamAsByteArray(bos
0776: .toByteArray());
0777: authorizeRequest(soapHandler, trans, wrapper);
0778: } else {
0779: LOG
0780: .logDebug("the proxyHandler is not defined so no user Authentification.");
0781: }
0782:
0783: List<Operation> ops = trans.getOperations();
0784: // find all the ids which were referenced by the transaction.
0785: int countInserts = 0;
0786: for (Operation op : ops) {
0787:
0788: if ("Insert".equalsIgnoreCase(op.getName())) {
0789:
0790: Map<String, Element> objects = ((Insert) op)
0791: .getExtrinsicObjects();
0792: Set<String> keys = objects.keySet();
0793: LOG.logDebug("This insert operation ("
0794: + ++countInserts
0795: + ") contains the following keys: "
0796: + keys);
0797: // set the keys to the operations they were referenced in.
0798: for (String key : keys) {
0799: if (insertOpContainingExtObj
0800: .containsKey(key)) {
0801: throw new OGCWebServiceException(
0802: "The following key is not unique, "
0803: + key
0804: + ", the transaction therefore failed.",
0805: CSWExceptionCode.WRS_INVALIDREQUEST);
0806: }
0807: insertOpContainingExtObj.put(key,
0808: (Insert) op);
0809: }
0810: }
0811: }
0812: } else {
0813: if (LOG.getLevel() == ILogger.LOG_DEBUG) {
0814: InputStream contentIS = null;
0815:
0816: if (!"UTF-8".equalsIgnoreCase(content
0817: .getEncoding())) {
0818: contentIS = MimeUtility.decode(content
0819: .getInputStream(), content
0820: .getEncoding());
0821: } else {
0822: contentIS = content.getInputStream();
0823: }
0824:
0825: BufferedReader reader = new BufferedReader(
0826: new InputStreamReader(contentIS));
0827: String firstLine = reader.readLine();
0828: if (!reader.ready() || firstLine == null) {
0829: LOG
0830: .logInfo("CSW (Ebrim) Insert-Filter: no characters found in multipart, is this an error?");
0831: }
0832: LOG.logDebug("first line of multipart: "
0833: + firstLine);
0834: }
0835: LOG.logDebug("found Keys: "
0836: + insertOpContainingExtObj.keySet());
0837: if (insertOpContainingExtObj.size() > 0) {
0838: if (insertOpContainingExtObj
0839: .containsKey(nameID)) {
0840: LOG
0841: .logDebug("found the key to insert ("
0842: + nameID
0843: + ") trying to find associated multipart.");
0844: Insert insertOperation = insertOpContainingExtObj
0845: .remove(nameID);
0846: Map<String, Element> extrinsicObjects = insertOperation
0847: .getExtrinsicObjects();
0848: // find the extrinsicobject element and add the multipartmime type
0849: // containing it's id.
0850: if (extrinsicObjects.containsKey(nameID)) {
0851: List<Element> records = insertOperation
0852: .getRecords();
0853: Element extrinsicObject = extrinsicObjects
0854: .get(nameID);
0855: if (records.contains(extrinsicObject)) {
0856: int objectIndex = records
0857: .indexOf(extrinsicObject);
0858: LOG
0859: .logDebug("removing extrinsicObject at index: "
0860: + objectIndex
0861: + " from the records list");
0862: records.remove(extrinsicObject);
0863: Element handledExtrinsicObject = addDescribedExtrinsicObject(
0864: content, extrinsicObject);
0865: if (LOG.getLevel() == ILogger.LOG_DEBUG) {
0866: XMLFragment testFrag = new XMLFragment(
0867: handledExtrinsicObject);
0868: LOG
0869: .logDebug("The extrinsicObject after the insertion of the multipart: "
0870: + testFrag
0871: .getAsPrettyString());
0872: }
0873: records.add(objectIndex,
0874: handledExtrinsicObject);
0875: // records.add( handledExtrinsicObject );
0876: } else {
0877: LOG
0878: .logDebug("Following extrinsicObject was not found in the records list, this cannot be!: "
0879: + extrinsicObject
0880: .toString());
0881: }
0882: } else {
0883: LOG
0884: .logDebug("The given id: "
0885: + nameID
0886: + " was not found in the list of extrinsicObjects in the given InsertOperation, this cannot be!");
0887: }
0888: }
0889: } else {
0890: throw new OGCWebServiceException(
0891: "Some mime multiparts remain, but there are no more "
0892: + "referenced ids, something is wrong with the transaction",
0893: CSWExceptionCode.WRS_INVALIDREQUEST);
0894: }
0895: }
0896: }
0897: } catch (IOException ioe) {
0898: throw new OGCWebServiceException(
0899: "Can't handle your insert request, because an IOException "
0900: + "(with following message occured) while handling the mime multiparts:"
0901: + ioe.getMessage(),
0902: CSWExceptionCode.WRS_INVALIDREQUEST);
0903: } catch (MessagingException me) {
0904: throw new OGCWebServiceException(
0905: "Can't handle your insert request, because a MessagingException "
0906: + "(with following message occured) while handling the mime multiparts:"
0907: + me.getMessage(),
0908: CSWExceptionCode.WRS_INVALIDREQUEST);
0909: } catch (XMLException xmle) {
0910: throw new OGCWebServiceException(
0911: "Can't handle your insert request, because an XMLException (with "
0912: + "following message occured) while handling the mime multiparts:"
0913: + xmle.getMessage(),
0914: CSWExceptionCode.WRS_INVALIDREQUEST);
0915: } catch (SAXException saxe) {
0916: throw new OGCWebServiceException(
0917: "Can't handle your insert request, because an SAXException (with "
0918: + "following message) occured while handling the mime multiparts:"
0919: + saxe.getMessage(),
0920: CSWExceptionCode.WRS_INVALIDREQUEST);
0921: }
0922: // finished so lets give back the transaction as a result.
0923: return trans;
0924: }
0925:
0926: /**
0927: * Adds an deegreecsw:DescribedObject to the rim:EextrinsicObject, which will contain the xml
0928: * encoded object given in the MimeBodyPart.
0929: *
0930: * @param content
0931: * holding the described object
0932: * @param extrinsicObject
0933: * which will receive the deegreecsw:DescribedObject
0934: * @return the modified extrinsicObject xml-Element.
0935: * @throws OGCWebServiceException
0936: * @throws MessagingException
0937: */
0938: private Element addDescribedExtrinsicObject(MimeBodyPart content,
0939: Element extrinsicObject) throws OGCWebServiceException,
0940: MessagingException {
0941:
0942: String contentType = content.getContentType();
0943: LOG.logDebug("in the multipart, we found the contentType: "
0944: + contentType);
0945: if (contentType == null
0946: || !(contentType.contains("application/xml") || contentType
0947: .contains("text/xml"))) {
0948: throw new OGCWebServiceException(
0949: "Other than xml-encoded data can not be handled in the multiparts",
0950: CSWExceptionCode.WRS_INVALIDREQUEST);
0951: }
0952: try {
0953: InputStream contentIS = null;
0954: if (!"UTF-8".equalsIgnoreCase(content.getEncoding())) {
0955: contentIS = MimeUtility
0956: .decode(content.getInputStream(), content
0957: .getEncoding());
0958: } else {
0959: contentIS = content.getInputStream();
0960: }
0961:
0962: BufferedReader reader = new BufferedReader(
0963: new InputStreamReader(contentIS));
0964: String firstLine = reader.readLine();
0965: if (!reader.ready() || firstLine == null) {
0966: LOG
0967: .logInfo("CSW (Ebrim) Insert-Filter: no request characters found, not handling request");
0968: }
0969: StringBuffer sb = new StringBuffer();
0970: while (firstLine != null) {
0971: sb.append(firstLine);
0972: firstLine = reader.readLine();
0973: }
0974: String resultString = sb.toString();
0975: LOG.logDebug("content of multipart: " + resultString);
0976:
0977: // first delete the old element of the records list.
0978: // XMLFragment doc = new XMLFragment( new InputStreamReader( contentIS ),
0979: // XMLFragment.DEFAULT_URL );
0980: Element describedObject = XMLTools.appendElement(
0981: extrinsicObject, CommonNamespaces.DEEGREECSW,
0982: CommonNamespaces.DEEGREECSW_PREFIX
0983: + ":DescribedObject");
0984: CDATASection dataSection = describedObject
0985: .getOwnerDocument()
0986: .createCDATASection(resultString);
0987: LOG.logDebug("content of multipart(after cdata encoding): "
0988: + dataSection.getWholeText());
0989: describedObject.appendChild(dataSection);
0990: // Document ownerDoc = extrinsicObject.getOwnerDocument();
0991: // Node newInsertNode = ownerDoc.importNode( doc.getRootElement(), true );
0992: // describedObject.appendChild( newInsertNode );
0993:
0994: } catch (IOException e) {
0995: throw new OGCWebServiceException(
0996: "An error occurred while processing a multipart, discarding",
0997: CSWExceptionCode.WRS_INVALIDREQUEST);
0998: }
0999: return extrinsicObject;
1000: }
1001: }
|