Example usage for org.apache.commons.lang3 StringEscapeUtils escapeXml10

List of usage examples for org.apache.commons.lang3 StringEscapeUtils escapeXml10

Introduction

In this page you can find the example usage for org.apache.commons.lang3 StringEscapeUtils escapeXml10.

Prototype

public static String escapeXml10(final String input) 

Source Link

Document

Escapes the characters in a String using XML entities.

For example: "bread" & "butter" => "bread" & "butter" .

Usage

From source file:org.opendatakit.aggregate.format.structure.AbstractKmlElementBase.java

String generateDataElement(String name, String value) {
    return String.format(KmlConsts.KML_DATA_ELEMENT_TEMPLATE, StringEscapeUtils.escapeXml10(name),
            StringEscapeUtils.escapeXml10(value));
}

From source file:org.opendatakit.aggregate.format.structure.KmlFormatterWithFilters.java

@Override
public void beforeProcessSubmissions(CallingContext cc) throws ODKDatastoreException {
    output.write(String.format(KmlConsts.KML_PREAMBLE_TEMPLATE, StringEscapeUtils.escapeXml10(form.getFormId()),
            StringEscapeUtils.escapeXml10(form.getViewableName()),
            StringEscapeUtils.escapeXml10(form.getViewableName())));
    output.write(generateStyle(imgElement != null));
}

From source file:org.opendatakit.aggregate.format.structure.KmlFormatterWithFilters.java

@Override
public void processSubmissionSegment(List<Submission> submissions, CallingContext cc)
        throws ODKDatastoreException {
    // format row elements
    for (Submission sub : submissions) {

        String id = sub.getKey().getKey();
        StringBuilder placemarks = new StringBuilder();

        // check if gps coordinate is in top element, else it's in a repeat
        if (gpsParent == topElement) {
            // since both gpsParent equals top element, title & imageURL must be in submission
            String title = getTitle(sub);
            String imageURL = getImageUrl(sub);

            GeoPoint geopoint = getGeoPoint(sub);
            Row row = sub.getFormattedValuesAsRow(propertyNames, elemFormatter, false, cc);
            placemarks.append(generateFormattedPlacemark(row, StringEscapeUtils.escapeXml10(id),
                    StringEscapeUtils.escapeXml10(title), imageURL, geopoint));
        } else {//from  w w w.  j av a 2s .com
            // clear previous rows generated
            rowsForGpsInRepeats = new ArrayList<GpsRepeatRowData>();

            // the call back will populate rowsForGpsInRepeats
            sub.getFormattedValuesAsRow(propertyNames, elemFormatter, false, cc);
            for (GpsRepeatRowData repeatData : rowsForGpsInRepeats) {
                String title = titleInGpsRepeat ? repeatData.getTitle() : getTitle(sub);
                String imageURL = imgInGpsRepeat ? repeatData.getImgUrl() : getImageUrl(sub);
                placemarks.append(
                        generateFormattedPlacemark(repeatData.getRow(), StringEscapeUtils.escapeXml10(id),
                                StringEscapeUtils.escapeXml10(title), imageURL, repeatData.getGeoPoint()));
            }
        }
        output.write(placemarks.toString());
    }
}

From source file:org.opendatakit.aggregate.format.structure.KmlFormatterWithFilters.java

private String generateDataElement(String name, String value) {
    return String.format(KmlConsts.KML_DATA_ELEMENT_TEMPLATE, StringEscapeUtils.escapeXml10(name),
            StringEscapeUtils.escapeXml10(value));
}

From source file:org.opendatakit.aggregate.format.structure.KmlGeoPointGenerator.java

@Override
String generatePlacemarkSubmission(Submission sub, List<FormElementModel> propertyNames, CallingContext cc)
        throws ODKDatastoreException {

    StringBuilder placemarks = new StringBuilder();

    // check if gps coordinate is in top element, else it's in a repeat
    if (geoParentRootSubmissionElement()) {
        // since both gpsParent equals top element, title & imageURL must be in
        // submission
        String title = getTitle(sub);
        String imageURL = getImageUrl(sub, cc);

        GeoPoint geopoint = getGeoPoint(sub);
        Row row = sub.getFormattedValuesAsRow(propertyNames, elemFormatter, false, cc);
        String id = sub.getKey().getKey();
        placemarks.append(generateFormattedPlacemark(row, StringEscapeUtils.escapeXml10(id),
                StringEscapeUtils.escapeXml10(title), imageURL, geopoint));

    } else {/*from   www.jav  a 2s .  co  m*/
        // clear previous rows generated
        rowsForGpsInRepeats = new ArrayList<GpsRepeatRowData>();

        // the call back will populate rowsForGpsInRepeats
        sub.getFormattedValuesAsRow(propertyNames, elemFormatter, false, cc);
        for (GpsRepeatRowData repeatData : rowsForGpsInRepeats) {
            String title = repeatData.getTitle();
            String imageURL = repeatData.getImgUrl();
            placemarks.append(generateFormattedPlacemark(repeatData.getRow(),
                    StringEscapeUtils.escapeXml10(repeatData.getId()), StringEscapeUtils.escapeXml10(title),
                    imageURL, repeatData.getGeoPoint()));
        }
    }
    return placemarks.toString();
}

From source file:org.opendatakit.aggregate.format.structure.KmlGeoTraceNGeoShapeGenerator.java

private String generatePlacemark(SubmissionSet sub) {
    try {/*from w ww. j a  va 2s  .  c  om*/
        // parse value into geopoints
        SubmissionValue value = sub.getElementValue(getGeoElement());
        List<GeoPoint> points = getGeoLineCoordinates(value);

        // generate KML placemark
        if (!points.isEmpty()) {
            StringBuilder coordinateString = new StringBuilder(BasicConsts.EMPTY_STRING);
            for (GeoPoint gp : points) {
                if (gp != null) {
                    if (gp.getLatitude() != null && gp.getLongitude() != null) {
                        coordinateString.append(gp.getLongitude());
                        coordinateString.append(BasicConsts.COMMA);
                        coordinateString.append(gp.getLatitude());
                        if (gp.getAltitude() != null) {
                            coordinateString.append(BasicConsts.COMMA);
                            coordinateString.append(gp.getAltitude());
                        }
                    }
                    coordinateString.append(BasicConsts.NEW_LINE);
                }
            }
            String id = sub.getKey().getKey();
            String idStr = (id == null) ? BasicConsts.EMPTY_STRING : id;
            String name = getName(sub);
            String nameStr = (name == null) ? BasicConsts.EMPTY_STRING : name;
            return String.format(KmlConsts.KML_LINE_STRING_PLACEMARK_TEMPLATE,
                    StringEscapeUtils.escapeXml10(idStr), StringEscapeUtils.escapeXml10(nameStr),
                    coordinateString.toString().trim());
        }
    } catch (ODKParseException e) {
        // TODO: CHANGE SO THE ERROR GOES TO THE UI
        e.printStackTrace();
    }
    return BasicConsts.EMPTY_STRING;
}

From source file:org.opendatakit.aggregate.servlet.FormUploadServlet.java

/**
 * Handler for HTTP Post request that takes an xform, parses, and saves a
 * parsed version in the datastore/*from  w  ww  . j  a va 2 s.c  om*/
 *
 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
 *      javax.servlet.http.HttpServletResponse)
 */
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    CallingContext cc = ContextFactory.getCallingContext(this, req);

    Double openRosaVersion = getOpenRosaVersion(req);

    // verify request is multipart
    if (!ServletFileUpload.isMultipartContent(req)) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.NO_MULTI_PART_CONTENT);
        return;
    }

    StringBuilder warnings = new StringBuilder();
    // TODO Add in form title process so it will update the changes in the XML
    // of form

    try {
        // process form
        MultiPartFormData uploadedFormItems = new MultiPartFormData(req);

        FormParserForJavaRosa parser = null;

        MultiPartFormItem formNameData = uploadedFormItems.getFormDataByFieldName(ServletConsts.FORM_NAME_PRAM);
        MultiPartFormItem formXmlData = uploadedFormItems.getFormDataByFieldName(ServletConsts.FORM_DEF_PRAM);

        String formName = null;
        String inputXml = null;
        String xmlFileName = "default.xml";

        if (formNameData != null) {
            formName = formNameData.getStream().toString(HtmlConsts.UTF8_ENCODE);
        }
        if (formXmlData != null) {
            // TODO: changed added output stream writer. probably something better
            // exists
            inputXml = formXmlData.getStream().toString(HtmlConsts.UTF8_ENCODE);
            xmlFileName = formXmlData.getFilename();
        }

        try {
            parser = new FormParserForJavaRosa(formName, formXmlData, inputXml, xmlFileName, uploadedFormItems,
                    warnings, cc);
            logger.info("Upload form successful: " + parser.getFormId());
            // GAE requires some settle time before these entries will be
            // accurately retrieved. Do not re-fetch the form after it has been
            // uploaded.
            resp.setStatus(HttpServletResponse.SC_CREATED);
            resp.setHeader("Location", cc.getServerURL() + BasicConsts.FORWARDSLASH + ADDR);
            if (openRosaVersion == null) {
                // web page -- show HTML response
                resp.setContentType(HtmlConsts.RESP_TYPE_HTML);
                resp.setCharacterEncoding(HtmlConsts.UTF8_ENCODE);
                PrintWriter out = resp.getWriter();
                out.write(HtmlConsts.HTML_OPEN);
                out.write(HtmlConsts.BODY_OPEN);
                if (warnings.length() != 0) {
                    out.write("<p>Form uploaded with warnings. There are value fields in the form that do not "
                            + "have <code>&lt;bind/&gt;</code> declarations or those <code>&lt;bind/&gt;</code> "
                            + "declarations do not have a <code>type</code> attribute that "
                            + "identifies the data type of that field (e.g., boolean, int, decimal, date, dateTime, time, string, "
                            + "select1, select, barcode, geopoint or binary).</p>"
                            + "<p><b>All these value fields have been declared as string values.</b> It will use "
                            + "lexical ordering on those fields.  E.g., the value 100 will be considered less than 11.</p>"
                            + "<p><font color=\"red\">If these value fields hold date, dateTime, time or numeric data (e.g., decimal or int), then "
                            + "ODK Aggregate will produce erroneous sortings and erroneous filtering results against those value fields.</font></p>"
                            + "<table><th><td>Field Name</td></th>");
                    out.write(warnings.toString());
                    out.write("</table>");
                } else {
                    out.write("<p>Successful form upload.</p>");
                }
                out.write("<p>Click ");

                out.write(HtmlUtil.createHref(cc.getWebApplicationURL(ADDR), "here", false));
                out.write(" to return to add new form page.</p>");
                out.write(HtmlConsts.BODY_CLOSE);
                out.write(HtmlConsts.HTML_CLOSE);
            } else {
                addOpenRosaHeaders(resp);
                resp.setContentType(HtmlConsts.RESP_TYPE_XML);
                resp.setCharacterEncoding(HtmlConsts.UTF8_ENCODE);
                PrintWriter out = resp.getWriter();
                out.write("<OpenRosaResponse xmlns=\"http://openrosa.org/http/response\">");
                if (warnings.length() != 0) {
                    StringBuilder b = new StringBuilder();
                    b.append("<p>Form uploaded with warnings. There are value fields in the form that do not "
                            + "have <code>&lt;bind/&gt;</code> declarations or those <code>&lt;bind/&gt;</code> "
                            + "declarations do not have a <code>type</code> attribute that "
                            + "identifies the data type of that field (e.g., boolean, int, decimal, date, dateTime, time, string, "
                            + "select1, select, barcode, geopoint or binary).</p>"
                            + "<p><b>All these value fields have been declared as string values.</b> It will use "
                            + "lexical ordering on those fields.  E.g., the value 100 will be considered less than 11.</p>"
                            + "<p><font color=\"red\">If these value fields hold date, dateTime, time or numeric data (e.g., decimal or int), then "
                            + "ODK Aggregate will produce erroneous sortings and erroneous filtering results against those value fields.</font></p>"
                            + "<table><th><td>Field Name</td></th>");
                    b.append(warnings.toString());
                    b.append("</table>");
                    out.write("<message>");
                    out.write(StringEscapeUtils.escapeXml10(b.toString()));
                    out.write("</message>");
                } else {
                    out.write("<message>Successful upload.</message>");
                }
                out.write("</OpenRosaResponse>");
            }

        } catch (ODKFormAlreadyExistsException e) {
            logger.info("Form already exists: " + e.toString());
            resp.sendError(HttpServletResponse.SC_CONFLICT,
                    ErrorConsts.FORM_WITH_ODKID_EXISTS + "\n" + e.toString());
        } catch (ODKIncompleteSubmissionData e) {
            logger.warn("Form upload parsing error: " + e.toString());
            switch (e.getReason()) {
            case TITLE_MISSING:
                createTitleQuestionWebpage(resp, inputXml, xmlFileName, cc);
                return;
            case ID_MALFORMED:
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
                        ErrorConsts.JAVA_ROSA_PARSING_PROBLEM + "\n" + e.toString());
                return;
            case ID_MISSING:
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_FORM_ID);
                return;
            case MISSING_XML:
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_FORM_INFO);
                return;
            case BAD_JR_PARSE:
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
                        ErrorConsts.JAVA_ROSA_PARSING_PROBLEM + "\n" + e.toString());
                return;
            case MISMATCHED_SUBMISSION_ELEMENT:
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.FORM_INVALID_SUBMISSION_ELEMENT);
                return;
            default:
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.INVALID_PARAMS);
                return;
            }
        } catch (ODKEntityPersistException e) {
            // TODO NEED TO FIGURE OUT PROPER ACTION FOR ERROR
            logger.error("Form upload persistence error: " + e.toString());
            e.printStackTrace();
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    ErrorConsts.PERSISTENCE_LAYER_PROBLEM + "\n" + e.toString());
        } catch (ODKDatastoreException e) {
            logger.error("Form upload persistence error: " + e.toString());
            e.printStackTrace();
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    ErrorConsts.PERSISTENCE_LAYER_PROBLEM + "\n" + e.toString());
        } catch (ODKParseException e) {
            // unfortunately, the underlying javarosa utility swallows the parsing
            // error.
            logger.error("Form upload persistence error: " + e.toString());
            e.printStackTrace();
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
                    ErrorConsts.PARSING_PROBLEM + "\n" + e.toString());
        }
    } catch (FileUploadException e) {
        logger.error("Form upload persistence error: " + e.toString());
        e.printStackTrace(resp.getWriter());
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ErrorConsts.UPLOAD_PROBLEM);
    }
}

From source file:org.opendatakit.aggregate.servlet.ResetUsersAndPermissionsServlet.java

/**
 * Processes the multipart form that contains the csv file which holds the 
 * list of users and thier permissions. Returns success if the changes have
 * been applied; false otherwise.//  w  w w .j  a  v  a 2  s. c o m
 */
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    if (req.getScheme().equals("http")) {
        logger.warn("Resetting users and capabilities over http");
    }
    CallingContext cc = ContextFactory.getCallingContext(this, req);

    Double openRosaVersion = getOpenRosaVersion(req);

    // verify request is multipart
    if (!ServletFileUpload.isMultipartContent(req)) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.NO_MULTI_PART_CONTENT);
        return;
    }

    StringBuilder warnings = new StringBuilder();
    // TODO Add in form title process so it will update the changes in the XML
    // of form

    try {
        // process form
        MultiPartFormData resetUsersAndPermissions = new MultiPartFormData(req);

        MultiPartFormItem usersAndPermissionsCsv = resetUsersAndPermissions
                .getFormDataByFieldName(ACCESS_DEF_PRAM);

        String inputCsv = null;

        if (usersAndPermissionsCsv != null) {
            // TODO: changed added output stream writer. probably something better
            // exists
            inputCsv = usersAndPermissionsCsv.getStream().toString(HtmlConsts.UTF8_ENCODE);
        }

        StringReader csvContentReader = null;
        RFC4180CsvReader csvReader = null;
        try {
            // we need to build up the UserSecurityInfo records for all the users
            ArrayList<UserSecurityInfo> users = new ArrayList<UserSecurityInfo>();

            // build reader for the csv content
            csvContentReader = new StringReader(inputCsv);
            csvReader = new RFC4180CsvReader(csvContentReader);

            // get the column headings -- these mimic those in Site Admin / Permissions table. 
            // Order is irrelevant; no change-password column.
            //
            String[] columns;
            int row = 0;

            for (;;) {
                ++row;
                columns = csvReader.readNext();

                if (columns == null) {
                    logger.error("users and capabilities .csv upload - empty csv file");
                    resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
                            ErrorConsts.MISSING_PARAMS + "\nusers and capabilities .csv is empty");
                    return;
                }

                // count non-blank columns
                int nonBlankColCount = 0;
                for (String col : columns) {
                    if (col != null && col.trim().length() != 0) {
                        ++nonBlankColCount;
                    }
                }

                // if there are fewer than 4 columns, it must be a comment field.
                // if there are 4 or more columns, then we expect it to be the column headers
                // for the users and capabilities table. We could require just 3, but that
                // would not be very useful or realistic.
                if (nonBlankColCount < 4)
                    continue;

                break;
            }
            if (row != 1) {
                logger.warn("users and capabilities .csv upload -- interpreting row " + row
                        + " as the column header row");
                warnings.append("<tr><td>Interpreting row " + row + " as the column header row.</td></tr>");
            }

            // TODO: validate column headings....
            int idxUsername = -1;
            int idxFullName = -1;
            int idxUserType = -1;
            int idxDataCollector = -1;
            int idxDataViewer = -1;
            int idxFormManager = -1;
            int idxSyncTables = -1;
            int idxTablesSU = -1;
            int idxTablesAdmin = -1;
            int idxSiteAdmin = -1;

            for (int i = 0; i < columns.length; ++i) {
                String heading = columns[i];
                if (heading == null || heading.trim().length() == 0) {
                    continue;
                }
                heading = heading.trim();
                // 'Username' is required
                if ("Username".compareToIgnoreCase(heading) == 0) {
                    if (idxUsername != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Username' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Username' is repeated");
                        return;
                    }
                    idxUsername = i;
                }
                // 'Full Name' is optional. The value in 'Username' will be used to construct this if unspecified.
                else if ("Full Name".compareToIgnoreCase(heading) == 0) {
                    if (idxFullName != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Full Name' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Full Name' is repeated");
                        return;
                    }
                    idxFullName = i;
                }
                // 'Account Type' is required
                else if ("Account Type".compareToIgnoreCase(heading) == 0) {
                    if (idxUserType != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Account Type' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Account Type' is repeated");
                        return;
                    }
                    idxUserType = i;
                }
                // Permissions columns begin here. All are optional
                else if ("Data Collector".compareToIgnoreCase(heading) == 0) {
                    if (idxDataCollector != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Data Collector' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Data Collector' is repeated");
                        return;
                    }
                    idxDataCollector = i;
                } else if ("Data Viewer".compareToIgnoreCase(heading) == 0) {
                    if (idxDataViewer != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Data Viewer' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Data Viewer' is repeated");
                        return;
                    }
                    idxDataViewer = i;
                } else if ("Form Manager".compareToIgnoreCase(heading) == 0) {
                    if (idxFormManager != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Form Manager' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Form Manager' is repeated");
                        return;
                    }
                    idxFormManager = i;
                } else if ("Synchronize Tables".compareToIgnoreCase(heading) == 0) {
                    if (idxSyncTables != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Synchronize Tables' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Synchronize Tables' is repeated");
                        return;
                    }
                    idxSyncTables = i;
                } else if ("Tables Super-user".compareToIgnoreCase(heading) == 0) {
                    if (idxTablesSU != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Tables Super-user' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Tables Super-user' is repeated");
                        return;
                    }
                    idxTablesSU = i;
                } else if ("Administer Tables".compareToIgnoreCase(heading) == 0) {
                    if (idxTablesAdmin != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Administer Tables' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Administer Tables' is repeated");
                        return;
                    }
                    idxTablesAdmin = i;
                } else if ("Site Administrator".compareToIgnoreCase(heading) == 0) {
                    if (idxSiteAdmin != -1) {
                        logger.error(
                                "users and capabilities .csv upload - invalid csv file -- column header 'Site Administrator' is repeated");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- column header 'Site Administrator' is repeated");
                        return;
                    }
                    idxSiteAdmin = i;
                } else {
                    logger.warn("users and capabilities .csv upload - invalid csv file -- column header '"
                            + heading + "' is not recognized");
                    warnings.append("<tr><td>Column header '" + heading
                            + "' is not recognized and will be ignored.</tr></td>");
                }
            }

            if (idxUsername == -1) {
                logger.error("users and capabilities .csv upload - invalid csv file");
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                        + "\nusers and capabilities invalid .csv -- column header 'Username' is missing");
                return;
            }
            if (idxUserType == -1) {
                logger.error("users and capabilities .csv upload - invalid csv file");
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                        + "\nusers and capabilities invalid .csv -- column header 'Account Type' is missing");
                return;
            }

            while ((columns = csvReader.readNext()) != null) {
                ++row;

                // empty -- silently skip
                if (columns.length == 0)
                    continue;

                // count non-blank columns
                int nonBlankColCount = 0;
                for (String col : columns) {
                    if (col != null && col.trim().length() != 0) {
                        ++nonBlankColCount;
                    }

                }

                // all blank-- silently skip
                if (nonBlankColCount == 0)
                    continue;

                // ignore rows where...
                // the row is not long enough to include the Username and Account Type columns
                if (columns.length <= idxUsername || columns.length <= idxUserType) {
                    warnings.append("<tr><td>Ignoring row " + row
                            + " -- does not specify a Username and/or Account Type.</tr></td>");
                    continue;
                }

                // ignore rows where...
                // Username is not specified or it is not the anonymousUser and Account Type is blank
                if ((columns[idxUsername] == null || columns[idxUsername].trim().length() == 0)
                        || (!columns[idxUsername].equals(User.ANONYMOUS_USER) && (columns[idxUserType] == null
                                || columns[idxUserType].trim().length() == 0))) {
                    warnings.append("<tr><td>Ignoring row " + row + " -- Username is not the "
                            + User.ANONYMOUS_USER + " and no Account Type specified.</tr></td>");
                    continue;
                }

                String accType = (idxUserType == -1) ? "ODK" : columns[idxUserType];
                UserType type = (accType == null) ? UserType.ANONYMOUS : UserType.REGISTERED;

                if ((type != UserType.ANONYMOUS) && (columns[idxUsername] == null)) {
                    logger.error("users and capabilities .csv upload - invalid csv file");
                    resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                            + "\nusers and capabilities invalid .csv -- username not specified");
                    return;
                }

                String username;
                String email;
                String fullname = (idxFullName == -1 || columns.length < idxFullName) ? null
                        : columns[idxFullName];

                if (accType == null) {
                    username = User.ANONYMOUS_USER;
                    email = null;
                    fullname = User.ANONYMOUS_USER_NICKNAME;
                } else if ("ODK".equals(accType)) {

                    Collection<Email> emails = EmailParser.parseEmails(columns[idxUsername]);
                    if (emails.size() != 1) {
                        logger.error("users and capabilities .csv upload - invalid csv file");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- username \'" + columns[idxUsername]
                                + "\' contains illegal characters (e.g., spaces)");
                        return;
                    }
                    email = null;
                    Email parsedValue = emails.iterator().next();
                    if (parsedValue.getType() == Form.EMAIL) {
                        username = parsedValue.getEmail().substring(EmailParser.K_MAILTO.length());
                    } else {
                        username = parsedValue.getUsername();
                    }
                    if (fullname == null) {
                        fullname = parsedValue.getFullName();
                    }
                } else if ("Google".equals(accType)) {
                    username = null;
                    Collection<Email> emails = EmailParser.parseEmails(columns[idxUsername]);

                    if (emails == null || emails.size() == 0) {
                        logger.error("users and capabilities .csv upload - invalid csv file");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
                                ErrorConsts.MISSING_PARAMS
                                        + "\nusers and capabilities invalid .csv -- username \'"
                                        + columns[idxUsername] + "\' could not be parsed into valid e-mail");
                        return;
                    }

                    if (emails.size() != 1) {
                        logger.error("users and capabilities .csv upload - invalid csv file");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
                                ErrorConsts.MISSING_PARAMS
                                        + "\nusers and capabilities invalid .csv -- username \'"
                                        + columns[idxUsername] + "\' could not be parsed into a valid e-mail");
                        return;
                    }

                    // will execute loop once
                    email = null;
                    for (Email e : emails) {
                        if (e.getType() != Email.Form.EMAIL) {
                            logger.error("users and capabilities .csv upload - invalid csv file");
                            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                    + "\nusers and capabilities invalid .csv -- username \'"
                                    + columns[idxUsername] + "\' could not be parsed into a valid e-mail");
                            return;
                        }
                        email = e.getEmail();
                        if (fullname == null) {
                            fullname = e.getFullName();
                        }
                    }
                } else {
                    logger.error("users and capabilities .csv upload - invalid csv file");
                    resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
                            ErrorConsts.MISSING_PARAMS
                                    + "\nusers and capabilities invalid .csv -- Account Type \'" + accType
                                    + "\' is neither 'ODK' nor 'Google' nor blank (anonymous)");
                    return;
                }
                UserSecurityInfo info = new UserSecurityInfo(username, fullname, email, type);
                // now add permissions
                TreeSet<GrantedAuthorityName> authorities = new TreeSet<GrantedAuthorityName>();

                if (idxDataCollector != -1 && columns.length > idxDataCollector
                        && columns[idxDataCollector] != null
                        && columns[idxDataCollector].trim().length() != 0) {
                    authorities.add(GrantedAuthorityName.GROUP_DATA_COLLECTORS);
                }
                if (idxDataViewer != -1 && columns.length > idxDataViewer && columns[idxDataViewer] != null
                        && columns[idxDataViewer].trim().length() != 0) {
                    authorities.add(GrantedAuthorityName.GROUP_DATA_VIEWERS);
                }
                if (idxFormManager != -1 && columns.length > idxFormManager && columns[idxFormManager] != null
                        && columns[idxFormManager].trim().length() != 0) {
                    authorities.add(GrantedAuthorityName.GROUP_FORM_MANAGERS);
                }
                if (idxSyncTables != -1 && columns.length > idxSyncTables && columns[idxSyncTables] != null
                        && columns[idxSyncTables].trim().length() != 0) {
                    authorities.add(GrantedAuthorityName.GROUP_SYNCHRONIZE_TABLES);
                }
                if (idxTablesSU != -1 && columns.length > idxTablesSU && columns[idxTablesSU] != null
                        && columns[idxTablesSU].trim().length() != 0) {
                    authorities.add(GrantedAuthorityName.GROUP_SUPER_USER_TABLES);
                }
                if (idxTablesAdmin != -1 && columns.length > idxTablesAdmin && columns[idxTablesAdmin] != null
                        && columns[idxTablesAdmin].trim().length() != 0) {
                    authorities.add(GrantedAuthorityName.GROUP_ADMINISTER_TABLES);
                }
                if (idxSiteAdmin != -1 && columns.length > idxSiteAdmin && columns[idxSiteAdmin] != null
                        && columns[idxSiteAdmin].trim().length() != 0) {
                    authorities.add(GrantedAuthorityName.GROUP_SITE_ADMINS);
                }

                info.setAssignedUserGroups(authorities);
                users.add(info);
            }

            // allGroups is empty. This is currently not used.
            ArrayList<GrantedAuthorityName> allGroups = new ArrayList<GrantedAuthorityName>();

            // now scan for duplicate entries for the same username
            {
                HashMap<String, HashSet<UserSecurityInfo>> multipleRows = new HashMap<String, HashSet<UserSecurityInfo>>();
                for (UserSecurityInfo i : users) {
                    if (i.getType() != UserType.REGISTERED) {
                        continue;
                    }
                    if (i.getUsername() != null) {
                        HashSet<UserSecurityInfo> existing;
                        existing = multipleRows.get(i.getUsername());
                        if (existing == null) {
                            existing = new HashSet<UserSecurityInfo>();
                            multipleRows.put(i.getUsername(), existing);
                        }
                        existing.add(i);
                    }
                }
                for (Entry<String, HashSet<UserSecurityInfo>> entry : multipleRows.entrySet()) {
                    if (entry.getValue().size() != 1) {
                        logger.error("users and capabilities .csv upload - invalid csv file");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
                                ErrorConsts.MISSING_PARAMS + "\nusers and capabilities invalid .csv -- "
                                        + "multiple rows define the capabilities for the same username: "
                                        + entry.getKey());
                        return;
                    }
                }
            }

            // and scan for duplicate entries for the same e-mail address
            {
                HashMap<String, HashSet<UserSecurityInfo>> multipleRows = new HashMap<String, HashSet<UserSecurityInfo>>();
                for (UserSecurityInfo i : users) {
                    if (i.getType() != UserType.REGISTERED) {
                        continue;
                    }
                    if (i.getEmail() != null) {
                        HashSet<UserSecurityInfo> existing;
                        existing = multipleRows.get(i.getEmail());
                        if (existing == null) {
                            existing = new HashSet<UserSecurityInfo>();
                            multipleRows.put(i.getEmail(), existing);
                        }
                        existing.add(i);
                    }
                }
                for (Entry<String, HashSet<UserSecurityInfo>> entry : multipleRows.entrySet()) {
                    if (entry.getValue().size() != 1) {
                        logger.error("users and capabilities .csv upload - invalid csv file");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
                                ErrorConsts.MISSING_PARAMS + "\nusers and capabilities invalid .csv -- "
                                        + "multiple rows define the capabilities for the same e-mail: "
                                        + entry.getKey().substring(EmailParser.K_MAILTO.length()));
                        return;
                    }
                }
            }

            // now scan for the anonymousUser
            UserSecurityInfo anonUser = null;
            for (UserSecurityInfo i : users) {
                if (i.getType() == UserType.ANONYMOUS) {
                    if (anonUser != null) {
                        logger.error("users and capabilities .csv upload - invalid csv file");
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.MISSING_PARAMS
                                + "\nusers and capabilities invalid .csv -- "
                                + "multiple rows define the capabilities for the anonymousUser - did you forget to specify Account Type?");
                        return;
                    }
                    anonUser = i;
                }
            }

            // and figure out whether the anonymousUser currently has ROLE_ATTACHMENT_VIEWER capabilities
            // (these allow Google Earth to access the server). 
            //
            // If it does, preserve that capability.
            // To do this, fetch the existing info for anonymous...
            UserSecurityInfo anonExisting = new UserSecurityInfo(User.ANONYMOUS_USER,
                    User.ANONYMOUS_USER_NICKNAME, null, UserSecurityInfo.UserType.ANONYMOUS);
            SecurityServiceUtil.setAuthenticationListsForSpecialUser(anonExisting,
                    GrantedAuthorityName.USER_IS_ANONYMOUS, cc);
            // test if the existing anonymous had the capability
            if (anonExisting.getAssignedUserGroups().contains(GrantedAuthorityName.ROLE_ATTACHMENT_VIEWER)) {
                if (anonUser == null) {
                    // no anonUser specified in the incoming .csv -- add it with just that capability.
                    TreeSet<GrantedAuthorityName> auths = new TreeSet<GrantedAuthorityName>();
                    auths.add(GrantedAuthorityName.ROLE_ATTACHMENT_VIEWER);
                    anonExisting.setAssignedUserGroups(auths);
                    users.add(anonExisting);
                } else {
                    // add this capability to the existing set of capabilities
                    anonUser.getAssignedUserGroups().add(GrantedAuthorityName.ROLE_ATTACHMENT_VIEWER);
                }
            }

            SecurityServiceUtil.setStandardSiteAccessConfiguration(users, allGroups, cc);

            // GAE requires some settle time before these entries will be
            // accurately retrieved. Do not re-fetch the form after it has been
            // uploaded.
            resp.setStatus(HttpServletResponse.SC_OK);
            if (openRosaVersion == null) {
                // web page -- show HTML response
                resp.setContentType(HtmlConsts.RESP_TYPE_HTML);
                resp.setCharacterEncoding(HtmlConsts.UTF8_ENCODE);
                PrintWriter out = resp.getWriter();

                StringBuilder headerString = new StringBuilder();
                headerString.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
                headerString.append(cc.getWebApplicationURL(ServletConsts.AGGREGATE_STYLE));
                headerString.append("\" />");
                headerString.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
                headerString.append(cc.getWebApplicationURL(ServletConsts.UPLOAD_BUTTON_STYLE_RESOURCE));
                headerString.append("\" />");
                headerString.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
                headerString.append(cc.getWebApplicationURL(ServletConsts.UPLOAD_TABLE_STYLE_RESOURCE));
                headerString.append("\" />");
                headerString.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
                headerString.append(cc.getWebApplicationURL(ServletConsts.UPLOAD_NAVIGATION_STYLE_RESOURCE));
                headerString.append("\" />");

                // header info
                beginBasicHtmlResponse(TITLE_INFO, headerString.toString(), resp, cc);
                if (warnings.length() != 0) {
                    out.write("<p>users and capabilities .csv uploaded with warnings.</p>" + "<table>");
                    out.write(warnings.toString());
                    out.write("</table>");
                } else {
                    out.write("<p>Successful users and capabilities .csv upload.</p>");
                }
                out.write("<p>Click ");

                out.write(HtmlUtil.createHref(cc.getWebApplicationURL(ADDR), "here", false));
                out.write(" to return to Upload users and capabilities .csv page.</p>");
                finishBasicHtmlResponse(resp);
            } else {
                addOpenRosaHeaders(resp);
                resp.setContentType(HtmlConsts.RESP_TYPE_XML);
                resp.setCharacterEncoding(HtmlConsts.UTF8_ENCODE);
                PrintWriter out = resp.getWriter();
                out.write("<OpenRosaResponse xmlns=\"http://openrosa.org/http/response\">");
                if (warnings.length() != 0) {
                    StringBuilder b = new StringBuilder();
                    b.append("<p>users and capabilities .csv uploaded with warnings.</p>" + "<table>");
                    b.append(warnings.toString());
                    b.append("</table>");
                    out.write("<message>");
                    out.write(StringEscapeUtils.escapeXml10(b.toString()));
                    out.write("</message>");
                } else {
                    out.write("<message>Successful users and capabilities .csv upload.</message>");
                }
                out.write("</OpenRosaResponse>");
            }

        } catch (DatastoreFailureException e) {
            logger.error("users and capabilities .csv upload persistence error: " + e.toString());
            e.printStackTrace();
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    ErrorConsts.PERSISTENCE_LAYER_PROBLEM + "\n" + e.toString());
        } catch (AccessDeniedException e) {
            logger.error("users and capabilities .csv upload access denied error: " + e.toString());
            e.printStackTrace();
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
        } finally {
            if (csvReader != null) {
                csvReader.close();
            }
            if (csvContentReader != null) {
                csvContentReader.close();
            }
        }

    } catch (FileUploadException e) {
        logger.error("users and capabilities .csv upload persistence error: " + e.toString());
        e.printStackTrace(resp.getWriter());
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ErrorConsts.UPLOAD_PROBLEM);
    }
}

From source file:org.opendatakit.aggregate.servlet.SubmissionServlet.java

/**
 * Handler for HTTP post request that processes a form submission Currently
 * supports plain/xml and multipart//from w  w w .ja  v a 2s  .  c  o  m
 *
 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
 *      javax.servlet.http.HttpServletResponse)
 */
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    CallingContext cc = ContextFactory.getCallingContext(this, req);

    Double openRosaVersion = getOpenRosaVersion(req);
    boolean isIncomplete = false;
    try {
        SubmissionParser submissionParser = null;
        if (ServletFileUpload.isMultipartContent(req)) {
            MultiPartFormData uploadedSubmissionItems = new MultiPartFormData(req);
            String isIncompleteFlag = uploadedSubmissionItems
                    .getSimpleFormField(ServletConsts.TRANSFER_IS_INCOMPLETE);
            isIncomplete = (isIncompleteFlag != null && isIncompleteFlag.compareToIgnoreCase("YES") == 0);
            submissionParser = new SubmissionParser(uploadedSubmissionItems, isIncomplete, cc);
        } else {
            // TODO: check that it is the proper types we can deal with
            // XML received, we hope...
            submissionParser = new SubmissionParser(req.getInputStream(), cc);
        }

        IForm form = submissionParser.getForm();

        // Only trigger uploads if this submission was not already
        // marked as complete before this interaction and if it is
        // now complete. AND...
        // Issue a publish request only if we haven't issued one recently.
        // use BackendActionsTable to mediate that decision.
        // This test ONLY OCCURS during submissions, not during Watchdog
        // firings, so we don't have to worry about bugs here affecting Watchdog.
        if (!submissionParser.wasPreexistingComplete() && submissionParser.getSubmission().isComplete()
                && BackendActionsTable.triggerPublisher(form.getUri(), cc)) {
            // send information to remote servers that need to be notified
            List<ExternalService> tmp = FormServiceCursor.getExternalServicesForForm(form, cc);
            UploadSubmissions uploadTask = (UploadSubmissions) cc.getBean(BeanDefs.UPLOAD_TASK_BEAN);

            // publication failures should not fail the submission...
            try {
                CallingContext ccDaemon = ContextFactory.getCallingContext(this, req);
                ccDaemon.setAsDaemon(true);
                for (ExternalService rs : tmp) {
                    // only create upload tasks for active publishers
                    if (rs.getFormServiceCursor().getOperationalStatus() == OperationalStatus.ACTIVE) {
                        uploadTask.createFormUploadTask(rs.getFormServiceCursor(), false, ccDaemon);
                    }
                }
            } catch (ODKExternalServiceException e) {
                logger.info("Publishing enqueue failure (this is recoverable) - " + e.getMessage());
                e.printStackTrace();
            }
        }

        // form full url including scheme...
        String serverUrl = cc.getServerURL();
        String url = serverUrl + BasicConsts.FORWARDSLASH + ADDR;
        resp.setHeader("Location", url);

        resp.setStatus(HttpServletResponse.SC_CREATED);
        if (openRosaVersion == null) {
            logger.info("Successful non-OpenRosa submission");

            resp.setContentType(HtmlConsts.RESP_TYPE_HTML);
            resp.setCharacterEncoding(HtmlConsts.UTF8_ENCODE);
            PrintWriter out = resp.getWriter();
            out.write(HtmlConsts.HTML_OPEN);
            out.write(HtmlConsts.BODY_OPEN);
            out.write("Successful submission upload.  Click ");
            out.write(HtmlUtil.createHref(cc.getWebApplicationURL(ADDR), "here", false));
            out.write(" to return to upload submissions page.");
            out.write(HtmlConsts.BODY_CLOSE);
            out.write(HtmlConsts.HTML_CLOSE);
        } else {
            logger.info("Successful OpenRosa submission");

            addOpenRosaHeaders(resp);
            resp.setContentType(HtmlConsts.RESP_TYPE_XML);
            resp.setCharacterEncoding(HtmlConsts.UTF8_ENCODE);
            PrintWriter out = resp.getWriter();
            out.write("<OpenRosaResponse xmlns=\"http://openrosa.org/http/response\">");
            if (isIncomplete) {
                out.write("<message>partial submission upload was successful!</message>");
            } else {
                out.write("<message>full submission upload was successful!</message>");
            }

            // for Briefcase2, use the attributes on a <submissionMetadata> tag to
            // update the local copy of the data (if these attributes are
            // available).
            {
                XmlAttributeFormatter attributeFormatter = new XmlAttributeFormatter();
                Submission sub = submissionParser.getSubmission();
                Row attributeRow = new Row(sub.constructSubmissionKey(null));
                //
                // add what could be considered the form's metadata...
                //
                attributeRow.addFormattedValue("id=\""
                        + StringEscapeUtils.escapeXml10(form.getFormId()
                                .replace(ParserConsts.FORWARD_SLASH_SUBSTITUTION, ParserConsts.FORWARD_SLASH))
                        + "\"");
                if (form.isEncryptedForm()) {
                    attributeRow.addFormattedValue("encrypted=\"yes\"");
                }
                sub.getFormattedNamespaceValuesForRow(attributeRow,
                        Collections.singletonList(FormElementNamespace.METADATA), attributeFormatter, false,
                        cc);

                out.write("<submissionMetadata xmlns=\""
                        + StringEscapeUtils.escapeXml10(ParserConsts.NAMESPACE_ODK) + "\"");
                Iterator<String> itrAttributes = attributeRow.getFormattedValues().iterator();
                while (itrAttributes.hasNext()) {
                    out.write(" ");
                    out.write(itrAttributes.next());
                }
                out.write("/>");
            }
            out.write("</OpenRosaResponse>");
        }
    } catch (ODKFormNotFoundException e) {
        e.printStackTrace();
        logger.warn("Form not found - " + e.getMessage());
        odkIdNotFoundError(resp);
    } catch (ODKParseException e) {
        logger.warn("Parsing failure - " + e.getMessage());
        e.printStackTrace();
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.PARSING_PROBLEM);
    } catch (ODKEntityPersistException e) {
        logger.error("Persist failure - " + e.getMessage());
        e.printStackTrace();
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ErrorConsts.PARSING_PROBLEM);
    } catch (ODKIncompleteSubmissionData e) {
        logger.warn("Incomplete submission failure - " + e.getMessage());
        e.printStackTrace();
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.PARSING_PROBLEM);
    } catch (ODKConversionException e) {
        logger.warn("Datatype casting failure - " + e.getMessage());
        e.printStackTrace();
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.PARSING_PROBLEM);
    } catch (ODKDatastoreException e) {
        logger.error("Datastore failure - " + e.getMessage());
        e.printStackTrace();
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ErrorConsts.PARSING_PROBLEM);
    } catch (FileUploadException e) {
        logger.warn("Attachments parsing failure - " + e.getMessage());
        e.printStackTrace();
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.PARSING_PROBLEM);
    } catch (ODKFormSubmissionsDisabledException e) {
        logger.warn("Form submission disabled - " + e.getMessage());
        e.printStackTrace();
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorConsts.FORM_DOES_NOT_ALLOW_SUBMISSIONS);
    } catch (Exception e) {
        logger.error("Unexpected exception: " + e.getMessage());
        e.printStackTrace();
        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unexpected exception");
    }
}

From source file:org.openestate.io.openimmo.OpenImmoFeedbackDocumentTest.java

private static Document buildExampleDocument(String version) throws Exception {
    String xmlns = ("1.2.0".equals(version) || "1.1".equals(version))
            ? " xmlns=\"" + OpenImmoUtils.OLD_NAMESPACE + "\""
            : StringUtils.EMPTY;//  w  ww.ja  v  a2s. com

    OpenImmoVersion v = OpenImmoVersion.detectFromString(version);
    if (OpenImmoVersion.V1_2_4.isNewerThen(v)) {
        return XmlUtils.newDocument("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
                + "<openimmo_feedback" + xmlns + ">\n" + "</openimmo_feedback>");
    } else {
        return XmlUtils.newDocument("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
                + "<openimmo_feedback" + xmlns + ">\n" + "  <version>" + StringEscapeUtils.escapeXml10(version)
                + "</version>\n" + "</openimmo_feedback>");
    }
}